简体   繁体   中英

GameObject can rotate around Y and Z but not X

I'm new with Unity development and I'm having some issues rotating GameObjects.

I want to make and object rotate -90 degrees each time you call a function. 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º.
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.

Why do you bother to go through the eulerAngles at all?

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. Instead, the X, Y & Z values are converted to the Quaternion 's internal format.

When you read the .eulerAngles property, Unity converts the Quaternion 's internal representation of the rotation to Euler angles. 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 .

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. For better ways to achieve this, see the Quaternion * operator .

Rather directly use 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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM