Hi all,
I’m new to Unity. I’ve been working on a small game where the player has to navigate a maze with enemies that will start chasing the player if the player enters their line of sight. The enemy will quit chasing the player if the player can escape the enemy’s line of sight for a consecutive number of seconds. If the enemy “sees” the player again after they’ve already escaped their line of sight, but before the countdown has finished, the timer will reset and the chase will continue. The code I have works, but it feels unruly. Is there any better way to implement this?
What I have:
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class EnemyAI : MonoBehaviour
{
public GameObject target,
timerHUD;
public float timerInit;
public AudioClip detectedSFX,
clearSFX;
private NavMeshAgent navAgent;
private Ray ray;
private RaycastHit hit;
private AudioSource sounds;
private Vector3 originPos;
private Quaternion originRot;
private bool playerDetected = false;
private float timer;
// Use this for initialization
void Start()
{
navAgent = GetComponent<NavMeshAgent>();
sounds = GetComponent<AudioSource>();
originPos = transform.position;
originRot = transform.rotation;
timer = timerInit;
}
// Update is called once per frame
void FixedUpdate()
{
ray = new Ray(transform.position, transform.forward);
timerHUD.GetComponent<Text>().text = timer.ToString("0.0");
if (playerDetected == false)
{
Undetected();
}
if (playerDetected == true)
{
Detected();
}
}
void Detected()
{
navAgent.destination = target.transform.position;
if (Physics.Raycast(ray, out hit, 3f))
{
if (hit.collider.transform.tag == target.transform.tag)
{
timer = timerInit; // Start the countdown over if the player is seen again
}
else
{
timer -= Time.deltaTime; // Countdown if the player breaks the line of sight
}
}
else
{
timer -= Time.deltaTime; // Countdown if the player breaks the line of site
}
if (timer <= 0)
{
timer = 0;
playerDetected = false; // Switch to undetected behaviour if the timer reaches zero
sounds.PlayOneShot(clearSFX); // Play a sound to let the player know the enemy has stopped their pursuit
}
}
void Undetected()
{
if (timer != timerInit)
{
timer = timerInit; // Reset the timer if it is less than timer Init (IE after a detection event)
}
if (Physics.Raycast(ray, out hit, 3f))
{
if (hit.collider.transform.tag == target.transform.tag)
{
playerDetected = true; // Switch to detected behaviour if the raycast hits the target (player)
sounds.PlayOneShot(detectedSFX); // Play a sound to let the player know they've been detected
}
}
if (navAgent.destination != originPos)
{
navAgent.SetDestination(originPos); // Reset the enemy's position
}
if (transform.position.x == originPos.x && transform.position.z == originPos.z)
{
transform.rotation = originRot; // Reset the enemy's rotation
}
}
}
Any advice would be greatly appreciated. Thanks in advance.