简体   繁体   中英

Unity, Quaternion.Euler, rotate only around Y axis

I have my main camera in the scene:

我的照相机

And I have this code that smoothly rotates the camera:

private IEnumerator SmoothlyRotateCamera()
{
    float duration = 0.3f;
    Quaternion from = transform.rotation;
    Quaternion to = from * Vector3.up * 180f;

    float elapsed = 0.0f;

    while (elapsed < duration)
    {
        transform.rotation = Quaternion.Slerp(from, to, elapsed / duration);
        elapsed += Time.deltaTime;
        yield return null;
    }

    transform.rotation = to;

    isRotating = false;

    yield return null;
}

Currently, my camera's rotation is [30, -60, 0] and I want it to rotate around Y axis by 180 degrees.

In theory, to achieve that I need to rotate it for Vector3.up * 180f , everything sound fine, except the fact, when I rotate it that way, it also rotates all other axes as well.

If I rotate it by new Vector3(180f, 0f, 0f) - only X axis will be affected.

If I rotate it by new Vector3(0f, 0f, 180f) - only Z axis will be affected.

And if I rotate it by new Vector3(0f, 180f, 0f) - all of the axis will rotate as well.

I've checked the rotation by setting my X rotation to 0, so now my camera's rotation is [0, -60, 0] and if I rotate it the way it intended to be, by Vector3.up * 180f , then everything works fine! BUT, I need my camera's X to stay in the place. Eg, rotation in the Editor itself only by Y gives me the result that I want.

What should I do? How do I rotate it by 180 degrees by Y axis only?

PS I know about transform.Rotate but in my case I need to rotate it using the way that I have described here.

Thanks!

Rather use transform.Rotate

private IEnumerator SmoothlyRotateCamera()
{
    var duration = 0.3f;

    // in angles per second
    var rotationSpeed = 180f / duration;

    float rotated = 0;

    do
    {
        var angle = Mathf.Min(180.0f - rotated, rotationSpeed * Time.deltaTime);
        var rotation = Vector3.up * angle;

        rotated += angle;

        // depends which Y axis you want to rotate around here
        // pass Space.World to rotate around the global Y axis instead of the local one
        // if left out it rotates around its transform.up vector instead
        transform.Rotate(rotation, Space.World);

        yield return null;
    } while (rotated < 180f);

    isRotating = false;

    // your last yield return is redundant
}

I added the Mathf.Min to make sure there is no overshooting. As you can see it lands exactly on 180° and is smooth in time (you don't need necessarily Lerp for that only use Time.deltaTime ).

In order to show the effect I only changed the duration to 3 instead of 0.3 (which is to fast to notice it).

Rotating around global Y using transform.Rotate(rotation, Space.World);

在此处输入图片说明

Rotating around local Y using transform.Rotate(rotation);

在此处输入图片说明

You can try with Euler Angles.

transform.eulerAngles = new Vector3(transform.eulerAngles.x, transform.eulerAngles.y + 180, transform.eulerAngles.);

Your code will become:

private IEnumerator SmoothlyRotateCamera()
{
    float duration = 0.3f;
    Vector3 from = transform.eulerAngles;
    Vector3 to = new Vector3(transform.eulerAngles.x, transform.eulerAngles.y +180, transform.eulerAngles.z);

    float elapsed = 0.0f;

    while (elapsed < duration)
    {
        transform.eulerAngles =  Vector3.Slerp(from, to, elapsed / duration);
        elapsed += Time.deltaTime;
        yield return null;
    }

    transform.eulerAngles = to;

    isRotating = false;

    yield return null;
}

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