Fast Question about Coroutines

Hi. Im coding my character´s movement so if it getmousebutton (1), he will do an animation, and after X secs(animation length), it will be false… (melee ones)

So worked fine until now.

Now im trying to change weapons, and i dont want to change the weapon if the animation melee1 is playing so…

I thought about this:

                if (Input.GetMouseButton (1) && m == 1) {
                        canSwing = true;
                       
                        animador.SetBool ("Aim", true);
                       //v & h movement on x and y axis.
                        if (v > 0.1) {
                                animador.SetBool ("Aim", false);
                                animador.SetBool ("Walk", true);
                        }
                        if (v < 0) {
                                animador.SetBool ("Aim", false);
                                animador.SetBool ("Atras", true);
                        }

                        if (h < -0.1) {
                                animador.SetBool ("Aim", false);
                                animador.SetBool ("WalkLeft", true);
                        }
                        if (h > 0.1) {
                                animador.SetBool ("Aim", false);
                                animador.SetBool ("Walkright", true);
                        }
                       
                        StartCoroutine(WaitSec(0.83F));
                        animador.SetBool ("Aim",false);
                        canSwing=false;
                }

With a simple IEnumerator:

IEnumerator WaitSec(float waitime)
    {
        yield return new WaitForSeconds(waitime);
    }

And it seems that its not working… I mean the conditional isnt doint anything. It seems that animation will have true and instanly false value. Thats not the purpose of the StartCoroutine? Wait 0.83secs (animation lenght) and change that parameters? (true-to false) :S

I think i missunderstanding something

The way a coroutine works is when it reaches that ‘yield return new WaitForSeconds(waitime)’ line there, it yields control to the rest of your program. So it hits that line, then it goes on to do the rest of your program. The only thing that’s held up by the yield statement is the code inside the WaitSec coroutine function itself. Any code after that yield statement will not run until the wait time is complete.

So what you can do is make the code with your if conditions a coroutine itself, then put in:

yield return StartCoroutine(WaitSec(0.83F);

Instead of the regular StartCoroutine call.

This will ensure your first coroutine waits for the second coroutine to finish. And the second coroutine won’t finish until the wait time is done.

1 Like

Two other things you could do, that might make more sense:

  1. Put this code:

animador.SetBool (“Aim”,false);
canSwing=false;

Inside the WaitSec coroutine under the yield statement.

  1. Use Invoke. Put that code in a separate function, and call it using the Invoke(“Method_Name”, wait_time) function.
1 Like

Except that the first function will be running every frame (I assume it’s part of Update) - Every single frame, it’ll check for the input, then launch a new coroutine. Then the next frame, it checks for input, and launches a new coroutine. You’ll have hundreds of these things running simultaneously, causing all sorts of problems. Update cannot be a coroutine, explicitly to prevent this. Truth is, Update and Coroutines don’t get along very well. It’s a “use carefully, and only if you fully understand coroutines” sort of thing.

Coroutines aren’t the solution for this. Actually, MecAnim has a solution - animation events. Especially since these events are, conceptually, dependent on animations anyway. Have these animations call a function on your script that does the thing you need them to do, at the end of the animation.

1 Like

Thanks guys! Very helpfull. And yup its in the update function. Didnt know how animations events work!

The problem is that i havent the animations in here. Its a code for a friend… So i cant use the animation stuff. He has on mecanim if (“melee1”,true)-> enter the animation… and exit if exit time->animation.length.

So im thinking about make the things in another way:

1.Tell him to change exit conditional on mecanim from exit time to animationbool->false
2. Change GetmouseButton for GetMouseButtonDown and animationbool=true
3. Get a GetMouseButtonUp to gave it the animationbool a false value
4. Put inside a timer(insideGetMouseButtonDown bassed on time.deltatime) for the raycast stuff when the animation is in the middle of it.