UGUI框架

article/2025/10/5 21:55:48

记录最新学习的UGUI框架。
在这里插入图片描述
UIType类保存面板基本信息(名称、路径),该面板会在具体的面板类里面(StartPanel)进行实例化。

public class UIType
{private string name;public string Name { get => name; }private string path;public string Path { get => path; }public UIType(string name,string path){this.name = name;this.path = path;}
}

BasePanel类为所有UI面板的基类

public class BasePanel 
{public UIType uiType;/// <summary>/// 继承此类的具体物体/// </summary>public GameObject ActiveObj;public BasePanel(UIType uiType){this.uiType = uiType;}public virtual void OnStart(){Debug.LogError($"{uiType.Name}开始使用!");}public virtual void OnEnable(){}public virtual void OnDisable(){}public virtual void OnDestroy(){}
}

UIMehod为UI工具类

/// <summary>
/// UI工具类
/// </summary>
public class UIMehod 
{private static UIMehod instance;public static UIMehod Instance{get{if (instance==null){instance = new UIMehod();}return instance;}}/// <summary>/// 获取场景中的Canvas画布/// </summary>/// <returns></returns>public GameObject FindCanvas(){GameObject go = GameObject.FindObjectOfType<Canvas>().gameObject;if (go==null){Debug.LogError("在此场景中没有找到Canvas");return go;}return go;}/// <summary>/// 根据名称查找父物体下面的子物体/// </summary>/// <param name="panel"></param>/// <param name="child_name"></param>/// <returns></returns>public GameObject FindObjectInChild(GameObject panel,string child_name){Transform[] transforms = panel.GetComponentsInChildren<Transform>();foreach (var item in transforms){if (item.gameObject.name.Equals(child_name)){return item.gameObject;}}Debug.LogError($"在{panel.name}下面没有查找到子物体{child_name}");return null;}/// <summary>/// 从目标物体上获取目标组件/// </summary>/// <typeparam name="T">要获取的组件</typeparam>/// <param name="Get_Obj"></param>/// <returns></returns>public T AddOrGetComponent<T>(GameObject Get_Obj)where T : Component{if (Get_Obj.GetComponent<T>()!=null){return Get_Obj.GetComponent<T>();}Debug.LogError($"无法在{Get_Obj}物体上获取目标组件");return null;}/// <summary>/// 从目标物体上根据子物体名称获取子物体并获取对应的组件/// </summary>/// <typeparam name="T">要获取的组件</typeparam>/// <param name="panel">目标物体(父物体)</param>/// <param name="ComponentName">要获取的子物体名称</param>/// <returns></returns>public T GetOrAddSingleComponentInChild<T>(GameObject panel,string ComponentName)where T : Component{Transform[] transforms = panel.GetComponentsInChildren<Transform>();foreach (var item in transforms){if (item.gameObject.name.Equals(ComponentName)){return item.gameObject.GetComponent<T>();}}Debug.LogError($"在{panel.name}父物体上没有找到名为{ComponentName}的子物体");return null;}
}

StartPanel类为开始面板类

