using UnityEngine;
namespace Code.Interfaces
{
public interface IEnemyState
{
void UpdateState();
void OnTriggerEnter (Collider other);
void ToPatrolState();
void ToAlertState();
void ToChaseState();
}
}
using UnityEngine;
using Code.States;
using Code.Interfaces;
public class StatePatternEnemy : MonoBehaviour
{
public float searchingTurnSpeed = 120f;
public float searchingDuration = 4f;
public float sightRange = 20f;
public Transform[] wayPoints;
public Transform eyes;
public Vector3 offset = new Vector3 (0,.5f,0);
public MeshRenderer meshRendererFlag;
[HideInInspector] public Transform chaseTarget;
[HideInInspector] public IEnemyState currentState;
[HideInInspector] public ChaseState chaseState;
[HideInInspector] public AlertState alertState;
[HideInInspector] public PatrolState patrolState;
[HideInInspector] public NavMeshAgent navMeshAgent;
private void Awake()
{
chaseState = new ChaseState (this);
alertState = new AlertState (this);
patrolState = new PatrolState (this);
navMeshAgent = GetComponent<NavMeshAgent> ();
}
// Use this for initialization
void Start ()
{
currentState = patrolState;
}
// Update is called once per frame
void Update ()
{
currentState.UpdateState ();
}
private void OnTriggerEnter(Collider other)
{
currentState.OnTriggerEnter (other);
}
}
using UnityEngine;
using System.Collections;
using Code.Interfaces;
namespace Code.States
{
public class PatrolState : IEnemyState
{
private readonly StatePatternEnemy enemy;
private int nextWayPoint;
public PatrolState (StatePatternEnemy statePatternEnemy)
{
enemy = statePatternEnemy;
}
public void UpdateState()
{
Look ();
Patrol ();
}
public void OnTriggerEnter (Collider other)
{
if (other.gameObject.CompareTag ("Player"))
ToAlertState ();
}
public void ToPatrolState()
{
Debug.Log ("Can't transition to same state");
}
public void ToAlertState()
{
enemy.currentState = enemy.alertState;
}
public void ToChaseState()
{
enemy.currentState = enemy.chaseState;
}
private void Look()
{
RaycastHit hit;
if (Physics.Raycast (enemy.eyes.transform.position, enemy.eyes.transform.forward, out hit, enemy.sightRange) && hit.collider.CompareTag ("Player")) {
enemy.chaseTarget = hit.transform;
ToChaseState();
}
}
void Patrol ()
{
enemy.meshRendererFlag.material.color = Color.green;
enemy.navMeshAgent.destination = enemy.wayPoints [nextWayPoint].position;
enemy.navMeshAgent.Resume ();
if (enemy.navMeshAgent.remainingDistance <= enemy.navMeshAgent.stoppingDistance && !enemy.navMeshAgent.pathPending) {
nextWayPoint =(nextWayPoint + 1) % enemy.wayPoints.Length;
}
}
}
}
using UnityEngine;
using System.Collections;
using Code.Interfaces;
namespace Code.States
{
public class AlertState : IEnemyState
{
private readonly StatePatternEnemy enemy;
private float searchTimer;
public AlertState (StatePatternEnemy statePatternEnemy)
{
enemy = statePatternEnemy;
}
public void UpdateState()
{
Look ();
Search ();
}
public void OnTriggerEnter (Collider other)
{
}
public void ToPatrolState()
{
enemy.currentState = enemy.patrolState;
searchTimer = 0f;
}
public void ToAlertState()
{
Debug.Log ("Can't transition to same state");
}
public void ToChaseState()
{
enemy.currentState = enemy.chaseState;
searchTimer = 0f;
}
private void Look()
{
RaycastHit hit;
if (Physics.Raycast (enemy.eyes.transform.position, enemy.eyes.transform.forward, out hit, enemy.sightRange) && hit.collider.CompareTag ("Player")) {
enemy.chaseTarget = hit.transform;
ToChaseState();
}
}
private void Search()
{
enemy.meshRendererFlag.material.color = Color.yellow;
enemy.navMeshAgent.Stop ();
enemy.transform.Rotate (0, enemy.searchingTurnSpeed * Time.deltaTime, 0);
searchTimer += Time.deltaTime;
if (searchTimer >= enemy.searchingDuration)
ToPatrolState ();
}
}
}
using UnityEngine;
using System.Collections;
using Code.Interfaces;
namespace Code.States
{
public class ChaseState : IEnemyState
{
private readonly StatePatternEnemy enemy;
public ChaseState (StatePatternEnemy statePatternEnemy)
{
enemy = statePatternEnemy;
}
public void UpdateState()
{
Look ();
Chase ();
}
public void OnTriggerEnter (Collider other)
{
}
public void ToPatrolState()
{
}
public void ToAlertState()
{
enemy.currentState = enemy.alertState;
}
public void ToChaseState()
{
}
private void Look()
{
RaycastHit hit;
Vector3 enemyToTarget = (enemy.chaseTarget.position + enemy.offset) - enemy.eyes.transform.position;
if (Physics.Raycast (enemy.eyes.transform.position, enemyToTarget, out hit, enemy.sightRange) && hit.collider.CompareTag ("Player")) {
enemy.chaseTarget = hit.transform;
}
else
{
ToAlertState();
}
}
private void Chase()
{
enemy.meshRendererFlag.material.color = Color.red;
enemy.navMeshAgent.destination = enemy.chaseTarget.position;
enemy.navMeshAgent.Resume ();
}
}
}