1、什么是MVVM

借用一下百度百科上对MVVM的介绍,MVVM是Model-View-ViewModel的简写,它本质上就是MVC 的改进版。MVVM 就是将其中的View 的状态和行为抽象化,让我们将视图 UI 和业务逻辑分开。当然这些事 ViewModel 已经帮我们做了,它可以取出 Model 的数据同时帮忙处理 View 中由于需要展示内容而涉及的业务逻辑。
 

2、MVVM在unity开发中的应用

MVVM框架应用面十分广泛,通常在前端开发中应用很广,最近看到周围同事在开发WPF时用到了这个框架,抱着好奇的态度来学习一下这个框架,MVVM框架在unity开发中同样适用,在unity中,将每个UI抽象成一个个View,通常我们为每一个UI面板定义一个View,View中包含了该面板中涉及到的UI元素,比如一个Text,一个Button;每一个View都有独立的ViewModel来管理,ViewModel中提供必要的属性和方法来控制View, 而Model只是单纯的定义一个数据模型。前两天在github上发现了这个叫uMVVM的框架,拿来试用了一下,下面分析一下该框架对MVVM模式的设计。
 

3、uMVVM的设计与实现

下载uMVVM后,它提供了一些使用示例:

在这个示例中,有两个panel,就定义了两个view,每个view中定义该界面的元素,比如SetupView:

public class SetupView:UnityGuiView<SetupViewModel>
{ public InputField nameInputField;
public Text nameMessageText; public InputField jobInputField;
public Text jobMessageText; public InputField atkInputField;
public Text atkMessageText; public Slider successRateSlider;
public Text successRateMessageText; public Toggle joinToggle;
public Button joinInButton;
public Button waitButton; public SetupViewModel ViewModel { get { return (SetupViewModel)BindingContext; } } }
可以看到,View中需要指定对应的ViewModel来管理该View,ViewModel中定义的属性需要具备当数据改变时通知订阅者的功能,因此uMVVM对这种属性进行了一层封装,具体设计如下:

public class BindableProperty<T>
{
public delegate void ValueChangedHandler(T oldValue, T newValue); public ValueChangedHandler OnValueChanged; private T _value;
public T Value
{
get
{
return _value;
}
set
{
if (!Equals(_value, value))
{
T old = _value;
_value = value;
ValueChanged(old, _value);
}
}
} private void ValueChanged(T oldValue, T newValue)
{
if (OnValueChanged != null)
{
OnValueChanged(oldValue, newValue);
}
} public override string ToString()
{
return (Value != null ? Value.ToString() : "null");
}
}
可以看到,BindableProperty类中维护一个T类型数据,当T发生变化时,可以通知到订阅者,有了这种属性之后,那么ViewModel就是这样的了:

public class SetupViewModel:ViewModelBase
{
public readonly BindableProperty<string> Name = new BindableProperty<string>();
public readonly BindableProperty<string> Job=new BindableProperty<string>();
public readonly BindableProperty<int> ATK = new BindableProperty<int>();
public readonly BindableProperty<float> SuccessRate=new BindableProperty<float>();
public readonly BindableProperty<State> State=new BindableProperty<State>();
}
uMVVM的设计中,每个View都继承UnityGuiView这个泛型类,UnityGuiView大概的内容是这样:

