一:目的
在製做遊戲過程當中,UI界面都是必不可少的,多則上百個少則幾個,若是這些UI界面都放在場景裏(以下圖所示),那麼運行的時候會佔用大量的內存
canvas
通常都是將每個UI界面製做成一個Prefab動態的進行顯示隱藏,加載卸載
因此咱們須要一個管理器統一管理UI的相關操做ide
二:解決的問題及優勢ui
——不須要建立UI畫布和UI相機,動態建立並設置屬性
——管理每個UI界面的層級
——打開和關閉UI界面
——查找某一個UI界面spa
三:使用方法code
——將全部UI製做成預製體統一放在Resources—Prefabs—UI文件夾下
——全部的UI預製體都須要與掛載在身上的腳本名相同
——全部的UI預製體身上的腳本都須要繼承UIBase基類
——使用UIMgr.Ins.XXXorm
UIMgr.Ins.OpenUI<UI_Main>(); UIMgr.Ins.CloseUI<UI_Main>(); UIMgr.Ins.TopUI;
——根據不一樣項目需求設置UI畫布的縮放:UIMgr.Ins.SetCanvasScaler()繼承
四:代碼實現遊戲
using UnityEngine; using UnityEngine.UI; using System.Collections.Generic; using UnityEngine.EventSystems; /// <summary> /// UI基類 /// </summary> public class UIBase : MonoBehaviour { /// <summary> /// 打開UI時 /// </summary> public virtual void OnView() { transform.SetAsLastSibling(); gameObject.SetActive(true); } /// <summary> /// 關閉UI時 /// </summary> public virtual void OnDisView() { gameObject.SetActive(false); } } /// <summary> /// UI管理器 /// </summary> public class UIMgr : Singleton<UIMgr> { public const string UIDir = "Prefabs/UI/";//UI目錄 //渲染UI的畫布 private Canvas uiCanvas; public Canvas UICanvas { get { return uiCanvas; } } //渲染UI的相機 private Camera uiCamera; public Camera UICamera { get { return uiCamera; } } //顯示在最頂部的UI private UIBase topUI; public UIBase TopUI { get { return topUI; } } private Dictionary<string, UIBase> uiDict = new Dictionary<string, UIBase>();//場景中的UI protected override void Init() { base.Init(); if (uiCamera == null) { uiCamera = CreateUICamera(); } if (uiCanvas == null) { uiCanvas = CreateUICanvas(); } //設置Canvas縮放 SetCanvasScaler(new Vector2(750, 1334), false); } /// <summary> /// 打開UI /// </summary> public T OpenUI<T>(string uiRoot = "") where T : UIBase { string uiName = typeof(T).Name; if (!uiDict.ContainsKey(uiName)) { CreateUI(uiName, uiRoot); } UIBase ui = uiDict[uiName]; ui.OnView(); FindTopUI(); return ui as T; } /// <summary> /// 關閉UI /// </summary> public void CloseUI(string uiName, bool destroy = false) { if (!uiDict.ContainsKey(uiName)) { Debug.LogError("場景中沒有此UI:" + uiName); return; } if (destroy) { GameObject.Destroy(uiDict[uiName].gameObject); uiDict.Remove(uiName); } else { uiDict[uiName].OnDisView(); } FindTopUI(); } /// <summary> /// 關閉UI /// </summary> public void CloseUI<T>(bool destroy = false) { string uiName = typeof(T).Name; if (!uiDict.ContainsKey(uiName)) { Debug.LogError("場景中沒有此UI:" + uiName); return; } if (destroy) { GameObject.Destroy(uiDict[uiName].gameObject); uiDict.Remove(uiName); } else { uiDict[uiName].OnDisView(); } FindTopUI(); } /// <summary> /// 查找UI /// </summary> public T FindUI<T>() where T : UIBase { string uiName = typeof(T).Name; if (!uiDict.ContainsKey(uiName)) { Debug.LogError("場景中沒有此UI:" + uiName); return default; } return uiDict[uiName] as T; } /// <summary> /// 查找最頂部的UI /// </summary> private void FindTopUI() { for (int i = uiCanvas.transform.childCount - 1; i >= 0; i--) { if (uiCanvas.transform.GetChild(i).GetComponent<UIBase>() != null && uiCanvas.transform.GetChild(i).gameObject.activeSelf) { topUI = uiCanvas.transform.GetChild(i).GetComponent<UIBase>(); break; } } } /// <summary> /// 設置Canvas縮放 /// </summary> /// <param name="referResolution">參考的分辨率</param> /// <param name="isLandscape">是否爲橫屏</param> public void SetCanvasScaler(Vector2 referResolution, bool isLandscape) { CanvasScaler canvasScaler = uiCanvas.GetComponent<CanvasScaler>(); canvasScaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize; canvasScaler.matchWidthOrHeight = isLandscape ? 1 : 0; canvasScaler.referenceResolution = referResolution; } /// <summary> /// 建立UI /// </summary> private void CreateUI(string uiName, string uiRoot) { string path = UIDir + uiName; GameObject uiPrefab = Resources.Load<GameObject>(path); if (uiPrefab == null) { Debug.LogError("UI不存在:" + path); return; } UIBase uiBase = GameObject.Instantiate(uiPrefab, uiRoot == "" ? uiCanvas.transform : GameObject.Find(uiRoot).transform).GetComponent<UIBase>(); uiBase.gameObject.name = uiName; uiDict.Add(uiName, uiBase); } /// <summary> /// 建立UI畫布 /// </summary> private Canvas CreateUICanvas() { GameObject uiCanvas = new GameObject("UICanvas"); uiCanvas.layer = 5; Canvas canvas = uiCanvas.AddComponent<Canvas>(); canvas.renderMode = RenderMode.ScreenSpaceCamera; canvas.worldCamera = uiCamera; uiCanvas.AddComponent<CanvasScaler>(); uiCanvas.AddComponent<GraphicRaycaster>(); GameObject eventSystem = new GameObject("EventSystem"); eventSystem.AddComponent<EventSystem>(); eventSystem.AddComponent<StandaloneInputModule>(); eventSystem.transform.SetParent(uiCanvas.transform); GameObject.DontDestroyOnLoad(uiCanvas); return uiCanvas.GetComponent<Canvas>(); } /// <summary> /// 建立UI相機 /// </summary> private Camera CreateUICamera() { GameObject uiCamera = new GameObject("UICamera"); Camera camera = uiCamera.AddComponent<Camera>(); camera.clearFlags = CameraClearFlags.Depth; camera.cullingMask = 1 << 5; camera.orthographic = true; camera.depth = 0; GameObject.DontDestroyOnLoad(uiCamera); return camera; } }
圖片來源:遊戲加盟圖片