Unity, Quaternion.Euler, вращается только вокруг оси Y - PullRequest
0 голосов
/ 17 мая 2019

У меня есть основная камера в сцене:

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

В настоящее время моя камера поворачивается на [30, -60, 0], и я хочу, чтобы она вращалась вокруг оси Y на 180 градусов.

Теоретически, чтобы добиться этого, мне нужно повернуть его на Vector3.up * 180f, все звучит нормально, кроме того факта, что когда я поворачиваю его таким образом, он также вращает и все другие оси.

Если я поверну его на new Vector3(180f, 0f, 0f) - будет затронута только ось X.

Если я поверну его на new Vector3(0f, 0f, 180f) - это повлияет только на ось Z.

И если я поверну его на new Vector3(0f, 180f, 0f) - все оси тоже будут вращаться.

Я проверил вращение, установив вращение X на 0, так что теперь вращение моей камеры равно [0, -60, 0], и если я поверну его так, как предполагалось, к Vector3.up * 180f, то все будет отлично! НО, мне нужен X моей камеры, чтобы оставаться на месте. Например, поворот в самом редакторе только на Y дает мне желаемый результат.

Что мне делать? Как мне повернуть его на 180 градусов только по оси Y?

P.S. Я знаю о transform.Rotate, но в моем случае мне нужно повернуть его так, как я описал здесь.

Спасибо!

Ответы [ 2 ]

2 голосов
/ 17 мая 2019

Скорее используйте 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
}

Я добавил Mathf.Min, чтобы убедиться в отсутствии перерегулирования.Как вы можете видеть, он приземляется точно на 180 °, а является гладким по времени (вам не обязательно Lerp, для этого используйте только Time.deltaTime).

Для того, чтобы показатьЭффект Я только изменил продолжительность на 3 вместо 0.3 (что нужно быстро заметить).

Вращение вокруг глобального Y с использованием transform.Rotate(rotation, Space.World);

enter image description here

Вращение вокруг локального Y с использованием transform.Rotate(rotation);

enter image description here

1 голос
/ 17 мая 2019

Можно попробовать с углами Эйлера.

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

Ваш код станет:

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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...