简体   繁体   English

GameObject 可以绕 Y 和 Z 旋转,但不能绕 X

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

I'm new with Unity development and I'm having some issues rotating GameObjects.我是 Unity 开发的新手,我在旋转游戏对象时遇到了一些问题。

I want to make and object rotate -90 degrees each time you call a function.每次调用 function 时,我都想让 object 旋转 -90 度。 At this moment I can make it rotate around its Y and Z axis and there's no trouble, however, if i change the parameters so it rotates around X it gets stuck after rotating from -90º (270º actually) to 180º.此时我可以让它围绕它的 Y 和 Z 轴旋转并且没有问题,但是,如果我改变参数让它围绕 X 旋转,它在从 -90º(实际上是 270º)旋转到 180º 后会卡住。
Here's the code I'm using for testing:这是我用于测试的代码:

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;
    }
}

I'm updating all the coordinates in Quaternion.Euler in each iteration because I want the user to be able drag the object while it's rotating, but I wouldn't mind if the solution requires to define the Quaternion before the loop.我在每次迭代中更新 Quaternion.Euler 中的所有坐标,因为我希望用户能够在 object 旋转时拖动它,但我不介意解决方案是否需要在循环之前定义四元数。

Why do you bother to go through the eulerAngles at all?你为什么要通过eulerAngles来打扰 go 呢?

When using the .eulerAngles property to set a rotation, it is important to understand that although you are providing X, Y, and Z rotation values to describe your rotation, those values are not stored in the rotation.使用.eulerAngles属性设置旋转时,请务必了解,尽管您提供 X、Y 和 Z 旋转值来描述旋转,但这些值不会存储在旋转中。 Instead, the X, Y & Z values are converted to the Quaternion 's internal format.相反,X、Y 和 Z 值被转换为Quaternion的内部格式。

When you read the .eulerAngles property, Unity converts the Quaternion 's internal representation of the rotation to Euler angles.当您阅读.eulerAngles属性时,Unity 会将Quaternion的内部旋转表示转换为欧拉角。 Because, there is more than one way to represent any given rotation using Euler angles, the values you read back out may be quite different from the values you assigned.因为,使用欧拉角表示任何给定旋转的方法不止一种,因此您读出的值可能与您分配的值完全不同。 This can cause confusion if you are trying to gradually increment the values to produce animation .如果您尝试逐渐增加值以生成 animation ,这可能会导致混淆

To avoid these kinds of problems, the recommended way to work with rotations is to avoid relying on consistent results when reading .eulerAngles particularly when attempting to gradually increment a rotation to produce animation.为避免此类问题,推荐使用旋转的方法是在读取.eulerAngles时避免依赖一致的结果,尤其是在尝试逐渐增加旋转以产生 animation 时。 For better ways to achieve this, see the Quaternion * operator .有关实现此目的的更好方法,请参阅四元数 * 运算符

Rather directly use Quaternion !而是直接使用Quaternion Simply add the desired rotation to the exsting one using the * operator只需使用*运算符将所需的旋转添加到现有的旋转

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