user3164083
user3164083

Reputation: 1073

Call function directly after animation stops - Unity

I am trying to turn my character around with an animation called Turnaround. My Turnaround animation was the opposite direction of what it should be because I was calling Flip() before or during the turn animation (which flipped the images in the animation). Turn() sets a trigger which will call the Turnaround animation to run. It looks almost perfect now but has a flickr because Flip() does not occur directly after the turnAround animation and never will. I need to Flip() directly after Turn() but it will never happen directly in time so this technique is not going to work as a professional solution. Does anyone have any other ideas how to do it?

 void Flip()
    {
        Vector3 theScale = transform.localScale;
        theScale.x *= -1;
        transform.localScale = theScale;
    }

    void Turn()
    {
        facingRight = !facingRight;
        anim.SetTrigger("JustTurned");
    }

    IEnumerator wait()
    {
        maxSpeed = 0;
        Turn();
        //float length = anim.animation["TurnAround"].clip.length;
        yield return new WaitForSeconds(1.1f);
        Flip();
        maxSpeed = 5;
    }

I have since created a new sprite sheet that is mirrored so I now have 2 of each animation (one for left, one for right) and now I don't need to flip the world. I found that flipping the world was going to cause one frame to be the opposite direction of what it should be, no matter what approach I took. Removing flip seems to be the best solution and looks nice. Please comment with your opinions.

Upvotes: 3

Views: 22216

Answers (3)

Ernesto Alfonso
Ernesto Alfonso

Reputation: 725

I edited my answer, because thanks to Unity 5, and you can know exactly when an animation ends: Within the state that executes the animation, you can add a behavior that is like this:

using UnityEngine;
using System.Collections;

public class uy : StateMachineBehaviour {
    // OnStateEnter is called when a transition starts and the state machine starts to evaluate this state
    override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {

    }

    // OnStateUpdate is called on each Update frame between OnStateEnter and OnStateExit callbacks
    override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {

    }

    // OnStateExit is called when a transition ends and the state machine finishes evaluating this state
    override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {

    }

    // OnStateMove is called right after Animator.OnAnimatorMove(). Code that processes and affects root motion should be implemented here
    override public void OnStateMove(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {

    }

    // OnStateIK is called right after Animator.OnAnimatorIK(). Code that sets up animation IK (inverse kinematics) should be implemented here.
    override public void OnStateIK(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {

    }
}

As you can see this behavior allows us to know several things, such as when entering or leaving a state.

Upvotes: 1

EoD
EoD

Reputation: 357

In the case your animation is a Unity Animation, you can set an Event in the Event Line that calls the function:

https://docs.unity3d.com/Documentation/Components/animeditor-AnimationEvents.html

In your case, put your event call at the end of the animation. Make sure that your gameObject has a script with the function you want to call (given that the functions you are able to call from the event are only functions from all the scripts attached to that gameObject).

Upvotes: 1

Esa
Esa

Reputation: 1666

Change your

yield return new WaitForSeconds(1.1f) to

yield return new WaitForSeconds(animation.clip.length)

Link to Unity docs

Upvotes: 1

Related Questions