Recently, I have been using Playable to create a new animation controller, and I am using AnimationScriptPlayable (ASP for short) to perform some motion corrections. However, I have noticed that in some cases, the corrections made by ASP do not take effect, and the values of Animator.velocity and AnimationStream.velocity are inconsistent.
For example, I have created a PlayableGraph with the following connections (→ represents the direction of Playable output):
AnimationClipPlayable → ASP → AnimationPlayableOutput
When no AnimationClip is assigned to the AnimationClipPlayable , the motion corrections made by ASP will take effect. However, when an AnimationClip is assigned to the AnimationClipPlayable , the motion corrections made by ASP will not take effect.
There is more information in these two posts:
Sample code:
using UnityEngine;
using UnityEngine.Animations;
using UnityEngine.Playables;
public struct ModifyMotionJob : IAnimationJob
{
public void ProcessAnimation(AnimationStream stream) { }
public void ProcessRootMotion(AnimationStream stream)
{
stream.velocity = Vector3.zero; // force zero velocity
//stream.angularVelocity += Vector3.up * 180 * Mathf.Deg2Rad;
}
}
[RequireComponent(typeof(Animator))]
public class Test : MonoBehaviour
{
public AnimationClip clip;
private Animator _animator;
private PlayableGraph _graph;
private void Awake()
{
_animator = GetComponent<Animator>();
_graph = PlayableGraph.Create("ASP Test");
_graph.SetTimeUpdateMode(DirectorUpdateMode.GameTime);
var acp = AnimationClipPlayable.Create(_graph, clip);
var asp = AnimationScriptPlayable.Create(_graph, new ModifyMotionJob());
asp.AddInput(acp, 0, 1f);
var output = AnimationPlayableOutput.Create(_graph, "Animation", _animator);
output.SetSourcePlayable(asp);
_graph.Play();
}
private void OnDestroy()
{
_graph.Destroy();
}
private void OnAnimatorMove()
{
//_animator.velocity is not zero
transform.rotation *= _animator.deltaRotation;
transform.position += _animator.deltaPosition;
}
}