平滑转向
本课属于 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。
挑战
中等让猫头鹰平滑地转向每个箭头所指的方向。
- 添加
Quaternion goal;,并在Start()中将它设置为transform.rotation。 - 按下每个方向键时,设置
goal,例如goal = Quaternion.LookRotation(Vector3.right);:上为 +z,右为 +x,下为 -z,左为 -x。 - 每帧都设置
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 在线编辑器