代码参考
见工程MgrBase、GameManager等代码文件,工程参考第零章工程说明
概述
在游戏的项目中,有一些APP中阶段的转换节点,如:进入App,登录,切地图等。通常有一些模块只在某个阶段被使用,比如:在玩家登录后启动玩家资产管理模块,玩家切地图清理(或刷新)地图资源管理模块等等。还要注意的是这些模块之间,会有顺序耦合的关系,如:组队模块要在角色数据管理模块后初始化,不如拿不到角色数据。
思路
生命周期管理
在游戏开发项目中常常使用模块化开发,常常定义“管理者类”来管理各个模块。有些模块如网络模块在进入游戏被初始化,而有些模块如玩家管理模块直到玩家登录时才被加载,而当玩家注销返回登录界面时被清理,定义一个管理者类,包含以下行为:
- 初始化
- 唤醒
- 休眠
- 释放
处理不同模块之间的依赖
例如脚本模块依赖于资源管理模块加载脚本,这样资源管理模块必须在脚本模块初始化之前初始化并在脚本模块被释放之后释放。定义一个管理者的管理者,这个类可以使用U3D的GameManager类。
- 在某个时机如进入游戏、玩家登录按遍历初始化模块并再次遍历唤醒模块,这样可以保证在相互依赖的时候能成功的初始化模块。类似的,在某个时机如退出登录返回大厅,先遍历休眠模块再遍历释放模块
- 因为U3D和开发者约定GameManager是个Mono脚本,挂载在场景的GameObj里。这样那些Mono管理者的GameObj可以以某种策略挂载在GameManager的GameObj上。
详解
- GameManager 是一个和U3D约定的特殊的类,定义它为单例作为所有管理者的管理者,通过静态注册的方式注册各个节点的模块,并在管理这些模块的生命周期(见下文)。
- MgrRegister 静态的模块管理者注册器,通过这个类来静态配置模块的生命周期节点
- MgrBase 管理者基类
- MonoMgrBase Mono类型的管理者基类
其运行机制以玩家登录为例:玩家进入游戏后的状态为登录状态,此时选择服务器登录进入游戏状态。在选择服务器进入时,通知GameManager切换状态,触发模块管理机制:首先把运行在登录状态下的模块清理掉,加载游戏状态的模块。当然这里的状态节点是简化的,根据需求可能会有其他如:整个APP,大厅,战斗等生命周期。
生命周期开始和结束都会进行两次遍历如图所示,其主要目的在于可以在两次遍历中处理依赖,避免循环依赖。比如组队模块的初始化依赖角色模块,而角色模块又有对组队模块的引用,通常这种对其他模块有依赖或者引用初始化,放在第二次遍历,这里是Start,第一次遍历的初始化只初始化本模块相关的。这样可以保证,其依赖引用的模块一定被初始化了。释放的逻辑类似。
备注
- Mono的Mgr的单例在Awake里手动初始化
- C# 语言有反射的特性,也可以在程序初始化的时候使用反射分析特性(Attrbute)标签或者继承类型进行注册