【Unity 框架】QFramework v1.0 使用指南 架构篇:02. QFramework 的 MVC | Unity 游戏框架 | Unity 游戏开发 | Unity 独立游戏
QFramework 基于 MVC 的开发模式
所以我们先从最熟知的 MVC 架构开始着手 QFramework 的学习。
我们先做一个非常简单的计数器应用。
首先我们使用 UGUI 创建一个最简单的界面,如下图所示:

场景结构如下所示:

复制完之后,我们创建一个脚本叫做 CounterAppController,代码如下:
using UnityEngine;
using UnityEngine.UI;
namespace QFramework.Example
{
    // Controller
    public class CounterAppController : MonoBehaviour
    {
        // View
        private Button mBtnAdd;
        private Button mBtnSub;
        private Text mCountText;
        
        // Model
        private int mCount = 0;
        void Start()
        {
            // View 组件获取
            mBtnAdd = transform.Find("BtnAdd").GetComponent<Button>();
            mBtnSub = transform.Find("BtnSub").GetComponent<Button>();
            mCountText = transform.Find("CountText").GetComponent<Text>();
            
            
            // 监听输入
            mBtnAdd.onClick.AddListener(() =>
            {
                // 交互逻辑
                mCount++;
                // 表现逻辑
                UpdateView();        
            });
            
            mBtnSub.onClick.AddListener(() =>
            {
                // 交互逻辑
                mCount--;
                // 表现逻辑
                UpdateView();
            });
            
            UpdateView();
        }
        
        void UpdateView()
        {
            mCountText.text = mCount.ToString();
        }
    }
}
代码很简单,这是一个非常简易的 MVC 的实现。
我们将此脚本挂在 Canvas 节点上,运行 Unity 结果如下:

非常简单。
此时我们还没有导入我们的 QFramework,不着急,我们先看看代码中所介绍的概念。
首先是 Model、View、Controller
Model 的代码如下:
// Model
private int mCount = 0;
非常简单,只有一个成员变量,但是在这里它其实并不算是一个 Model,他只是要在 View 中显示的一个数据而已,具体为什么不是 Model 我们在后边再说。
View 的代码如下:
// View
private Button mBtnAdd;
private Button mBtnSub;
private Text mCountText;
View 的代码也很简单,View 在 QFramework 的 MVC 定义里就是提供关键组件的引用,比如这三个组件是要在 Controller 代码里要用到的。而其他的例如 Canvas Scaler 等这些组件目前 Controller 不需要,所以就不用声明。
Controller 的代码,如下:
void Start()
{
    ...
      
    // 监听输入
    mBtnAdd.onClick.AddListener(() =>
    {
        // 交互逻辑
        mCount++;
        // 表现逻辑
        UpdateView();        
    });
            
    mBtnSub.onClick.AddListener(() =>
    {
        // 交互逻辑
        mCount--;
        // 表现逻辑
        UpdateView();
    });
            
    UpdateView();
}
        
void UpdateView()
{
    mCountText.text = mCount.ToString();
}
以上就是 Controller 的代码。
好了,我们回头再看下完整代码。
using UnityEngine;
using UnityEngine.UI;
namespace QFramework.Example
{
    // Controller
    public class CounterAppController : MonoBehaviour
    {
        // View
        private Button mBtnAdd;
        private Button mBtnSub;
        private Text mCountText;
        
        // Model
        private int mCount = 0;
        void Start()
        {
            // View 组件获取
            mBtnAdd = transform.Find("BtnAdd").GetComponent<Button>();
            mBtnSub = transform.Find("BtnSub").GetComponent<Button>();
            mCountText = transform.Find("CountText").GetComponent<Text>();
            
            
            // 监听输入
            mBtnAdd.onClick.AddListener(() =>
            {
                // 交互逻辑
                mCount++;
                // 表现逻辑
                UpdateView();        
            });
            
            mBtnSub.onClick.AddListener(() =>
            {
                // 交互逻辑
                mCount--;
                // 表现逻辑
                UpdateView();
            });
            
            UpdateView();
        }
        
