Do something after animation finishes

Hi, so in the game I’m creating this script is attached to my enemy. The problem I’m having is with my attack animation “bash” attached to this object. When the player is in attacking range he attacks, but when the player moves out of range during “bash” he continues to move forward via NavMeshAgent, so I need for him to remain still while “bash” is being played. Here is the script:

using UnityEngine;
using UnityEngine.AI;
using UnityEngine;
using UnityEngine.AI;
using System.Collections;

public class Experimental : MonoBehaviour
{

	public Transform player;
	static Animator anim;
	static AnimationClip bashClip;
	bool stop;

	// Use this for initialization
	void Start () 
	{
		anim = GetComponent<Animator> ();
	}

	// Update is called once per frame
	void Update () 
	{
		NavMeshAgent agent = GetComponent<NavMeshAgent>();

		if(Vector3.Distance(player.position, this.transform.position) > 2)
		{
			//check if "bash" is playing...
			{
				//if it is... wait for for "bash" to stop
				{
					//then 
				}
			}
			//otherwise if "bash" isn't playing do...
			{

			}
		}

		if(Vector3.Distance(player.position, this.transform.position) <= 2)
		{
			anim.SetBool ("bash", true);
			anim.SetBool ("walk", false);
			GetComponent <NavMeshAgent> ().enabled = false;
		}
	}
}

So when the player exits the attacking range, I need to

  1. check if “bash” is playing

  2. if it is playing, wait for it to end

  3. then set bool “walk” to true

  4. otherwise if it isn’t playing already, then set bool “walk” to true

    if(Vector3.Distance(player.position, this.transform.position) > 2)
    {
    //check if “bash” is playing…
    {
    //if it is… wait for for “bash” to stop
    {
    //then do something
    }
    }
    //otherwise if “bash” isn’t playing do…
    {

    		}
    	}
    

How can I write this up in C#?
Thanks

Take a look to the State Machine Behaviours. You can put a Script component on an animation throug you Animator panel.
Go to the Animation where you want to change variables on Antimation End, and click Add Behaviour.
in that script you will have a OnStateExit() created by default. Change variables there, and you will be sure that are changed when the animation ends.

I have less idea about NavMeshAgent. If you want to play another animation before current animation ended you can do it using Any State of animation. Watch this:

Another way is to add event (Animation event) when animation finishes. Go through links below
https://docs.unity3d.com/Manual/animeditor-AnimationEvents.html

void Update()
{
NavMeshAgent agent = GetComponent(); // ← better make this a global variable. GetComponent every update is bad

        if (Vector3.Distance(player.position, this.transform.position) > 2)
        {
            if (anim.GetCurrentAnimatorStateInfo(0).IsName("bash")) // check if "bash" is playing...
            {
                return; // "bash" is playing so no more code will be executed
            }
            else
            {
                anim.SetBool("walk", true); // "bash" is NOT playing -> walk
            }
        }
        else // else means that distance is <= 2
        {
            anim.SetBool("bash", true);
            anim.SetBool("walk", false);
            GetComponent<NavMeshAgent>().enabled = false;
        }
    }

try this:

if(anim.GetCurrentAnimatorStateInfo(0).normalizedTime > 1)
Debug.Log("not playing");
else 
Debug.Log("playing");

I solved this using Animation Events:

very handy :slight_smile: