摘要:除了使用Layer还有没有更好的组织状态的方式呢?感觉一个Layer里面状态多的时候,还是很显得很乱。
大话Unity,让你快人几步。你好,我是跟着大智学Unity的萌新,我叫小新,这是复(yu)习(xi)动画系统的最后一节。
小新:“大智,除了使用Layer还有没有更好的组织状态的方式呢?感觉一个Layer里面状态多的时候,还是很显得很乱”
大智:“可以尝试使用Sub-State Machines,也就是子状态机,可以将一些状态放到子状态机里。我把链接发给你,你先去看看。”
小新:“好嘞”
小新收到了大智QQ发来的信息:https://docs.unity3d.com/Manual/NestedStateMachines.html
小新开始认真阅读文档,下面是他做的笔记:
Sub-State Machines 子状态机
很多时候,角色的一个行动由多个动作组成。比起使用一个动画完成这个行为,可能定义几个不同的阶段,并且给每个阶段使用一个单独的State会更合理。比如一个“稳定射击”的动作,包含蹲下、射击、站起的动作。
这样分拆的动画更利于控制,但是带来的负面影响是状态机会变得庞大、复杂、难以管理。这时候,可以使用状态机提供的子状态机的功能,将这些状态整合到一个子状态中。
创建子状态机
在Animator窗口的空白处右键,在弹出菜单中选择Create Sub-State Machine。
子状态机会显示为一个细长的六边形用来和正常的state区分。
编辑子状态机
双击这个子状态机可以打开它,界面会显示这个子状态机内的内容(初始会是一个空的状态机)。窗口的上方会有一个面包屑路径显示当前编辑的是哪个子状态机(子状态机内也可以再创建子状态机),点击对应的面包屑路径可以直接打开对应的位置。
子状态机内的State编辑和之前的State编辑相同。
子状态机的Transition
子状态机只是从视觉上将一些状态折叠到一个子状态机中,所以如果想转换到sub-state machine时,需要选择具体转换到哪一个状态或整个状态机。
选择状态时,Transition会直接转换到对应的状态。选择状态机时,相当于将Transition转换到对应状态机的Entry状态。
子状态机中有一个额外的状态名字为(Up)XXX
。
这个状态代表上一层的状态机。你可以在子状态机中创建Transition转换到上一层状态机中的某个状态。
选择状态时,Transition会直接转换到对应的状态。选择状态机时,相当于将Transition转换到对应状态机的Entry状态。
小新敲开大智的房门,“没想到动画系统这么多内容,刚开始学的时候感觉还挺简单的,现在越学东西越多了。”
大智:“所以说要掌握学习的方法,Unity的文档就是最好的突破口,每次阅读文档然后做笔记,是一个非常好的方式,想必这么久你也从中获益不少吧?”
小新:“对对,以前都是走马观花,遇到不懂的就去百度,下次再遇到还是不懂。现在每次逼自己看英文文档,翻译做笔记,能系统地掌握一个知识点,印象也深了不少。”
大智:“最终你还要建立起一套自己的学习方法,技术的道路上需要不断学习,终究有一天我没办法再指导你,但是你这段时间建立起的学习体系,可以一直帮你,让你走的更远。”
小新:“哎呀,怎么说的这么伤感,我一定好好学不辜负智哥你的栽培。对了,动画系统里学了这么多了,还有没有其他常用的我还没学到的东西?”
大智:“确实动画系统学习了这么久,该学的都差不多了,要说比较常用的知识点还有Animator Override Controller和State Machine Behaviour。Animator Override Controller可以让你在保留Animator Controller中的结构和逻辑的同时,覆盖里面的一些动画,比如你有多个角色的状态机结构逻辑都相同,但是动画不同,这时候就可以用Animator Override Controller。State Machine Behaviour是一种用脚本的形式,可以挂在State上面,会有一些回调用来处理State不同状态。具体的内容你还是去看下文档,系统地学习下做一下笔记。”
小新:“我这就去”
Animator Override Controller
Animator Override Controller是存放在Project中的一种资产,可以用来扩展已有的Animator Controller,替换Animator Controller中的动画,但是保留原Animator Controller中的结构、参数和逻辑。
例如:游戏中有很多类型的NPC(哥布林、兽人、精灵等),状态机逻辑相同,但是每种NPC有自己独特的动画。这时候你只需要创建一个基础的Animator Controller,结合使用Animator Override Controller可以创建出很多不同的变体。
创建Animator Override Controller
在Project中的Create菜单中,选择Animator Override Controller。
Animator Override Controller和Animator Controller的图标很相近,除了左下角一个是加号,一个是播放的标志。
编辑Animator Override Controller
首先需要给Animator Override Controller一个基础的Animator Controller。赋值完成后,下面会显示状态机中所有的动画,这时候你可以用新的动画来覆盖原来状态机对应状态的动画。
最后Override Controller可以赋值给Animator组件的Controller。
注意:Animator组件的Avatar属性可能需要替换为对应模型的Avatar。
State Machine Behaviour
State Machine Behaviour是一种特殊的脚本。和通用的Unity脚本(MonoBehaviour)挂到GameObject上面类似,StateMachineBehaviour可以挂到Animator Controller的State上面。可以在StateMachineBehaviour脚本中编写代码,在状态进入、离开、停留在特定的state时执行。你就不需要自己去检测状态的变化。
可能用于的场景举例:
- 进入、离开状态时播放音效
- 只在特定的状态中执行一些代码
- 只在特定的状态中激活特效
创建StateMachineBehaviour
选中一个State,点击Inspector中的Add Behaviour按钮可以选择已有的StateMachineBehaviour或创建一个新的StateMachineBehaviour。
StateMachineBehaviour中的事件
StateMachineBehaviour中有一些预定义的事件方法:
OnStateMachineEnter
转换到一个StateMachine时调用。注意转换到子状态机中的状态时不会调用。
OnStateMachineExit
离开StateMachine时调用。注意转换到子状态机中的状态时不会调用。
OnStateEnter
进入当前State时调用
OnStateExit
离开当前State时调用
OnStateUpdate
处于当前状态时,每次Update都会调用(不包括Enter和Exit的两帧)
OnStateMove
在MonoBehaviour.OnAnimatorMove之后调用
OnStateIK
在MonoBehaviour.OnAnimatorIK之后调用
总结
小新:“总算是把动画系统中的内容学完了,真是一个庞大的系统”
大智:“NoNoNo,这还不算完,其实还有很多细节上的东西,因为你没有实际用到,所以还没接触到。”
小新:“我的天呐!”
大智:“不过也不用担心,遇到问题的时候,好好去看文档,再解决不了就来找我呗”
小新:“嘿嘿,这个方法好”
今日思考题
大智:“好你个大头鬼,非得把我累死你才开心。给你布置个作业,用今天新学的内容把你的状态机好好整理整理”
“收到!我去也!”
“收获别忘了分享出来!也别忘了分享给你学Unity的朋友,也许能够帮到他。”
扩展阅读
呼~ 今天小新絮絮叨叨的真是够够的了。没讲清楚的地方欢迎评论,咱们一起探索。
我是大智,你的技术探路者,下次见!
别走!点赞,收藏哦!
好,你可以走了。