Menu
CoddyTech

Плавный поворот

Часть раздела Физика и игровой процесс путешествия по Unity на Coddy. Урок 45 из 71.

Если сразу задать transform.rotation новое вращение, объект повернётся за один кадр. Quaternion.RotateTowards(current, goal, maxDegrees) возвращает current, повёрнутое в сторону goal не более чем на maxDegrees и никогда не проходящее дальше цели. Если в качестве шага использовать turnSpeed * Time.deltaTime, объект поворачивается с постоянной скоростью и останавливается точно у цели, как MoveTowards для позиций. Этот подсолнух следует за солнцем со скоростью 30 градусов в секунду:

public Transform sun;
public float turnSpeed = 30f;

void Update()
{
    Quaternion goal = Quaternion.LookRotation(sun.position - transform.position);
    transform.rotation = Quaternion.RotateTowards(transform.rotation, goal, turnSpeed * Time.deltaTime);
}

Если солнце находится в 90 градусах от подсолнуха, ему потребуется 3 секунды — по 30 градусов за раз. Он поворачивается по кратчайшему пути, а цель пересчитывается в каждом кадре, поэтому подсолнух следует за движущимся солнцем.

Quaternion.Slerp(a, b, t) — это вращение на долю пути t от a до b, так же как Vector3.Lerp для точек. Если записать Slerp(transform.rotation, goal, 5f * Time.deltaTime) в Update(), в каждом кадре оно поворачивается на часть оставшегося угла: сначала быстро, а ближе к цели всё медленнее, никогда не с постоянной скоростью и так и не достигая цели полностью. Такое плавное замедление подходит для камеры или поворачивающейся головы. Когда скорость поворота задана правилами игры, например для пушки, поворачивающейся на 60 градусов в секунду, используй RotateTowards.

challenge icon

Задание

Средне

Сделай так, чтобы сова плавно поворачивалась в направлении каждой стрелки.

  1. Добавь Quaternion goal; и присвой ему значение transform.rotation в Start().
  2. При нажатии каждой стрелки, определяемом с помощью Input.GetKeyDown, присваивай значение goal, например goal = Quaternion.LookRotation(Vector3.right);: вверх +z, вправо +x, вниз -z, влево -x.
  3. Каждый кадр присваивай transform.rotation = Quaternion.RotateTowards(transform.rotation, goal, turnSpeed * Time.deltaTime);.

Нажми «Играть» и нажимай стрелки. Затем нажми «Проверить».

Попробуйте сами

using UnityEngine;

public class Owl : MonoBehaviour
{
    public float turnSpeed = 180f;

    void Update()
    {
        // Вверх, вправо, вниз, влево: поворачивайтесь в направлении +z, +x, -z, -x со скоростью turnSpeed градусов в секунду.
    }
}

Все уроки раздела Физика и игровой процесс

Потренируйтесь самостоятельно: Песочница Unity