UMVCL11——MVE基本实例

MVE基本实例

还是和上一章相同的UI需求

假设我们有一个主面板,它的各个UI控件需要的效果如下

image

有一个选角面板,它的各个UI控件需要的效果如下

image

前置知识

本章的代码编写使用了Unity小框架的UI管理器和UI基类以及事件中心,需要先学习这方面内容才能理解下列代码
并基于MP的代码进行修改

Model

相比之前的MVC的Model,这里不再需要向自己去触发数据更新的事件,而是直接向事件中心去触发事件

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
122
123
124
125
126
127
128
129
using UnityEngine;
using UnityEngine.Events;

public class PlayerModel
{
//Model层主要负责存储管理数据,及数据相关的操作
// 初始化,读取数据
// 更新数据
// 保存数据

private static PlayerModel instance = null;
public static PlayerModel Instance
{
get
{
if (instance == null)
{
instance = new PlayerModel();
instance.Init();
}
return instance;
}
}
private PlayerModel() { }

//数据内容
private string name;
private int level;
private int money;
private int gem;
private int power;

private int hp;
private int atk;
private int def;
private int crit;
private int miss;
private int luck;

#region 对外开放的属性
public string Name => name;
public int Level => level;
public int Money => money;
public int Gem => gem;
public int Power => power;

public int Hp => hp;
public int Atk => atk;
public int Def => def;
public int Crit => crit;
public int Miss => miss;
public int Luck => luck;

#endregion

//通知外部更新的事件(不再需要Model层触发事件,一切交给PlayerModel层)
//private event UnityAction<PlayerModel> updateEvent;

//数据相关的操作
//初始化
private void Init()
{
name = PlayerPrefs.GetString("PlayerName", "MrTang");
level = PlayerPrefs.GetInt("PlayerLev", 1);
money = PlayerPrefs.GetInt("PlayerMoney", 9999);
gem = PlayerPrefs.GetInt("PlayerGem", 8888);
power = PlayerPrefs.GetInt("PlayerPower", 99);

hp = PlayerPrefs.GetInt("PlayerHp", 100);
atk = PlayerPrefs.GetInt("PlayerAtk", 20);
def = PlayerPrefs.GetInt("PlayerDef", 10);
crit = PlayerPrefs.GetInt("PlayerCrit", 20);
miss = PlayerPrefs.GetInt("PlayerMiss", 10);
luck = PlayerPrefs.GetInt("PlayerLuck", 40);
}

//更新
public void LevelUp()
{
//升级 改变内容
level += 1;
hp += level;
atk += level;
def += level;
crit += level;
miss += level;
luck += level;

SaveData();
}

//保存
private void SaveData()
{
PlayerPrefs.SetString("PlayerName", name);
PlayerPrefs.SetInt("PlayerLev", level);
PlayerPrefs.SetInt("PlayerMoney", money);
PlayerPrefs.SetInt("PlayerGem", gem);
PlayerPrefs.SetInt("PlayerPower", power);

PlayerPrefs.SetInt("PlayerHp", hp);
PlayerPrefs.SetInt("PlayerAtk", atk);
PlayerPrefs.SetInt("PlayerDef", def);
PlayerPrefs.SetInt("PlayerCrit", crit);
PlayerPrefs.SetInt("PlayerMiss", miss);
PlayerPrefs.SetInt("PlayerLuck", luck);

UpdateInfo();
}

public void AddEventListener(UnityAction<PlayerModel> function)
{
//updateEvent += function;
}

public void RemoveEventListener(UnityAction<PlayerModel> function)
{
//updateEvent -= function;
}

//通知外部事件更新的方法
private void UpdateInfo()
{
//updateEvent(this);
//向事件中心触发"玩家数据"这个事件
EventCenter.Instance.EventTrigger<PlayerModel>("玩家数据", this);
}
}

View(Panel)

笔者注:实际学习时使用的对老师课上小框架的改编,实际代码可能与课上不符,你可以忽略掉那些意义不明的参数

相比MP的Panel,现在的Panel脚本不再需要向Model层监听数据,而是直接向事件中心去监听Model层触发的事件

MP_MainPanel.cs

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
using UnityEngine.UI;

public class MP_MainPanel : BasePanel
{
//1.找控件 通过集成小框架中的UI基类实现了
//2.逻辑处理
//3.数据更新

// Start is called before the first frame update
void Start()
{
UpdateInfo(PlayerModel.Instance);
//直接向事件中心去监听"玩家数据"的事件
//PlayerModel.Instance.AddEventListener(UpdateInfo);
EventCenter.Instance.AddEventListener<PlayerModel>("玩家数据", UpdateInfo);
}

private void OnDestroy()
{
//PlayerModel.Instance.RemoveEventListener(UpdateInfo);
EventCenter.Instance.RemoveEventListener<PlayerModel>("玩家数据", UpdateInfo);
}

protected override void BtnOnClick(string btnName)
{
base.BtnOnClick(btnName);
switch (btnName)
{
case "btnRole":
UIManager.Instance.ShowPanel<MP_RolePanel>(false);
break;
}
}

public void UpdateInfo(PlayerModel data)
{
//直接在这里获取控件 进行更新
GetControl<Text>("txtName").text = data.Name;
GetControl<Text>("txtLev").text = "LV." + data.Level;

GetControl<Text>("txtMoney").text = data.Money.ToString();
GetControl<Text>("txtGem").text = data.Gem.ToString();
GetControl<Text>("txtPower").text = data.Power.ToString();
}
}

MP_RolePanel.cs

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
using UnityEngine.UI;

public class MP_RolePanel : BasePanel
{
//1.找控件 通过集成小框架中的UI基类实现了
//2.逻辑处理
//3.数据更新

// Start is called before the first frame update
void Start()
{
UpdateInfo(PlayerModel.Instance);
//直接向事件中心去监听"玩家数据"的事件
//PlayerModel.Instance.AddEventListener(UpdateInfo);
EventCenter.Instance.AddEventListener<PlayerModel>("玩家数据", UpdateInfo);
}

private void OnDestroy()
{
//PlayerModel.Instance.RemoveEventListener(UpdateInfo);
EventCenter.Instance.RemoveEventListener<PlayerModel>("玩家数据", UpdateInfo);
}

protected override void BtnOnClick(string btnName)
{
base.BtnOnClick(btnName);
switch (btnName)
{
case "btnClose":
UIManager.Instance.HidePanel<MP_RolePanel>(false);
break;
case "btnLevUp":
PlayerModel.Instance.LevelUp();
break;
}
}

public void UpdateInfo(PlayerModel data)
{
GetControl<Text>("txtLev").text = "LV." + data.Level;
GetControl<Text>("txtHp").text = data.Hp.ToString();
GetControl<Text>("txtAtk").text = data.Atk.ToString();
GetControl<Text>("txtDef").text = data.Def.ToString();
GetControl<Text>("txtCrit").text = data.Crit.ToString();
GetControl<Text>("txtMiss").text = data.Miss.ToString();
GetControl<Text>("txtLuck").text = data.Luck.ToString();
}
}