基于行为树的MOBA技能系统:动画系统
动画系统已有重构版本,可前往 朝花夕拾·动画系统的重构 进行查看
前言
基于行为树的Moba技能系统系列文章总目录:https://www.lfzxb.top/nkgmoba-totaltabs/
这一篇来谈谈动画系统部分,别的先不说,先给大伙来个开幕雷击
相信很多读者都受过这个蜘蛛网的荼毒+迫害,事实上我并不是很能知道Unity出这个蜘蛛网有什么用,折磨我们吗?
其实我们想一想,我们真的需要这种可视化吗?
我对于这个问题的答案是否定的,在游戏开发中我们会有自己的状态系统,而动画系统往往就是与我们自己的状态系统相绑定的,根据状态来播放相应的动画,所以我们的需求就是切换状态然后播放动画,不需要知道,也不需要想象哪个动画可以切换到另一个动画,哪个不可以,这都是由我们状态系统控制的,所以完全不需要这个可视化工具,也不需要每次都一大堆的SetXXX,只需要几个能用的API就行。
所以众多开发者也是不堪其辱,干脆不用这个蜘蛛网方案,退而求其次,使用Animation自己控制播放,但是这样的话就没有办法使用Animator的新功能,比如动画重定向、Blend Tree、Avatar Mask等功能。
好在官方似乎意识到自己的不足,推出了一个Playable系统,简而言之这个系统可以让我们不需要受蜘蛛网的折磨就可以享受Animator的新功能,【Playable API】不用Animator如何播放动画?
当然了,构建PlayableGraph虽说不麻烦,但是挺烦人的,幸运的是,有一个插件帮我们做好了所有的工作,我们可以真正的只关心PlayAPI了,那就是大名鼎鼎的Animancer,它基于Playable,可以运行时自动动态构建PlayableGraph,我们开发者完全不用关心,只需要准备好AnimationClip和一些必须的数据(比如你需要使用Avatar Mask,就需要准备好Avatar Mask),然后调用API就好了。
与状态系统的联动
对于Animancer的使用,这里就不多说了,看一下Animancer自带的Demo就可以秒懂,这里主要说一下和状态系统的联动设计,关于状态系统的内容我会单独写一篇文章,这里不再赘述
先来看动画组件中的两个字段
1 | /// <summary> |
AnimationClips是动画名和动画资源的映射
RuntimeAnimationClips是状态名和状态名对应的动画资源的映射,可以看到RuntimeAnimationClips字段它的Key是字符串类型,并且有几个初始数据,分别是移动,默认和攻击状态的枚举字符串(这里顺带提一嘴,对于使用枚举做Key,或者对枚举进行ToString操作都是非常消耗性能的操作,需要注意优化,参照:Unity优化记录(3)——C#(如何解决使用enum和struct作为Dictionary的TKey带来的GC) 和 也谈用反射实现Enum→String映射:一种重视性能的方法 ,但是本Demo代码没有做。)
为什么这里要使用string,而不是直接使用状态枚举作为key呢?因为我们的状态会非常多,简单的如移动,攻击,复杂的如某些特殊状态,比如一些技能的二段,三段对应的动画不一样,所以状态也不一样,但是我们没有办法将游戏里所有的状态都用枚举表示出来,所以就选择在状态类中加一个string,作为状态的名称,然后用状态的名称,而不是枚举作为Key,这样就解决了这个问题。
嗯,基本上就这一个需要注意的点,需要切换状态然后播放动画的时候只需要进行以下调用
1 | //尝试切换到寻路状态,切换成功返回true,否则返回false |
如果我们想在不切换状态的情况下仍然播放另一个动画的话,就自己控制
1 | //先配备好状态名以及其对应的要播放的AnimationClip名 |
有时我们会有边播放技能动画,变播放移动动画的需求,使用Animancer的AvatarMask功能即可(由于Demo使用的模型在设置为人形时会出现鬼畜+骨骼错乱,就没有演示了)