using Akila.FPSFramework; using RaycastPro.Detectors; using UnityEngine; public class AIBehaviour : MonoBehaviour { public enum AIType { None, Enemy, Ally, Neutral } [SerializeField] private AIType aiType = AIType.None; [SerializeField] private float detectionRange, attackRange, contactRange, pointWaitTimer, moveSpeed, attackDamage, currentHealth, maxHealth; // Example ranges for detecting and attacking targets private float waitCounter; // Timer for waiting at patrol points [SerializeField] private Animator animator; // Animator for handling animations [SerializeField] private Transform[] patrolPoints; [SerializeField] private Transform pointsHolder; // Optional holder for patrol points private int currentPatrolPoint = 0; private bool isEngaged = false; // Flag to control patrolling [SerializeField] private Rigidbody theRB; // Rigidbody for movement control [SerializeField] private SightDetector sightDetector; // Sight detector for detecting targets private void Start() { // Start patrolling Patrol(); if (pointsHolder != null) { pointsHolder.SetParent(null); } if (patrolPoints.Length == 0) { Debug.LogWarning("No patrol points assigned. AI will not patrol."); } if (animator == null) { Debug.LogError("Animator not assigned. AI will not animate."); } if (theRB == null) { Debug.LogError("Rigidbody not assigned. AI will not move."); } currentPatrolPoint = 0; // Start at the first patrol point waitCounter = Random.Range(0.75f, 1.25f) * pointWaitTimer; currentHealth = maxHealth; // Initialize current health detectionRange = sightDetector.Radius; // Set detection range based on sight detector radius attackRange = detectionRange - 10f; // Set attack range based on detection range minus 10 contactRange = sightDetector.fullAwareness; // Set contact range based on sight detector full awareness } private void Update() { if (!isEngaged && patrolPoints.Length > 0) { Patrol(); } else if (patrolPoints.Length == 0) { Debug.LogWarning("No patrol points assigned. AI will not patrol."); } } public void TargetDetected(Collider detectedCollider) { if (detectedCollider == null) return; float distance = Vector3.Distance(transform.position, detectedCollider.transform.position); if (detectedCollider.gameObject.CompareTag("Player") && this.aiType == AIType.Ally) { // Player logic remains unchanged if (distance <= attackRange) { Debug.Log("Keep moving civilian, don't get too close!"); // Add logic to attack the player } else if (distance <= detectionRange) { Debug.Log("Stay safe civilian..."); // Add logic to engage with the player } else { Debug.Log("Player out of detection range."); } } else if (detectedCollider.CompareTag("Enemy") && this.aiType == AIType.Ally) { if (distance <= attackRange) { isEngaged = true; StopMovement(); Debug.Log("Open fire!"); animator.SetBool("shooting", true); // Start attacking animation AttackTarget(detectedCollider); // Call the attack method } else if (distance <= detectionRange) { isEngaged = true; StopMovement(); Debug.Log("Zombie sighted!"); transform.LookAt(detectedCollider.transform); animator.SetBool("aiming", true); // Start aiming animation } else { isEngaged = false; Debug.Log("Enemy out of detection range."); animator.SetBool("shooting", false); // Stop shooting animation animator.SetBool("aiming", false); // Stop aiming animation currentPatrolPoint = (currentPatrolPoint + 1) % patrolPoints.Length; Patrol(); } } // You can add more logic here, such as engaging with the target or updating AI state } public void Patrol() { animator.SetFloat("speed", 0.5f); // Slow down the patrol animation for better visibility if (patrolPoints.Length == 0) return; Transform targetPoint = patrolPoints[currentPatrolPoint]; transform.LookAt(targetPoint); transform.position = Vector3.MoveTowards(transform.position, targetPoint.position, moveSpeed * Time.deltaTime); if (Vector3.Distance(transform.position, targetPoint.position) < 0.1f) { currentPatrolPoint = (currentPatrolPoint + 1) % patrolPoints.Length; waitCounter -= Time.deltaTime; if (waitCounter <= 0) { currentPatrolPoint++; if (currentPatrolPoint >= patrolPoints.Length) { currentPatrolPoint = 0; } waitCounter = Random.Range(0.75f, 1.25f) * pointWaitTimer; } } } private void StopMovement() { if (theRB != null) { theRB.linearVelocity = Vector3.zero; // Stop the Rigidbody movement } animator.SetFloat("speed", 0f); // Set animation speed to idle } private void AttackTarget(Collider collider) { if (theRB != null) { theRB.linearVelocity = Vector3.zero; // Stop the Rigidbody movement } animator.SetFloat("speed", 0f); // Set animation speed to idle animator.SetBool("shooting", true); // Start attacking animation collider.GetComponent().TakeDamage(attackDamage); // Example damage value Debug.Log("Attacked target: " + collider.name + " for " + attackDamage + " damage."); } public void TakeDamage(float damageToTake) { // Handle taking damage logic here Debug.Log("AI took " + damageToTake + " damage."); currentHealth -= damageToTake; if (currentHealth <= 0) { Die(); } } private void Die() { Debug.Log("AI has died."); animator.SetTrigger("die"); // Trigger death animation isEngaged = false; // Stop any engagement StopMovement(); // Stop movement // Additional logic for AI death, such as disabling components or destroying the object } }