user393267
user393267

Reputation:

Controlling animations in an animator via parameters, in sequences

So I am animating an avatar, and this avatar has its own animator with states and such. When interacting with props, the props itself has an animator with states in it. In both case, I transition to some animations through parameters in the animator (bool type).

For example, for a door, the character will have "isOpeningDoor", while the door will have "isOpen".

Now the question: when I change the value on an animator on GO1, and then change the bool on GO2; do the first animation finish and then the second start? Because in my case, it does not happen; they start almost at the same time.

void OnTriggerEnter (collider door)
{
    if (door.gameObject.tag=="door")
    {
         GOAnimator1.SetBool("isOpeningDoor", true);
         GOAnimator2.SetBool("isOpen", true);
    }
}

I believe that I am doing it wrong, since I change the parameter on the animator, but I do not check for the animation to end; is this even possible or am I doing something not kosher?

Upvotes: 1

Views: 284

Answers (1)

Jordi
Jordi

Reputation: 36

I really think it might be doable!

As you have it in your code now, the animations on GO1 and GO2 start at almost the same time because that's how it's written. The OnTriggerEnter() function will complete the execution in the frame it is called, and return the control to Unity.

What I think that might help you are coroutines and sendMessage between gameobjects:

The idea is to:

  1. Create a coroutine in GO2 that waits an amount of time until it sets the GOAnimator2 variable to activate the door animation.
  2. Create a function in GO2 that calls the aforementioned coroutine
  3. From the OnTriggerEnter() send a message to GO2 to execute the newly created function

It reads complicated, but it's fairly simple. The execution would be like this:

1.Code for the coroutine:

    function GO2coroutine(){
      float timeToWait = 0.5f; //Tweak this
      for ( float t = 0f; t < timeToWait; t+=time.deltaTime)
        yield; 
      GetComponent<Animator>().SetBool("isOpen",true);
    }
  1. Code for the function calling it:

    function callCoroutine() {
      StartCoroutine("Fade");
    }
    
  2. And the code modification for your OnTriggerEnter():

    void OnTriggerEnter (collider door)
    {
        if (door.gameObject.tag=="door")
        {
             GOAnimator1.SetBool("isOpeningDoor", true);
             GO2.SendMessage("callCoroutine");
        }
    }
    

I didn't have a chance to test the code, so please don't copy paste it, there might be slight changes to do.

There is another way, but I don't like it much. That is making the animation longer with an idle status to wait for the first game object animation to end... but it will be a hassle in case you shorten the animation because you have to, or have any other models or events.

Anyway, I think the way to go is with the coroutine! Good Luck!

Upvotes: 1

Related Questions