繁体   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