Home > Net >  Unity - Delay Code Doesn't work in update script
Unity - Delay Code Doesn't work in update script

Time:04-12

I have code to changer the gravity of the character and to flip the camera after a second but I'm getting the error, "The body of 'Gravity.Update()' cannot be an iterator block because 'void' is not an iterator interface type".

void Update()
{
    if (Input.GetKey(KeyCode.Mouse1) && grounded)
    {
        Physics.gravity = new Vector3(0, 10.0f, 0);
        yield return new WaitForSeconds(1);
        transform.localEulerAngles = new Vector3(0, 0, 180);

    }
    if (Input.GetMouseButtonDown(0) && grounded)
    {
        Physics.gravity = new Vector3(0, -10.0f, 0);

        yield return new WaitForSeconds(1);
        transform.localEulerAngles = new Vector3(0, 0, 0);


    }
}

CodePudding user response:

You will want to create a coroutine. You cannot yield return in void Update().

Here is an example for your code:

void Update()
{
    if (Input.GetMouseButtonDown(0) && grounded)
    {
        StartCoroutine(WaitAndThenDoSomething(1));
    }
}

private IEnumerator WaitAndThenDoSomething(float waitTime)
{
    //any code before yield will run immediately
    Physics.gravity = new Vector3(0, -10.0f, 0);

    yield return new WaitForSeconds(waitTime);
        
    //any code after yield will run after the defined waitTime in seconds
    transform.localEulerAngles = new Vector3(0, 0, 0);

    //you can add more yield return new WaitForSeconds(waitTime) if multiple pauses are necessary

}

Insure that you don't run StartCoroutine every frame, and keep it in a single trigger, such as how you have it under GetMouseButtonDown. You don't want a bunch of coroutines getting called every frame for the same wait action.

If you need to cancel the coroutine before the wait time ends, you can stop all coroutines with

StopAllCoroutines();

But this will stop every coroutine, so it might be more useful to create an instance of each coroutine type that you intend to run. For example, instead of StartCoroutine(WaitAndDoSomething(1)), you can do this:

IEnumerator waitAndDoSomething = WaitAndThenDoSomething(1);
StarCoroutine(waitAndDoSomething);

then whenever you want to stop this specific coroutine, you can call

StopCoroutine(waitAndDoSomething);

Note that you will need to stop this coroutine whenever your character jumps again, otherwise if they land and jump before 1 second is up, the code will run when it is unintended. Coroutines run in the background, so be aware of that. Or you will have to insure the user cannot jump again within 1 second time.

  • Related