
我们在上一篇文章中提到了 MVC(Model-View-Controller)设计模式。在 Unity 中,MVC 模式通常体现在将游戏数据(M)和表现(V)分开,而 C 则负责管理输入和调度更新,在代码中更新 UI 的状态。
在这篇文章中,我将介绍另一种设计模式 MVVM(Model - View - ViewModel)。MVVM 是一种将用户界面与业务逻辑分离的设计模式,与 MVC 模式相比,MVVM 模式在 MVC 的基础上进一步解耦了 View 和 Model,取代 Controller 的 ViewModel 层(VM 层)作为中介层提供了数据绑定的能力,使 View 层可以自动同步 ViewModel 中的数据。
维度 | MVC | MVVM |
---|---|---|
核心思想 | 关注点分离 | 数据驱动视图 |
数据流向 | 单向(View → Controller → Model) | 双向(View ↔ ViewModel ↔ Model) |
耦合度 | 中(V 层与 C 层直接交互) | 低(通过数据绑定解耦) |
适用场景 | 简单UI交互 | 复杂数据驱动型UI |
Unity实现 | 需要手动更新视图 | 自动响应数据变化 |
在 Unity 中,采用 MVVM 架构可以让 UI 开发更加响应式,当 Model 发生变化时,通过 ViewModel 自动更新 UI。我们还是以上篇文章中的金币案例为例,分析一下 MVVM 框架的代码结构。
pie
classDiagram class UIManager{ +CoinView _view +CoinModel _model +CoinViewModel _viewModel +Start() } class CoinModel{ -int _coins +event OnCoinsChanged +AddCoins(int) +ResetCoins() } class CoinViewModel{ -CoinModel _model +BindablePropertyCoins +ICommand AddCoinCommand +ICommand ResetCommand +CoinViewModel(CoinModel) } class CoinView{ +TMP_Text _coinText +Button _addButton +Initialize(CoinViewModel) } UIManager --> CoinViewModel UIManager --> CoinView UIManager --> CoinModel CoinViewModel --> CoinModel CoinView --> CoinViewModel
Model(M)
MVVM 中的 M 层与 MVC 中的 M 层相同,都负责了数据存储和相关业务逻辑:
1 | [ ] |
View(V)
V 层负责了用户图像界面的展示,通过绑定器与 ViewModel 层连接:
1 | public class CoinView : MonoBehaviour |
在 MVC 中,我们是通过 Initialize
方法直接实现 UI 对象和事件的绑定的,而在 MVVM 中则是使用了绑定器的思想,在 Initialize
中绑定数据和命令。
ViewModel(VM)
VM 层是联系 M 层和 V 层的核心桥梁,实现了数据转换与命令处理:
1 | public class CoinViewModel |
在 VM 的示例代码中,我们看到了 ICommand
和 BindableProperty<T>
,分别实现了命令和数据的绑定。
数据绑定器 BindableProperty<T>
数据绑定器 BindableProperty<T> 实现了在所绑定的属性变更时发出通知。
1 | public class BindableProperty<T> |
命令绑定器 ICommand
熟悉命令模式的同学看到 ICommand 这个名字的时候,大概就能想到这是一系列命令的接口,包含了命令的执行逻辑 Execute
(如果需要,也可以为命令模式加上重做逻辑 Redo
)。
RelayCommand封装了操作请求的独立对象,是一个具体命令的包装器,可以将任意方法包装成符合 ICommand 接口的对象。
1 | // 命令接口 |
实际应用
由于同一个 ViewModel 可以绑定不同 View,因此我们可以建立一个管理器来管理 MVVM:
1 | // 使用示例 |
MVVM 的交互流程如下所示:
pie
sequenceDiagram participant View as 视图层 participant ViewModel as 视图模型 participant Model as 数据层 View->>ViewModel: 绑定命令和数据 View->>ViewModel: 用户点击按钮触发命令 ViewModel->>Model: 执行 AddCoin() Model->>ViewModel: 触发 OnCoinsChanged ViewModel->>View: 通过 BindableProperty 更新数值
在 Unity 中,MVVM 的优势体现在以下三个方面:
- 自动同步:当 Model 数据变化时,View 自动更新。
- 解耦视图逻辑:ViewModel 不直接操作UI组件。
- 复用性:同一 ViewModel 可绑定不同 View。
参考资料
https://docs.unity3d.com/Packages/com.unity.dt.app-ui@0.3/manual/mvvm-intro.html
https://medium.com/etermax-technology/embracing-changes-with-mvvm-14fcf6d35468