UnityGameProjectsCode / RelianceGame / AI Control / Enemy Scripts / EnemyPartnerState.cs
EnemyPartnerState.cs
Raw
using EnemyAIMachineTools;
using System.Collections;
using UnityEngine;

public class EnemyPartnerState : EnemyState
{
    private static EnemyPartnerState _instance; //only declared once

    private EnemyPartnerState() //set instance to itself
    {
        if (_instance != null)
        {
            return;
        }

        _instance = this;
    }

    public static EnemyPartnerState instance //creates the instance of the first state if it does not exist
    {
        get
        {
            if (_instance == null)
            {
                new EnemyPartnerState();
            }

            return _instance;
        }
    }

    public override IEnumerator InState(EnemyAIMachine owner) //no errors but not all leaders get followers and some bots wont move after spawning
    {
        bool followTargetFound = false;
        GameObject followTarget = null;

        while (owner.botMachine.currentState == EnemyPartnerState.instance)
        {
            if (!owner.disabled)
            {
                if (!followTargetFound) //check if the target has been found before entering the loop
                {
                    //check each bot for open slots and then set them as the follow target
                    for (int i = 0; i < owner.movingBotsOnly.Count; i++)
                    {
                        var targetBot = owner.movingBotsOnly[i].GetComponent<EnemyAIMachine>();

                        if (targetBot.leader == true) //check if the bot is a leader
                        {
                            if (targetBot.partnerBot == null) //if the first partner slot is empty, fill it and then break out of the for loop
                            {
                                targetBot.partnerBot = owner.gameObject;
                                followTarget = owner.movingBotsOnly[i];
                                followTargetFound = true;
                                break;
                            }

                            if (targetBot.partnerBot1 == null) //if the second partner slot is empty, fill it and then break out of the loop
                            {
                                targetBot.partnerBot1 = owner.gameObject;
                                followTarget = owner.movingBotsOnly[i];
                                followTargetFound = true;
                                break;
                            }
                        }
                    }
                    if (!followTargetFound || followTarget == null || !followTarget.activeSelf) //if a follow target is not found after checking each bot, revert to regular searching
                    {
                        followTarget = null;
                        followTargetFound = false;

                        owner.insidePartner = false;
                        owner.insideNormalSearch = true;
                        owner.botMachine.ChangeState(EnemySearchState.instance);
                    }
                }

                if (followTargetFound == true && followTarget != null && followTarget.activeSelf) //check if the target exists and is active
                {
                    if (Vector3.Angle(owner.transform.forward, followTarget.transform.position - owner.transform.position) < 15)
                    {
                        owner.thisAgent.SetDestination(followTarget.transform.position);

                        //if the bot is too close to the target, stop where you are
                        if (Vector3.Distance(owner.transform.position, followTarget.transform.position) <= owner.followDistance)
                        {
                            owner.thisAgent.SetDestination(owner.transform.position);
                        }
                    }
                    else
                        RotateBody(owner, followTarget.transform.position);

                    //if the bot finds an enemy while following, chase it
                    if (owner.canSeeEnemy && owner.enemyObject != null)
                    {
                        //enter the partner chase state
                        owner.botMachine.ChangeState(EnemyChaseState.instance);
                    }
                }

                if (followTarget == null || followTargetFound == false || !followTarget.activeSelf) //if the target is null or inactive, reset the variables
                {
                    followTarget = null;
                    followTargetFound = false;

                    owner.insidePartner = false;
                    owner.insideNormalSearch = true;
                    owner.botMachine.ChangeState(EnemySearchState.instance);
                }
            }
            else
            {
                owner.thisAgent.SetDestination(owner.transform.position);
            }
            yield return null;
        }
    }

    private void RotateBody(EnemyAIMachine _owner, Vector3 navPoint) //called to have the bot rotate to face the waypoint before navigating to it
    {
        //declare variables that will be used to determine how to move the bot
        Quaternion targetRot = Quaternion.LookRotation(navPoint - _owner.transform.position);

        //rotate the bot over time to face the enemy
        _owner.transform.rotation = Quaternion.RotateTowards(_owner.transform.rotation, targetRot, Time.deltaTime * _owner.bodyRotateSpeed);

        //set the bots y euler angle so that it only moves on that transform
        _owner.transform.localEulerAngles = new Vector3(0, _owner.transform.localEulerAngles.y, 0);
    }

}