        void UpdateView()
        {
            mCountText.text = mCount.ToString();
        }
    }
}
目前像计数器这样的逻辑,以上的代码完全没有问题。
但是我们要用发展的眼光看待问题。
假如这是一个初创项目,那么接下来很有可能需要添加大量的业务逻辑。
其中很有可能让 mCount 在多个 Controller 中使用,甚至需要针对 mCount 这个数据写一些其他逻辑,比如增加 mCount 则增加 5 个分数,或者 mCount 需要存储等,总之 mCount 在未来可能会发展成一个需要共享的数据,而 mCount 目前只属于 CounterAppController,显然在未来这是不够用的。
我们就需要让 mCount 成员变量变成一个共享的数据,最快的做法是吧 mCount 变量变成静态变量或者单例,但是这样虽然写起来很快,但是在后期维护额度时候会产生很多的问题。
而 QFramework 架构提供了 Model 的概念。
我们来使用一下。
我们先导入 QFramework 架构。
导入 QFramework 的方式非常简单,只需要复制 QFramework.cs 的代码到 Unity 工程中即可。
QFramework.cs 地址:
- Gitee: https://gitee.com/liangxiegame/QFramework/blob/master/QFramework.cs
- Github: https://github.com/liangxiegame/QFramework/blob/master/QFramework.cs
导入之后,我们将 CounterAppController 的代码改成如下:
using UnityEngine;
using UnityEngine.UI;
namespace QFramework.Example
{
    
    // 1. 定义一个 Model 对象
    public class CounterAppModel : AbstractModel
    {
        public int Count;
        
        protected override void OnInit()
        {
            Count = 0;
        }
    }
    // 2.定义一个架构(提供 MVC、分层、模块管理等)
    public class CounterApp : Architecture<CounterApp>
    {
        protected override void Init()
        {
            // 注册 Model
            this.RegisterModel(new CounterAppModel());
        }
    }
    // Controller
    public class CounterAppController : MonoBehaviour , IController /* 3.实现 IController 接口 */
    {
        // View
        private Button mBtnAdd;
        private Button mBtnSub;
        private Text mCountText;
        
        // 4. Model
        private CounterAppModel mModel;
        void Start()
        {
            // 5. 获取模型
            mModel = this.GetModel<CounterAppModel>();
            
            // View 组件获取
            mBtnAdd = transform.Find("BtnAdd").GetComponent<Button>();
            mBtnSub = transform.Find("BtnSub").GetComponent<Button>();
            mCountText = transform.Find("CountText").GetComponent<Text>();
            
            
            // 监听输入
            mBtnAdd.onClick.AddListener(() =>
            {
                // 6. 交互逻辑
                mModel.Count++;
                // 表现逻辑
                UpdateView();        
            });
            
            mBtnSub.onClick.AddListener(() =>
            {
                // 7. 交互逻辑
                mModel.Count--;
                // 表现逻辑
                UpdateView();
            });
            
            UpdateView();
        }
        
        void UpdateView()
        {
            mCountText.text = mModel.Count.ToString();
        }
        // 3.指定架构
        public IArchitecture GetArchitecture()
        {
            return CounterApp.Interface;
        }
        private void OnDestroy()
        {
            // 8. 将 Model 设置为空
            mModel = null;
        }
    }
}
好了,代码引入了两个新的概念,一个是 Architecture,另一个是 Model。
Architecture 用于管理模块,或者说 Architecture 提供一整套架构的解决方案,而模块管理和提供 MVC 只是其功能的一小部分。
我们运行一下 Unity 结果如下:

运行正确。
好了,我们上手了 QFramework 提供的 MVC 架构。
这里要注意一点,Model 的引入是为了解决数据共享的问题,而不是说单只是为了让数据和表现分离,这一点是非常重要的一点。
数据共享分两种:空间上的共享和时间上的共享。
空间的共享很简单,就是多个点的代码需要访问 Model 里的数据。
时间上的共享就是存储功能,将上一次关闭 App 之前的数据存储到一个文件里,这次打开时获得上次关闭 App 之前的数据。
虽然我们上手了 MVC,但是这样的 MVC 还有很多问题,我们下一篇继续解决。
更多内容
- 转载请注明地址:liangxiegame.com (首发) 微信公众号:凉鞋的笔记
- QFramework 主页:qframework.cn
- QFramework 交流群: 623597263
- QFramework Github 地址: https://github.com/liangxiegame/qframework
- QFramework Gitee 地址:https://gitee.com/liangxiegame/QFramework
- GamePix 独立游戏学院 & Unity 进阶小班地址:https://www.gamepixedu.com/
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号