Menu
CoddyTech

平滑跟随

本课属于 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,因此调用中的任何内容都不需要乘以它。

challenge icon

挑战

中等

让摄像机从固定高度平滑地跟随玩家。

  1. 添加一个字段 Vector3 velocity;。
  2. 在 LateUpdate() 中,构建 Vector3 target = new Vector3(player.position.x, height, player.position.z - back);,这样跳跃时视野不会移动。
  3. 设置 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 在线编辑器