Animancer Events and End Events normally use callback delegates to run your code when the event occurs, but you can also use Async Methods or Coroutines to wait for an event before doing something.
Waiting for the End of an Animation
To wait for an End Event you can await or yield return an AnimancerState directly. For example:
| Async Method | Coroutine |
|---|---|
|
|
Both of the above scripts achieve the same thing:
- On startup, they call the
PlayThenLogmethod (or start it as a coroutine). - That method immediately plays the
_Animationwhich creates anAnimancerStatefor it. - Then it waits for the animation to end or be interrupted. See When does it stop waiting for details.
- Then it logs a message saying it finished.
You can also await or yield an entire Layer or AnimancerComponent to wait for all their states to finish.
Waiting for Time or an Animancer Event
To wait for a specific time or an Animancer Event you can call AnimancerState.Await and await or yield return the Awaiter it returns.
AnimancerState.Await can be given an AnimancerState.NormalizedTime. For example:
public async void PlayUntilTime(float normalizedTime)
{
AnimancerState state = _Animancer.Play(_Animation);
await state.Await(normalizedTime);
Debug.Log("Passed normalized time " + normalizedTime);
await state;
Debug.Log("Finished " + state);
}
Or it can be given an event name like when using Animancer Events with the Hybrid approach. For example:
public async void PlayUntilEvent(StringReference eventName)
{
AnimancerState state = _Animancer.Play(_Animation);
await state.Await(eventName);
Debug.Log("Passed event " + eventName);
await state;
Debug.Log("Finished " + state);
}
The event name can be a regular string or any of the options explained on the Strings page.
When does it stop waiting?
The above await and yield statements will wait for one of the following conditions:
- The state successfully passes the target time.
- It doesn't matter if the state is looping or not, time increases linearly as explained on the
AnimancerState.NormalizedTimepage.
- The state is interrupted by:
- The
state.TargetWeightbecoming0, such as if it starts fading out or is stopped by playing something else. - The state is destroyed.
If you want to wait forever until the state is interrupted, you can use state.Await(float.PositiveInfinity).
Awaiting a result
In many situations, you only want to continue executing logic for a state if that state is still playing. For example, if you play an Attack animation and wait for its Hit event to apply damage to another character, then you might not want to apply damage if the animation was interrupted before reaching that event.
The above await statements can also optionally return a result to indicate whether the state successfully reached the target time. For example:
public async void PlayWithResult()
{
AnimancerState state = _Animancer.Play(_Animation);
bool success = await state;
if (success)
{
Debug.Log("Finished " + state);
}
else
{
Debug.Log("Interrupted " + state);
}
}
The same can be done in a coroutine, but it takes a bit more effort since you need to get the Awaiter before the yield so that you can check if it WasSuccessful afterwards:
public IEnumerator PlayWithResult()
{
AnimancerState state = _Animancer.Play(_Animation);
AnimancerState.Awaiter awaiter = state.Await();
yield return awaiter;
if (awaiter.WasSuccessful)
{
Debug.Log("Finished " + state);
}
else
{
Debug.Log("Interrupted " + state);
}
}