Unity动画系统详解10:子状态机是什么?

摘要:除了使用Layer还有没有更好的组织状态的方式呢?感觉一个Layer里面状态多的时候,还是很显得很乱。

洪流学堂,让你快人几步。你好,我是跟着大智学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会直接转换到对应的状态。选择状态机时,相当于将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。

左边是Override Controller的图标(加号),右边是Animator Controller的图标(播放符号)

Animator Override Controller和Animator Controller的图标很相近,除了左下角一个是加号,一个是播放的标志。

编辑Animator Override Controller

给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的朋友,也许能够帮到他。”

扩展阅读

  • Unity动画系统详解1:在Unity中如何制作动画?
  • Unity动画系统详解2:如何导入使用外部的动画?
  • Unity动画系统详解3:如何播放、切换动画?
  • Unity动画系统详解4:如何用代码控制动画?
  • Unity动画系统详解5:BlendTree混合树是什么?
  • Unity动画系统详解6:如何做好角色的移动动画?(Root Motion详解)
  • 【建议收藏】找不到免费的角色动画?来试试mixamo

【扩展学习】洪流学堂公众号回复动画可以阅读本系列所有文章,更有视频教程等着你!


呼~ 今天小新絮絮叨叨的真是够够的了。没讲清楚的地方欢迎评论,咱们一起探索。

我是大智(微信:zhz11235),你的技术探路者,下次见!

别走!点赞收藏哦!

好,你可以走了。

你可能感兴趣的:(Unity动画系统详解10:子状态机是什么?)