Skip to content

Instantly share code, notes, and snippets.

@pekalicious
Created March 3, 2015 03:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pekalicious/21d9438807999646b71e to your computer and use it in GitHub Desktop.
Save pekalicious/21d9438807999646b71e to your computer and use it in GitHub Desktop.
Basic attack animation component with animation events and coroutines for Unity
public class CharacterAttackController : MonoBehaviour
{
// Our own animator
private Animator unitAnimator;
// Target attack controller, used temporary when playing attack animations
private CharacterAttackController target;
// Flag that will help us with some animation timings
private bool waitingForTargetDamageAnimation;
private void Awake()
{
// Let’s cache the animator so we don’t have to grab it every time
this.unitAnimator = GetComponent();
}
public IEnumerator PlayAttackAnimations(int attackTimes, CharacterAttackController targetAttackController)
{
// Temporary store our target attack controller.
this.target = targetAttackController;
// And setup our flag
this.waitingForTargetDamageAnimation = true;
// Play this attack sequence as many times as requested
for (int i = 0; i < attackTimes; i++)
{
// Fire the “attack” trigger
unitAnimator.SetTrigger(“attack”);
// We know that we will eventually transition back to Idle, so we wait
while (!unitAnimator.GetCurrentAnimatorStateInfo(0).IsName(“Idle”))
{
yield return null; // Wait a single frame and try again.
}
// We also want to wait for our target to finish playing its Damage animation
while (this.waitingForTargetDamageAnimation)
{
yield return null;
}
}
// Clean up
this.target = null;
}
// This is called automatically by Unity when the “DamageTarget” animation event fires
// (method name has to be the same as the animation event name).
private void DamageTarget()
{
StartCoroutine(TriggerTargetDamageAnimation());
}
// We want to wait for the target damage animation to complete before moving on, so we need a nested coroutine
private IEnumerator TriggerTargetDamageAnimation()
{
// Nested coroutine, notice that we “yield return StartCoroutine” instead of just “StartCoroutine”.
// Basically, we will not continue this method until the target coroutine is complete.
yield return StartCoroutine(this.target.PlayDamageAnimation());
// Target coroutine is complete, let’s tell the attack animation coroutine that we are no longer waiting
this.waitingForTargetDamageAnimation = false;
}
// Plays the damage taken animation.
private IEnumerator PlayDamageAnimation()
{
this.unitAnimator.SetTrigger(“DamageTaken”);
// We know that the state machine will transition to the Attack state and then back to Idle, so we wait.
while (!unitAnimator.GetCurrentAnimatorStateInfo(0).IsName(“Idle”))
{
yield return null; // Wait a single frame and try again.
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment