一、整体目录结构
![]()
最外层有三个文件夹,Scripts是写的核心功能,Demo是他的例子,Editor是与Scripts配套的面板
image.png
标注出来的是比较核心的代码部分。没有被框选的,都是独立的模块,可以不管。
二、插件基本使用及原理介绍
角色(Nolan)
![]()
点击场景中Nolan,肉眼看到挂了这么多的脚本。不要慌,请等我慢慢分析。
UltimateCharacterLocomotion
这个是主流程拥有者。点开后发现,上面面板上显示了一堆的东西,但不是所有的都是重要的。下面说几个重要的。
1.Motor
发动机属性,上面可以设置一些速度、阻力参数,也可以设置使用动画RootMotion和非RootMotion的切换。这里可以先跳过,后面会在讲解代码流程的时候,提到这个,以及速度的控制。
2.Abilities、ItemAbilities、Effects
这三个东西,从代码的写法上来讲,都是很类似的(代码会在后面专门介绍)。它们都是基本上类似的写法,抽象出的管理不同功能的逻辑。ItemAbility继承自Ability,Ability代表着角色的行为,ItemAbility代表着角色身上Item的行为。
后面会专门介绍Ability。
3.Events
这个工程里会使用自己实现的事件系统,这里显示的是Unity的事件系统,开放在面板上方便用户使用,但是基本不会用到。可以直接忽略。
4.States
这个是比较核心的一个东西,对应上面目录中的StateSystem。它相当于一套加强版的状态机,通过反射的方式,让某个状态对各个持有这个状态名的对象产生不同的影响。
先介绍使用方法:1.![]()
点击创建新的Preset。
2.
![]()
点击这个创建出来的Preset。
3.![]()
点击Add Property,上面会有一大堆的参数,这些参数都是当前脚本上,开放出来允许修改的参数。以TimeScale为例:![]()
image.png
在TimeScaleChange这个名字的状态为True时,时间流速就会变成0.2 下面在JumpAbility里,触发这个状态为True:
![]()
这样,在Jump Ability进入的时候,会设置"TimeScaleChange"这个State为True。
![]()
UltimateCharacterLocomotionHandler && UnityInput
UnityInput是在独立的InputSystem中的,它获取角色的输入。
这个项目里面,所有带xxxHandler名字的脚本,基本都是处理角色Input和xxx之间的关系的。
AttributeManager
属性管理器,角色身上的数值相关的东西(最好是在UI面板上有显示的)都可以以这种形式表示,比如说血量,护盾值,能量值...
LayerManager
角色层级管理器
PerspectiveMonitor
控制物体显示隐藏的,不用看,没啥用,看了费脑子
Inventory(背包) 、ItemSetManager(可持有Item类型列表)、 Item(代表一个物件)、ItemAction(该物件的具体行为,一个物件可以有多种行为,比如说用刀横砍,用刀连劈砍,用刀刺击...)、ItemAbilities(角色对物件的行为,如使用物件,切换物件)
这些东西都是复杂的,耦合性很高的逻辑。后面会进行代码的解读。
总管理器(Game)
![]()
如图所示,都是字面意思。介绍一下重要的:
KinematicObjectManager
该系统是基于物理的运动,是在FixedUpdate中进行绝对位置设置,然后在Update中做位置相对时间的计算插值。
每个想要做基于物理运动的物体都要到这里进行注册,人物和相机都会进来注册(重点是人物)。
ObjectPool
不仅仅是预制体的对象池,它也可以给任意一个类创建对象池。例:看JumpAbility中,获取输入的时候就是从池中获取。如果池中没有会先创建池然后从中获取。
StateSystem
任意一个继承自StateBehavior的脚本,或者继承自StateObject的类(它俩唯一的区别,就是StateBehavior是继承自MonoBehaviour,而StateObject是一个原生的类),都会拥有一个“根物体”,对于Nolan这个角色来说,就是Nolan。Nolan身上所有的这些脚本都共用同样的状态名,当状态发生变化的时候它们也会相应的变化。
三、代码主流程
Tips:
1.该框架结构用到了他自己实现的序列化工具,这套序列化工具用在很多地方,但是都是用来处理偏底层的一些操作,与主流程关系不大。可以先掠过。
2.最会让人混乱的是他提供的一大堆参数,这些参数是为了实现多样性及可调配性,可以全部忽略,只看主流程。
角色的主流程是在FixedUpdate中更新的,由KinematicObjectManager(简称KOManager)驱动。
KinematicObjectManager
KinematicCharacter
CharacterLocomotion
以上为角色更新的主流程。
四、各个模块解析及在我们项目中的应用
到这里,就可以看他官方文档了。
Abilities
- 优先级:由图知,越上面的优先级越高。如果想让Ability和其他Ability共存,那么需要重写IsConcurrent属性(是否并发),且返回true。这时候,默认的优先级就对这个Ability无效了。
网友评论