Unity中如何让攻击状态下的敌方AI停止移动与旋转?
Got it, let's sort this out for you. The core issue here is that your current code doesn't fully block rotation and movement logic when the enemy is in attack mode—even though you trigger the attack animation, state checks might still interfere if the player moves mid-attack. Here's a clean, reliable solution:
Step-by-Step Implementation
1. Add an Attack State Flag
First, add a private boolean variable to track if the enemy is actively attacking. This will let us skip all movement/rotation logic entirely when they're in the middle of an attack.
2. Block Logic During Attack
At the start of your Update() method, check if the enemy is attacking. If yes, skip the rest of the frame's logic so the enemy stays locked in the attack state until it finishes.
3. Sync with Animation Events
To make sure the flag updates perfectly when the attack starts and ends, we'll use animation events—this is more reliable than checking animation state every frame.
Modified Full Code
using System.Collections; using UnityEngine; public class Chasev2 : MonoBehaviour { public Transform Player; public float Attack_range = 8.5f; public float Chase_range = 50.0f; public float rotation_speed = 10.0f; public float move_speed = 10.0f; private Animator anim; private float Distance; private bool isAttacking = false; // Track if enemy is in attack state void Start () { anim = GetComponent<Animator>(); } void Update () { // Skip all movement/rotation logic if currently attacking if (isAttacking) return; // Default state setup anim.SetBool("Run", true); anim.SetBool("Idle", false); anim.SetBool("Attack", false); Distance = (Player.transform.position - transform.position).magnitude; // Chase state: move and rotate towards player if (Distance <= Chase_range && Distance > Attack_range) { Vector3 Direction = Player.position - transform.position; Direction.y = 0; // Keep rotation on Y-axis only transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Direction), rotation_speed * Time.deltaTime); transform.eulerAngles = new Vector3(0, transform.eulerAngles.y, 0); transform.position += transform.forward * move_speed * Time.deltaTime; } // Idle state: no movement else { anim.SetBool("Run", false); anim.SetBool("Idle", true); anim.SetBool("Attack", false); } // Trigger attack when player is in range if (Distance < Attack_range) { anim.SetBool("Run", false); anim.SetBool("Attack", true); anim.SetBool("Idle", false); } } // Called via animation event when attack starts public void StartAttack() { isAttacking = true; } // Called via animation event when attack ends public void EndAttack() { isAttacking = false; } void OnDrawGizmosSelected() { Gizmos.color = Color.red; Gizmos.DrawWireSphere(transform.position, Attack_range); Gizmos.color = Color.yellow; Gizmos.DrawWireSphere(transform.position, Chase_range); } }
How to Set Up Animation Events
- Open your enemy's attack animation clip in the Animation window.
- Move the playhead to the start frame of the attack, right-click the timeline, and select
Add Event. - In the event inspector, select your
Chasev2component, then choose theStartAttack()method. - Move the playhead to the last frame of the attack (or just before it loops), add another event, and select the
EndAttack()method.
Why This Works
- The
isAttackingflag ensures that once the enemy starts attacking, all movement and rotation logic is paused until the attack finishes. - Animation events sync the flag perfectly with the attack animation, so you won't get weird state glitches if the player moves during the attack.
内容的提问来源于stack exchange,提问作者Mike Tenrec

