How to make enemy vs ally AI Controller?

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

A more sensible approach to this is through inheritance… then back to one AI Controller…
Start with a base controller:
public abstract class ControllerBase: MonoBehavior
{
public int Team;
}

Then make both AIController and PlayerController inherit from ControllerBase
public class AIController: ControllerBase
{
}
public class PlayerController: ControllerBase
{
}
Set the Team to 0 for the player and the allies, 1 for the enemies.
Then when you search for controllers, instead of searching for AllyControllers/AIControllers/etc, just search for ControllerBase. If the other controller’s team is not the same as your team, then it shoudl become the target and you’ll attack it.

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms