I’m trying to make an AI controller to make the enemy attack enemy allies and the same goes for allies to attack the enemy. I’ve modified the AIController.cs
this works but not as expected.
using RPG.Stats;
using RPG.Movement;
using UnityEngine;
using GameDevTV.Utils;
using System;
using System.Collections;
namespace RPG.Control
{
public class AIController : MonoBehaviour
{
[SerializeField] public float chaseDistance = 5f;
[SerializeField] float suspictionTime = 3f;
[SerializeField] PatrolPath patrolPath;
[SerializeField] float waypointTolerance = 1f;
[SerializeField] float waypointDwellTime = 3f;
[Range(0, 1)]
[SerializeField] float patrolSpeedFraction = 0.2f;
Fighter fighter;
GameObject player;
GameObject[] allies;
Health health;
Mover mover;
LazyValue<Vector3> guardPosition;
float timeSinceLastSawPlayer = Mathf.Infinity;
float timeSinceArrivedAtWaypoint = Mathf.Infinity;
int currentWaypointIndex = 0;
private void Awake()
{
fighter = GetComponent<Fighter>();
health = GetComponent<Health>();
mover = GetComponent<Mover>();
player = GameObject.FindWithTag("Player");
allies = GameObject.FindGameObjectsWithTag("Ally");
guardPosition = new LazyValue<Vector3>(GetGuardPosition);
}
private Vector3 GetGuardPosition()
{
return transform.position;
}
private void Start()
{
guardPosition.ForceInit();
}
private void Update()
{
AttackPlayer();
AttackAlly(allies);
}
private void AttackAlly(GameObject[] allies)
{
foreach(GameObject ally in allies)
{
Fighter fighter = GetComponent<Fighter>();
Health health = GetComponent<Health>();
if (health.IsDead()) return;
if (InAttackRangeOfAlly(ally) && fighter.CanAttack(ally))
{
AttackAllyBehaviour(ally);
}
else if (timeSinceLastSawPlayer < suspictionTime)
{
SuspicionBehaviour();
}
else
{
PatrolBehaviour();
}
UpdateTimers();
}
}
private void AttackPlayer()
{
if (health.IsDead()) return;
if (InAttackRangeOfPlayer() && fighter.CanAttack(player))
{
AttackBehaviour();
}
else if (timeSinceLastSawPlayer < suspictionTime)
{
SuspicionBehaviour();
}
else
{
PatrolBehaviour();
}
UpdateTimers();
}
private void UpdateTimers()
{
timeSinceLastSawPlayer += Time.deltaTime;
timeSinceArrivedAtWaypoint += Time.deltaTime;
}
private void PatrolBehaviour()
{
Vector3 nextPosition = guardPosition.value;
if (patrolPath != null)
{
if (AtWaypoint())
{
timeSinceArrivedAtWaypoint = 0;
CycleWaypoint();
}
nextPosition = GetCurrentWaypoint();
}
if (timeSinceArrivedAtWaypoint > waypointDwellTime)
{
mover.StartMoveAction(nextPosition, patrolSpeedFraction);
}
}
private bool AtWaypoint()
{
float distanceToWaypoint = Vector3.Distance(transform.position, GetCurrentWaypoint());
return distanceToWaypoint < waypointTolerance;
}
private void CycleWaypoint()
{
currentWaypointIndex = patrolPath.GetNextIndex(currentWaypointIndex);
}
private Vector3 GetCurrentWaypoint()
{
return patrolPath.GetWaypoint(currentWaypointIndex);
}
private void SuspicionBehaviour()
{
GetComponent<ActionSchedular>().CancelCurrentAction();
}
private void AttackBehaviour()
{
timeSinceLastSawPlayer = 0;
fighter.Attack(player);
}
private bool InAttackRangeOfPlayer()
{
float distanceToPlayer = Vector3.Distance(player.transform.position, transform.position);
return distanceToPlayer < chaseDistance;
}
private void AttackAllyBehaviour(GameObject ally)
{
timeSinceLastSawPlayer = 0;
fighter.Attack(ally);
}
private bool InAttackRangeOfAlly(GameObject ally)
{
float distanceToPlayer = Vector3.Distance(ally.transform.position, transform.position);
return distanceToPlayer < chaseDistance;
}
// Called by Unity
private void OnDrawGizmosSelected()
{
Gizmos.color = Color.blue;
Gizmos.DrawWireSphere(transform.position, chaseDistance);
}
}
}
and I created AllyController.cs the same as above but i removed the FindWithTag(“Player”);
also they attack one time and stops after and this is not the behavior i’m looking for.
can someone point me in the right direction