Unity框架——MVC框架
阿新 • • 發佈:2019-01-08
前言——什麼是MVC框架
MVC全名是Model View Controller,是模型(model)-檢視(view)-控制器(controller)的縮寫,一種軟體設計典範,用一種業務邏輯、資料、介面 顯示分離的方法組織程式碼,將業務邏輯聚集到一個部件裡面,在改進和個性化定製介面及使用者互動的同時,不需要重新編寫業務邏輯。MVC被獨特的發展起來用於 對映傳統的輸入、處理和輸出功能在一個邏輯的圖形化使用者介面的結構中。目的——Unity UI使用時的優勢
框架其實是一種思想,一種在製作遊戲時對程式碼的邏輯化整理,在Unity開發過程中,很多的公司在製作遊戲開發專案的時候都用到了MVC的邏輯模式,既資料模型—檢視—控制器。
作為碼農,我們在寫程式碼的時候,都在追求程式碼的高聚合、低耦合,高聚合通俗來講就是說將程式碼的模組區分開,每個模組的功能高度集中,低耦合是說盡量減少模組與模組之間的相互影響,這樣在後期維護程式碼的時候將會非常的輕鬆,但產品經理要求改需求的時候也不會“牽一髮而動全身”,將程式碼大改特改。當然也沒有完全的高聚合低耦合的模式,但我們要儘量以這個思想來設計程式碼。
舉一個簡單的例子:很多的遊戲開發專案釋出後,看上去各個功能實現的都很完善,但是如果在某個節日要釋出遊戲活動,要將遊戲UI變更相對應的節日時,有的專案各個UI下掛在了大量的指令碼,這樣很難進行UI的替換,當替換UI會導致其他的功能受到影響時,這將會嚴重影響遊戲的質量。所以我們在設計遊戲的時候,在UI方面可以考慮MVC的結構模式,將模組之間的功能區分開,達到低耦合的效果。
實現——簡單的UI專案
下面我們用MVC框架的思想來0簡單的實現一個製作的UI介面來了解一下如何寫MVC框架。
~第一個指令碼:Model
1,在這個腳本里面,只存放資料
2,指令碼是一個單例物件,不需要掛載在物體上
3,所有的資料通過外部賦值,不需要有初始值
~第二個指令碼:ViewPath(各個UI的路徑)using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerModel{ /// <summary> /// 單例模式 /// </summary> private static PlayerModel instance; public static PlayerModel GetMod() { if (instance == null) { instance = new PlayerModel(); } return instance; } /// <summary> /// 私有構造方法 /// </summary> private PlayerModel() { } //建立Action事件 public System.Action levelUpEvent; public System.Action takeDamageEvent; public System.Action makeMagicEvent; private int playerLevel; private int playerCoin; private int playerDiamond; private float playerHealth; private float playerMagic; private float maxPlayerHealth; private float maxplayerMagic; public float MaxPlayerHealth { get {return maxPlayerHealth; } set { maxPlayerHealth = value; } } public float MaxplayerMagic { get { return maxplayerMagic; } set { maxplayerMagic = value; } } public int PlayerLevel { get { return playerLevel; } set { playerLevel = value; if (levelUpEvent != null) { levelUpEvent(); } } } public int PlayerCoin { get { return playerCoin; } set { playerCoin = value; } } public int PlayerDiamond { get { return playerDiamond; } set { playerDiamond = value; } } public float PlayerHealth { get { return playerHealth; } set { playerHealth = value; if (takeDamageEvent != null) { takeDamageEvent(); } } } public float PlayerMagic { get { return playerMagic; } set { playerMagic = value; if (makeMagicEvent != null) { makeMagicEvent(); } } } }
儲存所有UI的path路徑
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ViewPath {
#region PlayerView
public const string PLAYLEVEL = "PlayerHead/PlayerLevelBG/PlayerLevel";
public const string PLAYERCOIN = "PlayerHead/PlayerCoin/CoinCount";
public const string PLAYERDIAMOND = "PlayerHead/PlayerDiamond/DiamondCount";
public const string PLAYERHEALTH = "PlayerHealth/PlayerHealthBg/PlayerHealthData";
public const string PLAYERMAGIC = "PlayeMagic/PlayerMagicBg/PlayerMagicData";
public const string HEALTH = "PlayerHealth/Health";
public const string MAGIC = "PlayeMagic/Magic";
public const string LEVELUP = "LevelUpButton";
public const string DAMAGE = "DemageButton";
public const string SKILL = "SkillButton";
#endregion
}
~第三個指令碼:PlayerViewusing System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PlayerView : MonoBehaviour {
private Text playerLevelText;
private Text playerCoinText;
private Text playerDiamondText;
private Text healthData;
private Text magicData;
private RectTransform playerHealth;
private RectTransform playerMagic;
private Button levelUpBtn;
private Button damageBtn;
private Button skillBtn;
public static PlayerView view;
// Use this for initialization
void Awake() {
//單例指令碼
view = this;
//找到需要用到的所有UI
playerLevelText = transform.Find(ViewPath.PLAYLEVEL).GetComponent<Text>();
playerCoinText = transform.Find(ViewPath.PLAYERCOIN).GetComponent<Text>();
playerDiamondText = transform.Find(ViewPath.PLAYERDIAMOND).GetComponent<Text>();
playerHealth = transform.Find(ViewPath.PLAYERHEALTH).GetComponent<RectTransform>();
playerMagic = transform.Find(ViewPath.PLAYERMAGIC).GetComponent<RectTransform>();
healthData = transform.Find(ViewPath.HEALTH).GetComponent<Text>();
magicData = transform.Find(ViewPath.MAGIC).GetComponent<Text>();
levelUpBtn = transform.Find(ViewPath.LEVELUP).GetComponent<Button>();
damageBtn = transform.Find(ViewPath.DAMAGE).GetComponent<Button>();
skillBtn = transform.Find(ViewPath.SKILL).GetComponent<Button>();
BindUIChangeEvent();
}
private void Start() {
levelUpBtn.onClick.AddListener(PlayerController.GetController().OnLevelUp);
damageBtn.onClick.AddListener(PlayerController.GetController().OnDamage);
skillBtn.onClick.AddListener(PlayerController.GetController().OnSkill);
}
/// <summary>
/// 繫結通知UI改變事件
/// </summary>
void BindUIChangeEvent() {
//升級按鈕點選事件委託
PlayerModel.GetMod().levelUpEvent = () => {
playerLevelText.text = PlayerModel.GetMod().PlayerLevel.ToString();
playerCoinText.text = PlayerModel.GetMod().PlayerCoin.ToString();
playerDiamondText.text = PlayerModel.GetMod().PlayerDiamond.ToString();
healthData.text = string.Format("{0} / {1}", PlayerModel.GetMod().PlayerHealth, PlayerModel.GetMod().MaxPlayerHealth);
magicData.text = string.Format("{0} / {1}", PlayerModel.GetMod().PlayerMagic, PlayerModel.GetMod().MaxplayerMagic);
};
//受傷按鈕點選事件委託
PlayerModel.GetMod().takeDamageEvent = () => {
//計算血量UI長度
float currentUIHealth = 400 *PlayerModel.GetMod().PlayerHealth/ PlayerModel.GetMod().MaxPlayerHealth;
//設定長度
playerHealth.sizeDelta = new Vector2(currentUIHealth, playerHealth.sizeDelta.y);
};
//使用技能按鈕點選事件委託
PlayerModel.GetMod().makeMagicEvent = () => {
//計算藍量UI長度
float currentUIMagic = 400 * PlayerModel.GetMod().PlayerMagic / PlayerModel.GetMod().MaxplayerMagic;
//設定長度
playerMagic.sizeDelta = new Vector2(currentUIMagic, playerMagic.sizeDelta.y);
};
}
}
~第四個指令碼:PlayerControllerusing System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController {
private static PlayerController instance;
public static PlayerController GetController() {
if(instance == null) {
instance = new PlayerController();
}
return instance;
}
private PlayerController() {
PlayerModel.GetMod().PlayerLevel = 1;
PlayerModel.GetMod().PlayerCoin = 100;
PlayerModel.GetMod().PlayerDiamond = 10;
PlayerModel.GetMod().MaxPlayerHealth = 400;
PlayerModel.GetMod().PlayerHealth = 300;
PlayerModel.GetMod().MaxplayerMagic = 100;
PlayerModel.GetMod().PlayerMagic = 80;
}
/// <summary>
/// 升級事件
/// </summary>
public void OnLevelUp() {
int currentLevel = PlayerModel.GetMod().PlayerLevel;
//金幣遞增
PlayerModel.GetMod().PlayerCoin += currentLevel * 10;
//鑽石遞增
if ((currentLevel+1) % 3 == 0) {
PlayerModel.GetMod().PlayerDiamond += 10;
}
//最大血量遞增
PlayerModel.GetMod().MaxPlayerHealth += currentLevel * 20;
//調整當前血量
PlayerModel.GetMod().PlayerHealth += currentLevel * 20;
//最大藍量遞增
PlayerModel.GetMod().MaxplayerMagic += currentLevel * 10;
//調整當前藍量
PlayerModel.GetMod().PlayerMagic += currentLevel * 10;
//升級
PlayerModel.GetMod().PlayerLevel++;
}
/// <summary>
/// 受到傷害
/// </summary>
public void OnDamage() {
float currentHealth = PlayerModel.GetMod().PlayerHealth - 200;
PlayerModel.GetMod().PlayerHealth = Mathf.Clamp(currentHealth, 0f, PlayerModel.GetMod().MaxPlayerHealth);
}
/// <summary>
/// 釋放技能事件
/// </summary>
public void OnSkill() {
float currentMagic = PlayerModel.GetMod().PlayerMagic - 30;
PlayerModel.GetMod().PlayerMagic = Mathf.Clamp(currentMagic, 0f, PlayerModel.GetMod().MaxplayerMagic);
}
}
https://pan.baidu.com/s/1pMPN4Np
附贈原始碼連結,內涵精美扁平化UI檔案