Unity3D-UI框架
Monday, February 21 2022
Tasks
Notes
创建了UI框架和场景框架
UI Framework
其中包括Base,Concrete,Manager,UITool和UIType
Base
含有BasePanel脚本,是所有UI面板的父类,包含UI面板的状态信息。
BasePanel
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 所有UI面板的父类,包含UI面板的状态信息
/// </summary>
public class BasePanel
{
/// <summary>
/// UI信息
/// </summary>
public UIType UIType { get; private set; }
/// <summary>
/// UI管理工具
/// </summary>
public UITool UITool { get; private set; }
/// <summary>
/// 面板管理器
/// </summary>
public PanelManager PanelManager { get; private set; }
/// <summary>
/// UI管理器
/// </summary>
public UIManager UIManager { get; private set; }
#region Initialize
/// <summary>
/// 初始化
/// </summary>
/// <param name="uIType"></param>
public BasePanel(UIType uIType) {
UIType = uIType;
}
/// <summary>
/// 初始化UITool
/// </summary>
/// <param name=""></param>
public void Initialize(UITool tool) {
UITool = tool;
}
/// <summary>
/// 初始化面板管理器
/// </summary>
/// <param name="manager"></param>
public void Initialize(PanelManager manager) {
PanelManager = manager;
}
/// <summary>
/// 初始化UI管理器
/// </summary>
/// <param name="manager"></param>
public void Initialize(UIManager manager) {
UIManager = manager;
}
#endregion
/// <summary>
/// UI进入时执行的操作,只会执行一次
/// </summary>
public virtual void OnEnter() { }
/// <summary>
/// UI暂停时执行的操作
/// </summary>
public virtual void OnPause() { }
/// <summary>
/// UI继续时执行的操作
/// </summary>
public virtual void OnResume() { }
/// <summary>
/// UI退出时的操作
/// </summary>
public virtual void OnExit() { }
/// <summary>
/// 显示一个面板
/// </summary>
/// <param name="panel"></param>
public void Push(BasePanel panel) => PanelManager?.Push(panel);
/// <summary>
/// 弹出一个面板
/// </summary>
/// <param name="panel"></param>
public void Pop(BasePanel panel) => PanelManager?.Pop();
}
Concrete
存储面板的脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class StartPanel : BasePanel
{
//面板的地址
static readonly string path = "Prefab/Star";
//载入面板
public StartPanel() : base(new UIType(path)) { }
public override void OnEnter() {
//进入时添加的功能
}
}
Manager
包括PanelManager,UIManager。
PanelManager
PanelManager是面板管理,使用栈来存储UI
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 面板管理器,用栈来存储UI
/// </summary>
public class PanelManager
{
/// <summary>
/// 存储UI面板的栈
/// </summary>
private Stack<BasePanel> stackPanel;
/// <summary>
/// UI管理器
/// </summary>
private UIManager uIManager;
private BasePanel panel;
/// <summary>
/// 初始化
/// </summary>
public PanelManager() {
stackPanel = new Stack<BasePanel>();
uIManager = new UIManager();
}
/// <summary>
/// 执行面板入栈操作,此操作会显示一个面板
/// </summary>
/// <param name="nextpanel">要显示的面板</param>
public void Push(BasePanel nextpanel) {
if(stackPanel.Count > 0) {
panel = stackPanel.Peek();
panel.OnPause();
}
stackPanel.Push(nextpanel);
GameObject panelGo = uIManager.GetSingleUI(nextpanel.UIType);
nextpanel.Initialize(new UITool(panelGo));
nextpanel.Initialize(this);
nextpanel.Initialize(uIManager);
nextpanel.OnEnter();
}
/// <summary>
/// 执行面板出栈操作,此操作会执行面板的OnExit方法
/// </summary>
public void Pop() {
if (stackPanel.Count > 0) {
stackPanel.Pop().OnExit();
}
if(stackPanel.Count > 0) {
stackPanel.Peek().OnResume();
}
}
/// <summary>
/// 清除所有面板
/// </summary>
public void PopAll() {
while (stackPanel.Count > 0) {
stackPanel.Pop().OnExit();
}
}
}
UIManager
UIManager存储所有的UI信息,并进行创建或者销毁
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 储存所有UI信息,并可以创建或者销毁
/// </summary>
public class UIManager
{
/// <summary>
/// 储存所有UI信息的字典,每一个UI信息都会对应一个GameObject
/// </summary>
private Dictionary<UIType, GameObject> dicUI;
public UIManager() {
dicUI = new Dictionary<UIType,GameObject>();
}
/// <summary>
/// <para>获取一个UI对象</para>
/// </summary>
/// <param name="type">UI信息</param>
/// <returns></returns>
public GameObject GetSingleUI(UIType type) {
GameObject parent = GameObject.Find("Canvas");
if (parent == null) {
Debug.LogWarning("Canvas不存在,请仔细查找有无这个对象");
return null;
}
if (dicUI.ContainsKey(type))
return dicUI[type];
GameObject ui = GameObject.Instantiate(Resources.Load<GameObject>(type.Path), parent.transform);
ui.name = type.Name;
dicUI.Add(type, ui);
return ui;
}
/// <summary>
/// 销毁一个UI对象
/// </summary>
/// <param name="type">UI信息</param>
public void DestroyUI(UIType type) {
if (dicUI.ContainsKey(type)) {
GameObject.Destroy(dicUI[type]);
dicUI.Remove(type);
}
}
}
UITool
UITool是UI的管理工具,可以获取某个和添加某个子对象
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// UI的管理工具,包括获取某个子对象组件
/// </summary>
public class UITool
{
/// <summary>
/// 当前活动面板
/// </summary>
GameObject activePanel;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="panel"></param>
public UITool(GameObject panel) {
activePanel = panel;
}
/// <summary>
/// 给当前活动页面获取或添加一个组件
/// </summary>
/// <typeparam name="T">组件类型</typeparam>
/// <returns>组件</returns>
public T GetOrAddComponent<T>() where T : Component {
if (activePanel.GetComponent<T>() == null) {
activePanel.AddComponent<T>();
}
return activePanel.GetComponent<T>();
}
/// <summary>
/// 根据名称查找子对象
/// </summary>
/// <param name="name">子对象名称</param>
/// <returns>子对象</returns>
public GameObject FindChildGameObject(string name) {
Transform[] Trans = activePanel.GetComponentsInChildren<Transform>();
foreach (var item in Trans) {
if(item.name == name) {
return item.gameObject;
}
}
Debug.LogWarning($"{activePanel.name}未找到{name}的相关组件!!!");
return null;
}
/// <summary>
/// 根据名称查找或添加子对象组件
/// </summary>
/// <typeparam name="T">组件类型</typeparam>
/// <param name="name">组件名字</param>
/// <returns>组件,多个同名返回第一个</returns>
public T GetOrAddComponentInChildren<T>(string name) where T : Component {
GameObject child = FindChildGameObject(name);
if (child != null) {
if(child.GetComponent<T>() == null) {
child.AddComponent<T>();
}
return child.GetComponent<T>();
}
Debug.LogWarning($"未获取到{name}组件");
return null;
}
}
UIType
UI的数据
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// UI数据
/// </summary>
public class UIType
{
/// <summary>
/// UI名字
/// </summary>
public string Name { get; private set; }
/// <summary>
/// UI地址
/// </summary>
public string Path { get; private set; }
public UIType(string path) {
Path = path;
Name = path.Substring(path.LastIndexOf('/') + 1);
}
}
Scenes
其中包括Base,Concrete和SceneSystem
Base
其中包括SceneState脚本,为抽象类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 场景状态
/// </summary>
public abstract class SceneState
{
/// <summary>
/// 场景进入
/// </summary>
public abstract void OnEnter();
/// <summary>
/// 场景退出
/// </summary>
public abstract void OnExit();
}
Concrete
为场景脚本加载场景时的操作和退出时的操作
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
/// <summary>
/// 开始场景
/// </summary>
public class StarScene : SceneState
{
/// <summary>
/// 场景名称
/// </summary>
readonly string sceneName = "Star 1";
PanelManager panelManager;
public override void OnEnter() {
panelManager = new PanelManager();
if(SceneManager.GetActiveScene().name != sceneName) {
SceneManager.LoadScene(sceneName);
SceneManager.sceneLoaded += SceneLoaded;
}
else {
panelManager.Push(new StartPanel());
}
}
public override void OnExit() {
SceneManager.sceneLoaded -= SceneLoaded;
panelManager.PopAll();
}
/// <summary>
/// 场景加载完毕之后执行的方法
/// </summary>
/// <param name="scene"></param>
/// <param name="load"></param>
private void SceneLoaded(Scene scene,LoadSceneMode load) {
panelManager.Push(new StartPanel());
Debug.Log($"{sceneName}加载完毕!");
}
}
SceneSystem
这个为场景的状态管理系统,来判断是否进入当前场景
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 场景的状态管理系统
/// </summary>
public class SceneSystem
{
/// <summary>
/// 场景状态类
/// </summary>
SceneState sceneState;
/// <summary>
/// 设置当前场景并进入当前场景
/// </summary>
/// <param name="state"></param>
public void SetScene(SceneState state) {
//if(sceneState != null) {
// sceneState.OnExit();
//}
//sceneState = state;
//if (sceneState != null) {
// sceneState.OnEnter();
//}
sceneState?.OnExit();
sceneState = state;
sceneState?.OnEnter();
}
}