using System; using RPG.Combat; using RPG.Core; using RPG.Movement; using UnityEngine; using UnityEngine.AI; namespace RPG.Control { public class AIController : MonoBehaviour, IAction { [SerializeField] float chaseDistance = 5f; [SerializeField] float suspicionTime = 3f; [SerializeField] PatrolPath patrolPath; [SerializeField] float waypointTolerence = 1f; [SerializeField] float dwellingTime = 3f; Fighter fighter; Health health; Mover mover; GameObject player; Vector3 guardPosition; float timeSinceLastSawPlayer = Mathf.Infinity; float timeSinceArrivedAtWaypoint = Mathf.Infinity; int currentWaypointIndex = 0; private void Start() { fighter = GetComponent(); health = GetComponent(); player = GameObject.FindWithTag("Player"); mover = GetComponent(); guardPosition = transform.position; } private void Update() { if (health.IsDead()) return; if (InAttackRangeOfPlayer() && fighter.CanAttack(player)) { AttackBehaviour(); } else if (timeSinceLastSawPlayer < suspicionTime) { SuspicionBehaviour(); } else { //fighter.Cancel(); PatrolBehaviour(); } UpdateTimers(); } private void UpdateTimers() { timeSinceLastSawPlayer += Time.deltaTime; timeSinceArrivedAtWaypoint += Time.deltaTime; } private void PatrolBehaviour() { Vector3 nextPosition = guardPosition; if (patrolPath != null) { if (AtWaypoint()) { timeSinceArrivedAtWaypoint = 0; CycleWaypoint(); } nextPosition = GetCurrentWaypoint(); } if (timeSinceArrivedAtWaypoint > dwellingTime) { mover.StartMoveAction(nextPosition); } } private Vector3 GetCurrentWaypoint() { return patrolPath.GetWaypoint(currentWaypointIndex); } private void CycleWaypoint() { currentWaypointIndex = patrolPath.GetNextIndex(currentWaypointIndex); } private bool AtWaypoint() { float distanceToWaypoint = Vector3.Distance(transform.position, GetCurrentWaypoint()); return distanceToWaypoint < waypointTolerence; } private void SuspicionBehaviour() { GetComponent().CancelCurrentAction(); } private void AttackBehaviour() { timeSinceLastSawPlayer = 0; fighter.Attack(player); } private bool InAttackRangeOfPlayer() { float distanceToPlayer = Vector3.Distance(player.transform.position, transform.position); return distanceToPlayer < chaseDistance; } public void Cancel() { } //Called bt Unity private void OnDrawGizmosSelected() { Gizmos.color = Color.blue; Gizmos.DrawWireSphere(transform.position, chaseDistance); } } }