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

server/2024/10/19 5:21:22/

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.ppmy.cn/server/132955.html

相关文章

CSP-S模拟5复盘

T1 题目描述 小 S 在和小 W 玩游戏&#xff01; 小 S 有一个 n 阶排列 p1,p2,⋯,pn。小 S 和小 W 轮流操作&#xff0c;小 S 先手。每次操作时&#xff0c;玩家可以以任意顺序重排 p1,p2,⋯,pp1。如果一个玩家操作时发现 p1 和自己之前某次操作时的 p1 相同&#xff0c;那么…

Error: testWhileIdle is true, validationQuery not set

说明 连接数据库&#xff0c;启动的时候报错&#xff1a;testWhileIdle is true, validationQuery not set。但是不影响系统使用&#xff0c;数据库等一切访问正常。 原因 空闲的时候需要进行检测&#xff0c;但是检测的查询语句没有设置。大致意思就是说&#xff0c;当数据…

Windows 10 安装配置WSL2

一、开启HyperV 1.打开控制面板&#xff1a; 在 Windows 搜索栏中输入“控制面板”&#xff0c;然后打开它。 2.程序和功能&#xff1a; 点击“程序”&#xff0c;然后选择“启用或关闭 Windows 功能”。 3.启用 Hyper-V&#xff1a; 在弹出…

软件定义汽车时代,当前智能汽车软件开发模式是什么?

软件定义汽车&#xff0c;EE架构从分布式向中央计算演进。当前智能汽车控制器正在从智驾域、座舱域、车身域、动力域和底盘域等五域于一体的网关时代向可能仅剩下前区、后区控制器的中央计算时代演进。 智舱一体、行泊一体大融合情况下&#xff0c;智能汽车的开发模式是什么&a…

bml上部署yolov8

第一步 #第二步 在这里插入代码片git clone https://github.com/ultralytics/ultralytics.git一定要创建一个storage来专门存放yolov8&#xff0c;放在其他路径容易出错。 如果下载之后storage路径里面没有ultralytics&#xff0c;那是没有下载成功&#xff0c;多下载几次就行…

第一百零七周周报

学习时间&#xff1a; 2024.10.12-2024.10.18 学习产出&#xff1a; 这周大部分时间都在黄山开会&#xff0c;目前cifar10还没调好&#xff0c;celebA128的fid到了13点多&#xff0c;还没有跑完&#xff0c;其他时间都在找工作。

OpenStack服务Swift重启失效(已解决)

案例分析Swift重启失效 1. 报错详情 在重新启动 VMware 虚拟机后&#xff0c;我们发现 OpenStack 的 Swift 服务出现了 503 Service Unavailable 错误。经过排查&#xff0c;问题根源在于 Swift 服务所使用的存储挂载是临时挂载&#xff0c;而非永久挂载。 Swift 服务依赖于…

【在Linux世界中追寻伟大的One Piece】应用层自定义协议|序列化

目录 1 -> 应用层 2 -> 网络版计算器 3 -> 序列化与反序列化 4 -> 重新理解read、write、recv、send和tcp为什么支持全双工 5 -> 开始实现 5.1 -> 定制协议 5.2 -> 关于流式数据的处理 1 -> 应用层 应用层是OSI模型或TCP/IP模型中的最高层&…