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
| 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; }
}
|