目前使用的框架:
1.ui类
(1)每一个ui都放在一个panel里面,panel当中要加入CanvesGroup组件以便控制其子物件与ui的交互
(2)BasePanel为所有自定义Panel的父类,每一个自定义的Panel要继承BasePanel并实现抽象方法
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BasePanel
{
/// <summary>
/// 储存uiPanel的名字和加载路径信息
/// </summary>
public UIType uIType;
/// <summary>
/// 当前ui在场景中绑定的物体
/// </summary>
public GameObject activeObj;
public BasePanel(UIType _uIType)
{
uIType = _uIType;
}
public virtual void onStart()
{
UIMethod.AddOrGetComponent<CanvasGroup>(activeObj).interactable = true;
}
public virtual void onEnable()
{
UIMethod.AddOrGetComponent<CanvasGroup>(activeObj).interactable = true;
}
public virtual void onDisable()
{
UIMethod.AddOrGetComponent<CanvasGroup>(activeObj).interactable = false;
}
public virtual void onDestory()
{
UIMethod.AddOrGetComponent<CanvasGroup>(activeObj).interactable = false;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UIType
{
private string _name;
private string _path;
public UIType(string uIType,string objPath)
{
_name = uIType;
_path = objPath;
}
public string Name { get => _name; }
public string Path { get => _path; }
}
实现示例:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class StartPanel : BasePanel
{
private static string _name = "StartPanel";
private static string _path = @"Panel\StartPanel";
public static UIType uiType = new UIType(_name, _path);
public StartPanel() : base(uiType)
{
}
public override void onStart()
{
base.onStart();
UIMethod.AddOrGetComponentInChildren<Button>(activeObj, "CloseDD").onClick.AddListener(closeDD);
UIMethod.AddOrGetComponentInChildren<Button>(activeObj, "Load").onClick.AddListener(changeScene);
UIMethod.AddOrGetComponentInChildren<Button>(activeObj, "Load0").onClick.AddListener(changeScene0);
}
private void closeDD()
{
GameObject.DestroyImmediate(UIMethod.findObjInChildren(activeObj, "Dropdown"));
//UIMethod.findObjInChildren(activeObj, "Dropdown").SetActive(false);
}
private void changeScene()
{
Scene1 scene1 = new Scene1();
SceneControl.getInstance().Load(Scene1.nameScene, scene1);
}
private void changeScene0()
{
Scene0 scene0 = new Scene0();
SceneControl.getInstance().Load(Scene0.nameScene, scene0);
}
public override void onEnable()
{
base.onEnable();
}
public override void onDisable()
{
base.onDisable();
}
public override void onDestory()
{
base.onDestory();
}
}
2.UI工具类
(1)从当前物体的子物体获得组件
public static T AddOrGetComponentInChildren<T>(GameObject panel,string nameChildren) where T:Component
(2)从当前物体获取组件
public static T AddOrGetComponent<T> (GameObject panel) where T:Component
(3)寻找在这个物体下面的子物体
public static GameObject findObjInChildren(GameObject panel,string nameChildren)
(4)获取当前场景下的画布
public static GameObject getCanves()
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public static class UIMethod
{
/// <summary>
/// 获取当前场景下的画布
/// </summary>
/// <returns></returns>
public static GameObject getCanves()
{
GameObject canves = GameObject.FindObjectOfType<Canvas>().gameObject;
if(canves==null)
{
Debug.LogError("Cannot find Canves");
}
return canves;
}
/// <summary>
/// 寻找在这个物体下面的子物体
/// </summary>
/// <param name="panel"></param>
/// <param name="nameChildren">子物体的名字</param>
/// <returns></returns>
public static GameObject findObjInChildren(GameObject panel,string nameChildren)
{
Transform[] ts = panel.GetComponentsInChildren<Transform>();
foreach (var item in ts)
{
if(item.gameObject.name==nameChildren)
{
return item.gameObject;
}
}
Debug.LogError($"NotFindChildren:{nameChildren}");
return null;
}
/// <summary>
/// 从当前物体获取组件
/// </summary>
/// <typeparam name="T">组件名字</typeparam>
/// <param name="panel">父物体</param>
/// <returns></returns>
public static T AddOrGetComponent<T> (GameObject panel) where T:Component
{
T target = panel.GetComponent<T>();
if(target==null)
{
Debug.LogError($"NotFindConponent:{panel.name}");
target=panel.AddComponent<T>();
}
return target;
}
/// <summary>
/// 从当前物体的子物体获得组件
/// </summary>
/// <typeparam name="T">组件类型</typeparam>
/// <param name="panel">父物体</param>
/// <param name="nameChildren"></param>
/// <returns></returns>
public static T AddOrGetComponentInChildren<T>(GameObject panel,string nameChildren) where T:Component
{
GameObject obj = findObjInChildren(panel,nameChildren);
T target = obj.GetComponent<T>();
if (target == null)
{
Debug.LogError($"NotFindConponent:{obj.name}");
target = obj.AddComponent<T>();
}
return target;
}
}
3.UIManager
使用其中的push和pop方法来加入ui和弹出当前ui
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class UIManager
{
private Dictionary<string, GameObject> dic_ui;
private Stack<BasePanel> sta_ui;
/// <summary>
/// 场景下的画布
/// </summary>
public GameObject canvesObj;
private static UIManager instance;
public static UIManager getInstance()
{
if(instance==null)
{
Debug.LogError("NotFoundInstance");
return null;
}
return instance;
}
public UIManager()
{
dic_ui = new Dictionary<string, GameObject>();
sta_ui = new Stack<BasePanel>();
instance = this;
}
public GameObject getSingleObj(UIType uIType)
{
if(dic_ui.ContainsKey(uIType.Name))
{
return dic_ui[uIType.Name];
}
if(canvesObj==null)
{
canvesObj = UIMethod.getCanves();
}
GameObject uiObj = GameObject.Instantiate<GameObject>(Resources.Load<GameObject>(uIType.Path), canvesObj.transform);
dic_ui.Add(uIType.Name, uiObj);
return uiObj;
}
public void push(BasePanel uiPanel)
{
if(sta_ui.Count==0)
{
GameObject uiObj = getSingleObj(uiPanel.uIType);
uiPanel.activeObj = uiObj;
uiObj.name = uiPanel.uIType.Name;
sta_ui.Push(uiPanel);
}
else
{
if(sta_ui.Peek().uIType.Name!=uiPanel.uIType.Name)
{
sta_ui.Peek().onDisable();
GameObject uiObj = getSingleObj(uiPanel.uIType);
uiPanel.activeObj = uiObj;
uiObj.name = uiPanel.uIType.Name;
sta_ui.Push(uiPanel);
}
}
uiPanel.onStart();
}
public void pop(bool isLoad)
{
if(isLoad)
{
if(sta_ui.Count>0)
{
dic_ui.Remove(sta_ui.Peek().uIType.Name);
sta_ui.Peek().onDisable();
sta_ui.Peek().onDestory();
GameObject.DestroyImmediate(sta_ui.Peek().activeObj);
sta_ui.Pop();
pop(true);
}
}
else
{
if (sta_ui.Count > 0)
{
dic_ui.Remove(sta_ui.Peek().uIType.Name);
sta_ui.Peek().onDisable();
sta_ui.Peek().onDestory();
GameObject.DestroyImmediate(sta_ui.Peek().activeObj);
sta_ui.Pop();
if(sta_ui.Count>0)
{
sta_ui.Peek().onEnable();
}
}
}
}
}
4.场景加载基类
所有自定义场景类都要继承这个基类,并且定义场景名字
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class SceneBase
{
public abstract void enterScene();
public abstract void exitScene();
}
场景类示例:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class Scene0 : SceneBase
{
public static string nameScene = "Scene0";
public override void enterScene()
{
UIManager.getInstance().push(new StartPanel());
//Debug.Log($"Load{SceneManager.GetActiveScene().name}");
}
public override void exitScene()
{
//UIManager.getInstance().pop(true);
}
}
5.场景控制类
切换场景在事件或者GM当中调用方法场景控制类当中的load即可
注意:每一次创建新场景,在创建场景类之后,记得在这里进行注册
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class SceneControl
{
private Dictionary<string, SceneBase> dic_scene = new Dictionary<string, SceneBase>
{
[Scene0.nameScene] = new Scene0(),
[Scene1.nameScene]=new Scene1(),
[SceneLaucher.nameScene]=new SceneLaucher()
};
private static SceneControl instance;
public static SceneControl getInstance()
{
if(instance==null)
{
Debug.Log("NotFindSceneInstance");
}
return instance;
}
public SceneControl()
{
instance = this;
}
public void Load(string nameScene,SceneBase sceneBase)
{
if(!dic_scene.ContainsKey(nameScene))
{
dic_scene.Add(nameScene, sceneBase);
}
dic_scene[SceneManager.GetActiveScene().name].exitScene();
#region popAllUI
UIManager.getInstance().pop(true);
#endregion
SceneManager.LoadScene(nameScene);
sceneBase.enterScene();
}
}
6.GameManeger
用以初始化SceneControl和UIManager
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager : MonoBehaviour
{
public static GameManager _instance;
public static GameManager getInstance()
{
if(_instance==null)
{
Debug.LogError("NotHaveInstance");
}
return _instance;
}
private UIManager _uIManager;
public UIManager uIManager { get => _uIManager; }
private SceneControl _sceneControl;
public SceneControl sceneControl { get => _sceneControl; }
private void Awake()
{
if(_instance==null)
{
_instance = this;
}
else
{
GameManager.Destroy(this.gameObject);
}
_uIManager = new UIManager();
_sceneControl = new SceneControl();
}
private void Start()
{
DontDestroyOnLoad(this);
uIManager.push(new StartPanel());
//SceneControl.getInstance().Load(Scene0.nameScene, new Scene0());
}
}