IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 【Unity】简单的UI框架 -> 正文阅读

[游戏开发]【Unity】简单的UI框架

最近在写项目,但是模型比较慢,之前一直是硬写程序,也有用过其他人的框架,现在自己在B站上看了一些视频,也搜了一些文章,写了几天的简单框架,有一些心得,发出来,让大家看一看,有什么问题的大家多喷一下哈

核心的类有如下几个:

UIType:物体的基本属性,包含名称和地址。

public class UIType?
{
? ? public string Name { get; private set; }
? ? public string Path { get; private set; }

? ? public UIType(string path)
? ? {
? ? ? ? Path = path;
? ? ? ? Name = path.Substring(path.LastIndexOf('/')+1) ;
? ? }
}

BasePanel:主要用于面板类的基类,同时存储的有面板的状态信息。

public abstract class BasePanel?
{
? ? public UIType UIType { get; private set; }
? ? public UITool UITool { get; private set; }
? ? public PanelManager PanelManager { get; private set; }

? ? public UIManager UIManager { get; private set; }

? ? public BasePanel(UIType uIType)
? ? {
? ? ? ? UIType = uIType;
? ? }

? ? public void Initialize(UITool tool)
? ? {
? ? ? ? UITool = tool;
? ? }

? ? public void Initialize(PanelManager panel)
? ? {

? ? ? ? PanelManager = panel;
? ? }
? ? public void Initialize(UIManager uIManager)
? ? {

? ? ? ? UIManager = uIManager;
? ? }

? ? public virtual void OnEnter() { }

? ? public virtual void OnPause() {
? ? ? ?UITool.GetOrAddComponent<CanvasGroup>().blocksRaycasts = false;
? ? }

? ? public virtual void OnResume() {
? ? ? ? UITool.GetOrAddComponent<CanvasGroup>().blocksRaycasts = true;
? ? }

? ? public virtual void OnExit() { }
}
?

PanelManager:面板管理器,里面有一个栈,使用栈来存储UI。

public class PanelManager?
{
? ? private Stack<BasePanel> stackPanel;
? ? private UIManager uIManager;
? ? private BasePanel panel;

? ? public PanelManager()
? ? {
? ? ? ? stackPanel = new Stack<BasePanel>();
? ? ? ? uIManager = new UIManager();
? ? }


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

? ? public void Pop()
? ? {
? ? ? ? if (stackPanel.Count>0)
? ? ? ? {
? ? ? ? ? ? stackPanel.Peek().OnExit();
? ? ? ? ? ? stackPanel.Pop();
? ? ? ? }
? ? ? ? if (stackPanel.Count > 0)
? ? ? ? ? ? stackPanel.Peek().OnResume();
? ? }
}

UIManager:存储所有的UI信息,用字典进行存储。

public class UIManager?
{
? ? private Dictionary<UIType, GameObject> dicUI;

? ? public UIManager()
? ? {
? ? ? ? dicUI = new Dictionary<UIType, GameObject>();
? ? }
? ? public GameObject GetSingleUI(UIType type)
? ? {
? ? ? ? GameObject parent = GameObject.Find("Canvas");
? ? ? ? if (!parent)
? ? ? ? {
? ? ? ? ? ? Debug.LogError("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;
? ? }

? ? public void DestroyUI(UIType type)
? ? {
? ? ? ? if (dicUI.ContainsKey(type))
? ? ? ? {
? ? ? ? ? ? GameObject.Destroy(dicUI[type]);
? ? ? ? ? ? dicUI.Remove(type);
? ? ? ? }
? ? }
}

UITool:UI管理工具,用于获取物体以及相关组件

public class UITool?
{

? ? GameObject activePanel;

? ? public UITool(GameObject panel)
? ? {
? ? ? ? activePanel = panel;
? ? }

? ? public T GetOrAddComponent<T>() where T : Component
? ? {
? ? ? ? if (activePanel.GetComponent<T>() == null)
? ? ? ? ? ? activePanel.AddComponent<T>();
? ? ? ? return activePanel.GetComponent<T>();
? ? }

? ? public GameObject FindChildGameObject(string name)
? ? {
? ? ? ? Transform[] trans = activePanel.GetComponentsInChildren<Transform>();
? ? ? ? foreach (Transform item in trans)
? ? ? ? {
? ? ? ? ? ? if (item.name==name)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? return item.gameObject;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? Debug.LogError(activePanel+"里找不到名为"+name+"的子物体");
? ? ? ? return null;
? ? }

? ? public T GetOrAddComponentInChildren<T>(string name)where T:Component
? ? {
? ? ? ? GameObject child = FindChildGameObject(name);
? ? ? ? if (child)
? ? ? ? {
? ? ? ? ? ? if (child.GetComponent<T>() == null)
? ? ? ? ? ? ? ? child.AddComponent<T>();

? ? ? ? ? ? return child.GetComponent<T>();
? ? ? ? }
? ? ? ? return null;
? ? }
}

通过以上5个核心脚本,可以搭配一个比较简单的UI框架。

使用方法:

我们可以创建一个新的脚本挂载在场景中的空物体上如下图的GameRoot,提前搭建好场景中的Canvas当作父物体。

?

?然后GameRoot内容如下:

public class GameRoot : MonoBehaviour
{
? ? PanelManager panelManager;
? ? private void Awake()
? ? {
? ? ? ? panelManager = new PanelManager();
? ? }
? ? // Start is called before the first frame update
? ? void Start()
? ? {
? ? ? ? panelManager.Push(new StartPanel());
? ? }
}

当实例化之后,我们的开始面板就展示在眼前了

其他面板的按钮调用可以使用如下内容的方法:

public class StartPanel : BasePanel?
{
? ? static readonly string path = "Prefabs/Panel/StartPanel";

? ? ? //这里需要放置我们自己面板预设体的路径

? ? public StartPanel() : base(new UIType(path)) { }

? ? public override void OnEnter()
? ? {
? ? ? ? UITool.GetOrAddComponentInChildren<Button>("BtnSetting").onClick.AddListener(()=> {

? ? ? ? ? ? PanelManager.Push(new SettingPanel());

? ? ? ? ? ?//通过点击设置按钮打开设置面板,但必须要有设置面板的脚本

? ? ? ? });

? ?? ? ? UITool.GetOrAddComponentInChildren<Button>("BtnPlay").onClick.AddListener(()=> {

? ? ? ? ? ? PanelManager.Push(new MainPanel());
? ? ? ? ? ? UIManager.DestroyUI(UIType);

? ? ? ? ? ? ?//通过点击开始按钮,打开主面板,同时删除当前面板。
? ? ? ? });

? ? }
}

其中,我们的面板开启使用PanelManager.Push(new 面板名称),前提是有该面板同时继承了basePanel并设置了路径。

按钮点击事件可以使用UITool中的GetOrAddComponentInChildren方法来进行按钮和事件的绑定:

UITool.GetOrAddComponentInChildren<Button>("BtnPlay").onClick.AddListener(()=> {

? ? ? ? ? ? PanelManager.Push(new MainPanel());
? ? ? ? ? ? UIManager.DestroyUI(UIType);

? ? ? ? ? ? ?//通过点击开始按钮,打开主面板,同时删除当前面板。
? ? ? ? });

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-09-19 08:17:57  更:2021-09-19 08:18:55 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 18:09:54-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码