U
16 / 22 · 8 分钟
常见问题

不卡顿的跟随相机

简短回答

怎么让相机平滑跟随玩家、不抖动?

在 LateUpdate 里移动相机,绝不在 Update 里:LateUpdate 在所有其他东西都移动完之后才运行。如果玩家用了 Rigidbody,还要把 Rigidbody 的 Interpolate 选项设为 Interpolate。

跟随相机就是四行代码,外加一个决定:放在哪。放在 Update 里,相机读到的是玩家还没走完的位置,每一帧都慢一帧 —— 你的眼睛会把它看成抖动。

动态图解

Unity 先跑完所有 Update,再跑所有 LateUpdate。你在前半段移动相机,它读到的就是玩家下一帧才走到的位置。

永远放在 LateUpdate

Unity 会把场景里所有 Update 跑完,然后才跑所有 LateUpdate。凡是必须根据这一帧最终位置来反应的,就该放在 LateUpdate 里,跟随相机就是教科书级的例子。

FollowCamera.cs — attach to the camera, drag the player into target
using UnityEngine;

public class FollowCamera : MonoBehaviour
{
    public Transform target;
    public Vector3 offset = new Vector3(0f, 6f, -8f);

    [Range(1f, 30f)]
    public float smooth = 10f;

    void LateUpdate()
    {
        if (target == null) return;

        Vector3 wanted = target.position + offset;

        // Frame-rate independent smoothing. A plain Lerp with a constant t
        // moves further per second at higher frame rates.
        transform.position = Vector3.Lerp(
            transform.position, wanted, 1f - Mathf.Exp(-smooth * Time.deltaTime));

        transform.LookAt(target.position + Vector3.up * 1.5f);
    }
}

如果玩家用的是 Rigidbody

这里光有 LateUpdate 还不够。物理每秒推进 50 步,画面却要画 60、90 甚至 120 次,所以大多数帧里,玩家自上次物理步之后根本没动,相机却已经走了。这个错位就是抖动本身。

  • 把玩家的 Rigidbody 的 Interpolate 设成 Interpolate。这样 Unity 会在两个物理步之间插值绘制它,而不是跳格,相机也就有了平滑的东西可跟。

  • 只给玩家开,别给场景里每个 Rigidbody 都开 —— 插值是每个刚体都要吃内存的,而且没谁会盯着那几个箱子看。

  • 有相机在跟着的时候,绝对不要用 transform.position 去移动 Rigidbody。那样等于完全跳过插值,抖动立刻回来。

还是不流畅?

  • 检查是不是还有别的东西在写相机的 position。两个脚本抢一个 transform,看起来和抖动一模一样。

  • 先看 Game view 的 Stats 面板里的帧率。锁在 30 FPS 下出现的顿挫不是相机 bug。

  • 如果相机已经是玩家的子物体,就把脚本删掉 —— 作为子物体它本来就会跟着走。两边同时留着,只会互相拉扯。

做出这个的那一课

跟随镜头

这篇指南单独成篇,是一份可以直接照着做的配方。在课程里,同样的东西会作为贯穿全部五个章的那个项目的一部分来搭建 —— 镜头与操作,第 01 课。