使用Unity的动画事件时需要注意的“坑”

当我们需要根据当前动画状态执行一些事件的时候,我们往往会需要使用动画事件。

我们可能会使用下面的方法

对动画添加动画事件,当进入动画时调用 OnEnterAnimation 方法

复制代码
var clips = this.animator.runtimeAnimatorController.animationClips;
for (int i = 0; i < clips.Length; i++)
{
    var clip = clips[i];
    AnimationEvent e = new AnimationEvent()
    {
        time = 0,
        functionName = "OnEnterAnimation",
    };
    clip.AddEvent(e);
}          
this.animator.Rebind()
复制代码

然后在 OnEnterAnimation 里面去更新记录状态信息

复制代码
// 上一次的状态
int hashLast;
 // 当前进入的动画的状态
int hashCurrent;
public void OnEnterAnimation()
{
    hashLast = hashCurrent;
    hashCurrent = this.animator.GetCurrentAnimatorStateInfo(0).shortNameHash;
    // do something....
}
复制代码

然后根据 每一次更新的 当前状态与上一次状态去调用相应的事件。

但是这里有一个坑:当进入某个动画的时候,调用 this.animator.GetCurrentAnimatorStateInfo(0) 方法返回的状态信息中的 shortNameHash 并没有更新到当前播放的动画。

这里我们修改上面绑定的事件进行验证

复制代码
// 添加动画事件
var clips = this.animator.runtimeAnimatorController.animationClips;
for (int i = 0; i < clips.Length; i++)
{
    var clip = clips[i];
    AnimationEvent e = new AnimationEvent()
    {
        time = 0,
        functionName = "OnEnterAnimation",
        stringParameter = clip.name
    };
    clip.AddEvent(e);
}          
this.animator.Rebind()


// 添加的事件 与 相关字段
// 上一个的动画
string animationLast;
// 当前动画
string animationCurrent;
public void OnEnterAnimation(string name)
{
    animationLast = animationCurrent;
    animationCurrent = name;
    var animationCurrentByStateInfo = animator.GetCurrentAnimatorStateInfo(0).shortNameHash.ToNameFromHash();
    Debug.Log("进入动画 {}\t离开动画{}\t动画控制器StateInfo{}"
        .format(
            animationCurrent
            , animationLast
            , animationCurrentByStateInfo)
        );
}
复制代码

可以看到第二行,播放Fight_attack动画时,动画控制器的状态同步到 Fight_attack

而第三行,进入Fight_idle动画时,动画控制器却还没有同步到 Idle状态。

因为时间关系目前没有去深究,猜测应该是因为勾选了动画控制器的 HasExitTime,所以开始播放这个动画的时候没有完全离开上一个动画。

解决办法就是调用事件的时候传入动画名称,而不去依赖Animator.GetCurrentAnimatorStateInfo

上文代码中的 format 和 ToNameFromHash() 是自己实现的扩展方法,所以直接复制粘贴没法运行。

 

posted @   LaNashTT  阅读(834)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示