(37 封私信 / 81 条消息) 在 Unity 查找场景下的对象,一篇就够了!!! - 知乎
通用的UIPanle管理类
公共UI
UIType
//==========================
// - FileName: UiType.cs
// - Created: yeyuotc
// - CreateTime: #CreateTime#
// - Email: 1079221637@qq.com
// - Description:存储当前UI的信息,包括名字路径
//==========================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
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);
//取最后一个路径前的名称
}
}
BasePanel
//==========================
// - FileName: BasePanel.cs
// - Created: yeyuotc
// - CreateTime: #CreateTime#
// - Email: 1079221637@qq.com
// - Description:所有UI继承的基类
// 包含所有UI面板的状态信息
//==========================
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
public abstract class BasePanel
{
/// <summary>
/// UI信息
/// </summary>
public UIType UIType { get; private set; }
/// <summary>
/// UI工具管理器
/// </summary>
public UITool UITool { get; private set; }
/// <summary>
/// 面板管理器
/// </summary>
public PanleManager PanleManager { get; private set; }
/// <summary>
/// UI管理器
/// </summary>
public UIManager UIManager { get; private set; }
public BasePanel(UIType uitype)
{
UIType = uitype;
}
/// <summary>
/// 初始化UITool
/// </summary>
/// <param name="tool"></param>
public void Initialize(UITool tool)
{
UITool = tool;
}
public void Initialize(PanleManager panleManager)
{
PanleManager= panleManager;
}
public void Initialize(UIManager uIManager)
{
UIManager = uIManager;
}
/// <summary>
/// 进入时候的方法,只会执行一次,onLoad
/// </summary>
public virtual void OnEnter() { }
/// <summary>
/// 暂停执行,点开别的UI,对原有UI的处理
/// </summary>
public virtual void OnPuase()
{
UITool.GetOrAddComponent<CanvasGroup>().blocksRaycasts = false;
}
/// <summary>
/// 暂停结束后继续执行
/// </summary>
public virtual void OnResume()
{
UITool.GetOrAddComponent<CanvasGroup>().blocksRaycasts = true;
}
/// <summary>
/// 退出时执行的方法
/// </summary>
public virtual void OnExit()
{
UIManager.DestorySingleUI(UIType);
}
}
PanleManager
//==========================
// - FileName: PanleManager.cs
// - Created: yeyuotc
// - CreateTime: #CreateTime#
// - Email: 1079221637@qq.com
// - Description:面板的管理器,用栈来存
//==========================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PanleManager
{
/// <summary>
/// 栈来存储UI
/// </summary>
private Stack<BasePanel> stackPanel;
/// <summary>
/// 面板管理器
/// </summary>
private UIManager uiManager;
private BasePanel panel;
public PanleManager()
{
stackPanel = new Stack<BasePanel>();
uiManager = new UIManager();
}
/// <summary>
/// UI的入栈操作,此操作会显示一个面板
/// </summary>
/// <param name="nextPanel">要显示的面板</param>
public void Push(BasePanel nextPanel)
{
if (stackPanel.Count > 0)
{
panel=stackPanel.Peek();
panel.OnPuase();
}
GameObject panleGo = uiManager.GetSingleUI(nextPanel.UIType);
nextPanel.Initialize(new UITool(panleGo));
nextPanel.Initialize(this); //这里添加的是自己的
nextPanel.Initialize(uiManager);
stackPanel.Push(nextPanel);
nextPanel.OnEnter();
}
/// <summary>
/// 弹出操作
/// </summary>
public BasePanel Peek()
{
if(stackPanel.Count > 0)
{
panel= stackPanel.Peek();
panel.OnResume();
return panel;
}
else
{
Debug.LogError("当前无在运行的UI,请注意检查是否入栈");
return null;
}
}
/// <summary>
/// 删除操作
/// </summary>
public void Pop()
{
if(stackPanel.Count > 0 )
{
panel=stackPanel.Peek();
panel.OnExit();
stackPanel.Pop();
if (stackPanel.Count > 0)
{
stackPanel.Peek().OnResume();
}
}
else
{
Debug.LogError("当前无在运行的UI,请注意检查是否入栈");
}
}
}
StartManager
//==========================
// - FileName: StarManger.cs
// - Created: yeyuotc
// - CreateTime: #CreateTime#
// - Email: 1079221637@qq.com
// - Description:
//==========================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class StartManger : MonoBehaviour
{
public PanleManager PanleManager;
private void Awake()
{
PanleManager = new PanleManager();
}
private void Start()
{
PanleManager.Push(new StarPanle());
}
}
UITool
//==========================
// - FileName: UITool.cs
// - Created: yeyuotc
// - CreateTime: #CreateTime#
// - Email: 1079221637@qq.com
// - Description: UI的管理工具
// 包括获取某个子对象的操作
//==========================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UITool
{
/// <summary>
/// 当前的活动面板
/// </summary>
private GameObject activePanle;
public UITool(GameObject panle)
{
activePanle = panle;
}
/// <summary>
/// 给当前的活动面板获取或者添加一个组件
/// </summary>
/// <typeparam name="T">组件的类型</typeparam>
/// <returns>组件</returns>
public T GetOrAddComponent<T>() where T : Component
{
if(activePanle.GetComponent<T>() == null)
{
activePanle.AddComponent<T>();
}
return activePanle.GetComponent<T>();
}
/// <summary>
/// 根据名称找一个子对象
/// </summary>
/// <param name="name">子对象名称</param>
/// <returns></returns>
public GameObject FindChildGameObject(string name)
{
Transform[] trans= activePanle.GetComponentsInChildren<Transform>();
//找到所有儿子
foreach(var item in trans)
{
if(item.name == name)
{
return item.gameObject;
}
}
Debug.LogError($"{activePanle.name}里找不到名称为" + name + "的prefab");
return null;
}
/// <summary>
/// 根据名称找子对象的组件
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="name"></param>
/// <returns></returns>
public T GetOrAddCopmponentInChildren<T>(string name) where T : Component
{
GameObject son=FindChildGameObject(name);
if (son != null)
{
if (son.GetComponent<T>() == null)
son.AddComponent<T>();
return son.GetComponent<T>();
}
return null;
}
}
UIManager
//==========================
// - FileName: UIManager.cs
// - Created: yeyuotc
// - CreateTime: #CreateTime#
// - Email: 1079221637@qq.com
// - Description:控制UI的创建与销毁
// 存储所有UI信息
//==========================
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
public class UIManager
{
/// <summary>
/// 存储所有UI信息的字典,每一个UI都会对应一个GameObject
/// </summary>
private Dictionary<UIType, GameObject> dicUI;
public UIManager()
{
dicUI= new Dictionary<UIType, GameObject>();
}
/// <summary>
/// 获取UI,没有则创建
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public GameObject GetSingleUI(UIType type)
{
GameObject parent = GameObject.Find("Canvas"); //这里的父类是运行时的名称,在页面上
if (!parent)
{
Debug.LogError("ui未添加Canvas,请仔细检查有无对象" + type.Path);
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[type] = ui;
return ui;
}
/// <summary>
/// 销毁一个UI对象
/// </summary>
/// <param name="type"></param>
public void DestorySingleUI(UIType type)
{
if(dicUI.ContainsKey(type))
{
GameObject.Destroy(dicUI[type]);
dicUI.Remove(type);
}
else
{
return ;
}
}
}
具体ui的使用
SettingPanle
//==========================
// - FileName: SettingPanel.cs
// - Created: yeyuotc
// - CreateTime: #CreateTime#
// - Email: 1079221637@qq.com
// - Description:
//==========================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class SettingPanel : BasePanel
{
static readonly string path = "Prefabs/UI/Panle/SetingPanle";
public SettingPanel() : base(new UIType(path))
{
}
public override void OnEnter()
{
Debug.Log("yzh进入设置界面");
UITool.GetOrAddCopmponentInChildren<Button>("BtnExit").onClick.AddListener(() =>
{
Debug.Log("销毁");
PanleManager.Pop();
});
}
}
StarPanle
//==========================
// - FileName: StarPanle.cs
// - Created: yeyuotc
// - CreateTime: #CreateTime#
// - Email: 1079221637@qq.com
// - Description: 开始面板
//==========================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class StarPanle : BasePanel
{
static readonly string path = "Prefabs/UI/Panle/Canvas2";
public StarPanle() : base(new UIType(path))
{
}
public override void OnEnter()
{
UITool.GetOrAddCopmponentInChildren<Button>("btn1").onClick.AddListener(() =>
{
Debug.Log("yzh真帅");
PanleManager.Push(new SettingPanel());
});
}
/*
* 这些都移到父类去写
public override void OnPuase()
{
UITool.GetOrAddComponent<CanvasGroup>().blocksRaycasts = false;
}
public override void OnResume()
{
UITool.GetOrAddComponent<CanvasGroup>().blocksRaycasts = true;
}
public override void OnExit()
{
UIManager.DestorySingleUI(UIType);
}
*/
}