You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

Unity中使用LookAt实现相机跟随抖动,如何实现平滑跟随?

相机平滑跟随的解决方案

嘿,我来帮你搞定相机颤抖的问题~你当前的代码是直接硬赋值相机位置+用LookAt瞬间旋转,这种“跳变”操作很容易因为帧率波动、目标移动的帧同步问题导致颤抖——毕竟目标的移动逻辑在Update,相机也在Update,有时候目标还没完成当前帧的移动,相机就先更新了,自然会出现抽搐感。

下面给你两种平滑跟随的实现方案,都能解决这个问题:

方案1:线性插值(Lerp)实现基础平滑

这种方式简单直观,适合大多数场景:

修改你的cubeCamera脚本为下面的代码:

public class cubeCamera : MonoBehaviour {
    public Transform target;
    // 调整这个值控制移动平滑度,越大越快跟上目标
    public float smoothMoveSpeed = 5f;
    // 调整这个值控制旋转平滑度,越大越快转向目标
    public float smoothRotateSpeed = 10f;
    // 相机相对于目标的固定偏移量
    private Vector3 cameraOffset;

    void Start() {
        // 初始化偏移:用相机初始位置减去目标初始位置,保持初始相对位置
        cameraOffset = transform.position - target.position;
    }

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

        // 计算相机需要到达的目标位置
        Vector3 targetPosition = target.position + cameraOffset;
        // 平滑移动相机位置
        transform.position = Vector3.Lerp(transform.position, targetPosition, smoothMoveSpeed * Time.deltaTime);

        // 计算相机需要朝向的目标旋转
        Quaternion targetRotation = Quaternion.LookRotation(target.position - transform.position);
        // 平滑旋转相机
        transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, smoothRotateSpeed * Time.deltaTime);
    }
}

关键优化点:

  • 改用LateUpdate:确保相机在目标完成当前帧的移动后再更新,避免帧同步导致的位置偏差
  • Vector3.Lerp做位置平滑:每次帧只移动一小段距离到目标位置,不会突然跳变
  • Quaternion.Lerp做旋转平滑:旋转也是渐进式过渡,不会瞬间转头导致颤抖
  • 初始化偏移量:灵活保留相机和目标的初始相对位置,不用硬编码数值

方案2:平滑阻尼(SmoothDamp)实现更自然的缓动效果

如果想要更柔和的“缓入缓出”跟随效果(比如目标突然加速时,相机慢慢跟上,不会生硬拉扯),可以用Vector3.SmoothDamp

修改后的代码如下:

public class cubeCamera : MonoBehaviour {
    public Transform target;
    // 平滑时间,值越大跟随越柔和,越小越灵敏
    public float smoothTime = 0.1f;
    // 旋转平滑速度
    public float smoothRotateSpeed = 10f;
    private Vector3 cameraOffset;
    // 用于SmoothDamp的速度缓存变量
    private Vector3 currentMoveVelocity;

    void Start() {
        cameraOffset = transform.position - target.position;
    }

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

        Vector3 targetPosition = target.position + cameraOffset;
        // 用SmoothDamp实现带缓动的平滑移动
        transform.position = Vector3.SmoothDamp(transform.position, targetPosition, ref currentMoveVelocity, smoothTime);

        Quaternion targetRotation = Quaternion.LookRotation(target.position - transform.position);
        transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, smoothRotateSpeed * Time.deltaTime);
    }
}

小提示:

  • 你可以根据实际游戏手感调整smoothMoveSpeedsmoothRotateSpeed或者smoothTime的值,找到最舒服的跟随效果
  • 如果目标的移动有物理引擎参与(比如Rigidbody),记得把相机的逻辑也放在LateUpdate,避免物理更新和相机更新不同步导致的抖动

内容的提问来源于stack exchange,提问作者AxOn

火山引擎 最新活动