【Unity之UI编程】编写一个面板交互界面需要注意的细节

news2025/3/12 1:20:40

在这里插入图片描述


👨‍💻个人主页:@元宇宙-秩沅

👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅!

👨‍💻 本文由 秩沅 原创

👨‍💻 收录于专栏:Unity基础实战

🅰️



文章目录

    • 🅰️
    • 前言
    • 🎶(==1==) 面板传递个人数据的优化
    • 🎶(==2==) 如何优化频繁的Destroy()
    • 🎶(==3==)公共Updata的优化
    • 🎶(==4==) 全局脑图
    • 🅰️


前言


🎶(1 面板传递个人数据的优化


  • 当登录成功后,将玩家信息类通过,UI管理器中的显示加载方法中的委托函数,进行,加载面板后的逻辑处理(在里面执行传递玩家数据的操作),当然前提是进行传达的面板中里面都要有一个玩家信息类
    在这里插入图片描述
  palyerData = DataContorl.GetInstance().ReadData(userName);
              
                        //验证成功
                        if (DataContorl.GetInstance().Tip(userName, password))
                        {

                            UIContorl.GetInstance().ChangeTipPanel("登录成功"); //显示提示面板
                            UIManager.GetInstance().ShowPanel<SelectPanel>("SelectPanel", E_UI_Layer.Mid, (panel) =>
                            {
                                panel.playerInfo = palyerData;
                            });  //显示选服面板 

                            UIManager.GetInstance().RemovePanel("LoginPanel");//移除登录面板


                        //记录临时数据
                        LoginData.GetInstance().userName  = InputAC.text;
                        LoginData.GetInstance().password  = InputPW.text;
  • 后来一想,这个想法也不优化,因为涉及到如果每个面板为方便传递一个玩家的信息数据而每一个都去声明一个玩家信息类成员参数的话,那当面板移除之后,那个数据也会跟着消失,因为,现在的框架UI面板不是单例模式,只有管理器才是单例模式,所以现在想了一个办法就是:
    将当前登录的玩家信息 作为一个全局性的玩家信息,保存在一个单例模式类里面,这样就不会导致数据丢失,也方便到时,选服之后进行数据更新时方便调用,优化了全局

  • 实践

刚注册完数据
在这里插入图片描述


🎶(2 如何优化频繁的Destroy()


  • 此时采用了,List列表的方式进行显隐处理(或者也可以采用它的升级版本缓存池模块)


    /// <summary>
    /// 动态加载左侧Item
    /// </summary>
    public void AotuLoadLeftItem()
    {
        int num = ServerLists.Count / 5 + 1; //分成多少个区服集按钮Item
        for (int i = 1; i <= num; i++)
        {
            //加载预制体
            GameObject leftItem = Instantiate(Resources.Load<GameObject>("UI/UIItem/leftItem1"));

            leftItem.transform.SetParent(LeftServe.content); //固定其父对象

            LeftItemData serverData = leftItem.GetComponent<LeftItemData>();

            //设置每个Item显示的区间范围
            int star, end;
            star  = (i-1) * 5 + 1;
            end = i  * 5;          
            if (i * 5 >= ServerLists.Count )
            {
                end = ServerLists.Count;
            }         
            serverData.ChangeTextShow(star, end );  //更新显示的区间范围文本

            Button leftItemButton = leftItem.GetComponent<Button>(); //给按钮添加监听,点击后更新右边的区服

            //  AotuLoadRightItem(star, end);  //更新对应的区间服务器集
            AotuLoadRightItem(star, end);
            //按下才可以激活
            leftItemButton.onClick.AddListener(() =>
            {
        
                ActiveTrue(star, end);
            });

        }
    }

    /// <summary>
    /// 动态加载右侧Item
    /// </summary>
    /// <param name="start"></param>
    /// <param name="end"></param>
    public void AotuLoadRightItem(int start ,int end)
    {
        for (int i = start; i <= end; i++)
        {

            GameObject rightItem = Instantiate(Resources.Load<GameObject>("UI/UIItem/ChooseItem1"));          
            rightItem.transform.SetParent(RightServe.content,false); //固定其父对象
           // rightItem.transform.localScale = Vector3.one;
            ChooseItemData serverData = rightItem.GetComponent<ChooseItemData>();

            serverData.UpdataItemInfo(ServerLists[i-1]); //更新服务器数据

            serverData.gameObject.SetActive(false);//先全部失活

            rightItemList.Add(rightItem);//然后存储到List列表中
        }
    }


    /// <summary>
    /// 激活,(好处减少了Destory的性能消耗)
    /// </summary>
    /// <param name="start"></param>
    /// <param name="end"></param>
    public void ActiveTrue(int start, int end)
    {
        textRange.text = "服务器" + start + "-" + end; //更新显示的范围文本
        for (int i = 0; i < 5; i++)
        {
            if (temparyList[ i ]!= null)
            {
                temparyList[ i ].SetActive(false);
            }
        }

        for (int i = start, j = 0; i <= end; i++,j++)
        {

            rightItemList[i - 1].SetActive(true);  //激活
            temparyList[ j ] = rightItemList[ i - 1 ]; //记录上一次显示的数据
        }
    }

}


🎶(3公共Updata的优化


  • 以前当把事件传到Updata生命函数中每帧运行时,时用委托传递的,此时想要删除它,特别不方便,需要在原函数里面重新声明一个委托,
  • 那么此时我用字典以键值的方式来存储它,移除 的时候只要用名字字符串即可
    在这里插入图片描述
    在这里插入图片描述

    /// <summary>
    /// 提供给外部 用于移除帧更新事件函数
    /// </summary>
    /// <param name="fun"></param>
    public void RemoveUpdateListener(string name)
    {
        controller.RemoveUpdateListener(name);
    }

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

/// <summary>
/// Mono的管理者
/// 1.声明周期函数
/// 2.事件 
/// 3.协程
/// </summary>
public class MonoController : MonoBehaviour {

 
    private Dictionary<string, UnityAction> eventDic = new Dictionary<string, UnityAction>();

    // Use this for initialization
    void Start () {
        DontDestroyOnLoad(this.gameObject);
	}
	
	// Update is called once per frame
	void Update () {
        foreach( UnityAction monoEvent in eventDic.Values )
        {
            if (monoEvent != null)
                monoEvent();
        }
       
    }

    /// <summary>
    /// 给外部提供的 添加帧更新事件的函数
    /// </summary>
    /// <param name="fun"></param>
    public void AddUpdateListener(string name ,UnityAction fun)
    {
        if(eventDic.ContainsKey(name))
        {
            eventDic[name] += fun;
        }
        else
        {
            if(fun != null )
            eventDic.Add(name, fun);
        }
       // updateEvent += fun;
    }

    /// <summary>
    /// 提供给外部 用于移除帧更新事件函数
    /// </summary>
    /// <param name="fun"></param>
    public void RemoveUpdateListener(string name)
    {

        if (eventDic.ContainsKey(name))
        {
            eventDic.Remove(name);
        }
        else
        {
            Debug.Log("未添加过该事件!!");
        }
    }
}


🎶(4 全局脑图


在这里插入图片描述
在这里插入图片描述

🅰️


⭐【Unityc#专题篇】之c#进阶篇】

⭐【Unityc#专题篇】之c#核心篇】

⭐【Unityc#专题篇】之c#基础篇】

⭐【Unity-c#专题篇】之c#入门篇】

【Unityc#专题篇】—进阶章题单实践练习

⭐【Unityc#专题篇】—基础章题单实践练习

【Unityc#专题篇】—核心章题单实践练习


你们的点赞👍 收藏⭐ 留言📝 关注✅是我持续创作,输出优质内容的最大动力!


在这里插入图片描述


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

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

相关文章

SpringBoot 缓存之 @Cacheable 详细介绍

一、简介 1、缓存介绍 Spring 从 3.1 开始就引入了对 Cache 的支持。定义了 org.springframework.cache.Cache 和 org.springframework.cache.CacheManager 接口来统一不同的缓存技术。并支持使用 JCache&#xff08;JSR-107&#xff09;注解简化我们的开发。&#xfeff; 其…

【Linux网络】系统调优之聚合链路bonding,可以实现高可用和负载均衡

一、什么是多网卡绑定 二、聚合链路的工作模式 三、实操创建bonding设备&#xff08;mode1&#xff09; 1、实验 2、配置文件解读 3、查看bonding状态,验证bonding的高可用效果 三、nmcli实现bonding 一、什么是多网卡绑定 将多块网卡绑定同一IP地址对外提供服务&#xf…

MATLAB 全景图切割及盒图显示的实现步骤

参考&#xff1a;MATLAB 全景图切割及盒图显示的实现步骤 | w3cschool笔记 在摄像领域中全景图是一种可以将周围360度景象全部收录的一种拍照技术&#xff0c;但全景图的实际观感并不是那么好&#xff08;可以看下文的全景图的样例&#xff09;。我们可以通过matlab来进行全景…

通信信道:无线信道中衰落的类型和分类

通信信道&#xff1a;无线信道中衰落的类型和分类 在进行通信系统仿真时&#xff0c;简单的情况下选择AWGN信道&#xff0c;但是AWGN信道和真是通信中的信道相差甚远&#xff0c;所以需要仿真各种其他类型的信道&#xff0c;为了更清楚理解仿真信道的特点&#xff0c;首先回顾…

vue 项目配置跨越

要在vue开发中实现跨域需要先进入到vue项目根目录&#xff0c;找到vue.config.js文件&#xff0c;然后在proxy中设置跨域&#xff1a; devServer: { proxy: { /api: { target: http://47.93.220.246:8300, changeOrigin: true, pathRewrite: { ^/api: , }, }, }, }, 在vue中使用…

Python之文件与文件夹操作及 pytest 测试习题

目录 1、文本文件读写基础。编写程序&#xff0c;在 当前目录下创建一个文本文件 test.txt&#xff0c;并向其中写入字符串 hello world。2、编写一个程序 demo.py&#xff0c;要求运行该程序后&#xff0c;生成 demo_new.py 文件&#xff0c;其中内容与demo.py 一样&#xff0…

2023年05月 Python(四级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 下列程序段的运行结果是?( ) def s(n):if n==0:return 1else:

云栖大会丨桑文锋:打造云原生数字化客户经营引擎

近日&#xff0c;2023 云栖大会在杭州举办。今年云栖大会回归了 2015 的主题&#xff1a;「计算&#xff0c;为了无法计算的价值」。神策数据创始人 & CEO 桑文锋受邀出席「生态产品与伙伴赋能」技术主题&#xff0c;并以「打造云原生数字化客户经营引擎」为主题进行演讲。…

安全通信网络(设备和技术注解)

网络安全等级保护相关标准参考《GB/T 22239-2019 网络安全等级保护基本要求》和《GB/T 28448-2019 网络安全等级保护测评要求》 密码应用安全性相关标准参考《GB/T 39786-2021 信息系统密码应用基本要求》和《GM/T 0115-2021 信息系统密码应用测评要求》 1网络架构 1.1保证网络…

[量化投资-学习笔记011]Python+TDengine从零开始搭建量化分析平台-MACD金死叉策略回测

在上一章节 MACD金死叉中结束了如何根据 MACD 金死叉计算交易信号。 目录 脚本说明文档&#xff08;DevChat 生成&#xff09;MACD 分析脚本安装依赖库参数配置查询与解析数据计算 MACD 指标判断金叉和死叉计算收益绘制图形运行脚本 本次将根据交易信号&#xff0c;模拟交易。更…

SQL SELECT INTO 语句

SQL SELECT INTO 语句 使用 SQL&#xff0c;您可以将信息从一个表中复制到另一个表中。 SELECT INTO 语句从一个表中复制数据&#xff0c;然后将数据插入到另一个新表中。 SQL SELECT INTO 语法 我们可以把所有的列都复制到新表中&#xff1a; SELECT * INTO newtable [IN ex…

CIFAR-100数据集的加载和预处理教程

一、CIFAR-100数据集介绍 CIFAR-100&#xff08;Canadian Institute for Advanced Research - 100 classes&#xff09;是一个经典的图像分类数据集&#xff0c;用于计算机视觉领域的研究和算法测试。它是CIFAR-10数据集的扩展版本&#xff0c;包含了更多的类别&#xff0c;用…

Semantic Kernel 学习笔记1

1. 挂代理跑通openai API 2. 无需魔法跑通Azure API 下载Semantic Kernel的github代码包到本地&#xff0c;主要用于方便学习python->notebooks文件夹中的内容。 1. Openai API&#xff1a;根据上述文件夹中的.env.example示例创建.env文件&#xff0c;需要填写下方两个内…

51单片机应用从零开始(一)

1. 单片机在哪里 单片机是一种集成电路芯片&#xff0c;通常被嵌入到电子设备中用于控制和处理数据&#xff0c;例如家电、汽车、电子玩具、智能家居等。因此&#xff0c;你可以在许多电子设备中找到单片机的存在。单片机通常被放置在设备的主板或控制板上。 2. 单片机是什么…

【C语言】冒泡排序(图解)

&#x1f308;write in front :&#x1f50d;个人主页 &#xff1a; 啊森要自信的主页 &#x1f308;作者寄语 &#x1f308;&#xff1a; 小菜鸟的力量不在于它的体型&#xff0c;而在于它内心的勇气和无限的潜能&#xff0c;只要你有决心&#xff0c;就没有什么事情是不可能的…

WebRTC简介及使用

文章目录 前言一、WebRTC 简介1、webrtc 是什么2、webrtc 可以做什么3、数据传输需要些什么4、SDP 协议5、STUN6、TURN7、ICE 二、WebRTC 整体框架三、WebRTC 功能模块1、视频相关①、视频采集---video_capture②、视频编解码---video_coding③、视频加密---video_engine_encry…

AI:83-基于深度学习的手势识别与实时控制

🚀 本文选自专栏:人工智能领域200例教程专栏 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带有在本地跑过的代码,详细讲解供大家学习,希望可以帮到大家。欢迎订阅支持,正在不断更新中,…

ArcGIS:如何迭代Shp文件所有要素并分别导出为Shp文件?

01 前言 尝试用IDL实现&#xff0c;奈何又涉及新的类IDLffShape&#xff0c;觉得实在没有必要学习的必要&#xff0c;毕竟不是搞开发&#xff0c;只是做做数据处理&#xff0c;没必要拿IDL不擅长的且底层的东西自己造轮子。 这里想到使用Python去解决&#xff0c;gdal太久没用…

安装包 amd,amd64, arm,arm64 都有什么区别

现在的安装包也不省心&#xff0c;有各种版本都不知道怎么选。 根据你安装的环境配置。 amd&#xff1a; 32位X86 amd64&#xff1a; 64位X86 arm&#xff1a; 32位ARM arm64&#xff1a; 64位ARM amd64是X86架构的CPU&#xff0c;64位版。amd64又叫X86_64。主流的桌面PC&am…

25期代码随想录算法训练营第十四天 | 二叉树 | 递归遍历、迭代遍历

目录 递归遍历前序遍历中序遍历后序遍历 迭代遍历前序遍历中序遍历后序遍历 递归遍历 前序遍历 # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, leftNone, rightNone): # self.val val # self.left left # …