Unity中Character Controller蹲起时Mathf.Lerp视觉缓慢问题的修复
问题分析与解决方案
你的问题出在Lerp的用法错误,导致站起/下蹲的插值逻辑出现速度衰减,视觉上显得拖沓卡顿,和帧率无关。
问题根源
原来的代码里,每次Update都用_characterController.height作为Lerp的起始值,再配合t *= t的缓入曲线,相当于每帧都重新计算一段短距离的插值——越接近目标值,每帧移动的距离就越小,最后阶段几乎看不出变化,看起来就像“卡帧”。
修正方案
核心是固定插值的起始和目标值,而不是每帧用当前值作为起点。同时可以调整缓动逻辑让动作更自然:
1. 添加变量存储起始/目标状态
在类中新增几个变量:
private float _targetHeight; private float _startHeight; private Vector3 _startCenter; private Vector3 _targetCenter;
2. 修改Crouch方法,记录初始和目标状态
点击蹲伏时,先把当前的碰撞体状态(高度、中心)和目标状态存下来:
public void Crouch() { _isCrouching = !_isCrouching; _crouchTimer = 0; speed = _isCrouching ? crouchSpeed : walkSpeed; _lerpCrouch = true; // 记录当前状态和目标状态 _startHeight = _characterController.height; _targetHeight = _isCrouching ? 1 : 2; _startCenter = _characterController.center; _targetCenter = new Vector3(0, _isCrouching ? 0.5f : 1f, 0); }
3. 修正Update中的插值逻辑
用固定的起始/目标值做插值,同时调整缓动曲线和总时长:
private void Update() { _isGrounded = _characterController.isGrounded; if (_lerpCrouch) { _crouchTimer += Time.deltaTime; // 总时长设为0.3秒(可根据需求调整,越小动作越快) float t = Mathf.Clamp01(_crouchTimer / 0.3f); // 用SmoothStep让动作启动/结束更平滑,避免生硬感 t = Mathf.SmoothStep(0, 1, t); // 同时插值高度和碰撞体中心 _characterController.height = Mathf.Lerp(_startHeight, _targetHeight, t); _characterController.center = Vector3.Lerp(_startCenter, _targetCenter, t); if (t >= 1) { _lerpCrouch = false; _crouchTimer = 0; // 强制设置最终状态,避免浮点计算误差 _characterController.height = _targetHeight; _characterController.center = _targetCenter; } } }
额外说明
- 调整总时长:把
0.3f改成你觉得合适的数值,比如0.2f会让动作更敏捷,0.4f更平缓。 - 碰撞体中心:必须同步调整
center.y,否则蹲姿时胶囊体底部会浮空,导致地面检测异常,同时视觉上也不自然。 - SmoothStep vs 自定义曲线:如果你想要更个性化的缓动效果,可以用AnimationCurve自定义曲线,代替Mathf.SmoothStep。
内容的提问来源于stack exchange,提问作者Ole
相关产品推荐
相关产品推荐