public abstract class UnityGuiView<T>:MonoBehaviour,IView<T> where T:ViewModelBase
{
private bool _isInitialized;
public bool destroyOnHide;
protected readonly PropertyBinder<T> Binder=new PropertyBinder<T>();
public readonly BindableProperty<T> ViewModelProperty = new BindableProperty<T>(); public T BindingContext
{
get { return ViewModelProperty.Value; }
set
{
if (!_isInitialized)
{
OnInitialize();
_isInitialized = true;
}
//触发OnValueChanged事件
ViewModelProperty.Value = value;
}
} /// <summary>
/// 初始化View,当BindingContext改变时执行
/// </summary>
protected virtual void OnInitialize()
{
//无所ViewModel的Value怎样变化,只对OnValueChanged事件监听(绑定)一次
ViewModelProperty.OnValueChanged += OnBindingContextChanged;
} /// <summary>
/// 当gameObject将被销毁时,这个方法被调用
/// </summary>
public virtual void OnDestroy()
{
if (BindingContext.IsRevealed)
{
Hide(true);
}
BindingContext.OnDestory();
BindingContext = null;
ViewModelProperty.OnValueChanged = null;
} /// <summary>
/// 绑定的上下文发生改变时的响应方法
/// 利用反射+=/-=OnValuePropertyChanged
/// </summary>
public virtual void OnBindingContextChanged(T oldValue, T newValue)
{
Binder.Unbind(oldValue);
Binder.Bind(newValue);
}
}
UnityGuiView中有一个BindingContext的属性, 当使用框架时,需要给View的BindingContext指定对应的ViewModel:

  public class Install:MonoBehaviour
{
// Use this for initialization
public SetupView setupView;
public TestView testView;
void Start()
{
//绑定上下文
setupView.BindingContext=new SetupViewModel();
testView.BindingContext=new TestViewModel();
}
}
在View中,就订阅model数据改变的消息,并定义相应的响应函数:

 public class SetupView:UnityGuiView<SetupViewModel>
{
//......省略ui元素的定义 protected override void OnInitialize()
{
base.OnInitialize();
Binder.Add<string>("Name", OnNamePropertyValueChanged);
Binder.Add<string>("Job",OnJobPropertyValueChanged);
Binder.Add<int>("ATK",OnATKPropertyValueChanged);
Binder.Add<float>("SuccessRate",OnSuccessRatePropertyValueChanged);
Binder.Add<State>("State",OnStatePropertyValueChanged);
} private void OnSuccessRatePropertyValueChanged(float oldValue, float newValue)
{
successRateMessageText.text = newValue.ToString("F2");
} private void OnATKPropertyValueChanged(int oldValue, int newValue)
{
atkMessageText.text = newValue.ToString();
} private void OnJobPropertyValueChanged(string oldValue, string newValue)
{
jobMessageText.text = newValue.ToString();
} private void OnNamePropertyValueChanged(string oldValue, string newValue)
{
nameMessageText.text = newValue.ToString();
}
private void OnStatePropertyValueChanged(State oldValue, State newValue)
{
//dosomething
}

最后看一下其中一个model的定义:

 public class Combatant
{
public int Id { get; set; }
public string Name { get; set; }
public string Job { get; set; }
public float SuccessRate { get; set; }
public State State { get; set; }
}
public enum State
{
JoinIn,
Wait
}

4、总结

本文只大概写了一下uMVVM框架的一些设计和使用方法,不全面,如果感兴趣,可以自行阅读源码,github地址为https://github.com/MEyes/uMVVM
 
如有错误,欢迎指正!

MVVM框架在unity开发中的使用的更多相关文章

  1. 二十八、带给我们一种新的编码思路——EFW框架CS系统开发中的MVC模式探讨

    回<[开源]EFW框架系列文章索引>        EFW框架源代码下载V1.3:http://pan.baidu.com/s/1c0dADO0 EFW框架实例源代码下载:http://p ...

  2. 二十七、EFW框架BS系统开发中的MVC模式探讨

    回<[开源]EFW框架系列文章索引>        EFW框架源代码下载V1.3:http://pan.baidu.com/s/1c0dADO0 EFW框架实例源代码下载:http://p ...

  3. 领域驱动和MVVM应用于UWP开发的一些思考

    领域驱动和MVVM应用于UWP开发的一些思考 0x00 起因 有段时间没写博客了,其实最近本来是根据梳理的MSDN上的资料(UWP开发目录整理)有条不紊的进行UWP学习的.学习中有了心得体会或遇到了问 ...

  4. MVVM 框架解析之双向绑定

    更好的阅读体验,点击 原文地址 MVVM 框架 近年来前端一个明显的开发趋势就是架构从传统的 MVC 模式向 MVVM 模式迁移.在传统的 MVC 下,当前前端和后端发生数据交互后会刷新整个页面,从而 ...

