So, I have scoured the internet for solutions to this problem, but am a beginner coder so haven’t been able to implement anything successfully. I need my enemies to pause when they spot the player, show their surprise at being disturbed with an exclamation mark, then chase the player (with the exclamation mark now vanished).
So far I have everything but the pause! I know I need to use either WaitForSeconds, or a CoRoutine, or something, but I can’t manage it! Any help would be much appreciated. 
using UnityEngine;
using System.Collections;
public class GuardLogic : MonoBehaviour {
public Transform sightStart, sightEnd;
public bool spotted = false;
public bool chasing = false;
public bool facingLeft = true;
public GameObject exclamation;
public float step;
void Start()
{
InvokeRepeating("Patrol", 0f, Random.Range (2f,6f));
}
void Update()
{
Raycasting ();
Behaviours ();
}
void Raycasting()
{
Debug.DrawLine (sightStart.position, sightEnd.position, Color.red);
spotted = Physics2D.Linecast (sightStart.position, sightEnd.position, 1 << LayerMask.NameToLayer("Engineer"));
}
void Behaviours()
{
if (spotted == true)
{
exclamation.SetActive (true);
chasing = true; <--- This is where I need a delay!
}
else
exclamation.SetActive (false);
if (chasing == true)
{
exclamation.SetActive (false);
Transform target;
float speed = 4f;
target = GameObject.FindWithTag ("Engineer").transform;
step = speed * Time.deltaTime;
transform.position = Vector3.MoveTowards (transform.position, target.position, step);
CancelInvoke("Patrol");
}
}
void Patrol()
{
facingLeft = !facingLeft;
if (facingLeft == true)
{
transform.eulerAngles = new Vector2 (0, 0);
}
else
{
transform.eulerAngles = new Vector2 (0, 180);
}
}
}
public Transform sightStart, sightEnd;
public bool spotted = false;
public bool chasing = false;
public bool facingLeft = true;
public GameObject exclamation;
public float step;
void Start()
{
InvokeRepeating("Patrol", 0f, Random.Range (2f,6f));
}
void Update()
{
Raycasting ();
Behaviours ();
}
void Raycasting()
{
Debug.DrawLine (sightStart.position, sightEnd.position, Color.red);
spotted = Physics2D.Linecast (sightStart.position, sightEnd.position, 1 << LayerMask.NameToLayer("Engineer"));
}
private bool wait = false;
IEnumerator justWait() {
yield return new WaitForSeconds(3f); //change the wait time here
spotted = false;
wait = false;
chasing = true;
}
void Behaviours()
{
if (spotted == true)
{
exclamation.SetActive (true);
if(!wait) {
StartCoroutine(justWait());
wait = true;
}
//chasing = true; <--- This is where I need a delay!
}
else
exclamation.SetActive (false);
if (chasing == true)
{
exclamation.SetActive (false);
Transform target;
float speed = 4f;
target = GameObject.FindWithTag ("Engineer").transform;
step = speed * Time.deltaTime;
transform.position = Vector3.MoveTowards (transform.position, target.position, step);
CancelInvoke("Patrol");
}
}
void Patrol()
{
facingLeft = !facingLeft;
if (facingLeft == true)
{
transform.eulerAngles = new Vector2 (0, 0);
}
else
{
transform.eulerAngles = new Vector2 (0, 180);
}
}
This should do the trick.
You can use a coroutine, like that:
public IEnumerator MyPause()
{
yield return new WaitForSeconds (3);
}
Insteatd of “3” create a variable! AFAIK a coroutine must not have a parameter,like MyPause(3)!
Before line 35: chasing is true,call the Coroutine:
StartCoroutine ("MyPause");
Hope, it helps!
Put this in when spotted is set to true
StartCoroutine(AppearStartledFor(3f));
IEnumerator AppearStartledFor(float seconds){
spotted = false;
exclamation.SetActive(true);
yield return new WaitForSeconds(seconds);
chase = true;
exclamation.SetActive(false);
}
This will wait for 3 seconds before setting chase to true, remember to set spotted to false, otherwise multiple coroutines will be started. You can also just to be safe use StopAllCoroutines
, if you want.
The invoke tutorial might be a good starting point