UMVCL3——使用MVC思想制作UI逻辑
使用MVC的UI逻辑制作实例
还是和上一章相同的UI需求
假设我们有一个主面板,它的各个UI控件需要的效果如下
有一个选角面板,它的各个UI控件需要的效果如下
该UI的MVC的代码逻辑如下:
Model层
Model层主要负责存储管理数据,及数据相关的操作,同时,对Controller层开放更新数据方法,更新数据时,执行Controller层的监听数据更新的函数
具体实现:
初始化,读取数据
更新数据(同时让Controller层脚本监听数据的更新)
保存数据
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 using UnityEngine;using UnityEngine.Events;public class PlayerModel { 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 private event UnityAction<PlayerModel> updateEvent; private void Init () { name = PlayerPrefs.GetString("PlayerName" , "SevenL" ); 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 ); } }
View层
View层主要负责管理UI控件,将用户行为传入Control层,对Control层开放更新控件显示方法
具体实现:
管理控件
更新控件显示
MainView.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 using UnityEngine;using UnityEngine.UI;public class MainView : MonoBehaviour { public Text txtName; public Text txtLev; public Text txtMoney; public Text txtGem; public Text txtPower; public Button btnRole; public void UpdateInfo (PlayerModel data ) { txtName.text = data.Name; txtLev.text = "LV." + data.Level.ToString(); txtMoney.text = data.Money.ToString(); txtGem.text = data.Gem.ToString(); txtPower.text = data.Power.ToString(); } }
RoleView.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 using UnityEngine;using UnityEngine.UI;public class RoleView : 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; public void UpdateInfo (PlayerModel data ) { txtLev.text = "LV." + data.Level.ToString(); txtHp.text = data.Hp.ToString(); txtAtk.text = data.Atk.ToString(); txtDef.text = data.Def.ToString(); txtCrit.text = data.Crit.ToString(); txtMiss.text = data.Miss.ToString(); txtLuck.text = data.Luck.ToString(); } }
Controller层
Control层主要负责控制面板的显隐,监听View层传入的用户行为,执行View层的更新方法,执行Model的操作数据方法,监听Model层的数据更新
具体实现:
界面的显隐
界面事件的监听 来处理对应的业务逻辑(触发Model层提供的操作数据方法)
监听Model层的数据更新
执行View层的控件更新方法
MainController.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 49 50 51 52 53 54 55 56 57 58 59 60 61 62 using System.Collections;using System.Collections.Generic;using UnityEngine;public class MainController : MonoBehaviour { private static MainController controller = null ; public static MainController Instance => controller; private MainView mainView; private void Start () { mainView = GetComponent<MainView>(); mainView.UpdateInfo(PlayerModel.Instance); PlayerModel.Instance.AddEventListener(UpdateInfo); mainView.btnRole.onClick.AddListener(() => { RoleController.ShowMe(); }); } private void OnDestroy () { PlayerModel.Instance.RemoveEventListener(UpdateInfo); } private void UpdateInfo (PlayerModel player ) { if (mainView != null ) mainView.UpdateInfo(player); } public static void ShowMe () { if (controller == null ) { GameObject res = Resources.Load<GameObject>("UI/MainPanel" ); GameObject obj = Instantiate(res); obj.transform.SetParent(GameObject.Find("Canvas" ).transform, false ); controller = obj.GetComponent<MainController>(); } controller.gameObject.SetActive(true ); } public static void HideMe () { if (controller != null ) { controller.gameObject.SetActive(false ); } } }
RoleController.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 49 50 51 52 53 54 55 56 57 58 59 using System.Collections;using System.Collections.Generic;using UnityEngine;public class RoleController : MonoBehaviour { private RoleView roleView; private static RoleController controller = null ; public static RoleController Controller => controller; void Start () { roleView = GetComponent<RoleView>(); roleView.UpdateInfo(PlayerModel.Instance); PlayerModel.Instance.AddEventListener(UpdateInfo); roleView.btnClose.onClick.AddListener(() => { HideMe(); }); roleView.btnLevUp.onClick.AddListener(() => { PlayerModel.Instance.LevelUp(); }); } private void OnDestroy () { PlayerModel.Instance.RemoveEventListener(UpdateInfo); } private void UpdateInfo (PlayerModel player ) { if (roleView != null ) roleView.UpdateInfo(player); } public static void ShowMe () { if (controller == null ) { GameObject res = Resources.Load<GameObject>("UI/RolePanel" ); GameObject obj = Instantiate(res); obj.transform.SetParent(GameObject.Find("Canvas" ).transform, false ); controller = obj.GetComponent<RoleController>(); } controller.gameObject.SetActive(true ); } public static void HideMe () { if (controller != null ) { controller.gameObject.SetActive(false ); } } }
使用MVC带来的改变
很显然,使用MVC的思路来编写UI脚本,数据管理,业务逻辑,用户界面这三块逻辑得到了分离
虽然脚本因此变的更多,但是面板交互的逻辑更加清晰了,各个类的职责也更加的清晰
MVC具体带来的改变在下一章具体讲解