  5. iOS开发中文件的上传和下载功能的基本实现-备用

    感谢大神分享 这篇文章主要介绍了iOS开发中文件的上传和下载功能的基本实现,并且下载方面讲到了大文件的多线程断点下载,需要的朋友可以参考下 文件的上传 说明:文件上传使用的时POST请求,通常把要上传 ...

  6. 使用MVVM框架(avalonJS)进行快速开发

    背景 在运营活动开发中,因为工作的重复性很大,同时往往开发时间短,某些情况下也会非常紧急,导致了活动开发时间被大大压缩,同时有些活动逻辑复杂,数据或者状态变更都需要手动渲染,容易出错,正是因为这些问题 ...

  7. 简单的介绍下WPF中的MVVM框架

    最近在研究学习Swift,苹果希望它迅速取代复杂的Objective-C开发,引发了一大堆热潮去学它,放眼望去各个培训机构都已打着Swift开发0基础快速上手的招牌了.不过我觉得,等同于无C++基础上 ...

  8. 【Unity游戏开发】浅谈Unity游戏开发中的单元测试

    一.单元测试的定义与作用 单元测试定义:单元测试在传统软件开发中是非常重要的工具,它是指对软件中的最小可测试单元进行检查和验证,一般情况下就是对代码中的一个函数去进行验证,检查它的正确性.一个单元测试 ...

  9. 浅析前端开发中的 MVC/MVP/MVVM 模式

    MVC,MVP和MVVM都是常见的软件架构设计模式(Architectural Pattern),它通过分离关注点来改进代码的组织方式.不同于设计模式(Design Pattern),只是为了解决一类 ...

随机推荐

  1. js-图片时间困难版(倒计时)

    <!DOCTYPE html><html>    <head>        <meta charset="UTF-8">      ...

  2. unigui导出EXCEL使用NATIVEEXCEL

    unigui导出EXCEL使用NATIVEEXCEL // 需要nativeexcel控件// cxg 2017-9-9 unit myExcel; interface uses System.Sys ...

  3. 为什么在UDP包中不能获取发包方的地址

    首先,我们要先了解一下UDP包的结构. 图1 UDP报文格式 从图1,我们可以看出,从UDP包中,我们可以获取的信息只有源端口和目的地端口.我们不能获取到源IP因为报文中没有源IP.真正包含IP地址的 ...

  4. vs2017常用快捷键

    项目相关的快捷键 Ctrl + Shift + B = 生成项目 Ctrl + Alt + L = 显示 Solution Explorer(解决方案资源管理器) Ctrl + Shift + A = ...

  5. node.js实现WebSocket

    最近在学习“HTML5游戏开发实战”,其中第8章内容是使用WebSocket来构建多人游戏---<你画我猜>.然而在实现过程中,却一直出错: 客户端请求时,服务器端会报错并终止: 而浏览器 ...

  6. 【BZOJ5306】 [Haoi2018]染色

    BZOJ5306 [Haoi2018]染色 Solution xzz的博客 代码实现 #include<stdio.h> #include<stdlib.h> #include ...

  7. ROC,AUC,Precision,Recall,F1的介绍与计算

    1. 基本概念 1.1 ROC与AUC ROC曲线和AUC常被用来评价一个二值分类器(binary classifier)的优劣,ROC曲线称为受试者工作特征曲线 (receiver operatin ...

  8. 移动端font-size适配方案

    概述 这是我研究移动端页面时的思考,记录下来供以后开发时参考,相信对其他人也有用.由于我写移动端页面写的还比较少,一些问题都还没遇到,所以我的这篇博文不免有些错误的地方,还请大佬多多指正. 这篇文章是 ...

  9. WebSocket集成XMPP网页即时通讯3:二进制文件收发

    WebSocket支持二进制的发送,见jetty官网: http://www.eclipse.org/jetty/documentation/current/jetty-websocket-api-s ...

  10. 05-创建kubectl-kubeconfig文件

    本文档介绍创建 kubeconfig 文件 下载 kubectl $ wget https://dl.k8s.io/v1.6.0/kubernetes-client-linux-amd64.tar.g ...