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 frame
void 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;
#endregion
public 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控件的信息进行更新,不需要实现按钮的注册事件逻辑
*/
#endregion
public 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 update
void Start()
{
//PlayerPrefs.DeleteAll();
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.M))
{
MainController.ShowMe();
}
else if(Input.GetKeyDown(KeyCode.N))
{
MainController.Hide();
}
}
}
脚本控件物体的连接
主界面的脚本
角色的脚本
相机添加脚本控制界面的显隐
总结
通过上面的两者编程方法,不知大家收获多少。
在普通的编程逻辑下。我们把控制该物体的行为都是写在一个脚本里面。控制UI的,按钮的注册,数据的显示更新保存等都是聚集在一个脚本内。
用了MVC框架,各各行为分工严明,具体是干甚的只需要把自己的内用写好就行。在控制器里来进行调用用于反馈通知。
同时MVC框架不是所有的游戏就可以使用,而是那种UI的游戏什么的可以运用,这种编程思想还需要我们用一些实际的项目来操作来去学习。