Unity 从零开始搭建一套简单易用的UGUI小框架 功能撰写与优化篇

Unity 从零开始搭建一套简单易用的UGUI小框架 基础分析篇-CSDN博客

开始撰写 

从基础分析篇我们得到了三个类,面板基类,管理类和面板子类

那就从面板基类开始,定义其基本行为

面板基类

基本方法都很简单,分别是首次加载并打开面板,关闭和重新打开

加载我就采用unity的资源加载Resources方法

Unity数据持久化 万物之源Resources动态资源加载_unity 动态加载资源-CSDN博客

但是需要考虑几个问题

0.需要一个面板预制体并放到对应路径下

我就将其放到Wnd下起名叫AnyWnd了

1.因为unity特性,面板加载出来需要放在Canvas下才会被显示

所以需要设置父物体为Canvas
2.放在Canvas下还需要设置位置

所以需要记录一下传入的面板的原来的位置

然后就可以写代码了

public abstract class BasePanel  {protected Transform tempTrans;//记录要打开窗口的位置//实例化窗口public void CreatWnd(string wndName,Transform canvas){//加载GameObject wnd = Resources.Load<GameObject>("Wnd/"+wndName);GameObject temp =GameObject.Instantiate(wnd);temp.transform.SetParent(canvas,false);//将该窗口的位置记录下来,以便打开和关闭tempTrans = temp.transform;}
}

重新打开和关闭面板如下

    //打开窗口public void OpenWnd(){tempTrans.gameObject.SetActive(true);}//关闭窗口public void CloseWnd() {tempTrans.gameObject.SetActive(false);}

 是不是非常简单!!!

面板子类

就是随便一个面板子类都可以继承基类,从而有基类的方法,这个我就不多说了

public class TestPanel:BasePanel
{//在这里可以写TestWnd自己的逻辑
}

面板管理类

因为面板基类的Creat方法要传入两个参数

所以我们就需,被实例化的面板的名字场景中Canvas的transform

public class PanelManager:MonoBehaviour
{public Transform canvesPos;public TestPanel testWnd;private void Start() {testWnd = new TestPanel();testWnd.CreatWnd("AnyWnd", canvesPos);}private void Update() {if(Input.GetKeyDown(KeyCode.W)){testWnd.OpenWnd();}if(Input.GetKeyDown(KeyCode.S)){testWnd.CloseWnd();}}
}

运行试一下效果

这样,我就让AnyWnd这个面板在没有挂载脚本的情况下

面板管理类可以控制所有面板

且,每一个子类对象都能控制其对应的实际面板

优化

面板基类

用作记录要打开窗口的位置的临时Transform

可以成一个属性,使得外部只能调用,不能修改

