2025-10-30 16:50:35 +00:00
|
|
|
using System;
|
2025-10-28 17:26:07 +00:00
|
|
|
using RPG.Combat;
|
|
|
|
|
using RPG.Core;
|
2025-10-30 16:50:35 +00:00
|
|
|
using RPG.Movement;
|
2025-10-28 17:26:07 +00:00
|
|
|
using UnityEngine;
|
|
|
|
|
using UnityEngine.AI;
|
|
|
|
|
|
|
|
|
|
namespace RPG.Control
|
|
|
|
|
{
|
2025-10-31 20:33:41 +00:00
|
|
|
public class AIController : MonoBehaviour, IAction
|
2025-10-28 17:26:07 +00:00
|
|
|
{
|
|
|
|
|
[SerializeField] float chaseDistance = 5f;
|
2025-10-30 16:50:35 +00:00
|
|
|
[SerializeField] float suspicionTime = 3f;
|
2025-10-31 20:33:41 +00:00
|
|
|
[SerializeField] PatrolPath patrolPath;
|
|
|
|
|
[SerializeField] float waypointTolerence = 1f;
|
|
|
|
|
[SerializeField] float dwellingTime = 3f;
|
2025-10-28 17:26:07 +00:00
|
|
|
Fighter fighter;
|
2025-10-30 16:50:35 +00:00
|
|
|
Health health;
|
|
|
|
|
Mover mover;
|
2025-10-28 17:26:07 +00:00
|
|
|
GameObject player;
|
2025-10-30 16:50:35 +00:00
|
|
|
Vector3 guardPosition;
|
|
|
|
|
float timeSinceLastSawPlayer = Mathf.Infinity;
|
2025-10-31 20:33:41 +00:00
|
|
|
float timeSinceArrivedAtWaypoint = Mathf.Infinity;
|
|
|
|
|
int currentWaypointIndex = 0;
|
2025-10-30 16:50:35 +00:00
|
|
|
private void Start()
|
2025-10-28 17:26:07 +00:00
|
|
|
{
|
|
|
|
|
fighter = GetComponent<Fighter>();
|
2025-10-30 16:50:35 +00:00
|
|
|
health = GetComponent<Health>();
|
2025-10-28 17:26:07 +00:00
|
|
|
player = GameObject.FindWithTag("Player");
|
2025-10-30 16:50:35 +00:00
|
|
|
mover = GetComponent<Mover>();
|
|
|
|
|
guardPosition = transform.position;
|
2025-10-28 17:26:07 +00:00
|
|
|
}
|
2025-10-30 16:50:35 +00:00
|
|
|
private void Update()
|
2025-10-28 17:26:07 +00:00
|
|
|
{
|
2025-10-30 16:50:35 +00:00
|
|
|
if (health.IsDead()) return;
|
2025-10-28 17:26:07 +00:00
|
|
|
if (InAttackRangeOfPlayer() && fighter.CanAttack(player))
|
2025-10-30 16:50:35 +00:00
|
|
|
{
|
|
|
|
|
AttackBehaviour();
|
|
|
|
|
}
|
|
|
|
|
else if (timeSinceLastSawPlayer < suspicionTime)
|
|
|
|
|
{
|
|
|
|
|
SuspicionBehaviour();
|
|
|
|
|
}
|
2025-10-28 17:26:07 +00:00
|
|
|
else
|
|
|
|
|
{
|
2025-10-30 16:50:35 +00:00
|
|
|
//fighter.Cancel();
|
2025-10-31 20:33:41 +00:00
|
|
|
PatrolBehaviour();
|
2025-10-28 17:26:07 +00:00
|
|
|
}
|
2025-10-31 20:33:41 +00:00
|
|
|
UpdateTimers();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void UpdateTimers()
|
|
|
|
|
{
|
2025-10-30 16:50:35 +00:00
|
|
|
timeSinceLastSawPlayer += Time.deltaTime;
|
2025-10-31 20:33:41 +00:00
|
|
|
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);
|
2025-10-30 16:50:35 +00:00
|
|
|
}
|
|
|
|
|
|
2025-10-31 20:33:41 +00:00
|
|
|
private bool AtWaypoint()
|
2025-10-30 16:50:35 +00:00
|
|
|
{
|
2025-10-31 20:33:41 +00:00
|
|
|
float distanceToWaypoint = Vector3.Distance(transform.position, GetCurrentWaypoint());
|
|
|
|
|
return distanceToWaypoint < waypointTolerence;
|
2025-10-30 16:50:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void SuspicionBehaviour()
|
|
|
|
|
{
|
|
|
|
|
GetComponent<ActionScheduler>().CancelCurrentAction();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void AttackBehaviour()
|
|
|
|
|
{
|
2025-10-31 20:33:41 +00:00
|
|
|
timeSinceLastSawPlayer = 0;
|
2025-10-30 16:50:35 +00:00
|
|
|
fighter.Attack(player);
|
2025-10-28 17:26:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool InAttackRangeOfPlayer()
|
|
|
|
|
{
|
|
|
|
|
float distanceToPlayer = Vector3.Distance(player.transform.position, transform.position);
|
|
|
|
|
return distanceToPlayer < chaseDistance;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Cancel()
|
|
|
|
|
{
|
2025-10-30 16:50:35 +00:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
//Called bt Unity
|
|
|
|
|
private void OnDrawGizmosSelected()
|
|
|
|
|
{
|
|
|
|
|
Gizmos.color = Color.blue;
|
|
|
|
|
Gizmos.DrawWireSphere(transform.position, chaseDistance);
|
2025-10-28 17:26:07 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|