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

Unity中首段攻击动画后触发二段攻击动画的技术求助

实现攻击动画连贯触发的解决方案

原代码的核心问题

  1. Attack方法使用了yield return但未声明为IEnumerator,属于协程语法错误
  2. 错误调用animation.IsPlaying,当前Unity主流使用Animator组件,需通过Animator的状态信息检测动画进度
  3. 协程内的Input.GetKeyDown仅在动画结束的单帧检测,用户极易错过触发时机,应在Update循环中持续检测

方法一:动画事件(最推荐,新手友好)

这是Unity中控制动画流程最直观的方式,直接在动画片段上绑定结束事件:

  1. 打开你的Animator Controller,找到第一段攻击动画MartialHeroAttack1
  2. 双击该动画片段,在时间轴末尾右键选择Add Event
  3. 在事件的函数名输入框中填写OnFirstAttackEnd,保存动画片段

修改后的代码:

using UnityEngine;

public class PlayerCombatBehaviour : MonoBehaviour
{
    public Animator animator;
    private bool _canTriggerSecondAttack;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.K))
        {
            _canTriggerSecondAttack = false;
            animator.SetTrigger("attack");
        }

        // 第一段动画结束后检测L键输入
        if (_canTriggerSecondAttack && Input.GetKeyDown(KeyCode.L))
        {
            _canTriggerSecondAttack = false;
            animator.SetTrigger("attack2");
        }
    }

    // 动画事件触发的方法,必须为public
    public void OnFirstAttackEnd()
    {
        _canTriggerSecondAttack = true;
    }
}

方法二:协程监听动画状态

如果不想依赖动画事件,可用协程实时检测Animator的状态:

using System.Collections;
using UnityEngine;

public class PlayerCombatBehaviour : MonoBehaviour
{
    public Animator animator;
    private bool _canTriggerSecondAttack;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.K))
        {
            _canTriggerSecondAttack = false;
            animator.SetTrigger("attack");
            StartCoroutine(WaitForFirstAttackFinish());
        }

        if (_canTriggerSecondAttack && Input.GetKeyDown(KeyCode.L))
        {
            _canTriggerSecondAttack = false;
            animator.SetTrigger("attack2");
        }
    }

    IEnumerator WaitForFirstAttackFinish()
    {
        // 等待进入第一段攻击动画状态
        yield return new WaitUntil(() => animator.GetCurrentAnimatorStateInfo(0).IsName("MartialHeroAttack1"));
        
        // 等待动画播放完成(normalizedTime >=1 表示动画播放完毕)
        yield return new WaitWhile(() => 
            animator.GetCurrentAnimatorStateInfo(0).normalizedTime < 1f 
            && animator.GetCurrentAnimatorStateInfo(0).IsName("MartialHeroAttack1"));

        _canTriggerSecondAttack = true;
    }
}

注意事项

  • 确保MartialHeroAttack1是Animator状态机中对应状态的准确名称(区分大小写)
  • GetCurrentAnimatorStateInfo(0)中的0是动画层索引,默认基础层为0,若动画在其他层需修改对应索引

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 06:01:25