簡體   English   中英

GameObject 可以繞 Y 和 Z 旋轉,但不能繞 X

[英]GameObject can rotate around Y and Z but not X

我是 Unity 開發的新手,我在旋轉游戲對象時遇到了一些問題。

每次調用 function 時,我都想讓 object 旋轉 -90 度。 此時我可以讓它圍繞它的 Y 和 Z 軸旋轉並且沒有問題,但是,如果我改變參數讓它圍繞 X 旋轉,它在從 -90º(實際上是 270º)旋轉到 180º 后會卡住。
這是我用於測試的代碼:

public class RotateCube : MonoBehaviour
{
    GameObject cube;
    bool rotating;

    private void Start()
    {
        cube = GameObject.Find("Cube");
        rotating = false;
    }

    private void Update()
    {
        if (!rotating)
        {
            StartCoroutine(Rotate());
        }
    }

    private IEnumerator Rotate()
    {
        rotating = true;
        float finalAngle = SubstractNinety(cube.transform.eulerAngles.x);
        while (cube.transform.rotation.eulerAngles.x != finalAngle)
        {
            cube.transform.rotation = Quaternion.RotateTowards(cube.transform.rotation, Quaternion.Euler(finalAngle, cube.transform.rotation.eulerAngles.y, cube.transform.rotation.eulerAngles.z), 100f * Time.deltaTime);
            yield return null;
        }
        cube.transform.rotation = Quaternion.Euler(finalAngle, cube.transform.rotation.eulerAngles.y, cube.transform.rotation.eulerAngles.z);
        yield return null;
        rotating = false;
    }

    private float SubstractNinety(float angle)
    {
        if (angle < 90)
        {
            return 270f;
        }

        return angle - 90;
    }
}

我在每次迭代中更新 Quaternion.Euler 中的所有坐標,因為我希望用戶能夠在 object 旋轉時拖動它,但我不介意解決方案是否需要在循環之前定義四元數。

你為什么要通過eulerAngles來打擾 go 呢?

使用.eulerAngles屬性設置旋轉時,請務必了解,盡管您提供 X、Y 和 Z 旋轉值來描述旋轉,但這些值不會存儲在旋轉中。 相反,X、Y 和 Z 值被轉換為Quaternion的內部格式。

當您閱讀.eulerAngles屬性時,Unity 會將Quaternion的內部旋轉表示轉換為歐拉角。 因為,使用歐拉角表示任何給定旋轉的方法不止一種,因此您讀出的值可能與您分配的值完全不同。 如果您嘗試逐漸增加值以生成 animation ,這可能會導致混淆

為避免此類問題,推薦使用旋轉的方法是在讀取.eulerAngles時避免依賴一致的結果,尤其是在嘗試逐漸增加旋轉以產生 animation 時。 有關實現此目的的更好方法,請參閱四元數 * 運算符

而是直接使用Quaternion 只需使用*運算符將所需的旋轉添加到現有的旋轉

private IEnumerator Rotate()
{
    rotating = true;
    // This returns a new Quaternion rotation which is the original
    // rotation and then rotated about -90° on the global X axis
    var finalRotation = currentRotation * Quaternion.Euler(-90, 0, 0);

    // simply directly use Quaternion comparison
    while (cube.transform.rotation != finalRotation)
    {
        cube.transform.rotation = Quaternion.RotateTowards(cube.transform.rotation, finalRotation, 100f * Time.deltaTime);
        yield return null;
    }

    cube.transform.rotation = finalRotation;

    rotating = false;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM