GameFramework解析:整体架构
整体架构
GF层
- 包含框架中各个模块的具体实现,不依赖于引擎
- 各个模块若有需要引擎传递的参数,可通过UGF层的Component在初始化时传入
- 若需要调用依赖于引擎实现的接口,可定义对应的IHelper接口,并在UGF层实现接口,GF层只调用,不关心具体实现
UGF层
- 实现框架中需要依赖Unity的逻辑,把框架与引擎解耦
- 作为Game层与GF层之间的桥梁
- 实例化并初始化框架各个模块
- 借助Unity的Editor扩展,实现各个模块参数的可视化配置
上图UGF与GF的关系其实简化了,实际上每个模块的XXXManager都会实现了对应的IXXXManager接口,UGF只会直接引用接口,不会直接引用Manager
Game层
游戏逻辑,只与UGF层直接接触
启动流程
Unity要启动游戏,至少要有一个自定义的Monobehaviour脚本挂在场景中的GameObject上,来作为我们游戏的逻辑入口,那么任何框架要在Unity中启动也不例外,需要依赖Monobehaviour的生命周期方法启动。
- GF中每个模块都有一个对应的Component(继承自Monobehaviour),并挂在各自对应的GameObject上,放在启动场景中,当运行游戏时,Unity便会调用各个Component的Awake方法。
- 在GameFrameworkComponent(UGF中所有Component的基类)的Awake方法中,会调用GameEntry.RegisterComponent把Component注册到GameEntry中,以方便在其他地方通过GameEntry来访问任意Component。
- 因为Component是继承自Monobehaviour并被直接挂在场景中的GameObject上,引擎会执行Component的实例化,而GF层中的各个模块(Module)是普通C#类,需要我们自己去实例化,GF便是在Component的Awake中去实例化各个模块类。(Resource模块比较特殊,在Start实例化)。
- 各个Component的Start方法被调用,考虑到模块可能需要依赖其他模块,所以在Awake过后,各个Component注册到GameEntry中后(这样才能获取到其他模块的引用),再在Start阶段初始化各个模块。
- 根据Inspector面板配置和Unity API的参数,初始化各个模块,并实例化Component所需要的GameObject。
- 实例化模块所需要的Helper,并以接口形式传递给对应模块。
- Procedure是框架中管理整个游戏流程的模块,Procedure的Component中的Start方法以协程方式启动,协程等待了一帧,这一帧猜测是等待步骤5中实例化出来的GameObject对象完成初始化,避免游戏启动逻辑与这些GameObject的初始化有依赖时产生时序问题。
- 游戏启动第二帧,Procedure模块启动我们指定的入口流程,在此例中,入口为ProcedureLaunch。
- 执行ProcedureLaunch流程的OnEnter方法,游戏的第一句具体逻辑,在这正式被调用。
GameFrameworkModule的实例化
GameFrameworkModule(GF层中各个模块的基类)采用惰性实例化,UGF的Component通过调用GameFrameworkModule.GetModule
可以看到GetModule是传入模块的接口的,而不是模块类本身,GetModule内部会通过反射获得传入接口名字的字符串,并裁掉第一个字符,如传入IXXXManager,会取得“XXXManager”字符串,这个字符串对应了模块类名,然后通过反射来创建该模块实例。
Tick
因为各个Monobehaviour之间不能很好地控制顺序问题,GF通过指定的一个Monobehaviour中的Update方法去驱动所有模块的Update,各自模块的Update顺序由各自模块定义的优先级决定,这样只要在框架管理下的模块,都能做到执行顺序可控。
- 引擎调用所有Monobehaviour的Update方法
- BaseComponent中的Update方法被调用
- BaseComponent中的Update方法调用GameFrameworkEntry的Update方法
- GameFrameworkEntry内部以链表的方式,把已经创建好的模块对象按优先级顺序(降序)组织好,GameFrameworkEntry的Update中会以链表顺序遍历各个模块,并调用Update方法
Shutdown
- 业务层调用GameEntry的Shutdown方法(会传入枚举值ShutdownType)
- GameEntry的Shutdown方法调用BaseComponent的Shutdown方法
- BaseComponent是个Monobehaviour类,在Shutdown中调用Monobehaviour的Destroy销毁自身
- 根据最初传入的ShutdownType来执行LoadScene(重新启动游戏)或Quit(退出游戏)。
- BaseComponent的OnDestroy被调用
- BaseComponent的OnDestroy里调用GameFrameworkEntry的Shutdown方法
- 与Update相反,GameFrameworkEntry的Shutdown中会以链表逆序遍历各个模块,并调用Shutdown方法
最后
GameFramework解析 系列目录:GameFramework解析:开篇
个人原创,未经授权,谢绝转载!
评论