找投资项目的网站,长沙网站推广排名,成都网站seo公司,石家庄网站建设求职简历一个通用的UGUI小框架就算是写完了#xff0c;下面是一步步的思考与优化过程 Unity 从零开始搭建一套简单易用的UGUI小框架 基础分析篇-CSDN博客 Unity 从零开始搭建一套简单易用的UGUI小框架 功能撰写与优化篇-CSDN博客 从使用者的角度来整理一下可能会发出的疑问
0. Panel… 一个通用的UGUI小框架就算是写完了下面是一步步的思考与优化过程 Unity 从零开始搭建一套简单易用的UGUI小框架 基础分析篇-CSDN博客 Unity 从零开始搭建一套简单易用的UGUI小框架 功能撰写与优化篇-CSDN博客 从使用者的角度来整理一下可能会发出的疑问
0. PanelManager.Instance.LoadPanelTestPanel(AnyWnd)
其中TestPanel和AnyWnd都代表了什么 AnyWnd面板预制体 TestPanel面板预制体的脚本 我特意将二者分开就是让你理清思路知道加载的是什么东西 其实二者可以合二为一只需要让脚本名和预制体名一致再修改LoadPanel中传入的名字即可 1.面板管理类的单例是如何创建的面板 是通过对面板基类的封装直接F12一步一步地向上阅读即可明白 2.为什么首次调用要清空面板字典可不可以不清除 防止重复添加确保数据一致避免内存泄漏 可以不清除关键是要确保字典中的数据始终是有效且一致 3.是不是还可以继续优化 是的比如采用异步加载的方式 比如通过代码设置面板的层级 比如在面板子类中对UI的显示隐藏的动画修改 因为我将面板基类写成了虚函数所以你可以对其在子类中修改加载打开和关闭 甚至直接修改面板基类也没什么不可能的 面板管理类 using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UIElements;public class PanelManager:MonoBehaviour
{private Transform canvasPos;//场景中的Canvas位置/// summary/// string 子类面板名/// BasePanel 里氏替换原则所有继承了面板基类的子类面板都可以用父类容器装/// /summaryprivate Dictionarystring, BasePanel panels;//存储所有面板子类的字典//单例private static PanelManager instance;public static PanelManager Instance instance;private void Awake() {if(instance null) {instance this;DontDestroyOnLoad(gameObject);}else{Destroy(gameObject);}//初始化字典panels new Dictionarystring, BasePanel();panels.Clear();canvasPos GameObject.Find(Canvas).transform;//虽然有性能消耗但是只用一次所以可以接受
}/// summary/// 加载面板/// /summary/// typeparam nameT需要加载的子类面板脚本/typeparam/// param namepanelName需要加载的面板名称/parampublic void LoadPanelT(string panelName) where T:BasePanel,new (){ T panel new T();//实例化面板子类 if(canvasPos!null)panel.CreatWnd(panelName, canvasPos);elseDebug.Log(没有找到Canvas);panels.Add(panelName, panel);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}****请检查预制体路径或者查看是否有该预制体); }
}面板基类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public abstract class BasePanel {protected Transform TempTrans { //记录要打开窗口的位置get;private set;}//实例化窗口public virtual void CreatWnd(string wndName,Transform canvas){//加载GameObject wnd Resources.LoadGameObject(Wnd/wndName);if( wnd!null){GameObject temp GameObject.Instantiate(wnd); temp.transform.SetParent(canvas,false);//将该窗口的位置记录下来以便打开和关闭TempTrans temp.transform;CloseWnd(); //首次实例化不要直接打开} else{Debug.Log(没有正确加载到面板);}}//打开窗口public virtual void OpenWnd(){TempTrans.gameObject.SetActive(true);}//关闭窗口public virtual void CloseWnd() {TempTrans.gameObject.SetActive(false);}public abstract void Init();
}面板子类示例
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class TestPanel : BasePanel {//在这里可以写TestWnd自己的逻辑public override void Init() {Debug.Log(子类可以在此进行自己的逻辑撰写);}
}使用示例
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Ctrl : MonoBehaviour
{// Start is called before the first frame updatevoid Start(){PanelManager.Instance.LoadPanelTestPanel(AnyWnd);}// Update is called once per framevoid Update(){if(Input.GetKeyDown(KeyCode.O)){PanelManager.Instance.OpenPanel(AnyWnd);}if (Input.GetKeyDown(KeyCode.P)) {PanelManager.Instance.ClosePanel(AnyWnd);}}
}