How to make an object do a behavior for a short amount of time

Total newbie at scripting here.
When this object hits a tagged wall, it needs to turn around and run for a few seconds then go back to it’s previous state. It’s doing everything correct except running straight for a few seconds. Its hitting the wall then it rotates but it just sits there for a few seconds instead of running in a straight line, then it goes back to it’s previous state of fleeing the player like it’s supposed to.

using UnityEngine;
using System.Collections;
public class catScript : MonoBehaviour {
public Transform target;
public Transform wall01;
public Transform wall02;
public Transform wall03;
public Transform wall04;

public float catSpeed;
public float catSpeed2;
public float stareAtPlayerDist;
public float fleePlayerDist;
public bool hitWallRun = false;
// Use this for initialization
void Start () {

}
void OnTriggerEnter(Collider other)
{
if (other.tag.Equals ("catZone")) {
Debug.Log ("I hit a wall");
hitWallRun = true;
Debug.Log ("cat hit boundry");

transform.Rotate (0, 60, 0);

StartCoroutine ("turnBoolFalse");

}
}
// Update is called once per frame
void Update () {


//z is forward, y is up
//Distance between object and player
float dist = Vector3.Distance (target.position, transform.position);

if (dist <= stareAtPlayerDist && dist > fleePlayerDist && hitWallRun == false)
{
transform.LookAt (target);
}
else if (dist <= fleePlayerDist && hitWallRun == false)
{
CharacterController controller = GetComponent<CharacterController> ();
Vector3 forward = transform.TransformDirection (Vector3.forward);
transform.LookAt (target);
transform.Rotate(0,180,0);
controller.SimpleMove (forward * catSpeed);
}

}
IEnumerator turnBoolFalse()
{
do {
CharacterController controller = GetComponent<CharacterController> ();
Vector3 forward = transform.TransformDirection (Vector3.forward);
controller.SimpleMove (forward * catSpeed2);
yield return new WaitForSeconds (5.0f);
hitWallRun = false;
} while (hitWallRun == false);
}
}

“yield return new WaitForSeconds (5.0f);”

This line will basically pause your ‘turnBoolFalse’ method for 5 seconds before resuming your code. What you need to do is create a loop that pauses for each WaitForEndOfFrame, then inside this loop you need to increment a counter using Time.deltaTime, and once the total exceeds 5 seconds, it exists the loop.

I too needed adding delays to things, so I came up with this extension method. Copy this class into your project and you should be good to go. Hope it helps.

public static class MonoExtensions
{

    /*
     * SAMPLE USAGE : (CAN ONLY BE CALLED FROM MONOBEHAVIOR)
     * this.PerformActionWithDelay(1.3f, () => {    Debug.Log("Executed after 1.3 seconds!");    }
     */

    public static void PerformActionWithDelay(this MonoBehaviour mono, float delay, Action action, Action callback = null)
    {
        mono.StartCoroutine(mono.PerformActionWithDelayRoutine(delay, action, callback));
    }

    private static IEnumerator PerformActionWithDelayRoutine(this MonoBehaviour ienum, float delay, Action action, Action callback)
    {
        yield return new WaitForSeconds(delay);

        action();

        if(callback != null)
            callback();
    }

    /******************************************************************************************************************************/
}

See the sample usage in comments inside the class. What it is doing is running a co-routine, just like @Darkcoder_1 suggested, but you won’t have to worry about it.

Feel free to add to it and share :slight_smile:

1 Like
StartCoroutine (MonoExtensions.PerformActionWithDelayRoutine(delay,action, callback));

this will work too it calling class has inherited from monobehavior and coroutine need to be public static…