Files
GoblinRaid/Assets/Scripts/Control/AIController.cs

120 lines
3.4 KiB
C#
Raw Normal View History

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
}
}
}