2011-12-10 169 views
6

我的問題是我想旋轉一個氣缸9次。 360/9是40,所以我所需要做的就是旋轉40度9次。然而,這並不起作用,因爲當我第一次旋轉圓柱體而不是40度時,它旋轉了39.99度。這也發生在其他旋轉。旋轉的對象統一旋轉的值不正確

我正在旋轉這樣做。

if(Input.GetKeyUp("i")) 
     transform.GetChild(m_Section).Rotate(0,40.0f,0); 

我有統一版本3.4它不是專業版,我在C#編碼。

任何幫助表示讚賞,因爲我剛開始嘗試學習團結。

回答

1

Unity3D將旋轉存儲在一個非常抽象的數學表示中,稱爲quaternion。從歐拉角到歐拉角的轉換(你在Unity編輯器中看到的)涉及三角函數的級聯,因此容易出現舍入誤差,尤其是對於簡單的浮點類型。

爲了解決您的問題,我建議在開始旋轉之前存儲初始Quaternion對象,並在流程結束時將其設置。一些僞代碼:

public class RotationController : MonoBehaviour { 
    Quaternion rotationAtStart; 
    int numOfRotations = 0; 

    void rotate() { 
     numOfRotations++; 
     if (numOfRotations == 1) { 
      rotationAtStart = transform.rotation; 
     } else if (numOfRotations < 9) { 
      transform.Rotate (new Vector3 (0,40.0f,0)); 
     } else if (numOfRotations == 9) { 
      transform.rotation = rotationAtStart; 
     } 
    } 
    void Update() { 
     if (numOfRotations < 9) { 
      rotate(); 
     } 
    } 
} 

360°的特殊情況使此方法穩定。對於小於360°,你必須忍受小的舍入誤差。對於這種情況,我會建議計算目標四元數Quaternion.RotateTowards並將其設置爲與360案例類似的最後一步。

另一個有用的東西是你Animations。您可以將動畫定義爲平滑或離散步驟,如果按「i」,則只需撥打GameObject.animation.Play("MyRotation")即可。動畫終止時,最後使用動畫事件通知。

最後Mathf包含一個處理浮點不精確問題的函數Approximately

+0

如果我曾經喜歡你的建議將是改變對象的本地軸,或者將它只能旋轉對象的動畫? – Dave

+0

您可以爲遊戲對象的變換的成員設置動畫。 transform.rotation在歐拉角 – Kay

+0

感謝您的幫助。儘管如此,它更像是一種側重解決問題的方式。我不能說如果(transform.eulerAngles.y == 40.0f),因爲即使旋轉朝向給出更準確的結果仍然存在錯誤。我還沒有嘗試過這個動畫建議,但是我現在就去試試看。 – Dave

0

看看Kungfoomanin this post的答案,他描述了90度或90度以及270度旋轉的問題。他提供了一個擴展,它將始終爲您想要設置的值計算Quaternion的正確掛件。看看這裏:

using UnityEngine; 
using System.Collections; 

public class ExtensionVector3 : MonoBehaviour { 

    public static float CalculateEulerSafeX(float x){ 
     if(x > -90 && x <= 90){ 
      return x; 
     } 

     if(x > 0){ 
      x -= 180; 
     } else { 
      x += 180; 
     } 
     return x; 
    } 

    public static Vector3 EulerSafeX(Vector3 eulerAngles){ 
     eulerAngles.x = CalculateEulerSafeX(eulerAngles.x); 
     return eulerAngles; 
    } 
} 

我用它像這樣:

Quaternion newQuat = m_directionalLight.transform.rotation; 
Vector3 nL = new Vector3(ExtensionVector3.CalculateEulerSafeX(xNewValueLight), 
         0, 
         0); 
newQuat.eulerAngles = nL; 

m_directionalLight.transform.rotation = 
    Quaternion.Lerp(m_directionalLight.transform.rotation, 
        newQuat, 
        Time.deltaTime);