using System.Collections; using System.Collections.Generic; using UnityEngine; public class EnemyAI : MonoBehaviour { [SerializeField] private float roamChangeDirFloat = 2f; // Interval for changing the enemy's roaming direction [SerializeField] private float attackRange = 0f; // The distance at which the enemy will engage in an attack [SerializeField] private MonoBehaviour enemyType; // Reference to the specific enemy behavior (e.g., melee, ranged) [SerializeField] private float attackCooldown = 2f; // The delay between consecutive attacks [SerializeField] private bool stopMovingWhileAttacking = false; // Determines if the enemy should halt movement during an attack private bool canAttack = true; // Tracks whether the enemy is ready to attack again private enum State { Roaming, // The enemy is wandering around Attacking // The enemy is actively engaging the player } private Vector2 roamPosition; // Target position for the enemy to move towards while roaming private float timeRoaming = 0f; // Elapsed time spent in the roaming state private State state; // Current behavior state of the enemy private EnemyPathfinding enemyPathfinding; // Reference to the enemy's pathfinding system private void Awake() { enemyPathfinding = GetComponent(); // Initialize the pathfinding system state = State.Roaming; // Set initial behavior to roaming } private void Start() { roamPosition = GetRoamingPosition(); // Set the initial target position for roaming } private void Update() { MovementStateControl(); // Update movement based on the enemy's current state } private void MovementStateControl() { switch (state) { case State.Roaming: Roaming(); // Handle roaming behavior break; case State.Attacking: Attacking(); // Handle attacking behavior break; default: break; } } private void Roaming() { timeRoaming += Time.deltaTime; // Track the time spent in roaming mode enemyPathfinding.MoveTo(roamPosition); // Move towards the target roam position // Check if the player is within attack range to switch to attacking if (Vector2.Distance(transform.position, PlayerController.Instance.transform.position) < attackRange) { state = State.Attacking; } // Change the roam direction after the specified interval if (timeRoaming > roamChangeDirFloat) { roamPosition = GetRoamingPosition(); } } private void Attacking() { // Switch back to roaming if the player leaves the attack range if (Vector2.Distance(transform.position, PlayerController.Instance.transform.position) > attackRange) { state = State.Roaming; } // If the enemy is within attack range and able to attack, perform the attack if (attackRange != 0 && canAttack) { canAttack = false; (enemyType as IEnemy).Attack(); // Execute the attack action specific to the enemy type // Decide whether to stop or continue moving during the attack if (stopMovingWhileAttacking) { enemyPathfinding.StopMoving(); } else { enemyPathfinding.MoveTo(roamPosition); } StartCoroutine(AttackCooldownRoutine()); // Start the cooldown before the next attack } } private IEnumerator AttackCooldownRoutine() { yield return new WaitForSeconds(attackCooldown); // Wait for the cooldown period to end canAttack = true; // Enable the enemy to attack again } private Vector2 GetRoamingPosition() { timeRoaming = 0f; // Reset the roaming timer return new Vector2(Random.Range(-1f, 1f), Random.Range(-1f, 1f)).normalized; // Generate a new random direction for roaming } }