小游戲UI框架用起來也比較方便。做UI時扩灯,首先要有個大致框架媚赖,大致的UI方向霜瘪,一般需要把UI的彈窗分為兩種,一種是layer惧磺,一種是dlg颖对,layer是主層級面板,一般用于主界面磨隘,游戲界面等缤底,dlg是二級彈窗,一般用于設置番捂,排行等彈窗界面个唧。UI需要一個管理類UIMgr統(tǒng)一管理這兩種分類。
UIMgr一般是單例類白嘁,那么我們就需要一個統(tǒng)一的全局單例類管理它坑鱼,讓其他需要單例的可以直接繼承使用膘流。
以下是一個繼承MonoBehavior的單例類MonoSingleton絮缅。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Mono singleton.
/// 單實例設計模式、保證整個游戲過程中只有一個實例
/// </summary>
public class MonoSingleton<T> : MonoBehaviour where T: MonoBehaviour {
[SerializeField]
bool _isDestory = false;
public static T Instance;
public virtual void Awake () {
Instance = this as T;
if (!_isDestory) {
DontDestroyOnLoad(gameObject);
}
}
public virtual void OnDestory() {
Instance = null;
}
}
然后就是繼承他的UIMgr了呼股。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UIMgr : MonoSingleton<UIMgr> {
[SerializeField]
Transform _layerRoot;
[SerializeField]
Transform _dlgRoot;
Dictionary<Enums.LayerId, BaseLayer> _layers = new Dictionary<Enums.LayerId, BaseLayer>();
Dictionary<Enums.DlgId, BaseDlg> _dlgs = new Dictionary<Enums.DlgId, BaseDlg>();
BaseLayer _showLayer = null;
[HideInInspector]
public Vector2 size; //實際的屏幕寬高
public override void Awake () {
base.Awake();
size = GetComponent<RectTransform>().sizeDelta;
}
private void Start () {
LoadUI();
}
void LoadUI () {
foreach (var layer in _layerRoot.GetComponentsInChildren<BaseLayer>(true)) {
if (!_layers.ContainsKey(layer.id)) {
if (layer.id == Enums.LayerId.LayerSplash) {
_showLayer = layer;
layer.gameObject.SetActive(true);
} else {
layer.gameObject.SetActive(false);
}
_layers.Add(layer.id, layer);
}
}
foreach (var dlg in _dlgRoot.GetComponentsInChildren<BaseDlg>(true)) {
if (!_dlgs.ContainsKey(dlg.id)) {
dlg.gameObject.SetActive(false);
_dlgs.Add(dlg.id, dlg);
}
}
var layerPrefabs = Resources.LoadAll<GameObject>("Prefabs/UIs/Layers");
foreach (var prefab in layerPrefabs) {
Enums.LayerId id = prefab.GetComponent<BaseLayer>().id;
if (!_layers.ContainsKey(id)) {
var layer = Instantiate(prefab, _layerRoot).GetComponent<BaseLayer>();
layer.gameObject.SetActive(false);
layer.transform.localScale = Vector3.one;
_layers.Add(id, layer);
}
}
var dlgPrefabs = Resources.LoadAll<GameObject>("Prefabs/UIs/Dlgs");
foreach (var prefab in dlgPrefabs) {
Enums.DlgId id = prefab.GetComponent<BaseDlg>().id;
if (!_dlgs.ContainsKey(id)) {
var dlg = Instantiate(prefab, _dlgRoot).GetComponent<BaseDlg>();
dlg.gameObject.SetActive(false);
dlg.transform.localScale = Vector3.one;
_dlgs.Add(id, dlg);
}
}
}
public void ShowLayer (Enums.LayerId id, params object[] objs) {
Debug.Log("ShowLayer0");
if (_showLayer != null && _showLayer.id == id)
{
Debug.Log("ShowLayer1");
_showLayer.OnShow();
return;
}
if (_showLayer != null) {
_showLayer.OnHide();
}
//Debug.Log(_showLayer);
if (_layers.ContainsKey(id)) {
_showLayer = _layers[id];
_showLayer.OnShow(objs);
} else {
Debug.Log("can't find layer:" + id);
}
}
public void ShowDlg(Enums.DlgId id, params object[] objs) {
if (_dlgs.ContainsKey(id))
{
_dlgs[id].OnShow(objs);
}
else {
Debug.Log("can't find dlg:" + id);
}
}
public BaseLayer GetLayer(Enums.LayerId id) {
if (_layers.ContainsKey(id))
{
return _layers[id];
}
else {
return null;
}
}
public BaseDlg GetDlg(Enums.DlgId id)
{
if (_dlgs.ContainsKey(id))
{
return _dlgs[id];
}
else
{
return null;
}
}
}
最后需要兩個基類讓layer和dlg分別繼承耕魄。
baselayer如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BaseLayer : MonoBehaviour {
public Enums.LayerId id;
protected Animator animator;
protected Coroutine animCoroutine = null;
protected object _params;
protected virtual void Awake() {
animator = GetComponent<Animator>();
}
protected virtual void Start() {
}
public virtual void OnShow(params object[] objs) {
_params = objs;
gameObject.SetActive(true);
if (animator != null)
{
animator.Play("Show");
}
}
public virtual void OnRefresh() {
}
public virtual void OnHide() {
if (animator != null)
{
animator.Play("Hide");
}
else {
gameObject.SetActive(false);
}
}
public void OnAnimListener(string animName) {
if (animName == "Hide")
{
gameObject.SetActive(false);
}
}
}
下面的是basedlg
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BaseDlg : MonoBehaviour {
public Enums.DlgId id;
protected object _params;
public virtual void OnShow (object objs) {
_params = objs;
gameObject.SetActive(true);
}
public virtual void OnHide () {
gameObject.SetActive(false);
}
public virtual void OnRefresh()
{
}
}
這樣用起來很方便,能拿到每個layer和dlg彭谁,便于管理和擴展