1. 程式人生 > >Unity框架——MVC框架

Unity框架——MVC框架


前言——什麼是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,所有的資料通過外部賦值,不需要有初始值

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();
            }
        }
    }
}
~第二個指令碼:ViewPath(各個UI的路徑)

儲存所有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
}
~第三個指令碼:PlayerView
using 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);
        };
    }
}
~第四個指令碼:PlayerController
using 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檔案