前言
最近学习了QFramework框架的知识,结合之前对设计模式的学习理解,越来越感觉在项目中使用框架开发的重要性。我个人的经历,要么就是在做各种的demo,要么就是用一些完善的框架,把自己写的功能嵌进去。从来没有写过完整的、较为复杂的整体系统级实现。往往就是不断地加新的脚本、全部Public、单例满天飞就可以解决问题。
学习QFramework最基本的框架后,虽然对MVC的形式和QF项目中的一些规则和工具有了概念,但是要是纯自己使用QF写东西我还没有什么头绪。恰好官方发布的管道鸟游戏的教程,轻度使用了QF框架。我认为非常值得借鉴,很适合我这类常年写demo的人hhhh。本文先总结一下轻度使用QF框架开发的一些技巧,后面我想拿出之前写的一个小项目进行QF重构。
要了解QF框架的兄弟们可以移步官方网站,案例很清晰。
“您好 我是 QFramework”
常用配置
QF框架比较精简,完整版包含了很多常用的功能,例如音频、UI、对象池等等,建议大家直接导入完整版就好。
导入QF框架后,使用CTRL + E可以打开QF的编辑器界面。这里要提前设置CodeGen、UIkit的命名空间、生成代码和资源的目录等信息,根据自己的喜好。如果使用UIKit的话,也要在这个界面生成UI。
自动生成代码和绑定
如果使用QF框架的话,自动生成功能是非常方便的,而且自动绑定也比手写和拖动更方便、更容易管理。
例如在管道鸟游戏开发中,我们会创建一个管道生成器,包含生成位置和要生成的预制体。如果是之前,我大概会这样写:
1、创建脚本
//先在Scripts文件夹下创建PipeGenerator脚本
public class PipeGenerator : MonoBehaviour
{
// 暴露在编辑器面板
public Transform PipeGeneratePos;
public GameObject PipeTemp;
}
2、在Unity新建这些游戏物体
3、然后用拖动的方式配置好。
使用QF框架会把这个过程变得更简单快捷,而且实现的方式能让我们对这些绑定关系更好管理。
QF做到同样的事情,步骤是这样的:
1、创建PipeGenerator游戏空物体
2、选择物体后,按下ALT + V,会默认在这个游戏物体上绑定了一个ViewController脚本,见下图
生成脚本名一栏默认是游戏物体的名字,此时点击生成代码,即可完成新建脚本PipeGenerator并绑定
3、创建PipeGeneratePos、PipeTemp并做好编辑,分别选中并按下ALT + B,此时物体上会出现Bind脚本并可以配置。
我们回到PipeGenerator脚本会发现,自动生成了名为PipeGenerator.Design.cs的脚本,所有的Bind都绑定在里面,相当于我们手动去拖动的绑定。
使用框架的属性工具和监听代替单例
做demo的时候常遇到,传递一个全局的值并监听,一般我就用单例直接获取了。
demo体积小的时候这样写没什么问题,比较快,但是一旦复杂起来这样就不行了。
QF提供了一个BindableProperty工具可以非常方便的处理这种 数据 + 事件 的逻辑。
下面的代码可以展示它的基本用法
public class Game : Architecture<Game>
{
//小项目全局的变量适合写在Architecture层,不至于用model
public static BindableProperty<int> Score = new(0);
public static BindableProperty<int> BestScore = new(0);
protected override void Init()
{
BestScore.Value = PlayerPrefs.GetInt(nameof(BestScore));
//每当BestScore有变化,就保存
BestScore.Register(bestScore =>
{
PlayerPrefs.SetInt(nameof(BestScore),bestScore);
});
//Score没变化也会先执行一次,比较适合UI初始化等
Score.RegisterWithInitValue(score =>
{
if (score > BestScore.Value)
{
BestScore.Value = score;
}
});
}
}
//在其它类中使用监听,要加unregister
BirdGame.Score.RegisterWithInitValue(state =>
{
}).UnRegisterWhenGameObjectDestroyed(gameObject);
使用UIkit
UIKit是一个UI管理工具,包括UI的创建和管理。
前置:使用UIKit时必须在框架初始化时初始化ResKit
在框架的Architecture层添加函数
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
public static void InitFramework()
{
ResKit.Init();
}
函数前的Attribute可以让你在某个时刻调用这个方法,参数可选具体时刻。
1、UI建立:CTRL + E打开QF的设置面板 -> UIKit创建服务,配置好分辨率和名称即可创建UI
2、生成的UI资源如下图所示,分别是预制体、测试场景和代码。
如果UI的绑定需要修改,保存到预制体后,记得右键预制体-> Create UI Code 重新生成绑定代码。
开关UI很方便:
UIKit.OpenPanel<Name>();
UIKit.ClosePanel<Name>();
使用对象池
QF框架自带了对象池SimpleObjectPool,接下来的一段代码就能展示它的用法
public static SimpleObjectPool<Pipe> PipePool;
void Start()
{
//初始化
PipePool = new SimpleObjectPool<Pipe>(
//工厂方法,用于生成对象
() =>
{
return PipeTemp.Instantiate().Hide();
},
//reset方法,用于回收时执行
(pipe) =>
{
pipe.Reset();
},
//预生成数量
5);
}
//取用
PipePool.Allocate();
//回收
PipePool.Recycle(pipe);