【Unity】Animation、Animator 和 Spine 的动画状态重置
这里提到的重置主要解决一个问题,就是动画重复播放时,和第一次播放的表现不同,或者动画异常中断后,下一次播放效果不符合期待。
·
【Unity】Animation、Animator 和 Spine 的动画状态重置
这里提到的重置主要解决一个问题,就是动画重复播放时,和第一次播放的表现不同,或者动画异常中断后,下一次播放效果不符合期待。
Animation
/// <summary>
/// 重置Animation动画状态
/// </summary>
public static void ResetAnimation(Animation ani, string name, bool toEnd = false)
{
AnimationState state = ani[name];
ani.Play(name);
if (toEnd)
state.time = state.length; // 重置到动画结束
else
state.time = 0; // 重置到动画一开始
ani.Sample(); // 及时更新到期待帧
state.enabled = false; // 暂停动画直至下次启用
}
这里的 toEnd 参数是当时为了某个特殊需求另加的,可以将动画状态重置到最后一帧的状态,同理通过修改 state.time
可以将动画状态重置到任意时刻
Animator
首先 Animator 的一般播放方法本身就是会重置动画状态的:
// 参数:动画名,层,时间
animator.Play("animName", -1, 0f);
网上关于Animator的重置,有一段广为流传的代码是在这一行后加 animator.Update(0f);
经测试发现毫无意义,默认的动画推进间隔本来就是0,重新设置一下动画的播放表现不会有任何异样表现。倘若期望重置动画状态后暂停动画的播放,则应该调用 animator.speed = 0f;
不过直接调用播放函数来重置状态也有意外情况,重复播放异常可以考虑使用以下方法重置状态:
animator.Rebind(); // 考虑性能消耗时慎用
这里补充一个判断 Animator 片段播放结束的方法:
private void Update()
{
if(m_bCheckEnd)
{
AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);
if(stateInfo.IsName("ClipName") /* 正在播放消失 */
&& false == stateInfo.loop /* 不是循环片段 */
&& stateInfo.normalizedTime >= 1) /* 已经播放结束 */
{
m_bCheckEnd = false;
//TODO 结束后要执行的方法
}
}
}
Spine
var trackEntry = spine.AnimationState.SetAnimation(0, "ClipName", false);
trackEntry.TimeScale = 0f; // 把动画暂停到第0帧
trackEntry.MixDuration = 0f; // 取消动画变换的过渡效果
大部分情况使用上述方法将动画重置到下次播放的0帧状态就满足重复播放的需求了
还有一些有关 spine 的重置方法需要深入了解才能合理应用,这里先列一下:
// 这一系列函数会直接把Spine动画重置为空状态,
// 现实应用时可能有些属性我们不想重置,
// 这就需要有选择地删减方法。
spine.AnimationState.ClearTracks();
spine.Skeleton.SetToSetupPose();
spine.Skeleton.UpdateWorldTransform();
spine.AnimationState.SetEmptyAnimation(0, 0f);
spine.Update(0);
spine.LateUpdate();
更多推荐
已为社区贡献1条内容
所有评论(0)