概述
想象一下一个完整游戏流程。
- Loading界面。
- 进入场景。
- 弹出Menu菜单
- 加载角色。
- 角色动画系统-切换动画系统(默认-剑客-拳手)
- 角色皮肤切换
- 相机
- 角色可以接收到用户输入,然后进行前后左右移动。
- 角色可以接收到用户输入,释放技能,开枪。
- 物品交互,背包。
- 场景中还有其它的敌人,怪物AI。
游戏不断迭代,推出不同活动后。这时候需要一种插拔式的功能模块。
- GameFeature
接下来讲解一下Lyra是如何实现以上的功能点的。
场景的扫描
通过AssetManager,获取到所有的FacingExperience资产,罗列出所有场景
GameMode(Eperience)的加载流程
-
GameMode通过命令参数,WordSettingsd等方式来寻找 Experience
1280X1280 (1).PNG
1280X1280 (2).PNG -
加载对应的GameMode下所有的重写类
1280X1280 (3).PNG -
ULyraExperienceManagerComponent 来加载Experience中配置的所有参数。
325e6a81-db3e-4828-b2e9-77d7e6961554.png -
执行Experiece中所有的Action
54df48e9-53af-49b5-b722-fdaec5af1d81.png -
加载并且执行完所有的Acton。后调用加载完成的回调。
e02e8a50-8a75-4285-b5a6-d27882422756.png -
在完成必备的Experience后。加载GameFeature。
efbda25b-5f4e-46b8-8506-3fb3bf5a042f.png
切换场景
-
根据FacingExperienceName创建场景Request。
1a23a116-ffd5-48d1-9fd6-de9b427a530e.png -
创建Session。然后切换场景。
f12c05d4-c24c-4910-9538-c450ffedb83e.png -
切换场景后加载GameMode的时候会通过第一步的Requeset中读取到对应的experience。来执行初始化流程。
51524d15-f59e-4004-a5da-ca61ba99a360.png
UI
加载界面
采用CommonLoadingScreen插件完成。
-
在切換地图的时候注冊播放加载动画的事件。
5635744a-6610-4a4c-af49-a88b4e4c237d.png
[/Script/CommonLoadingScreen.CommonLoadingScreenSettings]
LoadingScreenWidget=/Game/UI/Foundation/LoadingScreen/W_LoadingScreen_Host.W_LoadingScreen_Host_C
UI框架
采用CommanGame插件+UIExtension插件一起实现。
- 配置文件中配置UIPolice。
[/Script/LyraGame.LyraUIManagerSubsystem]
DefaultUIPolicyClass=/Game/UI/B_LyraUIPolicy.B_LyraUIPolicy_C - UIPolice指定对应的UI Layout 。主要用栈的结构来push或者pop layout。
-
W_OverallUILayout - PrimaryGameLayout 设置所有UI Layout。
5dde2947-4dc3-4deb-aa89-0deb7e500c65.png
9fc36718-4bc5-4231-a7a9-3e61ff645ef6.png
-
将ULyraActivatableWidget绑定到PrimaryGameLayout中。
c7cb1d4e-7b5a-4576-ba57-1f31f74c7deb.png ULyraActivatableWidget 可以添加slot。后续可以动态将widget注册到对应的slot下面
角色
角色动画
下面这篇文章讲的很详细了。
-
https://zhuanlan.zhihu.com/p/654430436
bccfe89f-3149-4449-a9d0-e09714ccf499.png
角色换装
换装资产在这里,可以自己看一下代码逻辑。
Input
-
LyraSettingsLocal去注册输入的配置文件。
02f2b00d-2504-4d9f-8b7c-a1bc97fc93b4.png Player Controller中调用SetupPlayerInputComponent
-
角色加载完成的时候调用加载HandleChangeInitState。在HandleChangeInitState调用InitializePlayerInput
1fe6b062-76d1-4917-adfb-81fef8afcea5.png -
注册InputMapping上下文。
b2cb767d-fe26-4ccd-a847-65b393cbf457.png -
绑定IA给对应的函数。
26ae59f6-5d8d-4105-ba3a-945934a8632d.png -
基础移动函数
72f716f0-a479-4cd3-9330-32b79f3bd187.png -
技能函数
373ff0ba-73f3-4ee2-8d10-f4e922517633.png
GAS
这里大概过一下GAS的流程,后续文章会剖析GAS框架源码
- https://www.bilibili.com/video/BV1zD4y1X77M/?spm_id_from=333.337.search-card.all.click&vd_source=f91b86a9db5d272fcc792e207e0f6f89
- https://zhuanlan.zhihu.com/p/486808688?utm_id=0
ASC
是整个GAS的基础组件。所有需要应用GAS的对象(Actor),都必须拥有GAS组件。也可以被赋予PlayerState(可以保存死亡角色的一些数据)一般只放在Character or PlayerState上
-
给角色注册能力ASC。通过ASC注册能力。
89d3a0fb-8a7a-4026-aeea-3cdc378710d0.png
da7d1282-6f5d-44b6-a868-6952cb98f3e2.png
完整的一个GA
-
制作一个IA
8921fab8-2b0e-4554-9c12-405fb078df73.png -
绑定IA到IMC中。
3b6a8398-58da-487e-a38b-f15937c15296.png IMC注册到Input Subsystem中
-
Input Subsystem来对IA逐个绑定对应的GA(通过GameTag来进行动态绑定)
dd3af8d9-bec7-447e-984c-68a65a6f5f7d.png -
制作一个GA。
c8754cac-cbfa-4380-8248-ef6ab59bbe17.png -
将GA和IA绑定(通过Gametag进行动态绑定)
14999ea6-50bf-4123-bd3b-8bd6d74ca731.png
GameFeature
该模块后续也会进行单独剖析讲解。
其它实用技巧
- bool标识的一种表达方式,可以减少内存。
/** is fire animation looped? */
UPROPERTY(EditDefaultsOnly, Category=Animation)
uint32 bLoopedFireAnim : 1;
-
UPROPERTY(config)。配置默认参数。
1327698d-4f43-410b-a4a8-bf8455558fe9.png
-
继承父类,修改父类中的变量类型。
addde1b6-c6e9-4e46-9553-82c3e21a0a47.png