UMVCL2——不使用MVC思想制作UI逻辑

不使用MVC的UI逻辑制作实例

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

image

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

image

两面板的代码逻辑如下:

MainPanel

这个脚本实现的功能如下:

  1. 面板的显隐(加载并装载自己)
  2. 控件监听
  3. 角色按钮显示RolePanel
  4. 读取并更新数据
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
using UnityEngine;
using UnityEngine.UI;

public class MainPanel : MonoBehaviour
{
public Text txtName;
public Text txtLev;
public Text txtMoney;
public Text txtGem;
public Text txtPower;

public Button btnRole;

private static MainPanel panel;

public static MainPanel Panel => panel;

public static void ShowMe()
{
if (panel == null)
{
//实例化面板对象
GameObject res = Resources.Load<GameObject>("UI/MainPanel");
GameObject obj = Instantiate(res);
obj.transform.SetParent(GameObject.Find("Canvas").transform, false);
panel = obj.GetComponent<MainPanel>();
}
panel.gameObject.SetActive(true);
panel.UpdateInfo();
}

public static void HideMe()
{
if (panel != null)
{
//隐藏方式一:直接删
//Destroy(panel.gameObject);
//panel = null;
//隐藏方式二:设置可见为隐藏
panel.gameObject.SetActive(false);
}
}

// Start is called before the first frame update
void Start()
{
btnRole.onClick.AddListener(() =>
{
Debug.Log("按钮点击");
RolePanel.ShowMe();
});
UpdateInfo();
}

public void UpdateInfo()
{
//获取玩家数据 更新玩家信息
//获取玩家数据的方式,1.网络请求 2.json 3.xml 4.二进制 5.PlayerPrefs
//通过PlayerPrefs来获取本地存储的玩家信息,更新到界面上
txtName.text = PlayerPrefs.GetString("PlayerName", "SevenL");
txtLev.text = "LV." + PlayerPrefs.GetInt("PlayerLev", 1).ToString();
txtMoney.text = PlayerPrefs.GetInt("PlayerMoney", 999).ToString();
txtGem.text = PlayerPrefs.GetInt("PlayerGem", 888).ToString();
txtPower.text = PlayerPrefs.GetInt("PlayerPower", 20).ToString();
}
}

RolePanel

这个脚本实现的功能如下:

  1. 面板显隐
  2. 控件监听
  3. 加载并更新数据
  4. 升级,改变并记录数据
  5. 关闭按钮隐藏RolePanel
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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class RolePanel : MonoBehaviour
{
public Text txtLev;
public Text txtHp;
public Text txtAtk;
public Text txtDef;
public Text txtCrit;
public Text txtMiss;
public Text txtLuck;

public Button btnClose;
public Button btnLevUp;

private static RolePanel panel;

public static void ShowMe()
{
if (panel == null)
{
//实例化面板对象
GameObject res = Resources.Load<GameObject>("UI/RolePanel");
GameObject obj = Instantiate(res);
obj.transform.SetParent(GameObject.Find("Canvas").transform, false);
panel = obj.GetComponent<RolePanel>();
}
panel.gameObject.SetActive(true);
panel.UpdateInfo();
}

public static void HideMe()
{
if (panel != null)
{
//隐藏方式一:直接删
//Destroy(panel.gameObject);
//panel = null;
//隐藏方式二:设置可见为隐藏
panel.gameObject.SetActive(false);
}
}

void Start()
{
btnClose.onClick.AddListener(() =>
{
HideMe();
});
btnLevUp.onClick.AddListener(() =>
{
Debug.Log("升级!");
//升级其实就是数据的更新
int lev = PlayerPrefs.GetInt("PlayerLev", 1);
int hp = PlayerPrefs.GetInt("PlayerHp", 100);
int atk = PlayerPrefs.GetInt("PlayerAtk", 20);
int def = PlayerPrefs.GetInt("PlayerDef", 10);
int crit = PlayerPrefs.GetInt("PlayerCrit", 20);
int miss = PlayerPrefs.GetInt("PlayerMiss", 10);
int luck = PlayerPrefs.GetInt("PlayerLuck", 40);
//然后通过一定的升级规则去改变它
lev += 1;
hp += lev;
atk += lev;
def += lev;
crit += lev;
miss += lev;
luck += lev;
//存起来
PlayerPrefs.SetInt("PlayerLev", lev);
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();
MainPanel.Panel.UpdateInfo();
});

}

public void UpdateInfo()
{
txtLev.text = "LV." + PlayerPrefs.GetInt("PlayerLev", 1);
txtHp.text = PlayerPrefs.GetInt("PlayerHp", 100).ToString();
txtAtk.text = PlayerPrefs.GetInt("PlayerAtk", 20).ToString();
txtDef.text = PlayerPrefs.GetInt("PlayerDef", 10).ToString();
txtCrit.text = PlayerPrefs.GetInt("PlayerCrit", 20).ToString();
txtMiss.text = PlayerPrefs.GetInt("PlayerMiss", 10).ToString();
txtLuck.text = PlayerPrefs.GetInt("PlayerLuck", 40).ToString();
}
}

