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

如何正确实现三段剑击连击动画?现有触发异常问题求助

三段剑击连击动画实现问题

遇到的问题

  • 首次输入三次攻击指令时,第三段动画需第四次点击才会播放;
  • 连续快速点击时,第一段动画要在三次快速点击后才会播放,且需等第三段动画结束后才会执行。

期望效果

每点击一次触发对应段动画(第1次点击触发Attack、第2次触发Attack2、第3次触发Attack3),连击完成后再次点击可重新开始三段连击。

现有代码

public class swordscript : MonoBehaviour
{
    public GameObject Sword;
    private Animator anim;

    private int comboStep = 0; // 当前连击阶段
    private float lastComboTime = 0f; // 上次攻击的启动时间
    private float comboTimeout = 1.0f; // 连击完成的时间窗口
    private float ResetAtkCooldown = 0.5f;

    void Start()
    {
        // 获取Sword对象上的Animator组件
        anim = Sword.GetComponent<Animator>();
    }

    void Update()
    {
        // 检测玩家鼠标左键点击
        if (Input.GetMouseButtonDown(0))
        {
            // 检查是否处于连击时间窗口内
            if (Time.time - lastComboTime <= comboTimeout)
            {
                // 递增连击阶段
                comboStep++;

                // 根据当前阶段执行对应动作
                switch (comboStep)
                {
                    case 1:
                        anim.SetTrigger("Attack");
                        StartCoroutine(ResetToIdle());
                        break;
                    case 2:
                        anim.SetTrigger("Attack2");
                        StartCoroutine(ResetToIdle());
                        break;
                    case 3:
                        anim.SetTrigger("Attack3");
                        StartCoroutine(ResetToIdle());
                        break;
                    default:
                        // 连击阶段超过3时重置为1
                        if (comboStep > 3)
                        {
                            comboStep = 1;
                        }
                        break;
                }
            }
            else
            {
                // 超时,启动新连击
                comboStep = 1;
            }

            // 记录上次攻击时间
            lastComboTime = Time.time;
        }
    }

    IEnumerator ResetToIdle()
    {
        yield return new WaitForSeconds(ResetAtkCooldown);
        comboStep = 0;
    }
}

问题分析与优化方案

问题根源

  1. 重复协程干扰状态:每次触发动画都启动ResetToIdle协程,多个协程会在不同时间点将comboStep重置为0,导致点击时的阶段数值不符合预期(比如第三次点击时,前序协程已把comboStep重置为0,导致触发的是第一段而非第三段)。
  2. 连击阶段逻辑混乱:快速点击时,comboStep被多次递增,但协程的延迟重置会打乱阶段顺序,造成动画触发滞后。

优化后的代码

public class swordscript : MonoBehaviour
{
    public GameObject Sword;
    private Animator anim;

    private int comboStep = 0; // 当前连击阶段
    private float lastComboTime = 0f; // 上次攻击的时间
    private float comboTimeout = 1.0f; // 连击超时窗口
    private Coroutine resetComboCoroutine; // 控制连击重置的协程

    void Start()
    {
        anim = Sword.GetComponent<Animator>();
    }

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            // 判断是否在连击超时窗口内
            if (Time.time - lastComboTime <= comboTimeout)
            {
                // 未完成连击则递增阶段,完成则重置为第一段
                comboStep = comboStep < 3 ? comboStep + 1 : 1;
            }
            else
            {
                // 超时后启动新连击
                comboStep = 1;
            }

            // 触发对应阶段的动画
            TriggerAttackAnimation(comboStep);

            // 更新上次攻击时间
            lastComboTime = Time.time;

            // 停止之前的重置协程,避免重复修改状态
            if (resetComboCoroutine != null)
            {
                StopCoroutine(resetComboCoroutine);
            }

            // 启动新的超时重置协程
            resetComboCoroutine = StartCoroutine(ResetComboAfterTimeout());
        }
    }

    /// <summary>
    /// 根据连击阶段触发对应动画
    /// </summary>
    void TriggerAttackAnimation(int step)
    {
        switch (step)
        {
            case 1:
                anim.SetTrigger("Attack");
                break;
            case 2:
                anim.SetTrigger("Attack2");
                break;
            case 3:
                anim.SetTrigger("Attack3");
                break;
        }
    }

    /// <summary>
    /// 连击超时后重置阶段
    /// </summary>
    IEnumerator ResetComboAfterTimeout()
    {
        yield return new WaitForSeconds(comboTimeout);
        comboStep = 0;
        resetComboCoroutine = null;
    }
}

优化核心点

  1. 单一协程控制重置:每次点击时停止之前的重置协程,仅保留最新的一个,避免多个协程同时修改comboStep。
  2. 清晰的阶段流转逻辑:连击完成(阶段3)后,再次点击直接回到第一段;超时后才重置为初始状态,确保连击流程连贯。
  3. 分离动画触发逻辑:将动画触发封装为独立方法,代码结构更清晰,便于维护。

修改后可实现:第一次点击触发Attack、第二次触发Attack2、第三次触发Attack3,第四次点击(超时内)回到Attack;超时后点击重新启动三段连击,完全符合预期效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 06:30:34