You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中使用Cinemachine实现第三人称相机时出现移动及旋转卡顿问题

卡顿原因及修复方案

核心问题点

  • 方向计算逻辑放在Update中执行,但角色移动、旋转的物理逻辑都在FixedUpdate中执行,两者刷新频率不匹配:转动相机时direction会在Update中实时更新,但FixedUpdate的执行频率固定,会导致角色旋转、移动的更新延迟,出现卡顿感
  • 原代码将速度值直接赋值给了direction变量,后续逻辑复用容易出错
  • Cinemachine虚拟相机的更新模式如果和物理帧绑定,也会和屏幕刷新频率不匹配,导致相机转动卡顿

代码修改方案

public class ThirdPersonScript : MonoBehaviour
{
    [SerializeField] private float speed;
    [SerializeField] private float jumpForce;
    [SerializeField] private float rotateSpeed = 1080f; // 旋转参数单独抽离方便调整
    [SerializeField] private Transform feet;
    [SerializeField] private LayerMask floorMask;
    [SerializeField] private Transform cam;

    private Vector3 inputDir; // 单独存储原始输入方向
    private Vector3 moveDir; // 存储经相机校准后的移动方向
    private Rigidbody rb;
    private bool canJump;

    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    // Update仅负责采集输入
    void Update()
    {
        inputDir = new Vector3(Input.GetAxis("Horizontal"), 0f, Input.GetAxis("Vertical"));
        canJump = Input.GetKeyDown(KeyCode.Space);
    }

    // 所有物理、角色变换相关逻辑统一放在FixedUpdate执行,相机角度计算也同步挪到此处
    void FixedUpdate()
    {
        // 基于当前相机角度计算实际移动方向
        moveDir = Quaternion.AngleAxis(cam.rotation.eulerAngles.y, Vector3.up) * inputDir;
        if (moveDir.magnitude > 1f)
        {
            moveDir.Normalize();
        }

        // 处理跳跃和移动逻辑
        if (Physics.CheckSphere(feet.position, 0.1f, floorMask))
        {            
            if (canJump)
                rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
            else    
                rb.velocity = new Vector3(moveDir.x * speed, 0, moveDir.z * speed);
        }
        else          
            rb.velocity = new Vector3(moveDir.x * speed, rb.velocity.y, moveDir.z * speed);
    
        // 处理角色朝向逻辑
        if (moveDir != Vector3.zero)
        {
            Quaternion targetRotation = Quaternion.LookRotation(moveDir);
            Quaternion newRotation = Quaternion.RotateTowards(transform.rotation, targetRotation, rotateSpeed * Time.fixedDeltaTime);
            rb.MoveRotation(newRotation);
        }

        // 重置跳跃标记,避免FixedUpdate多帧重复触发跳跃
        canJump = false;
    }
}

Cinemachine参数调整

打开Cinemachine虚拟相机的Inspector面板,找到Update Method选项,将值修改为LateUpdate,保证相机在每帧所有业务逻辑执行完成后再刷新位置/旋转,避免和物理帧冲突导致的卡顿。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 18:45:03