Unity中的MVC框架

Posted by 钟睿如 on 2020-11-28

Unity中的MVC框架

1.MVC的概念

MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中,数据-控制-显示分离的工作方式会使游戏(软件)的结构清晰化,逻辑更明了。

Model

负责数据的处理、能被Controller更新。

(1) 不保存任何View的数据或者View的状态

(2) 只能被Controller或者其他Model访问

(3) 会触发事件来通知外部系统进行处理和变更

View

在屏幕上渲染的视图,和用户交互的界面。

(1) 处理用户绘制元素的reference,包括纹理,特效等

(2) 播放动画

(3) 布局

(4) 接受用户输入

Controller

Controller是连接Model和View的桥梁。它会保存View的状态,并且根据外部事件来更新View的状态。

(1) 持有View所需要的应用状态

(2) 控制View的流程

(3) 根据状态show/hides/activates/deactivates/updates View或者View的某些部分。如controller可临时将攻击按钮Distable掉,因为此时攻击处于冷却状态,冷却状态一过,controller会re-enable这个按钮

(4) load/Instantiate需要的assets,比如显示particles, 动态改变sprites等

(5) 处理用户在View中触发的事件,比如用户按下了一个按钮;处理Model触发的事件,比如player获得了 XP并触发了升级,所以controller就更新了View中的Level Number

2.MVC的优势

多个视图能共享一个模型。同一个模型可以被不同的视图重用,大大提高了代码的可重用性。

由于MVC的三个模块相互独立,改变其中一个不会影响其他两个,所以依据这种设计思想能构造良好的松耦合的构件。

控制器提高了应用程序的灵活性和可配置性。控制器可以用来联接不同的模型和视图去完成用户的需求,这样控制器可以为构造应用程序提供强有力的手段。

不过,由于实际游戏开发中不同游戏的核心逻辑可能差异较大,MVC框架并不适合游戏开发的每个过程,而多用于UI的开发。

3.MVC框架实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
//实现通过MVC框架随机产生一名幸运儿并显示至面板上的功能
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;


public struct PlayerModel {
public string name;

public int age;

public int id;

}


public class GameModel : MonoBehaviour
{
public delegate void IUpdateView(PlayerModel playerModel);

public event IUpdateView OnUpdateView;

private PlayerModel _playerModel;


public PlayerModel playerModel {
get { return _playerModel; }
set {
_playerModel = value;
OnUpdateView?.Invoke(_playerModel);
}
}


}

public class GameController : MonoBehaviour
{
public static GameController instance;

public GameModel gameModel;
public GameView gameView;

private PlayerModel[] players = new PlayerModel[3];

private void Awake()
{
instance = this;
}
void Start()
{
SetPlayers();
gameModel.OnUpdateView += gameView.UpdateView;
gameModel.playerModel = GetPlayer();
}

PlayerModel GetPlayer() {
int id = Random.Range(0,players.Length);
return players[id];
}

void SetPlayers() {
PlayerModel playerModel = new PlayerModel();
PlayerModel playerModel2 = new PlayerModel();
PlayerModel playerModel3 = new PlayerModel();

playerModel.name = "小蓝";
playerModel.age = 18;
playerModel.id = 1;

playerModel2.name = "小绿";
playerModel2.age = 19;
playerModel2.id = 2;

playerModel3.name = "小黄";
playerModel3.age = 24;
playerModel3.id = 3;

players[0] = playerModel;
players[1] = playerModel2;
players[2] = playerModel3;
}


public void OnClickChangeBtn() {
PlayerModel playerModel = GetPlayer();
if (playerModel.Equals(gameModel.playerModel))
{

OnClickChangeBtn();
}
else {

gameModel.playerModel = playerModel;
}

}

}
public class GameView : MonoBehaviour
{

public Text showText;
public Button changeBtn;

private void Start()
{
changeBtn.onClick.AddListener(GameController.instance.OnClickChangeBtn);
}


public void UpdateView(PlayerModel playerModel)
{
showText.text = "姓名:"+playerModel.name+"年龄:"+playerModel.age+"ID: "+playerModel.id;

}

}