当前位置: 首页 > 工具软件 > Go2d > 使用案例 >

U3D性能优化之对象池思路(Object Pooling)

吉嘉珍
2023-12-01

对象池(Object Pooling)对性能优化的原理很简单:对象的频繁创建和销毁非常消耗性能,我们应当避免这种操作,所以可以将这些对象存到一个池子里,用的时候拿出来(SetActive(true)),不用的时候放回去(SetActive(false)),最后在合适的时机把这个对象池清空

下面代码是一个通用的对象池管理器(ObjectPoolManager),简单提供了一个思路,其中还有很多可优化可扩展的就不一一赘述了

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

public class ObjectPoolManager
{
    private static ObjectPoolManager Instance;
    private ObjectPoolManager() { }
    public static ObjectPoolManager getInstance()
    {
        if(Instance == null)
        {
            Instance = new ObjectPoolManager();
        }
        return Instance;
    }

    private Dictionary<string, List<GameObject>> objPoolDic = new Dictionary<string, List<GameObject>>();
    public void AddObject(string type,GameObject obj)
    {
        if (!objPoolDic.ContainsKey(type))
        {
            List<GameObject> objList = new List<GameObject>();
            objPoolDic.Add(type, objList);
        }
        obj.SetActive(false);
        objPoolDic[type].Add(obj);
    }

    public GameObject GetObject(string type)
    {
        if (!objPoolDic.ContainsKey(type))
        {
            Debug.Log(string.Format("没有{0}类型的池子", type));
            return null;
        }
        for (int i = 0; i < objPoolDic[type].Count; i++)
        {
            if (!objPoolDic[type][i].activeInHierarchy)
            {
                objPoolDic[type][i].SetActive(true);
                return objPoolDic[type][i];
            }
        }
        Debug.Log(string.Format("{0}类型的池子大小不够用,当前大小为{1}", type, objPoolDic[type].Count));
        return null;
    }

    public void ClearPool(string type)
    {
        if (!objPoolDic.ContainsKey(type))
        {
            Debug.Log(string.Format("没有{0}类型的池子", type));
            return;
        }
        objPoolDic[type].Clear();
    }
}

下面是调用对象池的测试脚本(Test)

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

public class Test : MonoBehaviour
{
    public GameObject obj1;
    public GameObject obj2;
    ObjectPoolManager objectPoolManager = ObjectPoolManager.getInstance();
    // Start is called before the first frame update
    void Start()
    {
        for (int i = 0; i < 5; i++)
        {
            GameObject gameObject = Instantiate(obj1);
            objectPoolManager.AddObject("partycle", gameObject);
        }
        for (int i = 0; i < 3; i++)
        {
            GameObject gameObject = Instantiate(obj2);
            objectPoolManager.AddObject("Cube", gameObject);
        }
        GameObject go1 = objectPoolManager.GetObject("partycle");
        go1.name = "GetObject_partycle";
        for (int i = 0; i < 2; i++)
        {
            GameObject go2 = objectPoolManager.GetObject("Cube");
            go2.name = "GetObject_Cube";
        }
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

可直接使用的代码可点击下方链接https://blog.csdn.net/Victor_Li_/article/details/122805760?spm=1001.2014.3001.5502

 类似资料: