一:目的
在制做游戏过程当中,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; } }
图片来源:游戏加盟图片