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


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

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

👨‍💻 本文由 秩沅 原创

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

🅰️




前言


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


  • 当登录成功后,将玩家信息类通过,UI管理器中的显示加载方法中的委托函数,进行,加载面板后的逻辑处理(在里面执行传递玩家数据的操作),当然前提是进行传达的面板中里面都要有一个玩家信息类
    【Unity之UI编程】编写一个面板交互界面需要注意的细节-LMLPHP
  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面板不是单例模式,只有管理器才是单例模式,所以现在想了一个办法就是:
    将当前登录的玩家信息 作为一个全局性的玩家信息,保存在一个单例模式类里面,这样就不会导致数据丢失,也方便到时,选服之后进行数据更新时方便调用,优化了全局

  • 实践


🎶() 如何优化频繁的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 ]; //记录上一次显示的数据
        }
    }

}


🎶()公共Updata的优化


  • 以前当把事件传到Updata生命函数中每帧运行时,时用委托传递的,此时想要删除它,特别不方便,需要在原函数里面重新声明一个委托,
  • 那么此时我用字典以键值的方式来存储它,移除 的时候只要用名字字符串即可
    【Unity之UI编程】编写一个面板交互界面需要注意的细节-LMLPHP
    【Unity之UI编程】编写一个面板交互界面需要注意的细节-LMLPHP

    /// <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("未添加过该事件!!");
        }
    }
}


🎶() 全局脑图


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

🅰️


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

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

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

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

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

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

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


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


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


11-12 10:14