Unity 2D中_isAttacking变量变更但攻击重复逻辑未正确执行
Unity 2D敌人重复攻击失效问题修复
问题根源
核心问题是攻击状态与动画/冷却逻辑脱节:
- 在
Update里直接调用Attack(),导致_isAttacking刚设为true,同一帧就被重置为false - 下一帧
Update检测到玩家在攻击范围内,立刻把_isAttacking改回true,但Unity的动画Trigger是一次性触发机制,短时间内重复设置不会生效 - 攻击冷却逻辑和状态控制没有绑定,导致状态切换过于频繁
修复方案
1. 重构代码:分离触发、伤害、状态重置逻辑
把攻击触发、伤害计算、状态重置拆分开,用动画事件替代同步调用,确保逻辑和动画帧同步:
void Update() { if (distanceToPlayer <= chaseRadius && !_isAttacking) { isMoving = true; ChasePlayer(); // 仅在冷却完成且玩家在攻击范围内时触发攻击 if (distanceToPlayer <= attackRange && Time.time > _nextAttackTime) { _isAttacking = true; isMoving = false; rb.velocity = Vector2.zero; anim.SetBool("isMoving", false); anim.SetTrigger("Attack"); // 提前更新冷却时间,避免短时间内重复触发 _nextAttackTime = Time.time + attackCooldown; } } else { isMoving = false; rb.velocity = Vector2.zero; anim.SetBool("isMoving", false); } anim.SetBool("isMoving", isMoving); } // 攻击动画的伤害帧触发此方法(通过动画事件添加) private void DealDamage() { if (_player != null && Vector2.Distance((Vector2)transform.position + offset, player.position) <= attackRange) { _player.TakeDamage(attackDamage); Debug.Log("A zombie has damaged a player!"); } } // 攻击动画结束时触发此方法(通过动画事件添加) private void FinishAttack() { _isAttacking = false; Debug.Log(_isAttacking); }
2. 动画设置调整
打开敌人的Animator窗口,修改攻击动画的事件:
- 找到攻击动画中伤害生效的帧(比如丧尸挥拳命中的瞬间),右键添加
动画事件,选择DealDamage()方法 - 找到攻击动画的最后一帧,添加
动画事件,选择FinishAttack()方法 - 确保攻击动画到idle/walk的过渡逻辑:攻击动画播放完毕后自动回到idle,无需额外条件(或仅当
_isAttacking = false时允许过渡)
原代码失效原因
- 原代码在
Update里同步调用Attack(),导致_isAttacking在一帧内完成true -> false的切换,下一帧又被设为true,但Unity的动画Trigger在帧末会自动重置,重复设置不会触发第二次动画 - 用动画事件控制状态重置,能保证
_isAttacking在整个攻击动画周期内保持true,避免状态频繁波动,同时让伤害逻辑和动画视觉效果完全同步
内容的提问来源于stack exchange,提问作者Mazz1lla
相关产品推荐
相关产品推荐

