【Unity程序小技巧】如何消除多次Destory带来的性能消耗

在这里插入图片描述


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

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

本文由 秩沅 原创

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



文章目录

    • 前言
    • (==1==) 使用简单的List显隐功能
    • (==2==) 升级——使用缓存池小框架


前言


1 使用简单的List显隐功能


1.先全部把资源资源存储到List中,并让其失活

【Unity程序小技巧】如何消除多次Destory带来的性能消耗_第1张图片

2.然后添加一个显隐方法,需要的时候显示,不需要的时候隐藏

【Unity程序小技巧】如何消除多次Destory带来的性能消耗_第2张图片


    /// 
    /// 动态加载左侧Item
    /// 
    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);
            });

        }
    }

    /// 
    /// 动态加载右侧Item
    /// 
    /// 
    /// 
    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列表中
        }
    }


   /// 
   /// 激活,(好处减少了Destory的性能消耗)
   /// 
   /// 
   /// 
    public void  ActiveTrue(int start, int end)
    {
        for (int i = start; i <= end; i++)
        {
            rightItemList[i - 1].SetActive(true);
        }
    }
   

2 升级——使用缓存池小框架


【Unity程序小技巧】如何消除多次Destory带来的性能消耗_第3张图片

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


// 抽屉数据  

public class PoolData
{

    public GameObject fatherObj;

    public List<GameObject> poolList;

    public PoolData(GameObject obj, GameObject poolObj)
    {
      
        fatherObj = new GameObject(obj.name);
        fatherObj.transform.parent = poolObj.transform;
        poolList = new List<GameObject>() {};
        PushObj(obj);
    }

    //存
    public void PushObj(GameObject obj)
    {
       
        obj.SetActive(false);
       
        poolList.Add(obj);
 
        obj.transform.parent = fatherObj.transform;
    }

    //取
    public GameObject GetObj()
    {
        GameObject obj = null;       
        obj = poolList[0];     //取第一个
        poolList.RemoveAt(0);  //然后容器中移除
       
        obj.SetActive(true);
  
        obj.transform.parent = null;     //断开了父子关系

        return obj;
    }
}

//缓存池管理器
public class PoolManager : SingleManager<PoolManager>
{
    //存储衣柜
    public Dictionary<string, PoolData> poolDic = new Dictionary<string, PoolData>();

    private GameObject poolObj;

    //衣柜里面拿东西
    public void GetObj(string name, UnityAction<GameObject> callBack)
    {
        //有抽屉 并且抽屉里有东西
        if (poolDic.ContainsKey(name) && poolDic[name].poolList.Count > 0)
        {
            callBack(poolDic[name].GetObj());
        }
        else
        {
            //通过异步加载资源 创建对象给外部用
            ResourceManager .GetInstance().LoadAsync<GameObject>(name, (obj2) =>
            {
                obj2.name = name;
                callBack(obj2); //异步加载出的资源不能直接给外部使用所以需要委托
            });
        }
    }

    //放东西进衣柜
    public void PushObj(string name, GameObject obj)
    {
        if (poolObj == null)  //防止报错
            poolObj = new GameObject("Pool");

        //里面有抽屉
        if (poolDic.ContainsKey(name))
        {
            poolDic[name].PushObj(obj);
        }
        else
        {
            poolDic.Add(name, new PoolData(obj, poolObj));
        }
    }


   //清空缓存池——在场景切换时
    public void Clear()
    {
        poolDic.Clear();
        poolObj = null;
    }
}



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

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

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

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

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

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

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


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


在这里插入图片描述


你可能感兴趣的:(#,unity实战基础,unity,游戏引擎)