I'm working on an AI system in Unity where the enemy alternates between patrolling, chasing the player, and hiding behind objects. I’m trying to implement a system where the AI not only decides whether to engage or hide but also dynamically chooses whether to run or walk based on the situation.
Here’s the main challenge I’m facing:
The AI should dynamically decide when to chase the player, hide behind an object, or continue patrolling.
The AI also needs to make a decision on whether to run or walk based on its current state (e.g., running when chasing or if the player is close, walking while patrolling).
Currently, the decision-making feels too random as I'm using Random.Range, and I want to make it more intelligent and reactive.
Below is a snippet of my code, where the AI switches between patrolling, chasing, hiding, and adjusts movement speed accordingly:
public class EnemyAI : MonoBehaviour { public Transform[] patrolPoints; public Transform hideSpot; public float patrolSpeed = 3f; // Walking speed during patrol public float chaseSpeed = 5f; // Running speed while chasing public float detectionRange = 10f; public float engageRange = 5f; public Transform player; private int currentPatrolIndex; private bool isHiding = false; private bool isChasing = false; private float[] qTable = new float[2]; // Q-learning table private enum State { Patrol, Chase, Hide } private State currentState; void Start() { currentPatrolIndex = 0; currentState = State.Patrol; StartCoroutine(Patrol()); } void Update() { float distanceToPlayer = Vector3.Distance(transform.position, player.position); if (distanceToPlayer < detectionRange && !isHiding) { // AI makes a decision whether to chase or hide currentState = MakeDecision(distanceToPlayer); } switch (currentState) { case State.Patrol: PatrolBehavior(); break; case State.Chase: ChaseBehavior(distanceToPlayer); break; case State.Hide: HideBehavior(); break; } } // Q-learning decision-making (choosing between chasing and hiding) private State MakeDecision(float distanceToPlayer) { int action = 0; if (distanceToPlayer < engageRange) { action = Random.Range(0, 2); // Random decision for now } // Update Q-table and return the chosen action if (action == 0) { qTable[0] += 0.1f; // Preference for hiding return State.Hide; } else { qTable[1] += 0.1f; // Preference for chasing return State.Chase; } } // Patrol behavior (walking between points) void PatrolBehavior() { MoveTowards(patrolPoints[currentPatrolIndex].position, patrolSpeed); if (Vector3.Distance(transform.position, patrolPoints[currentPatrolIndex].position) < 1f) { currentPatrolIndex = (currentPatrolIndex + 1) % patrolPoints.Length; } } // Chase behavior (running or walking based on distance) void ChaseBehavior(float distanceToPlayer) { if (distanceToPlayer < engageRange) { MoveTowards(player.position, chaseSpeed); // Run if close } else { MoveTowards(player.position, patrolSpeed); // Walk if farther away } if (distanceToPlayer > detectionRange) { currentState = State.Patrol; // Return to patrol if player escapes } } // Hide behavior void HideBehavior() { MoveTowards(hideSpot.position, patrolSpeed); // Walk towards hiding spot if (Vector3.Distance(transform.position, hideSpot.position) < 1f) { StartCoroutine(StayHidden()); } } void MoveTowards(Vector3 target, float speed) { Vector3 direction = (target - transform.position).normalized; transform.position += direction * speed * Time.deltaTime; } IEnumerator StayHidden() { yield return new WaitForSeconds(3f); currentState = State.Patrol; } } What I’m trying to achieve:
Dynamic Decision-Making: I’d like the AI to intelligently choose between running or walking based on the situation. For example, it should run when chasing the player but walk during patrols or when it’s not in immediate danger.
Cover System: The AI should use cover dynamically, and currently, it moves towards a single hide spot (hideSpot). I'd like to make this system more advanced in the future.
Improved Learning: The AI uses a basic Q-learning approach right now, but I’m not sure how to enhance this to make the decisions feel more natural and based on player interaction.
Additionally, the AI should also shoot at the player. This functionality is not currently included in the script but is essential for achieving the intended behavior, similar to what is found in Call of Duty: Modern Warfare.
Any advice or suggestions on improving the AI's movement speed decision-making, cover usage, or enhancing the Q-learning system would be greatly appreciated.