其中,更新UI显示数据的逻辑如下:

1
2
3
4
5
6
7
8
9
10
public void UpdateInfo()
{
txtLev.text = "LV." + PlayerPrefs.GetInt("PlayerLev", 1);
txtHp.text = PlayerPrefs.GetInt("PlayerHp", 100).ToString();
txtAtk.text = PlayerPrefs.GetInt("PlayerAtk", 20).ToString();
txtDef.text = PlayerPrefs.GetInt("PlayerDef", 10).ToString();
txtCrit.text = PlayerPrefs.GetInt("PlayerCrit", 20).ToString();
txtMiss.text = PlayerPrefs.GetInt("PlayerMiss", 10).ToString();
txtLuck.text = PlayerPrefs.GetInt("PlayerLuck", 40).ToString();
}

显示隐藏面板逻辑如下:

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
private static RolePanel panel;

public static void ShowMe()
{
if (panel == null)
{
//实例化面板对象
GameObject res = Resources.Load<GameObject>("UI/RolePanel");
GameObject obj = Instantiate(res);
obj.transform.SetParent(GameObject.Find("Canvas").transform, false);
panel = obj.GetComponent<RolePanel>();
}
panel.gameObject.SetActive(true);
panel.UpdateInfo();
}

public static void HideMe()
{
if (panel != null)
{
//隐藏方式一:直接删
//Destroy(panel.gameObject);
//panel = null;
//隐藏方式二:设置可见为隐藏
panel.gameObject.SetActive(false);
}
}

升级逻辑如下:

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
btnLevUp.onClick.AddListener(() =>
{
Debug.Log("升级!");
//升级其实就是数据的更新
int lev = PlayerPrefs.GetInt("PlayerLev", 1);
int hp = PlayerPrefs.GetInt("PlayerHp", 100);
int atk = PlayerPrefs.GetInt("PlayerAtk", 20);
int def = PlayerPrefs.GetInt("PlayerDef", 10);
int crit = PlayerPrefs.GetInt("PlayerCrit", 20);
int miss = PlayerPrefs.GetInt("PlayerMiss", 10);
int luck = PlayerPrefs.GetInt("PlayerLuck", 40);
//然后通过一定的升级规则去改变它
lev += 1;
hp += lev;
atk += lev;
def += lev;
crit += lev;
miss += lev;
luck += lev;
//存起来
PlayerPrefs.SetInt("PlayerLev", lev);
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();
MainPanel.Panel.UpdateInfo();
});

不使用MVC带来的问题

可以发现,不使用MVC思想时:
数据读取显示,数据保存,执行逻辑,控件监听,控件获取,面板显隐,
全部分别糅合在几个UI脚本里,它们都有各自的实现,
同时同一批数据控制分散在不同的UI脚本内。
显然随着项目的日益扩大,不加以改善关系会越来越混乱,
这不利于我们对代码的维护

image

接下来让我们试试用MVC再实现相同的功能