平滑跟随
本课属于 Coddy Unity 学习旅程的“物理与游戏玩法”单元。第 47 课,共 71 课。
如果相机在 LateUpdate() 中将玩家的位置加上偏移量后直接复制过来,那么玩家每次抖动都会让视野跟着抖动。Vector3.SmoothDamp(current, target, ref velocity, smoothTime) 会返回一个朝 target 移动后的位置,其运动方式就像阻尼弹簧:先加速,接近目标时减速,并且到达目标时不会超出。这个相机会在玩家上方 3 个单位、后方 6 个单位处跟随玩家,并稍微滞后一些:
public Transform player;
public Vector3 offset = new Vector3(0, 3, -6);
public float smoothTime = 0.3f;
Vector3 velocity;
void LateUpdate()
{
Vector3 target = player.position + offset;
transform.position = Vector3.SmoothDamp(transform.position, target, ref velocity, smoothTime);
}ref 会将变量本身而不是副本交给 SmoothDamp,因此该方法可以修改它。SmoothDamp 会将相机在三个轴上的当前速度保存在 velocity 中,并且下一帧还需要用到它,所以它必须是字段。如果在 LateUpdate() 内声明它,那么每一帧它都会从零开始,相机移动起来就会很慢,每帧只能移动目标距离的约 0.5%。对于单个数值,例如相机的缩放,Mathf.SmoothDamp 也能以相同的方式配合 float 类型的速度使用。
smoothTime 决定相机滞后多少:设为 0.3 时,突变发生后 0.3 秒内相机会跟上约 60%,1 秒后则几乎到达目标。值越小,跟随越紧密。SmoothDamp 会自行读取 Time.deltaTime,因此调用中的任何内容都不需要乘以它。
挑战
中等让摄像机从固定高度平滑地跟随玩家。
- 添加一个字段
Vector3 velocity;。 - 在
LateUpdate()中,构建Vector3 target = new Vector3(player.position.x, height, player.position.z - back);,这样跳跃时视野不会移动。 - 设置
transform.position = Vector3.SmoothDamp(transform.position, target, ref velocity, smoothTime);。
按“开始”,跑动并跳跃:摄像机会稍微滞后跟随,而且完全不会上下晃动。然后按“检查”。
亲手试试
using UnityEngine;
public class TopDownCamera : MonoBehaviour
{
public Transform player;
public float height = 12f;
public float back = 5f;
public float smoothTime = 0.25f;
void LateUpdate()
{
// 平滑移动到目标位置:x 坐标与 player 相同,z 坐标在其后方 back 单位处,高度保持固定。
}
}
物理与游戏玩法中的所有课
自己练习: Unity 在线编辑器