最近项目需求做一个效果动画,在unity自己编辑的关于Transfrom+Color Alpha变化的动画。动画编辑好后在Animator面板编辑动画切换条件。初始状态,动画进入一个空状态,当我们要展示效果的时候,就设置他的参数值Score=True,让他切换动画。切换完后再切回空状态并设置Score为false。如下图:
刚开始我一直在过度条件面板以及动画状态面板寻找可以添加的事件。但是并没有,百度也是搜到一些代码监控状态机动画播放是否结束。我觉得那个有点麻烦,不太符合我的需求。在我记忆里这个应该是可以更简单的实现。果然,在我不断尝试下终于找到了解决方法。我们点选状态时,会发现一个Add Behaviour。
我尝试Add一个新的脚本打开后发现这正是可以用来监听当前动画状态一些事件的一些函数。如下:
public class ParaSetting : StateMachineBehaviour {
// OnStateEnter is called when a transition starts and the state machine starts to evaluate this state
//override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
//
//}
// OnStateUpdate is called on each Update frame between OnStateEnter and OnStateExit callbacks
//override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
//
//}
// OnStateExit is called when a transition ends and the state machine finishes evaluating this state
override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
animator.SetBool("Score",false);
}
// OnStateMove is called right after Animator.OnAnimatorMove(). Code that processes and affects root motion should be implemented here
//override public void OnStateMove(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
//
//}
// OnStateIK is called right after Animator.OnAnimatorIK(). Code that sets up animation IK (inverse kinematics) should be implemented here.
//override public void OnStateIK(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
//
//}
}
这样我们就可以在状态机里添加一些动画完成状态后的响应了。
顺便记录一下查到的获取到当前动画时长代码如下:
public static float GetClipLength(this Animator animator, string clip)
{
if (null == animator || string.IsNullOrEmpty(clip) || null == animator.runtimeAnimatorController)
return 0;
RuntimeAnimatorController ac = animator.runtimeAnimatorController;
AnimationClip[] tAnimationClips = ac.animationClips;
if (null == tAnimationClips || tAnimationClips.Length <= 0) return 0;
AnimationClip tAnimationClip;
for (int tCounter = 0, tLen = tAnimationClips.Length; tCounter < tLen; tCounter++)
{
tAnimationClip = ac.animationClips[tCounter];
if (null != tAnimationClip && tAnimationClip.name == clip)
return tAnimationClip.length;
}
return 0F;
}
动画是否播放完毕:
public static bool PlayWasOver(this Animator animator)
{
AnimatorStateInfo info = animator.GetCurrentAnimatorStateInfo(0);
if (info.normalizedTime >= 1.0f) return true;
else return false;
}