public class StartPanel : BasePanel
{private static string name = "StartPanel";private static string path = "StartPanel";public static readonly UIType uIType = new UIType(path, name);public StartPanel():base(uIType){}public override void OnDestroy(){base.OnDestroy();}public override void OnDisable(){base.OnDisable();}public override void OnEnable(){base.OnEnable();}public override void OnStart(){//给StartPanel面板下UIMehod.Instance.GetOrAddSingleComponentInChild<Button>(ActiveObj, "Back").onClick.AddListener(() => { UIManager.Instance.Pop(false); });}
}

UIManager为UI控制类,UI面板会通过此类进行操作显示与隐藏

public class UIManager 
{/// <summary>/// 存储UI面板的栈/// </summary>public Stack<BasePanel> Stack_UI;/// <summary>/// 存储UI面板的名称与我物体的字典/// </summary>public Dictionary<string, GameObject> Dic_UIObject;/// <summary>/// 当前场景对应的Canvas/// </summary>public GameObject CanvasObj;private static UIManager instance;public static UIManager Instance {get{if (instance==null){instance = new UIManager();}return instance;}}public UIManager(){//instance = this;Stack_UI = new Stack<BasePanel>();Dic_UIObject = new Dictionary<string, GameObject>();}/// <summary>/// 创建UI面板/// </summary>/// <param name="uiType"></param>/// <returns></returns>public GameObject GetSingleObject(UIType uiType){if (Dic_UIObject.ContainsKey(uiType.Name)){return Dic_UIObject[uiType.Name];}if (CanvasObj==null){CanvasObj = UIMehod.Instance.FindCanvas();}GameObject go = GameObject.Instantiate<GameObject>(Resources.Load<GameObject>(uiType.Path), CanvasObj.transform);return go;}/// <summary>/// 入栈/// </summary>/// <param name="basePanel"></param>public void Push(BasePanel basePanel){if (Stack_UI.Count>0){//禁用栈顶的面板Stack_UI.Peek().OnDisable();}GameObject UI_Objecr = GetSingleObject(basePanel.uiType);Dic_UIObject.Add(basePanel.uiType.Name, UI_Objecr);basePanel.ActiveObj = UI_Objecr;if (Stack_UI.Count==0){Stack_UI.Push(basePanel);}else{if (Stack_UI.Peek().uiType.Name!=basePanel.uiType.Name){Stack_UI.Push(basePanel);}}basePanel.OnStart();Debug.Log($"{basePanel.uiType.Name}被Push入栈");}/// <summary>/// 出栈/// </summary>/// <param name="isLoad">是否清空栈(True:清空栈///                                 False:只弹出栈顶物体)</param>public void Pop(bool isLoad = false){if (isLoad==true){if (Stack_UI.Count>0){Stack_UI.Peek().OnDisable();Stack_UI.Peek().OnDestroy();//销毁栈顶面板并从字典中移除GameObject.Destroy(Dic_UIObject[Stack_UI.Peek().uiType.Name]);Dic_UIObject.Remove(Stack_UI.Peek().uiType.Name);Stack_UI.Pop();Pop(true);}}else{if (Stack_UI.Count>0){Stack_UI.Peek().OnDisable();Stack_UI.Peek().OnDestroy();//销毁栈顶面板并从字典中移除GameObject.Destroy(Dic_UIObject[Stack_UI.Peek().uiType.Name]);Dic_UIObject.Remove(Stack_UI.Peek().uiType.Name);Stack_UI.Pop();if (Stack_UI.Count > 0){///开启栈顶面板Stack_UI.Peek().OnEnable();}}}}
}

GameManager为游戏控制类,此类需要挂载到Unity场景中。此类有这个UI框架最基本的使用方法.

public class GameManager : MonoBehaviour
{private BasePanel Start_Panel = new StartPanel();public static GameManager Instance;private void Awake(){Instance = this;}private void Start(){DontDestroyOnLoad(this.gameObject);UIManager.Instance.CanvasObj = UIMehod.Instance.FindCanvas();UIManager.Instance.Push(Start_Panel);}private void Update(){if (Input.GetMouseButtonDown(0)){UIManager.Instance.Pop();}}
}

记录UI框架的学习使用过程,欢迎大佬进行指正!


http://chatgpt.dhexx.cn/article/TRQrXdPb.shtml

相关文章

UGUI的简单理解

1.Canvas(画布) UGUI中几乎所有的组件都要在Canvas下搭建 2.EventSysteam(事件系统) 如果进行UI搭建的时候,缺少或删除了EventSysteam的话会导致UGUI中的组件无法交互,无法发生事件. 3.Panel 平时我们进行UI工程搭建的时候,我们都会先创建Panel面板,创建Panel面板的…

UGUI底层

关于UGUI底层的小知识---上 (转雨松momo) 1 | UGUI原理简述 1.1 原理 首先得生成显示UI用的Mesh&#xff0c;如图1-1所示&#xff0c;一个矩形的Mesh&#xff0c;由4个顶点&#xff0c;2个三角形组成&#xff0c;每个顶点都包含UV坐标&#xff0c;如果需要调整颜色&#xf…

UGUI组件详解

什么是 UGUI UGUI 是 Unity 自带的一套 GUI 系统&#xff0c;含有基本的一些 UI 控件。 UGUI 控件有哪些&#xff1f; 我们常用的有 Canvas&#xff0c;Text&#xff0c;Image&#xff0c;Button&#xff0c;Toggle&#xff0c;Slider&#xff0c;Scroll Bar&#xff0c;Scroll…

【Unity基础】ugui的基础知识篇

文章目录 前言一、常用用可视化控件1、Image2、RawImageI.和Image的区别 3、Text组件4、画布是怎么渲染出可视化UI的&#xff1f;II.这里整理一下渲染相关的关系图&#xff0c;如下: 5、关于画布的布局重构 二、Button交互组件1、Button组件的源码以及使用方式2、Button组件是如…

Unity之UGUI详解

UGUI 文章目录 UGUI六大基础组件概述Canvas对象上依附的&#xff1a;CanvasCanvas ScalerGraphic RaycasterRectTransform EventSystem对象上依附的&#xff1a;EventSystemStandalone Input Module Canvas画布组件Screen Space overlayScreen Space CameraWorld Space CanvasS…

using namespace std

整体认识 —— 解决命名冲突 一个简单的C程序&#xff1a; #include<iostream>using namespace std;int main(int argc,char **argv) {cout<<"hello world !"<<endl;system("pause"); // 让程序暂停,按任意键继续 注意&#xff0c;…

K8S:Namespace详解

Namespace概念 Kubernetes 支持多个虚拟集群&#xff0c;它们底层依赖于同一个物理集群&#xff0c;这些虚拟集群被称为命名空间。 命名空间 namespace 是 k8s 集群级别的资源&#xff0c;可以给不同的用户、租户、环境或项目创建对应的命名空间。 在创建pod的时候可以指定p…

TypeScript中的命名空间—namespace

TypeScript中的命名空间—namespace 什么是命名空间&#xff1f;在很多语言中都有这个概念。 命名空间是为了解决命名冲突。比如你在代码的不同地方&#xff0c;都定义了同名但是不同含义的函数、变量等&#xff0c;虽然不提倡这么做&#xff0c;但是有时候需要这么做。那怎么…

c++ 中的 namespace 用法

多人代码的整合&#xff0c;namespace 还是非常有用的。可以很轻松的避免变量与函数一样的命名 1. namespace 在 单个头文件 中使用 下面给一个简单示例演示命名空间和自定义头文件的使用&#xff0c;代码如下&#xff1a; compare.h&#xff1a; namespace compare{double…

【C++】命名空间(namespace) 以及理解using namespace std

命名空间 1.命名空间使用的背景1.背景 2.命名空间的定义&#xff08;namespace&#xff09;2.1正常的定义2.2 命名空间可以嵌套定义2.3允许命名空间相同 3.域作用限定符&#xff08;&#xff1a;&#xff1a;&#xff09;和命名空间的使用3.1域作用限定符&#xff08;&#xff…

C++ namespace

C namespace 一、什么是 namespace1.1 C语言标识符作用域的缺陷1.2 namespace作用 二、namespace的定义2.1 命名空间可以嵌套定义小技巧 2.2 可定义重复的命名空间 三、namespace使用3.1 命名空间名称作用域限定符使用3.2 using将命名空间中成员引入3.3 使用using namespace将整…

Linux namespace概述

操作系统通过虚拟内存技术&#xff0c;使得每个用户进程都认为自己拥有所有的物理内存&#xff0c;这是操作系统对内存的虚拟化。操作系统通过分时调度系统&#xff0c;每个进程都能被【公平地】调度执行&#xff0c;即每个进程都能获取到CPU&#xff0c;使得每个进程都认为自己…

C++ | 你真的了解namespace吗?

文章目录 一、前言二、命名冲突三、命名空间1、域作用限定符2、命名空间的概念&#x1f449;示例1&#x1f449;示例2 3、命名空间的定义4、命名空间的使用① 指定命名空间访问【做项目】② 使用using部分展开【做项目】③ 使用using namespace全局展开【日常练习】 5、小结 解…

using namespace std 介绍

using namespace std&#xff1b; 首先我们要知道&#xff0c;这句代码的意思是&#xff1a;打开标准命名空间&#xff0c;即告诉编辑器我们将要使用名字空间std中的函数或者对象。 using 意思就是正在使用的意思。namespace 的引用是为了解决不同space中命名相同导致命名冲突…

Namespace基本知识

published: true tags: C author: persuez Namespace C中namespace简单来说就是用来控制标志符&#xff08;如变量&#xff0c;函数&#xff0c;类等&#xff09;的名字冲突的。 简单术语 declarative region: 指标志符声明的区域。具体见图一。 potential scope: 指从该标…

【C++】命名空间namespace详解

一、命名空间的引入 C中&#xff0c;名称(name)可以是符号常量、变量、宏、函数、结构体、枚举、类和对象等等。而在大型工程中&#xff0c;难免会有重名的现象&#xff0c;命名空间namespace&#xff0c;就是C引入的一种解决名称冲突的机制 1.1 如何解决命名冲突 C语言中 …

namespace介绍

命名空间 命名空间 namespace 1、::作用域运算符&#xff08;表明 数据、方法 的归属性问题&#xff09; 2、命名空间 namespace 解决命名冲突 2.1&#xff1a;namespace命名空间的定义 2.2:命名空间只能全局范围内定义&#xff08;以下错误写法&#xff09; 2.3:命名空间可嵌套…

【C++】命名空间(namespace)详解

一、为什么使用命名空间 考虑一种情况&#xff0c;当我们有两个同名的人&#xff0c;Zara&#xff0c;在同一个班里。当我们需要对它们进行区分我们必须使用一些额外的信息和它们的名字&#xff0c;比如这个区域&#xff0c;如果它们生活在不同的区域或者它们的母亲或父亲的名…

Python中,线程threading详解

Python中最常用的同步有&#xff1a;锁/互斥&#xff0c;以及信号量。其中锁是最简单最低级的机制&#xff0c;信号量用于多线程竞争有限资源的情况。但是锁被释放&#xff0c;线程不一定被释放。 threading.Lock同步锁&#xff08;原语锁&#xff09; 通常使用获得锁&#xff…

【Python】多线程及threading模块介绍

​目录 1. 多线程简单介绍 2. threading模块介绍 2.1 threading模块常用方法 2.2 Thread类使用 2.2.1 使用构造函数传递可调用对象的方法创建线程 2.2.2 继承threading.Thread类 3. 多线程程序中使用(共享)全局变量 4. 多线程共享全局变量遇到的问题 5. 线程同步 5.1 …