关于 Animator.SetTrigger 的一些迷思

近期一直在修改各种战斗中碰到的问题,其中有一个问题,让我困扰了很久,大概场景简单描述一下,有一天我们的策划同学给我反馈了一个问题,问题是这样的:

如果主角在战斗副本中一直按住攻击按钮进行攻击的话,貌似一直都处于霸体状态,小怪命中主角之后,能看到主角在掉血,但是主角几乎不会播放受击后仰的动画,让人觉得主角很 Bug,小怪完全不是对手。

好,这是一个很好的问题,在我听到这个反馈的第一时间里,我的反应是 “擦,这不可能啊”,好吧,程序猿总是这般自信和分裂。实际上这肯定是可能的,而且正在发生,可是我们总是想选择不相信事实,在看着我们的策划同学演示了大概 3 分钟,我发现这尼玛就是有这个问题。那么肿么解呢?

先检查代码呗,各种检查,各种推演,最终发现有可能存在一种情况,那就是 Animator 同时调用了多个 SetTrigger 方法,设置了多个不同的 Trigger 的值,可能会导致这个问题,那么接下来就是验证了,因为实际的工程中触发个情况肯定不是那么必然和容易的,那么我们验证的时候就直接非常直接地通过代码的方式来验证就好了。

我们直接就在某一个按钮按下的事件回调中,直接通过 Animator.SetTrigger() 方法设置了两个动作差别非常大的状态对应的 Trigger,最终会发现 Unity3D 会自动融合这两个过程,例如我们在 Idle 状态的时候通过设置 Attack 和 BackOff 两个状态的 Trigger:Attack 和 BackOff,然后我们就会发现,主角会先往后仰几帧,然后继续 Attack 的动作直到其完整播放完毕。unity3d_mecanim_set_trigger_myth测试结果是,会以当前触发的所有动画中播放时长最大的为主,其余的动画会在整个时间轴中对主角的动画综合地产生影响,所以一定要注意尽量不要让多个不同的 Trigger 在同一时间触发,因为 Unity4.6 版本未提供获取 Animator 参数列表的接口,所以我们得自己维护好 Trigger 列表,如果我们的实际需求中,不存在需要多个 Trigger 同时被触发的情况,那么记得在设置新的 Trigger 之前(当然也可以考虑优先级和权重值)将其他已经设置过但是还没有被 Animator 应用的 Trigger Reset 掉。