题记 不敢立FLAG,因为已经有人栽了。我打算随心所欲写哪是哪。
[GameFramewrok] https://gameframework.cn/
GF的官方网站给出了文档和API框架结构图,更多细节,你还是自己去官网看吧!
想稍微深入了解一点的话还是去GITHUB上看看,下面给出截图。
[GameFramewrok] https://github.com/EllanJiang/GameFramework.git
[UnityGameFramewrok] https://github.com/EllanJiang/UnityGameFramework.git
[StarForce] https://github.com/EllanJiang/StarForce.git
为什么会是这三个东西,其实在官方文档里已经说明了他们之间的关系。大概如下图
StarForce就是那个Game了,换句话说,如果新建工程的话其余三个方块基本不怎么动,把Game里整理一下一个新的项目就出来。
听说集齐这四颗龙珠就可以召唤飞机出场...于是...
因为Unity3d有很多不同版本,GF也最大限度的做了支持(太古老的版本...你就自己想办法吧^ ^;),我这边使用的是2019-4.2LTS版本的Unity3d。打开Unity3d,添加,选择StarForce,然后双击StarForce 看着进度条一顿走...
弹出一个对话框
选择[Yes],然后就是第二个对话框...
选项 [Contine]...一顿进度条之后就看到了熟悉的Unity3d的工作台界面了,这个时候选择Assets/StarForce场景...然后点击执行...第一没有飞机,只有一个报错...
莫慌问题不大,一切尽在控制之中,导入UnityGameFramewrok...
这个时候有一个很神奇的报错...
如果,你跟我一样也看到了这个错...好吧!没什么道理可以讲了,跟我一起去
StarForce/Packages/manifest.json 这个文件里,把[ "com.jiangyin.gameframework": "https://github.com/EllanJiang/UnityGameFramework.git",] 这一行删除掉,
然后世界一下子就和平了...就这么简单。等等,那个结构图里不是还有GameFramework的吗?怎么没看到它出场?问题不大,可以去UnityGameFramework/Libraries/ 找到一个GameFramework.dll和GameFramework.xml;这个动态库呢就是这么玩儿的...
[注]以下操作的前提是建立在你安装了Visual Studio 及 c#模块的前提下,没有的话去下载安装。
第一步先点开GameFramework文件夹(我之前下载完成的)
第二步选择GameFramework.sln点击打开
第三步选择 Release模式点击生成.
因为这些是动态链接库(DLL),所以不能直接运行,然后在GameFramework/bin/Release目录下就可以看到这三个东西。
如果,有什么需求需要改动/升级它们的话,改完之后测试无误,然后生成这三个东西。然后把生成出来的GameFramework.dll和GameFramework.xml拷贝到工程目录下的UnityGameFramework/Libraries 目录下,替换里面的那两个就可以了。当然,QQ群里E老大表示,【我的代码没有一行多余的】所以,改动的话一定要小心。
下面继续StarForce,点击Unity3d的运行,这个时候就可以看到
随便点击一下,还可以去玩一玩这个Demo游戏。
但是,这个看似简单的游戏到底是怎么跑起来的呢?
下面,我们来一起走一走这个启动游戏的小流程。
这个工程的目录结构,其实官方文档跟很多博客都提到了,我在犹豫要不要再科普一遍。
算了,扯几句吧!
从StarForce目录往里.
Assets/GameMain 星际力量Demo的东西
Assets/GameMain/Configs 工程的配置信息 游戏构建 发布之类的信息与业务逻辑关系不是很大
Assets/GameMain/DataTables 星际力量的配置信息 游戏里的数据
Assets/GameMain/Entities 游戏里的预制体
Assets/GameMain/Fonts 游戏里用到的字体文件
Assets/GameMain/Libraries 游戏里用到的第三方库(所以这也有一份库文件夹是要区别这是跟项目走的,UGF里的是跟Framework走的)
Assets/GameMain/Localization 多国语言的配置 我看到里面有 简体中文 繁体中文 英语和 朝鲜语,如果有需求可以继续添加类似法语 西班牙语 俄语 意大利语这样的。
Assets/GameMain/Materials 存放材质球
Assets/GameMain/Meshes 存放Mesh 我也不知道这个单词该怎么翻译才会比较合适 姑且叫Mesh吧
Assets/GameMain/Music 存放音乐文件的
Assets/GameMain/Scenes 存放场景文件的
Assets/GameMain/Scripts 存放脚本文件的
Assets/GameMain/Sounds 存放声音文件的
Assets/GameMain/Textures 存放纹理贴图的
Assets/GameMain/UI 存放UI相关的(这个目录有细分,我就不细说了,里面放了UI的预制体 音效文件 贴图文件)
Assets/StreamingAssets 这个是Unity3d的预留目录,用来存放安装包的资源,不同平台情况还不太一样(unity官方文档的话我不想贴了= =!)。
Assets/UnityGameFramework 这个是UGF目录
Assets/UnityGameFramework/Libraries 这是是存放库的地方 比如之前的GameFramework.dll 和一个(zip压缩和解压缩的库) ICSharpCode.SharpZipLib.dll 如果开发的过程中有需要的话可以继续添加别的DLL文件进去.
Assets/UnityGameFramework/Prefabs 存放预制体的文件夹(注意这个可不是项目里用的预制体,而是UnityGameFramework里的,开发的时候别乱放)
Assets/UnityGameFramework/Scripts/ 这个目录是存放脚本的地方,这里的脚本分两大块。
Assets/UnityGameFramework/Editor 是针对于编辑器的(编辑器的拓展 资源管理 打包发布资源啥的东西)
Assets/UnityGameFramework/Runtime 是针对于运行时(也就是俗称的业务逻辑 GF里有大量的抽象接口,这里挨个去实现它们)
目录这一块儿,先简单说这么多。剩下的来谈谈这个StarForce的启动过程
点击Unity3d的File菜单 选择Build Settings... 或者 Ctrl shift + B [ 我这是windows系统 其他系统的按键可能不一样,别冲动啊!]
也就是说StarForce的启动场景是StarForce Launcher
启动这个场景的时候 会把这个场景里有的节点(GameObject)全加上去,就比如Game Framework.
然后,点击这个叫Game Framework的GameObject就看到了一个脚本 GameEntry
打开这个脚本...
注释栏赫然写着游戏入口...我注意到以下几个细节点:
这个类继承自MonoBehaviour
在Start方法里 调用了两个方法 字面意思 初始化内置组件 初始化定制组件
虽然不是很懂,不过等我跟进去的时候,就看到了这些...
和这些...
上面写了一堆的set get方法直接就无视了,partial关键字什么意思之类的就自己百度去吧!我就不废话了。
这两个方法的意思也就是说,GF/UGF里存在的组件算内置组件,StarForce(工程)里存在的组件叫定制组件。
这里提及到了一个叫GameEntry的类,跟进去看看。
类太长,我没截全了,大概是一个管理器,用链表管理GameFrameworkComponent的派生类。在GameFrameworkComponent抽象类里有调用注册方法
它们都继承自MonoBehaviour,然后看一眼外面的那个GameFramework
每一个节点(Transform)都挂载了一个脚本,对应一个系统。
而每一个挂载的脚本都保留了一个GameFramework的接口.
在 Awake方法里调用GameFramewok里的GameFrameworkEntry(模块管理类)去获取对应的模块。然后初始化设定,比如类似有没有help类,有没有委托需要实现啥的。最后走一波初始化方法,这些模块基本就是这个样子了。
这篇没什么技术含量的文章看起来扯不完了,先扯扯那个启动流程吧。
当所有的系统都这样被唤醒了之后,有一个叫Procedure的系统开始发挥它应有的作用了。这个系统脚本名字叫ProcedureComponent
首先,在Awake方法里获取GF里的流程管理器接口。
然后,在Start()方法里获取当前C#系统下的所有ProcedureBase的派生类,这个时候全部用反射构建出来放进一个数组里。
找到编辑器模式下指定的启动Procedure,调用流程管理器的接口,执行初始化方法,把有限状态机管理器和Procedure数组一起设置进去。
然后,启动协程,延迟一帧,调用流程管理器接口,开始游戏流程,参数是启动流程的类型。
这里似乎一切都这么简单的搞定了?不不不,GF和UGF还有Unity帮我们做了很多你没注意到的事情。下面我们来一点点的掰扯一下具体做了哪些事情?
当我们选中Procedure 这个Transform的时候,在Inspector里显示了很多备选方案。我是指除了Transform之外的东西。比如Procedure里的 ProcedureBase的所有派生类,还有那个默认的启动Procedure。这些都是Unity3d提供的编辑器拓展,它们不是凭空出现的。首先我们找到了传说中的Assets/UnityGameFramework/Scripts/Editor/Inspector/ProcedureComponentInspector.cs这个脚本。
首先,在 RefreshTypeNames方法里获取所有的ProcedureBase的派生类,并且记录下来,找到选中的那个启动Procedure。这个刷新方法会在OnCompileComplete 和 OnEnable方法里调用。
其次,在OnInspectorGUI这个方法里 先做了一些防止意外情况发生的过滤处理。然后就是把获取到的Procedurel类型名字挨个显示在编辑器上。
最后,这里涉及了几个关于unity3d和c#语法特性的东西,我不做科普了。没搞明白的朋友自己找度娘去。
走到了这一步,也就是说启动流程的编辑器和数据来源都已经明白了,下面我们一起来掰扯一下有限状态机。
在GF的管理器GameFrameworkEntry这个类里,调用GetModule方法,如果存在就直接返回,不存在则挂载一个流程管理器接口。听起来有点拗口,但它真的是干这事儿了,我以后会好好掰扯这个的,现在重点屡一下整体流程。
在流程管理器里有一个有流程管理器接口的状态机接口和一个状态机管理器接口,听起来也有点奇怪。毕竟,这是框架嘛,里面都是接口也不奇怪,见怪不怪就好。
然后就是我们的有限状态机模块了。这个模块分有限状态机的持有者,有限状态机的基类(其实是个抽象类),有限状态机状态基类,有限状态机接口和有限状态管理接口。除了有限状态机的基类其余都用到了模板。这样子这个有限状态机就变得非常灵活好用。状态机我见过很多不同版本的,这个是我见过的复用性最好的一版。
回到流程管理器,这个时候流程启动(状态机也启动了)OnEnter OnInit OnDestory OnLeave OnUpdate 直接照着填空就可以了。当然,我稍微走马观花的看了一眼有限状态机的实现、数据来源和编辑器的支持。
启动这个星际力量还需要加载UI 显示游戏的界面,作为一个游戏项目这个很重要,也就是所谓的资源模块和UI模块。毕竟这个是单机的示例游戏,网络啥的扯不上。
有了前面流程模块的大致工作流程,这个资源模块其实也是按照差不多思路去做的。三位一体的路数。
有可以配置的Transform
有编辑器拓展的支持(Unity3d)
有接口(GF的)和实现部分(UGF的)
在Inspector里有资源模式 资源读取路径的选择 卸载资源延迟 资源辅助器 资源代理辅助器...一堆设置。有些我都没用过,有些在之前开发的时候有用过,不过不得不承认,我没想过让这些东西走配置或者说编辑器。
值得一提的是资源辅助器和加载资源代理辅助器可以继承它的父类新增一个,然后如果业务需要的话,可以拓展这个模块。套路跟之前的流程管理的那个编辑器支持差不多。也是根据基类找到所有的派生类提供可以编辑选项。
UI模块跟资源模块相似度就来了。
同样的也是三位一体,UI是依赖于资源模块的,毕竟UI是资源的一部分。
也提供了对应的编辑模块
需要注意到是 这里有界面辅助器和界面组辅助器可以继承它们的父类进行拓展。跟上面提及的流程管理和资源的拓展是差不多的。
扯到这儿,星际力量就可以启动起来了。
资源模块加载本地资源(这里其实是有分类处理和不同路径的管理,我以后再细说)
UI模块基于资源模块加载UI 贴图 音效 就可以看到我们之前启动的那个星际力量界面
工作流程整体是 启动Unity->加载初始场景 ->挂载transform ->挂载组件->启动UGF->调用GF->走流程管理器->加载资源->加载界面。