Animancer介绍

Animancer初步使用

使用方法:添加Animator组件和AnimancerComponent相关组件,再编写脚本控制动画;

脚本案例:

public sealed class PlayAnimation : MonoBehaviour
{
    [SerializeField] private AnimancerComponent _Animancer;
    [SerializeField] private AnimationClip _Clip;

    private void OnEnable()
    {
        _Animancer.Play(_Clip);
        var state = _Animancer.Play(_Clip);
        state.Speed = ...                
        state.Time = ...             
        state.NormalizedTime = ...      
        state.Events.OnEnd = ...           
        _Animancer.Play(_Clip).Time = 0;
    }
}

Animancer核心组件

AnimancerComponent

说明:普通的动画师组件

AnimancerComponent类中的API:

成员变量:
//1.获取Animator Controller组件
animancer.Animator
//2.获取Playable
animancer.Playable
//3.获取该组件上的动画状态字典
animancer.States
//4.获取该组件上的动画层级
animancer.Layers

成员方法:
//1.播放动画
animancer.Play(AnimationClip, float, FadeMode)
//2.使用键值播放动画。如果该键没有注册,返回null
animancer.TryPlay(Object, float, FadeMode)
//3.停止当前动画或者目标动画
animancer.Stop(参数)
//4.判断是否播放当前动画或者目标动画
animancer.IsPlaying()

NamedAnimancerComponent

说明:继承自AnimancerComponent并添加一个数组,并按名称注册动画,可以使用名字播放动画,这与 Unity 的旧版组件非常相似;

AnimancerComponent类中的API:

增加的成员变量:
//1.获取动画源列表
animancer.Animations
//1.获取默认动画源
animancer.DefaultAnimation

HybridAnimancerComponent

说明:继承自NamedAnimancerComponent,并且添加了控制器,可以融合Animator Controller组件和Animancer;

Animancer动画状态

动画状态说明:播放动画时,Animancer会创建一个状态来管理它并跟踪它的进度,如果以后再次播放相同的动画,它将重用相同的状态;

AnimancerState类API

成员变量:
//1.获取动画源文件
state.Clip
//2.动画事件集合
state.Events
//3.动画的长度
state.Length
//4.动画的速度
state.Speed
//5.状态的开始时间,该变量改变,动画事件也会变
state.NormalizedTime
//6.状态的结束时间,该变量改变,动画事件也会变
state.NormalizedEndTime
//7.状态的事件集合
state.Events

成员方法:
//1.销毁动画
state.Destroy()

主要访问和创建状态的方法:

//1.此属性存储该方法最近返回的状态
var state = animancer.States.Current;

//2.此属性存储最近由 Layer 的方法返回的状态
var state = animancer.Layers[x].CurrentState;

//3.索引器获取
var state = animancer.States[clip];

//4.方法获取
animancer.States.TryGet(clip, out var state);

//5.如果已存在的状态,则此方法将返回该状态。否则它将创建并返回一个新的
var state = animancer.States.GetOrCreate(clip);

//6.创建新状态,即使该动画已存在一个状态。请注意,每个状态必须具有不同的密钥,否则将引发,注意key时object类型,所以会有装拆箱问题
var state = animancer.States.Create(key, clip);

//7.创建新状态,而不为其提供键。
var state = new ClipState(clip);

//8.如果存在的状态,则此方法将销毁该状态并返回,否则,它将返回false
animancer.States.Destroy(clip);

Animancer动画过渡

过渡说明:Animancer中除了使用Clip动画源文件来进行使用,也可以使用ClipTransition播放动画,并且这样效果更好;

过渡类类型:

//基本过渡:
	1.ClipTransition:实现ITransition接口,最基本的过渡类型,FadeDuration可以控制动画淡入淡出过渡的时长,Speed控制速度,StartTime和EndTime控制起始时间,同时动画支持添加帧事件;
	2.ClipTransitionSequence:继承自ClipTransition并简单地添加一个数组,这些数组将在第一个之后按顺序播放(使用他们的每个结束事件来播放下一个);
	3.PlayableAssetTransition

