Menu
CoddyTech

平滑转向

本课属于 Coddy Unity 学习旅程的“物理与游戏玩法”单元。第 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) 表示从 a 到 b 之间距离为 t 的旋转,就像 Vector3.Lerp 用于点一样。在 Update() 中写成 Slerp(transform.rotation, goal, 5f * Time.deltaTime) 时,它会在每一帧转过剩余角度的一部分:一开始很快,接近目标时越来越慢,速度不会固定,也永远无法完全到达目标。这种平滑效果适合用于摄像机或头部转动。如果转动速度是游戏规则的一部分,例如炮台每秒转动 60 度,就使用 RotateTowards。

challenge icon

挑战

中等

让猫头鹰平滑地转向每个箭头所指的方向。

  1. 添加 Quaternion goal;,并在 Start() 中将它设置为 transform.rotation。
  2. 按下每个方向键时,设置 goal,例如 goal = Quaternion.LookRotation(Vector3.right);:上为 +z,右为 +x,下为 -z,左为 -x。
  3. 每帧都设置 transform.rotation = Quaternion.RotateTowards(transform.rotation, goal, turnSpeed * Time.deltaTime);。

按下 Play,然后轻按方向键。接着点击“检查”。

亲手试试

using UnityEngine;

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

    void Update()
    {
        // 按上、右、下、左方向,以每秒 turnSpeed 度的速度转向 +z、+x、-z、-x。
    }
}

物理与游戏玩法中的所有课

自己练习: Unity 在线编辑器