If you need to act on an animation being played for a specific duration or just completed, you could just constantly check the playing FlexMotionLayer's time values as follows:
using SV.FlexMotion;
using UnityEngine;
public class CheckForCompletionUpdate : MonoBehaviour
{
[SerializeField]
private FlexMotionAnimator animator;
[SerializeField]
private AnimationClip clip;
private FlexMotionLayer _layer;
private void Start()
{
_layer = animator.Play(clip);
}
private void Update()
{
if (_layer?.NormalizedTime >= 1.0f)
SomeAction();
}
private void SomeAction()
{
_layer.Stop();
_layer = null;
}
}
But it is less error prone and much more convenient to simply subscribe to the provided FlexMotionLayer callbacks.
There are 5 callbacks currently available:
- OnComplete - Triggered when the animation is completed once per animation loop. As it is based on the motion duration and current time even non-looping animation can trigger the underlying event multiple times.
- OnStopped - Triggered when the animation is stopped. Usually when another animation is played.
- OnTime - Triggered when the specified time in second is reached.
- OnNormalizedTime - Triggered when the specified normalized time is reached (for example 0.5f corresponds to 50%).
- OnUpdate - Triggered every time the layer is updated.
Here is an example of how you would use these callbacks:
using SV.FlexMotion;
using UnityEngine;
public class UseCallbacks : MonoBehaviour
{
[SerializeField]
private FlexMotionAnimator animator;
[SerializeField]
private AnimationClip clip;
private void Start()
{
animator.Play(clip)
// Using a lambda expression to double the speed of the layer at 50% completion
.OnNormalizedTime(0.5f, layer => layer.Speed = 2f)
// Call a method when the animation is complete (will be called once per loop)
.OnComplete(OnComplete)
.OnStopped(layer => Debug.Log("Stopped!"));
}
private void OnComplete(FlexMotionLayer layer)
{
Debug.Log("Completed!");
// On the third loop, stop the animation
if (layer.NormalizedTime >= 3f)
layer.Stop();
}
}
This script should produce that result:
Alternatively, you can directly subscribe to the Completed and Stopped events, like you would do with any other C# event.