Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Join us on March 30, 2023, between 5 am & 1 pm EST, in the Performance Profiling Dev Blitz Day 2023 - Q&A forum and Discord where you can connect with our teams behind the Memory and CPU Profilers.
    Dismiss Notice

Wait for animation to end inside a State Machine

Discussion in 'Scripting' started by dichtermut, Jul 27, 2022.

  1. dichtermut


    Jul 21, 2018
    I am implementing a state machine for an AI Enemy and one of the states involves just staying idle for some frames while an animation is rendered. I want to advance to the next state once the animation has ended, but I am not sure how to do it. Generally, I would add an event on the last frame of the animation to call the method, but the method to call is:

    Code (CSharp):
    1. public void ChangeState(BaseState newState) {
    2.         currentState.Exit();
    3.         currentState = newState;
    4.         currentState.Enter(allCellsList);
    5. }
    And here I have the problem that it doesn't seem possible to pass an instance of my self-defined Type BaseState from the Animation window in Unity. I could make an auxiliary method to call with an integer or something to represent the new state to change to, but that seems wrong.

    So I was wondering, is there a more elegant way to do it?
    - Would it be a good idea to start a coroutine to wait for the X frames until the animation ended, and then just called ChangeState() to the next one? I'm guessing that State Machines and Coroutines don't mix very well together, plus, it doesn't seem right to invoke a coroutine for X frames every time I want an animation to render.
    - Would it be a good idea to just delete the state and add the animation at the end of the previous one? But then again, I would still have the problem of how to wait for the animation to end...

    Just as information, the state machine I implemented has four methods per state:
    1. Enter()
    2. UpdateLogic()
    3. UpdatePhysics()
    4. Exit()
  2. R1PFake


    Aug 7, 2015
    I usually handle this logic directly in the specific state, so the state "detects" when the animation is done and triggers the state change to the next change

    I used different ways to "detect" the end of the animation, the old way was to use custom animator state behavior which invokes a custom C# event AnimationDone with the animation Id parameter, the state could then listen to the C# event of the custom component and then trigger the change to the next state.

    It worked fine but was to annoying to add the behavior / event to every animator / animation, so I just put the logic directly inside the state and detect the animation end with a combination of and

    It's only a few line of code and works for the most simple cases. I only use the animation behavior for complex animations with have multiple transitions etc and not just one simple animation, but even then I tend to convert more towards Timelines for these "complex" animations.

    Some additional hints:
    When you trigger a animation state change the GetCurrentAnimatorStateInfo will not immediately return the new state, because there is usually a 1 frame delay + additional delay for transitions, but you can use GetNextAnimatorStateInfo which returns the info of the next state during the transition.

    In the most basic case you could just check GetCurrentAnimatorStateInfo in every state update until your animation is started, set a flag somewhere in your state and then wait until the GetCurrentAnimatorStateInfo is not your specific animation anymore.

    But I also use GetNextAnimatorStateInfo to detect more "complex" cases, so it depends on your animator setup.
    Last edited: Jul 27, 2022