返回首页

Controller

CharacterController 项目里最常见的数值坑

使用 CharacterController 做移动角色时,表面上看最常见的问题是“脚感不对”,但真正容易把项目拖进线上异常的, 通常是数值稳定性。角色重生瞬间的位置、速度投影、地面吸附和重力累积,都会在极端情况下把一个看似正常的流程推成 NaN。

为什么 NaN 很危险

一旦某一帧的速度、位移或目标位置进入 NaN,后续依赖这个值的所有运动计算都会继续失真。更糟的是,很多异常并不会在第一时间中断, 而是先以“偶发瞬移”“特效飞走”“敌人出生位置非法”等形式出现,最后才在控制台里抛出 `Input position is { NaN, NaN, NaN }`。

高风险位置

更稳妥的写法

对关键数值做有限值检查,并在发现异常时优先归零,而不是继续把非法值传下去:

static bool IsFinite(float value)
{
    return !float.IsNaN(value) && !float.IsInfinity(value);
}

static bool IsFinite(Vector3 value)
{
    return IsFinite(value.x) && IsFinite(value.y) && IsFinite(value.z);
}

if (!IsFinite(velocity))
{
    velocity = Vector3.zero;
}

工程建议

我的建议是把“角色是否能动”和“角色数值是否合法”分开检查。前者是玩法问题,后者是稳定性问题。只要把这两个层面拆开,很多难复现的问题都会明显变得可定位。