192 lines
6.7 KiB
C#
192 lines
6.7 KiB
C#
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<EnemyController>().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
|
|
}
|
|
|
|
|
|
} |