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

无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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 10:06:03