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

Unity中如何实现带滚动动画的玩家移动并解决抖动问题?

解决2D闪避滚动后位置抖动的问题

从你提供的动画效果来看,滚动结束后玩家位置出现了明显的跳变抖动,结合你的代码和场景情况,给出几个针对性的解决办法:

1. 处理动画根运动冲突

大概率是滚动动画的**根运动(Root Motion)**在搞鬼——动画结束时会强制把玩家位置重置回动画起始点,和你代码里的MovePosition操作撞在一起,导致位置跳变。

解决:

  • 打开滚动动画片段的Inspector面板,找到「Root Motion」设置,把Root Transform Position (XZ)改成Bake Into Pose,让动画只负责视觉表现,不改变玩家的实际物理位置。
  • 同时检查动画状态机的对应状态,把Write Defaults设为false,避免动画结束时覆盖玩家的位置参数。

2. 让位置移动和物理更新同步

你现在直接在动画事件里调用MovePosition,可能和Unity的物理更新时序(FixedUpdate)不匹配,导致位置更新不连贯。

改成这样:

private bool _needMoveAfterRoll;

public void StopRolling()
{
    _needMoveAfterRoll = true;
    animator.SetBool("isRolling", false);
    canMove = true;
}

private void FixedUpdate()
{
    if (_needMoveAfterRoll)
    {
        rb.MovePosition(new Vector2(rb.position.x + 0.54f, rb.position.y));
        _needMoveAfterRoll = false;
    }
}

把位移逻辑放到FixedUpdate里执行,保证和物理引擎的更新节奏一致。

3. 避免一次性位移,改为同步动画进度移动

如果动画本身有位移的视觉表现,别等到结束才一次性挪位置,而是在动画播放过程中同步移动玩家:

  • 给动画添加一个动画曲线参数(比如RollProgress),在动画播放时实时更新这个参数。
  • 在Update里根据RollProgress的值,逐步把玩家移动到目标位置,比如:
private float _targetRollDistance = 0.54f;
private Vector2 _initialRollPosition;

// 开始滚动时记录初始位置
public void StartRolling()
{
    _initialRollPosition = rb.position;
    animator.SetBool("isRolling", true);
    canMove = false;
}

private void Update()
{
    if (animator.GetBool("isRolling"))
    {
        float progress = animator.GetFloat("RollProgress");
        float currentMove = _targetRollDistance * progress;
        rb.MovePosition(new Vector2(_initialRollPosition.x + currentMove, rb.position.y));
    }
}

这样动画视觉和实际物理位置完全同步,结束时不会有跳变。

4. 修正动画本身的关键帧

如果你的滚动动画最后一帧是回到初始位置的关键帧,那动画结束时会强制拉回模型位置,和代码移动冲突。

解决:

  • 打开动画剪辑,删除最后回到初始位置的关键帧,让动画最后一帧的位置和你代码要移动到的位置对齐;或者在调用StopRolling时,先把动画设置为停留在最后一帧,再执行位移。

内容的提问来源于stack exchange,提问作者blockchainlover

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 15:03:26