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

Unity攻击动画过渡异常求助:点击攻击后瞬间切回原动画

解决攻击动画闪现后切回的问题

我有一个独立脚本负责处理玩家动画,行走、跳跃和蹲伏动画均能正常工作,但当玩家按下鼠标左键发起攻击时,攻击动画仅闪现一瞬间就会切回行走、Idle、跳跃或蹲伏动画。

相关代码如下:

// Player Input
private void CheckCombatInput(InputAction.CallbackContext context)
{
    if (context.performed)
        isAttacking = true;
}

// Player Move 
public void PlayerMove()
{
    bool isWalking = false;
    if (isFacingRight && horizontal < 0)
    {
        Flip();
    }
    else if (!isFacingRight && horizontal > 0)
    {
        Flip();
    }

    moveSpeed = playerMovementForce * Time.fixedDeltaTime;
    if (isCrouching)
    {
        moveSpeed *= crouchSpeedMultiplier;
    }

    rb.velocity = new Vector2(horizontal * moveSpeed, rb.velocity.y);
    if (isGrounded && !jump && !isCrouching && !isAttacking)
    {
        isWalking = Mathf.Abs(horizontal) > 0;
        PlayerAnimator.Instance.ChangeAnimationState(isWalking ? PlayerAnimator.Player_Walk : PlayerAnimator.Player_Idle);
    }
}

// Player Attack
private void PlayerAttacks()
{
    if (isAttacking)
    {
        canFlip = false;
        PlayerAnimator.Instance.ChangeAnimationState(PlayerAnimator.Player_Attack);
        isAttacking = false;
    }
    else
    {
        canFlip = true;
        isAttacking = false;
    }
}

问题根源

  • 攻击状态生命周期太短:PlayerAttacks里刚播放攻击动画就把isAttacking设为false,下一帧PlayerMove的条件满足,直接覆盖了动画状态。
  • PlayerMove的动画切换逻辑没考虑攻击动画正在播放的情况,只要满足地面、非跳跃非蹲伏且非攻击的条件,就强制切回行走/Idle。

解决步骤

1. 让攻击状态持续到动画结束

给攻击动画添加动画结束事件,等动画播完再重置isAttacking:

  • 打开Animator窗口,选中攻击动画状态,在Inspector面板的「Events」里添加一个事件,选择你的玩家脚本,方法选OnAttackAnimationEnd,把事件拖到动画时间线的末尾位置。
  • 修改脚本代码:
// Player Input
private void CheckCombatInput(InputAction.CallbackContext context)
{
    // 攻击期间不能重复触发
    if (context.performed && !isAttacking) 
        isAttacking = true;
}

// Player Attack
private void PlayerAttacks()
{
    if (isAttacking)
    {
        canFlip = false;
        PlayerAnimator.Instance.ChangeAnimationState(PlayerAnimator.Player_Attack);
        // 不再立刻重置isAttacking,交给动画结束事件处理
    }
    else
    {
        canFlip = true;
    }
}

// 攻击动画结束时触发的方法(和Animator里的事件绑定)
private void OnAttackAnimationEnd()
{
    isAttacking = false;
    // 动画结束后根据当前状态切回行走/Idle
    if (isGrounded && !jump && !isCrouching)
    {
        bool isWalking = Mathf.Abs(horizontal) > 0;
        PlayerAnimator.Instance.ChangeAnimationState(isWalking ? PlayerAnimator.Player_Walk : PlayerAnimator.Player_Idle);
    }
}

2. 优化PlayerMove的动画切换逻辑

修改PlayerMove里的条件,确保攻击状态下不切换行走/Idle动画,同时攻击时禁止翻转方向:

// Player Move 
public void PlayerMove()
{
    bool isWalking = false;
    // 攻击时禁止翻转方向
    if (canFlip && isFacingRight && horizontal < 0)
    {
        Flip();
    }
    else if (canFlip && !isFacingRight && horizontal > 0)
    {
        Flip();
    }

    moveSpeed = playerMovementForce * Time.fixedDeltaTime;
    if (isCrouching)
    {
        moveSpeed *= crouchSpeedMultiplier;
    }

    rb.velocity = new Vector2(horizontal * moveSpeed, rb.velocity.y);
    
    // 只有非攻击状态下才切换行走/Idle
    if (!isAttacking && isGrounded && !jump && !isCrouching)
    {
        isWalking = Mathf.Abs(horizontal) > 0;
        PlayerAnimator.Instance.ChangeAnimationState(isWalking ? PlayerAnimator.Player_Walk : PlayerAnimator.Player_Idle);
    }
}

3. 额外提示

如果你的攻击动画有多个帧,确保动画事件的位置在动画最后一帧的前一点,避免出现动画还没播完就切换状态的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 05:35:09