Unity 框架QFramework v1.0 使用指南 架构篇:20. QFramework.cs 的更多内容 | Unity 游戏框架 | Unity 游戏开发 | Unity 独立游戏
Posted 凉鞋的笔记
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity 框架QFramework v1.0 使用指南 架构篇:20. QFramework.cs 的更多内容 | Unity 游戏框架 | Unity 游戏开发 | Unity 独立游戏相关的知识,希望对你有一定的参考价值。
终于把想介绍的内容都讲完了。
如果想进一步了解和学习 QFramework.cs 可以看如下内容。
使用 QFramework.cs 的案例与项目
更多的案例可以到 QFramework github 主页查看。
地址:
- github: https://github.com/liangxiegame/QFramework
- gitee: https://gitee.com/liangxiegame/QFramework
国内童鞋建议打开 gitee 版本仓库。
在 Readme 中可以看到如下内容:
在这里可以安装 QFramework.cs 与官方示例。
点击之后,再点击下图中的下载按钮。
就可以下载 QFramework.cs 官方示例了。
示例中,除了本教程包含的 CounterApp,还有很多其他示例,如下:
小游戏《点点点》
小游戏《FlappyBird》
作者:王二 soso https://github.com/so-sos-so
小游戏《Cube Master》
作者:王二 soso https://github.com/so-sos-so
简易关卡编辑器2D
小游戏《贪吃蛇》
作者:一只皮皮虾 https://gitee.com/PantyNeko/
以上的示例都是由 QFramework.cs 制作而成的官方示例。
另外还有群友制作的开源游戏
CrazyCar
Unity制作的联机赛车游戏,后台为SpringBoot + Mybatis;游戏采用QFramework框架,支持KCP和WebSocket网络(商用级)
作者: TastSone https://github.com/TastSong
项目地址: https://github.com/TastSong/CrazyCar
QFramework.cs 的架构如何演化出来的?
QFramework.cs 的架构当前的版本,是从 《框架搭建 决定版》中设计出来的,如果学习这门课程,可以对 QFramework.cs 的原理和理念理解得更深刻,更容易对 QFramework.cs 做修改和定制。
- 《框架搭建 决定版》B 站试听:https://www.bilibili.com/video/BV1wh411U7X6
- 《框架搭建 决定版》完整版
- Unity 官方中文课堂:https://learn.u3d.cn/tutorial/framework_design
- siki 学院:https://www.sikiedu.com/my/course/871
- GamePix 独立游戏学院:https://www.gamepixedu.com/my/course/2
另外 QFramework.Toolkits 和 QFramework.ToolkitsPro 里包含的工具很多都是由 QFramework.cs 设计的, 工具的源码本身也是不错的学习资料。
更多内容
- 转载请注明地址:liangxiegame.com (首发) 微信公众号:凉鞋的笔记
- QFramework 主页:qframework.cn
- QFramework Github 地址: https://github.com/liangxiegame/qframework
- QFramework Gitee 地址:https://gitee.com/liangxiegame/QFramework
- GamePix 独立游戏学院 & Unity 进阶小班地址:https://www.gamepixedu.com/
OpenSourceC#Unity框架-QFramework
前言
我在纠结这个放到哪个栏目,放到【UnityGamePlay】的话,这是个框架代码,放到
【开源代码解读】的话,我估计后面会看一些代码例子来讲解这个框架的使用。
纠结完还是决定放这里吧,如果后面写具体的例子了再放到【UnityGamePlay】里。
老规矩先放源码链接:QFramework
这个框架里还有许多其他工具,比如UIKit
,这里先不管这些Kit,只看QFramework.cs
这一个文件,这一个就是框架的所有代码。
这是一个Unity前端的MVC框架,MVC就不用说了,感觉是最好理解的框架了。
游戏开发实践
首先以游戏开发角度理解一下QFramework里的几个概念:
Control 对UI和游戏进度的控制。
System 是游戏具有哪些功能模块,对这些模块的功能支持。
Model 是用到了哪些数据,对数据的封装。
Utility 实现一些与逻辑无关的工具类
Commond 是对要去做某件事的封装。
Event 是达成了某个条件,让所有注册此事件的回调执行。
-------2022.11.21 update start-------
时隔几个月,对框架和游戏开发更熟悉了,再看这个框架,又有了不同的理解,来补充一下。
MVC主要是在ui管理中使用,具体的游戏逻辑比较复杂,根据情况而定。
Controller 主要是界面控制,ViewController,当做View层使用,监听一些需要改变数据的事件。
Model 层是数据层,可以发送事件,可以利用BindableProperty 在数据变化时发送ViewController监听的事件,更改UI。
System,可以当做MVC中的Controll层来用,也可以实现独立的游戏系统,当成Controller用的话,就是修改Model,发送View监听的事件,修改界面
最近看的xlua-framework中的ui框架也是mvc模式,主要是层级间的调用关系略有不同。
这个框架里,view可以读model,可以调用ctrl,ctrl可以读写model,model不能操作vc,view在Update()中每帧去读model更新UI。
对应到QF里,就是ViewController可以读写Model,可以调用System,System可以读写Model,Model层只可以发送事件。
-------2022.11.21 update end-------
Architecture
这个可以理解成整个框架的Main。
从这个接口定义就能看出这个框架的所有功能,如下。
public interface IArchitecture
void RegisterSystem<T>(T system) where T : ISystem;
void RegisterModel<T>(T model) where T : IModel;
void RegisterUtility<T>(T utility) where T : IUtility;
T GetSystem<T>() where T : class, ISystem;
T GetModel<T>() where T : class, IModel;
T GetUtility<T>() where T : class, IUtility;
void SendCommand<T>() where T : ICommand, new();
void SendCommand<T>(T command) where T : ICommand;
TResult SendQuery<TResult>(IQuery<TResult> query);
void SendEvent<T>() where T : new();
void SendEvent<T>(T e);
IUnRegister RegisterEvent<T>(Action<T> onEvent);
void UnRegisterEvent<T>(Action<T> onEvent);
Architecture
管理所有的System
、Model
、Utility
,提供注册和获取接口。除此之外,有发送Command
、 注册发送Event
和查询功能。
具体实现可以看接下来的抽象类 public abstract class Architecture<T> : IArchitecture where T : Architecture<T>, new()
,这个代码过长就不贴了。
其中mContainer
存储所有注册的对象,所有对象都有Init()
接口,在初始化时会依次调用。
发送Commond
时实际就是调用它的Execute()
方法。
事件的注册与发送依赖TypeEventSystem
类型。注意事件注册返回的是IUnRegister
接口,后面再说这个的作用。
Architecture<T>
里面要注意的就这么多吧,代码不难,但是要理解为什么这样写,就要明白这些类和接口的作用。
后面的OnGlobalEventExtension
,它的作用是扩展TypeEventSystem.Global
的事件注册功能。这种写法就是为了给原始类型扩展方法,特点:1、静态类 2、静态方法 3、第一个参数前加this。理解这个很重要,因为这个框架几乎所有接口都用这种写法扩展方法。不得不说这个写法实在是巧妙。
Controller
框架中只定义了一个接口,但这个接口提供了Controller
所具有的的功能
#region Controller
public interface IController : IBelongToArchitecture, ICanSendCommand, ICanGetSystem, ICanGetModel,
ICanRegisterEvent, ICanSendQuery
#endregion
这作者名字起的挺通俗易懂的,直接看这接口名就知道这个IController
有什么功能了,一次是:属于这个框架,可以发送Command
,可以取到Ststem
和Model
,可以注册事件,可以查询。
注意理解上面说过的“扩展方法”的用法,然后来看为什么继承这几个接口就实现了这几个功能。
Rule
这个规则就是使用扩展方法定义了几种接口,使用哪种接口就是使用这个接口的扩展方法,一共有好几种接口,不过都是下面这三个结构的格式。
public interface IBelongToArchitecture
IArchitecture GetArchitecture();
public interface ICanGetModel : IBelongToArchitecture
public static class CanGetModelExtension
public static T GetModel<T>(this ICanGetModel self) where T : class, IModel
return self.GetArchitecture().GetModel<T>();
IBelongToArchitecture
提供了获得本架构的接口,之后定义的规则都要继承这个接口,如这个ICanGetModel
,这个接口就提供了获得Model的功能,通过下面的扩展CanGetModelExtension
实现的。
也就是说,继承了ICanGetModel
接口,就能调用GetModel<T>()
这个方法来获得Model。
理解了后再看上面的IController
,也就是说Controller 能调用GetModel
获得Model,之后看具体例子的时候会理解更深。
剩下还有几个规则接口,就不全部说了,理解了上面这个就都懂了。
System 与 Model
这两个代码类似,主要是继承的接口不同,Model除了和架构相关的接口,只能获得Utility工具和发送事件。System能做的事情更多。
SetArchitecture
是设置架构,在Architecture
的注册代码中先调用这个方法。为了让Model持有架构的引用,这样才能像self.GetArchitecture().GetModel<T>();
这样调用。
自定义的System和Model需要重载OnInit()
方法。
Utility
工具类,不能只用其他功能,只能是通用的工具。
Command
这个可以理解成要做什么,在发送Command的时候会调用它的Execute方法,也就是说在实现Command的时候重载它的OnExecute() 方法。
代码没什么说的,就不贴了,看看示例怎么用的就懂了。
Query
和Command类似
IOC
见:IOC
BindableProperty
这个主要实现的类似MVVM 中的ViewModel、Binder 的作用,定义这个类的变量,在修改时会执行回调函数mOnValueChanged
,当然回调函数要自己实现。
应用场景,比如血量这个属性,当血量变化时要修改UI显示信息,就可以把血量定义成这个类,然后在回调函数中处理UI变化信息。
注意 Register
返回的是BindablePropertyUnRegister
,这是一个继承IUnRegister
接口的类,这个接口有一个扩展方法UnRegisterExtension
,它实现的是把gameObject添加一个UnRegisterOnDestroyTrigger
组件。
看这个组件的实现,它是一个Mono 类,在OnDestroy
,会调用unRegister.UnRegister();
解除事件注册,这里调用的实际是下面这个UnRegister
。
public class BindablePropertyUnRegister<T> : IUnRegister
public BindableProperty<T> BindableProperty get; set;
public Action<T> OnValueChanged get; set;
public void UnRegister()
BindableProperty.UnRegister(OnValueChanged);
BindableProperty = null;
OnValueChanged = null;
而这个又调用的BindableProperty.UnRegister(OnValueChanged);
,就是把BindableProperty
的值变化回调给删除了。
public void UnRegister(Action<T> onValueChanged)
mOnValueChanged -= onValueChanged;
理解了这个调用链,那这个有什么用呢?看下面这个例子,这没有用BindableProperty
,用的是接下来要说的Event,不过用法是一样的注册了一个事件后,又调用了.UnRegisterWhenGameObjectDestroyed(gameObject)
,看名字就知道,在销毁的时候把注册的事件清除。
this.RegisterEvent<GamePassEvent>(e => transform.Find("Enemies").gameObject.SetActive(false); )
.UnRegisterWhenGameObjectDestroyed(gameObject);
不过这里也有个疑惑,Event用这个机制没问题,因为它的事件是全局的,不取消注册就会越来越多,但BindableProperty
不是一个单独的变量吗,如果对象都销毁了,就算不取消注册也应该没事吧。不懂,疑惑先保留,如果以后解决了再来补充。
Event
最后一个模块了。看到这里会发现好像每个模块都能看懂,但又都不知道这有什么用,不用担心,先看完,然后看个例子,再来看框架就懂了。
前面都是和UnRegister
相关的代码,上节说的那个调用流程已经值得这是怎么用的了,其他看看就懂了。
主要是看TypeEventSystem
和EasyEvent
。
Event只提供了3个用法吧,一是Global
全局事件注册,二是发送事件,三是注册与取消事件。TypeEventSystem
是对这三种用法的包装,实际是靠EasyEvent
实现的。(ps:不知道从哪个版本开始改成这样的,之前只有TypeEventSystem)
但上述只提供了Action<T>
一种写法,TypeEventSystem
意思就是类型事件系统,T就是这个事件的类型。
EasyEvent
还重载了多参数的Action,和一个不依赖任何接口的EasyEvents
,自己看吧,没什么说的。
Over,框架就这么多了,之后看情况找个使用这个框架的项目讲讲吧。
以上是关于Unity 框架QFramework v1.0 使用指南 架构篇:20. QFramework.cs 的更多内容 | Unity 游戏框架 | Unity 游戏开发 | Unity 独立游戏的主要内容,如果未能解决你的问题,请参考以下文章
Unity 框架QFramework v1.0 使用指南 工具篇:09. SingletonKit 单例模板套件 | Unity 游戏框架 | Unity 游戏开发 | Unity 独立游戏
Unity 框架QFramework v1.0 使用指南 架构篇:05. 引入 Utility | Unity 游戏框架 | Unity 游戏开发 | Unity 独立游戏
Unity 框架QFramework v1.0 使用指南 工具篇:05. ResKit 资源管理&开发解决方案 | Unity 游戏框架 | Unity 游戏开发 | Unity 独立游戏
OpenSourceC#Unity框架-QFramework