//混合过渡:
1.ManualMixerTransition:简单的混合动画;
2.LinearMixerTransition:1D混合动画,用一个参数控制,参数信息和Animator里的混合一致;
3.MixerTransition2D:2D混合模式,用俩个参数控制,参数信息和Animator里的混合一致;

//控制器过渡:
1.ControllerTransition:使用控制器文件;

//过渡资源
1.过渡类+Asset:过渡资源在资源面板下可以创建该过渡资源文件,和上面不同的时,过渡文件整个项目全局共享,而不是每个对象都有自己单独的过渡。它们都遵循相同的命名约定;
2.过渡类+Asset.UnShared:不共享分过渡资源,一般用不着;

Animancer混合

动画淡入淡出

淡入淡出说明:淡入淡出通常不用于动画,因为它们不能混合,但是对于骨架动画非常有用,因为它允许角色模型从一个动画的结束姿势平滑地过渡到另一个动画的起始姿势,而不需要两个姿势完全相同。这也意味着,如果动画在任何时候被中断,过渡仍然可以是平滑的;

常用淡入淡出类型:

//1.参数值按百分比计算
下标0:FadeMode.FixedSpeed
//2.参数根据事件计算
下标1:FadeMode.FixedDuration
//3.好像是不会创建的新的状态
下标2:FadeMode.FromStart

动画的层

层说明:基本和Animator使用方法一致;

AnimancerLayer类API说明

重要成员变量:
//1.层级下标
layer.Index
//2.层级叠加模式还是覆盖模式
layer.IsAdditive
//3.层权重
layer.Weight

重要成员方法:
//1.设置骨骼蒙版
layer.SetMask(AvatarMask)
//2.设置层权重
layer.SetWeight(float)

动画混合树

混合树说明:基本和Animator使用方法一致;

混合树使用:

//混合类类型说明
1.ManualMixerState:没有参数
2.LinearMixerState:float参数,线性插值算法
3.CartesianMixerState:Vector参数,梯度波段O(n2)插值算法
4.DirectionalMixerState:Vector参数,极地梯度波段O(n2)插值算法

//案例
public sealed class LinearMixerExample : MonoBehaviour
{
    private AnimancerComponent _Animancer;
    private AnimationClip _back;
    private AnimationClip _forward;
    private AnimationClip _left;
    private AnimationClip _right;

    private float _MovementSpeed;
    public CartesianMixerState mixState;

    private void Awake()
    {
        mixState = new CartesianMixerState();
        //初始化混合动画
        mixState.Initialize(_back, _forward,_left,_right);
        //设置动画参数
        mixState.SetThreshold(0, new Vector2(0, 0));
        mixState.SetThreshold(1,new Vector2(0,-1));
        mixState.SetThreshold(2, new Vector2(0, 1));
        mixState.SetThreshold(3, new Vector2(-1, 0));
        mixState.SetThreshold(4, new Vector2(1, 0));
        //设置混合动画的同步,同步适用于移动,但对于空闲动画,通常应禁用同步
        MixerState.AutoSynchronizeChildren = false;
        mixer.DontSynchronizeChildren();
        mixer.DontSynchronize(mixer.GetChild(0));
        mixer.Synchronize(mixer.GetChild(1));
        //播放
        _Animancer.Play(mixState);
    }

    private void Update()
    {
            var input = new Vector2(
    Input.GetAxisRaw("Horizontal"),
    Input.GetAxisRaw("Vertical"));

            mixState.Parameter = Vector2.MoveTowards(
                mixState.Parameter,
                input,
                _MovementSpeed * Time.deltaTime);
    }
}

Animancer事件

事件说明:基本和Animator使用方法一致,但是性能更好,且使用Clip文件使用时,每次都会创建垃圾,除非您缓存事件回调,而ClipTransition访问它将直接引用ClipTransition拥有的,因此当您再次播放时,您所做的任何修改都将保留。这意味着修改通常只应在启动时执行一次,而不是每次播放时都重复进行;

用法说明:

//1.添加事件
state.Events.Add(0.4f, 事件);
//2.结束事件,结束一定会调用
  state.Events.OnEnd = 事件;

Animancer搭配推荐