using EnemyAIMachineTools; using System.Collections; using UnityEngine; public class EnemyChaseState : EnemyState { private static EnemyChaseState _instance; //only declared once private EnemyChaseState() //set instance to itself { if (_instance != null) { return; } _instance = this; } public static EnemyChaseState instance //creates the instance of the first state if it does not exist { get { if (_instance == null) { new EnemyChaseState(); } return _instance; } } public override IEnumerator InState(EnemyAIMachine owner) { float timeBeforeAttack = 2.0f; float timeSinceEnteredState = 0.0f; while (owner.botMachine.currentState == EnemyChaseState.instance) { if (!owner.disabled) { if (timeSinceEnteredState < timeBeforeAttack) timeSinceEnteredState += Time.deltaTime; if (owner.enemyObject == null) //if the enemy is gone, go back to search { owner.health = null; if (owner.insideNormalSearch) owner.botMachine.ChangeState(EnemySearchState.instance); else if (owner.insideDefend) owner.botMachine.ChangeState(EnemyMoveToState.instance); else if (owner.insidePartner) owner.botMachine.ChangeState(EnemyPartnerState.instance); yield break; } if (owner.enemyObject != null) //if the enemy is still around, go after it { if (Vector3.Angle(owner.transform.forward, owner.enemyObject.transform.position - owner.transform.position) <= 15) { MoveTurret(owner, owner.enemyObject.transform.position); owner.thisAgent.SetDestination(owner.enemyObject.transform.position); if (Vector3.Distance(owner.transform.position, owner.enemyObject.transform.position) <= owner.attackDistance && owner.canSeeEnemy && timeSinceEnteredState >= timeBeforeAttack) //if the enemy is in attack range and is visible, attack it { owner.botMachine.ChangeState(EnemyAttackState.instance); yield break; } } else RotateBody(owner, owner.enemyObject.transform.position); if (Vector3.Distance(owner.transform.position, owner.enemyObject.transform.position) <= owner.attackDistance && owner.canSeeEnemy && timeSinceEnteredState >= timeBeforeAttack) //if the enemy is in range and visible but the bot is not rotated, just attack it { owner.botMachine.ChangeState(EnemyAttackState.instance); yield break; } } } 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); } private void MoveTurret(EnemyAIMachine _owner, Vector3 hitPos) //called to move the bots turret so that it faces whatever Vector3 is sent { //declare variables that will be used to determine how to move the turret Quaternion hitRot = Quaternion.LookRotation(hitPos - _owner.transform.position); Quaternion turretRot = Quaternion.LookRotation(hitPos - _owner.turretPos.transform.position); if (Vector3.Angle(_owner.turretPos.transform.forward, hitPos - _owner.turretPos.transform.position) > 5) //rotate the turret until it is facing within 5 degrees of the target { //rotate the turret over time to the target _owner.turretPos.transform.rotation = Quaternion.RotateTowards(_owner.turretPos.transform.rotation, turretRot, Time.deltaTime * _owner.turretRotateSpeed); //set the turrets y euler angle so that it only moves on that transform _owner.turretPos.transform.localEulerAngles = new Vector3(0, _owner.turretPos.transform.localEulerAngles.y, 0); } //rotate the barrel over time to the target _owner.barrelPos.transform.rotation = Quaternion.RotateTowards(_owner.barrelPos.transform.rotation, turretRot, Time.deltaTime * _owner.barrelMoveSpeed); //set the barrels y euler angle so that it only moves on that transform _owner.barrelPos.transform.localEulerAngles = new Vector3(0, _owner.barrelPos.transform.localEulerAngles.y, 0); } }