Unity MVC框架之见解
- MVC框架认识
- 构架图
- 案例
- 无框架,普通逻辑代码脚本
- 主UI脚本
- 角色UI脚本
- 摄像机显示脚本
- 脚本的放置
- MVC框架的运用
- Model脚本
- View脚本
- 主界面的View脚本
- 角色View脚本
- Controller脚本
- 主界面的Controller脚本
- 角色Controller脚本
- 控制主界面的显示脚本
- 脚本控件物体的连接
- 总结
MVC框架认识
MVC框架本不是用于在游戏行业产生的框架,但是其编程思想对游戏开发的影响也很大。
M: model,是模型的意思,可是模型是为何物?是我们游戏中所要操作的人物模型等等。其主要就是存储数据的一个物体。我们所见到的的软件等等,都是本身去操作一条条的数据去运行。所以该M脚本的主要内容就是操作数据。数据有什么操作呢???数据无外乎有两个作用,更新和保存。
V: View,是视图的的意思。该部分应该很好理解,那就是控制UI的,控制一些什么按钮什么的。用该部分的脚本去实现和M数据的显示。
C: control,管理器的意思。该部分的脚本主要是控制模型和视图的交互作用。给视图中的UI注册事件,模型的实时更新保存。(也就是调用M和V中的方法)
构架图
人们通过点击View的ui按钮进行给控制器通知,通过控制器给ui注册是事件运行来操作model的数据。然后数据开始响应控制器的信息来进行数据的更新和保存,并反馈给控制器,控制器再进行响应通知view面板开始对数据的变化显示等等。
案例
我们分为两个模块来进行展示。一种是使用了框架,一种是没有使用框架。我们来进行对比试验,来发现实现该框架框架的好处和不足。
我们在做一个展示UI的例子,该例子当运行时,点击M键可以显示UI,点击N键可以关闭UI。再点击UI中的角色按钮可以再打开一个角色面板。点击角色面板的升级按钮,可以改变人物的属性数值,并且可以实时的进行面板的更新相应。
效果演示:
我的项目资源可供大家下载:项目资源包免费下载
无框架,普通逻辑代码脚本
主UI脚本
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class Main : MonoBehaviour
{public Text PlayerText;public Text LevelText;public Text CoinText;public Text JewelText;public Text PowerText;public Button RoleButton;private static Main intestMain;public static Main IntestMinMain//单例模式{get{return intestMain;}}private GameObject Role;private GameObject resGameObject;void Start(){SetDate();resGameObject = Resources.Load<GameObject>("RoleUI");RoleButton.onClick.AddListener(ButtonRole);}public void SetDate(){PlayerText.text = PlayerPrefs.GetString("Name", "玩家名字");LevelText.text ="LV. "+ PlayerPrefs.GetInt("Level", 1).ToString();CoinText.text = PlayerPrefs.GetInt("Coin", 0).ToString();JewelText.text = PlayerPrefs.GetInt("Jewel", 0).ToString();PowerText.text=PlayerPrefs.GetInt("Power",10).ToString();}public static void Showme()//控制自身的显示{if (intestMain == null){GameObject res = Resources.Load<GameObject>("UI");GameObject obj = Instantiate(res);obj.transform.SetParent(GameObject.Find("Canvas").transform, false);intestMain = obj.GetComponent<Main>();}intestMain.gameObject.SetActive(true);intestMain.SetDate();}public static void Hideme(){intestMain.gameObject.SetActive(false);}void ButtonRole(){if (Role == null){Role = Instantiate(resGameObject);Role.transform.SetParent(GameObject.Find("Canvas").transform,false);}Role.SetActive(true);}
}
角色UI脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;
using Random = System.Random;public class CloseRole : MonoBehaviour
{public Button ColoseButton;public Button UpgradeButton;public Text LevelText;public Text CoinText;public Text JewelText;public Text PowerText;private int Level=1;private int Coin=0;private int Jewel=0;private int Power=0;void Start(){ColoseButton.onClick.AddListener(Close);SetDate();UpgradeButton.onClick.AddListener(UpNumber);}public void Close(){gameObject.SetActive(false);}public void UpNumber(){Level = PlayerPrefs.GetInt("Level",1) + 1;Random random = new Random();Coin += random.Next(50, 100);Jewel += random.Next(50, 100);Power += random.Next(20, 80);PlayerPrefs.SetInt("Level",Level);PlayerPrefs.SetInt("Coin", Coin);PlayerPrefs.SetInt("Jewel", Jewel);PlayerPrefs.SetInt("Power", Power);SetDate();Main.IntestMinMain.SetDate();}public void SetDate(){LevelText.text = "LV. " + PlayerPrefs.GetInt("Level",1).ToString();CoinText.text = PlayerPrefs.GetInt("Coin", 0).ToString();JewelText.text = PlayerPrefs.GetInt("Jewel", 0).ToString();PowerText.text = PlayerPrefs.GetInt("Power", 10).ToString();}}
摄像机显示脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Show : MonoBehaviour
{void Start(){//PlayerPrefs.DeleteAll();}// Update is called once per framevoid Update(){if (Input.GetKeyDown(KeyCode.M)){Main.Showme();}if (Input.GetKeyDown(KeyCode.N)){Main.Hideme();}}
}
脚本的放置
摄像机及脚本
主界面及脚本
角色脚本
MVC框架的运用
Model脚本
把模型的数据都集中起来进行管理操作。并实现更新和保存的方法。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UnityEditor;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using Random = System.Random;public class ModelUI
{//Model只要就是存放数据,存放数据和更新数据,是MVC框架的核心//MVC只适用于UI游戏场景的游戏,并不是适合于所有的项目游戏private static ModelUI Intenst;#region 数据集合private string playerName;public string PlayerName => playerName;private int level;public int Level => level;private int coin;public int Coin => coin;private int jewel;public int Jewel => jewel;private int power;public int Power => power;#endregionpublic event UnityAction<ModelUI> ModelAction;//这个是unity的委托类型。我们要对其进行通知和反馈的操作注册。public static ModelUI Getit()//这里是单例模式,只有一个Model。{if (Intenst==null){Intenst=new ModelUI();Intenst.SetDate();}return Intenst;}//更新数据public void SetDate(){playerName = PlayerPrefs.GetString("Name", "皮学渣");level = PlayerPrefs.GetInt("Level", 1);coin = PlayerPrefs.GetInt("Coin", 0);jewel = PlayerPrefs.GetInt("Jewel", 0);power = PlayerPrefs.GetInt("Power", 10);}//点击升级按钮后修改数据public void LevelUp(){level += 1;Random random=new Random();coin += random.Next(10, 30);jewel += random.Next(10, 30);power += random.Next(10, 30);SaveDate();}//保存数据public void SaveDate(){PlayerPrefs.SetInt("Level",level);PlayerPrefs.SetInt("Coin",coin);PlayerPrefs.SetInt("Jewel",jewel);PlayerPrefs.SetInt("Power",power);//档保存后就自动更新数据UpdateInfo();}public void AddFuction(UnityAction<ModelUI> fun){ModelAction += fun;}public void SubtrctFuction(UnityAction<ModelUI> fun){ModelAction -= fun;}//通知外部更新数据public void UpdateInfo(){if (ModelAction != null){ModelAction(this);}}
}
View脚本
View的主要作用是对于数据的显示处理,并将该脚本放在特定的UI上面。不需要实现按钮的注册事件逻辑
主界面的View脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class MainUI:MonoBehaviour
{#region View作用/*view主要就是找UI的控件,对UI控件的信息进行更新,不需要实现按钮的注册事件逻辑*/#endregionpublic Text NameText;public Text LevelText;public Text CoinText;public Text JewelText;public Text PowerText;public Button Role;public void InfoDate(ModelUI model){NameText.text = model.PlayerName;LevelText.text = model.Level.ToString();CoinText.text = model.Coin.ToString();JewelText.text = model.Jewel.ToString();PowerText.text = model.Power.ToString();}
}
角色View脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class RoleUI :MonoBehaviour
{public Text LevelText;public Text CoinText;public Text JewelText;public Text PowerText;public Button UpClick;public Button Colose;public void InfoDate(ModelUI model){LevelText.text = model.Level.ToString();CoinText.text = model.Coin.ToString();JewelText.text = model.Jewel.ToString();PowerText.text = model.Power.ToString();}
}
Controller脚本
主界面的Controller脚本
控制器的作用是对UI的事件继续注册,完成代码逻辑的地方。用控制器来进行响应和反馈
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class MainController : MonoBehaviour
{// Controle主要用来控制UI的显隐,还有逻辑的处理,数据的更新,ui按钮事件的注册private MainUI _mainUi;//1.控制显隐private static MainController controller=null;public static MainController Controller(){if (controller == null){controller=new MainController();}return controller;}public static void ShowMe(){if (controller == null){GameObject res = Resources.Load<GameObject>("UI");GameObject obj = Instantiate(res);obj.transform.SetParent(GameObject.Find("Canvas").transform,false);controller = obj.GetComponent<MainController>();}controller.gameObject.SetActive(true);}public static void Hide(){if (controller != null){controller.gameObject.SetActive(false);}}//2.注册事件,给UI注册事件,当我们显示UI的时候,就可以和MainUI关联,将MainUI赋值,并给他的按钮注册事件//当显示UI的时候,就给他赋值,所以就在start函数进行初始化private void Start(){_mainUi = this.gameObject.GetComponent<MainUI>();_mainUi.InfoDate(ModelUI.Getit());_mainUi.Role.onClick.AddListener(RoleButton);ModelUI.Getit().AddFuction(Info);}public void RoleButton(){RpleController.ShowMe();}public void Info(ModelUI date){if (_mainUi != null){_mainUi.InfoDate(date);}}private void OnDestroy(){ModelUI.Getit().SubtrctFuction(_mainUi.InfoDate);}
}
角色Controller脚本
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class RpleController : MonoBehaviour
{private RoleUI _roleUi;//1.控制显隐private static RpleController controller=null;public static RpleController Controller(){if (controller == null){controller=new RpleController();}return controller;}public static void ShowMe(){if (controller == null){GameObject res = Resources.Load<GameObject>("RoleUI");GameObject obj = Instantiate(res);obj.transform.SetParent(GameObject.Find("Canvas").transform,false);controller = obj.GetComponent<RpleController>();}controller.gameObject.SetActive(true);}public static void Hide(){if (controller != null){controller.gameObject.SetActive(false);}}//2.注册事件,给UI注册事件,当我们显示UI的时候,就可以和MainUI关联,将MainUI赋值,并给他的按钮注册事件//当显示UI的时候,就给他赋值,所以就在start函数进行初始化private void Start(){_roleUi = this.gameObject.GetComponent<RoleUI>();_roleUi.InfoDate(ModelUI.Getit());_roleUi.Colose.onClick.AddListener(Hide);_roleUi.UpClick.onClick.AddListener(LevelUpClick);//这里对Model委托进行添加方法ModelUI.Getit().AddFuction(Info);}//3.更新数据public void LevelUpClick(){ModelUI.Getit().LevelUp();}public void Info(ModelUI date){if (_roleUi != null){_roleUi.InfoDate(date);}}private void OnDestroy(){ModelUI.Getit().SubtrctFuction(_roleUi.InfoDate);}
}
控制主界面的显示脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class InputMN : MonoBehaviour
{// Start is called before the first frame updatevoid Start(){//PlayerPrefs.DeleteAll();}// Update is called once per framevoid Update(){if (Input.GetKeyDown(KeyCode.M)){MainController.ShowMe();}else if(Input.GetKeyDown(KeyCode.N)){MainController.Hide();}}
}
脚本控件物体的连接
主界面的脚本
角色的脚本
相机添加脚本控制界面的显隐
总结
通过上面的两者编程方法,不知大家收获多少。
在普通的编程逻辑下。我们把控制该物体的行为都是写在一个脚本里面。控制UI的,按钮的注册,数据的显示更新保存等都是聚集在一个脚本内。
用了MVC框架,各各行为分工严明,具体是干甚的只需要把自己的内用写好就行。在控制器里来进行调用用于反馈通知。
同时MVC框架不是所有的游戏就可以使用,而是那种UI的游戏什么的可以运用,这种编程思想还需要我们用一些实际的项目来操作来去学习。