Unity添加Animator后CharacterController落地弹跳、重力异常问题
问题根因
这个异常是Animator根运动逻辑和Character Controller位移系统冲突导致的:
- Character Controller本身独立负责角色位移、重力计算、碰撞响应,会每帧根据传入的速度值计算目标位置,自动处理地面吸附
- Animator默认开启
Apply Root Motion时,会直接读取动画文件中烘焙的根节点位移数据,强制改写角色Transform坐标 - 两套位移逻辑同时生效时,落地瞬间动画的Y轴根位置偏移会把角色短暂抬离碰撞面,随后被Character Controller的重力逻辑拉回,就会出现单次弹跳;同时Animator持续输出的根位置偏移会抵消部分重力加速度,直接导致跳跃高度比移除Animator时更低。
解决步骤
按顺序调整即可,覆盖绝大多数同类场景:
- 关闭Animator根运动
选中角色对象,在Inspector面板找到Animator组件,取消勾选Apply Root Motion。对于自行通过代码实现移动、跳跃逻辑的Character Controller方案,不需要动画驱动角色整体位移,仅保留Animator对骨骼姿态的控制即可,不会影响走、跑、跳的动画表现。 - 匹配Animator更新频率
将Animator组件的Update Mode从默认的Normal修改为Animate Physics,让Animator的逻辑更新和物理引擎FixedUpdate帧同步,避免因Update和FixedUpdate执行顺序不固定产生的位置计算误差,这也是重力值出现偏差的核心诱因之一。 - 修正动画导入的根轴配置
如果前两步调整后仍有轻微弹跳,选中项目中角色使用的待机动画、落地动画对应的FBX资源,在导入设置的Animation标签页下做如下调整:- 找到Root Transform Position (Y) 配置项
- 勾选Bake Into Pose,将Y轴根变换偏移烘焙到骨骼姿态中,不向外输出位置修改
- 将Based Upon选项设置为
Feet,以角色足部为根位置对齐基准
- 代码层加落地防抖兜底
不要直接依赖CharacterController.isGrounded做落地判断,也不要在落地瞬间把垂直速度直接设为0,保留一个持续向下的小幅速度让Character Controller始终保持地面吸附状态,参考代码:private CharacterController controller; private Vector3 moveVelocity; public float gravity = -19.62f; // 可根据手感调整,比默认-9.81的贴地效果更好 void Update() { // 落地状态判断 if (controller.isGrounded && moveVelocity.y < 0) { // 给-2的持续下压力,避免碰撞检测帧间隙导致的弹跳 moveVelocity.y = -2f; } // 重力累加 moveVelocity.y += gravity * Time.deltaTime; // 执行位移 controller.Move(moveVelocity * Time.deltaTime); }
效果校验
调整完成后运行测试:
- 观察Scene视图中Character Controller的碰撞体轮廓,跳跃落地时碰撞体没有瞬间上下偏移即代表弹跳问题消除
- 若跳跃高度和预期有偏差,直接调整代码里的跳跃初速度、重力值即可,此时Animator不会再干扰位移计算,参数调整会和无Animator时的表现完全一致。
内容的提问来源于stack exchange,提问作者DenVebber
相关产品推荐
相关产品推荐

