无Rigidbody组件时如何获取移动速度以实现相机FOV动态调整
准确获取玩家移动速度的实现方案
方案1:修复Rigidbody速度读取异常
- 读取
Rigidbody.velocity的代码必须放在FixedUpdate()生命周期中执行,Rigidbody的物理更新为固定帧率,在Update()中读取会出现帧不同步导致数值异常 - 若玩家移动通过
Transform.Translate()或CharacterController实现,未通过物理力驱动,Rigidbody不会自动更新velocity数值,需将移动逻辑改为Rigidbody.AddForce()/Rigidbody.MovePosition()驱动,或直接使用方案2 - 检查Rigidbody的
Is Kinematic属性是否开启,开启状态下物理引擎不会更新velocity数值
方案2:手动计算实时移动速度(无依赖兼容性最高)
无需依赖任何物理组件,通过相邻帧位移差直接计算速度,适配所有移动实现逻辑:
// 类内全局变量声明 private Vector3 lastFramePosition; private float currentMoveSpeed; // 平滑系数,范围0-1,数值越小速度值越平滑,可按需调整 public float smoothFactor = 0.12f; // 可自行修改基础FOV、最大FOV、速度阈值参数 public float baseFov = 60f; public float maxFov = 75f; public float speedThreshold = 10f; void Start() { // 初始化记录玩家初始位置 lastFramePosition = playerTransform.position; } void Update() { // 计算相邻帧位移差 Vector3 deltaPos = playerTransform.position - lastFramePosition; // 可选:忽略Y轴位移,避免跳跃、下落动作影响FOV变化 deltaPos.y = 0; // 计算原始实时速度(单位:米/秒) float rawSpeed = deltaPos.magnitude / Time.deltaTime; // 平滑处理速度值,避免帧波动导致FOV抖动 currentMoveSpeed = Mathf.Lerp(currentMoveSpeed, rawSpeed, smoothFactor); // FOV更新逻辑 Camera.main.fieldOfView = Mathf.Lerp(baseFov, maxFov, currentMoveSpeed / speedThreshold); // 更新上一帧位置用于后续计算 lastFramePosition = playerTransform.position; }
该方案优势:
- 无组件依赖,不管玩家用什么方式实现移动都能拿到准确速度
- 支持自定义忽略指定轴向的位移,适配不同项目需求
- 平滑度可自由调整,适配不同的FOV变化节奏需求
内容的提问来源于stack exchange,提问作者Stanley Easthope
相关产品推荐
相关产品推荐