C# & Unity 面向对象补全计划 之 类class-CSDN博客

  protected Transform TempTrans { //记录要打开窗口的位置get;private set;}

先前的方法全部可以写成虚方法,另外添加一个抽象类Init方法,以便拓展子类的功能

C# & Unity 面向对象补全计划 之 初识继承方法与多态_unity 继承函数方法-CSDN博客

public abstract class BasePanel  {protected Transform TempTrans { //记录要打开窗口的位置get;private set;}//实例化窗口public virtual void CreatWnd(string wndName,Transform canvas){//加载GameObject wnd = Resources.Load<GameObject>("Wnd/"+wndName);GameObject temp =GameObject.Instantiate(wnd);temp.transform.SetParent(canvas,false);//将该窗口的位置记录下来,以便打开和关闭TempTrans = temp.transform;//首次实例化不要直接打开CloseWnd();}//打开窗口public virtual void OpenWnd(){TempTrans.gameObject.SetActive(true);}//关闭窗口public virtual void CloseWnd() {TempTrans.gameObject.SetActive(false);}public abstract void Init();
}

面板管理类

面板管理类写具体控制逻辑(比如input.getkeydown......)就不太正确

一般都是外部的什么东西去调用面板管理类封装好的方法,如下图

况且,面板管理类突出一个管理功能,那我就将其功能贯彻到底

0.设置成单例模式

private static PanelManager instance;
public static PanelManager Instance=>instance;
private void Awake() {if(instance == null) {instance = this;DontDestroyOnLoad(gameObject);}else{Destroy(gameObject);}
}

1.对其两个参数进行优化,使其自动得到Canvas和需要管理的子类

2.如果面板很多的情况下,可以添加一个字典进行管理

    private Transform canvesPos;//场景中的Canvas位置/// <summary>/// string =子类面板名/// BasePanel 里氏替换原则,所有继承了面板基类的子类面板都可以用父类容器装/// </summary>private Dictionary<string, BasePanel> panles;//存储所有面板子类的字典//单例private static PanelManager instance;public static PanelManager Instance=>instance;private void Awake() {if(instance == null) {instance = this;DontDestroyOnLoad(gameObject);}else{Destroy(gameObject);}//初始化字典panles = new Dictionary<string, BasePanel>();panels.Clear();canvesPos = GameObject.Find("Canvas").transform;//虽然有性能消耗但是只用一次所以可以接受
}

3.对面板基类进行再封装,让其他模块用到的时候直接调用

    /// <summary>/// 加载面板/// </summary>/// <typeparam name="T">需要加载的子类面板脚本</typeparam>/// <param name="panelName">需要加载的面板名称</param>public void LoadPanel<T>(string panelName) where T:BasePanel,new (){ T panel = new T();//实例化面板子类panels.Add(panelName, panel);panel.CreatWnd(panelName, canvesPos);panel.Init();//子类重写的抽象方法,用于执行自己的逻辑}public void OpenPanel(string panelName){ if (panels.TryGetValue(panelName, out BasePanel curPanel)){curPanel.OpenWnd(); }else            Debug.Log($"没有找到正确的面板****{panelName}****,请检查预制体路径或者查看是否有该预制体");}public void ClosePanel(string panelName) {if (panels.TryGetValue(panelName, out BasePanel panel)) {panel.CloseWnd(); }       else           Debug.Log($"没有找到正确的面板****{panelName}****,请检查预制体路径或者查看是否有该预制体");  }

好了,这就是全部内容了,关于所有代码和扩展性请看下一篇:扩展与总结篇

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/56850.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[含文档+PPT+源码等]精品基于springboot实现的原生微信小程序小区兼职系统

基于Spring Boot实现的原生微信小程序小区兼职系统背景&#xff0c;可以从以下几个方面进行阐述&#xff1a; 一、技术背景 移动互联网的普及&#xff1a;随着移动互联网的快速发展&#xff0c;微信小程序作为一种轻量级应用&#xff0c;因其无需下载安装、即用即走的特点&am…

基于STM32设计的智能婴儿床(华为云IOT)(244)

文章目录 一、前言1.1 项目介绍【1】开发背景【2】项目实现的功能【3】项目硬件模块组成【4】ESP8266工作模式配置1.2 设计思路【1】整体设计思路【2】整体构架【3】上位机开发思路1.3 项目开发背景【1】选题的意义【2】可行性分析【3】参考文献【4】摘要1.4 开发工具的选择【1…

SSD |(七)FTL详解(中)

文章目录 &#x1f4da;垃圾回收&#x1f407;垃圾回收原理&#x1f407;写放大&#x1f407;垃圾回收实现&#x1f407;垃圾回收时机 &#x1f4da;解除映射关系&#x1f4da;磨损均衡 &#x1f4da;垃圾回收 &#x1f407;垃圾回收原理 ✋设定一个迷你SSD空间&#xff1a; 假…

解决ImageIO无法读取部分JPEG格式图片问题

解决ImageIO无法读取部分JPEG格式图片问题 问题描述 我最近对在线聊天功能进行了一些内存优化&#xff0c;结果在回归测试时&#xff0c;突然发现有张图片总是发送失败。测试同事把问题转到我这儿来看&#xff0c;我仔细检查了一下&#xff0c;发现是上传文件的接口报错&#…

获取非加密邮件协议中的用户名和密码——安全风险演示

引言 在当今的数字时代,网络安全变得越来越重要。本文将演示如何通过抓包工具获取非加密邮件协议中的用户名和密码,以此说明使用非加密协议的潜在安全风险。通过这个演示,我们希望能提高读者的安全意识,促使大家采取更安全的通信方式。 注意: 本文仅用于教育目的,旨在提高安全…

每日一题学习笔记——移动零

给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 示例 1: 输入: nums [0,1,0,3,12] 输出: [1,3,12,0,0] 示例 2: 输入: nums [0] 输出…

Android开发蒙版引导操作功能

Android开发蒙版引导操作功能 复杂的功能&#xff0c;往往需要在上面加一层蒙版引导用户操作 一、思路&#xff1a; 堆积布局方式 二、效果图&#xff1a; 三、关键代码&#xff1a; <?xml version"1.0" encoding"utf-8"?> <FrameLayout x…

【大模型】AI视频课程制作工具开发

1. 需求信息 1.1 需求背景 讲师们在制作视频的过程中&#xff0c;发现录制课程比较麻烦&#xff0c;要保证环境安静&#xff0c;保证录制过程不出错&#xff0c;很容易反复重复录制&#xff0c;为了解决重复录制的工作量&#xff0c;想通过 ai 课程制作工具&#xff0c;来解决…

飞机大战告尾

参考 PPO算法逐行代码详解 链接 通过网盘分享的文件&#xff1a;PlaneWar 链接: https://pan.baidu.com/s/1cbLKTcBxL6Aem3WkyDtPzg?pwd1234 提取码: 1234 10.17关于博客发了又改这件事 悲催的事 今天训练了一早上ppo模型&#xff0c;满怀期待的检测成果时发现一点长进都…

【Linux】“echo $变量“ 命令打印变量值的底层原理

在 shell 中&#xff0c;echo $变量 命令的工作原理涉及几个关键步骤&#xff0c;主要是由 shell 解释器来处理变量的查找和替换。以下是详细的过程&#xff1a; 变量展开的过程顺序 变量引用&#xff1a; 在命令行中&#xff0c;变量通常以 $variable_name 或 ${variable_…

Rust与C++开发效率比较

Rust 和 C++ 都是高性能系统编程语言,但它们在开发效率上有所不同。以下是一些主要的区别: 1. 内存管理和安全性 Rust: 提供了内置的内存管理机制,通过所有权系统、借用检查器和生命周期规则避免了大多数内存安全问题。开发者在 Rust 中无需手动管理内存分配和释放,从而减…

Android 设置控件为圆形

Android的圆形控件 对于所有的View有效 在开发的过程中&#xff0c;肯定需要实现一个圆形的控件&#xff0c;而且不是绘制一个圆形&#xff0c;那么怎么弄呢&#xff0c;在Android5.0后&#xff0c;有一个类ViewOutlineProvider&#xff0c;可以实现这个功能&#xff0c;应该是…

机器学习-零基础学习机器学习-1019

1.安装pycharm专业版&#xff0c;安装python依赖&#xff0c;设置pip版本&#xff0c;设置国内镜像 打开cmd命令行&#xff0c;升级 pip 到最新的版本 (>10.0.0) 后进行配置&#xff1a; #更新pip源 python -m pip install --upgrade pip #换源 pip config set global.…

使用Shell脚本对Java应用等服务进行启停控制(支持批量)

通过shell脚本对Java服务启停进行控制。支持单个服务和多个服务的 start、stop、status、restart。支持自定义启动命令。(不限于Java服务,适用于各类通过命令行启动的服务) 脚本名称为 runjar.sh , 底部提供源码。通过三部分进行说明:操作说明、维护自定义服务列表、脚本源…

搭建`mongodb`副本集-开启权限认证 mongo:7.0.5

搭建mongodb副本集-开启权限认证 mongo:7.0.5 1.5.1、创建文件 创建配置文件保存目录和数据保存目录 mkdir -p /data/mongodb/{/conf,/data,/logs}生成和设置权限 这个文件一定要在一个服务里面生成然后复制到其它服务器&#xff0c;所有服务器的这个key一定是相同的。 op…

LeetCode383 赎金信 - Python中Counter在加减法和比较时的使用

在LeetCode上做了 383. 赎金信&#xff08;一道简单hash题&#xff09;之后&#xff0c;翻看官方题解时发现用了 Counter 类&#xff1a; class Solution:def canConstruct(self, ransomNote: str, magazine: str) -> bool:if len(ransomNote) > len(magazine):return F…

C语言 | Leetcode C语言题解之第480题滑动窗口中位数

题目&#xff1a; 题解&#xff1a; struct Heap {int* heap;int heapSize;int realSize;bool (*cmp)(int, int); };void init(struct Heap* obj, int n, bool (*cmp)(int, int)) {obj->heap malloc(sizeof(int) * (n 1));obj->heapSize 0;obj->cmp cmp; }bool c…

第二十二篇——菲欧几何:相对论的数学基础是什么?

目录 一、背景介绍二、思路&方案三、过程1.思维导图2.文章中经典的句子理解3.学习之后对于投资市场的理解4.通过这篇文章结合我知道的东西我能想到什么&#xff1f; 四、总结五、升华 一、背景介绍 对于几何的几个工具&#xff0c;让我再次感叹数学的伟大&#xff0c;逻辑…

国产大模型基础能力大比拼 - 计数:通义千文 vs 文心一言 vs 智谱 vs 讯飞-正经应用场景的 LLM 逻辑测试

在大语言模型&#xff08;LLM&#xff09;不断涌现的时代&#xff0c;如何评估这些国产大模型的逻辑推理能力&#xff0c;尤其是在处理基础计数问题上的表现&#xff0c;成为了一个备受关注的话题。随着越来越多的国产大模型进入市场&#xff0c;比较它们在不同任务中的表现尤为…

STM32笔记(1)GPIO之点亮LED

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 总结 第一步&#xff1a;先看原理图。PB0输出高电平是&#xff0c;LED1点亮。 初始化完成了两项工作&#xff1a; (1)从时钟上启动所用GPIO所在的总线&#xff1b…