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();
}
}
