缓存池

前言总结

缓存池是为了减少GC,没有缓存池的话频繁GC会造成卡顿。

基类

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

public class BaseManager<T> where T : new()
{
    
    

    private static T instance;


    public static T GetInstance()
    {
    
    
        if (instance == null)
        {
    
    
            instance = new T();
        }
        return instance;
    }

}

public class GameManager : BaseManager<GameManager>
{
    
    

}

#缓存池
用字典表示缓存池,List泛型增删不同预制体

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


/// <summary>
/// 缓存池模块
/// 1.字典、链表
/// 2.GameObject和Resource中的API
/// </summary>
public class PoolMgr : BaseManager<PoolMgr>
{
    
    
    //缓存池容器
    public Dictionary<string, List<GameObject>> poolDic = new Dictionary<string, List<GameObject>>();
    

    /// <summary>
    /// 往外拿东西
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public GameObject GetObj(string name)
    {
    
    
        GameObject obj = null;

        if (poolDic.ContainsKey(name) && poolDic[name].Count > 0)
        {
    
    
            obj = poolDic[name][0];
            poolDic[name].RemoveAt(0);
        }
        else
        {
    
    
            //没继承monobehaviour不能直接调Instantiate
            obj = GameObject.Instantiate(Resources.Load<GameObject>(name));
            //把对象名字改成池子名字
            obj.name = name;
        }
        //激活,让其显示
        obj.SetActive(true);
        return obj;

    } 

    /// <summary>
    /// 还暂时不用的东西
    /// </summary>
    public void PushObj(string name, GameObject obj)
    {
    
    
        //放进池子就隐藏
        obj.SetActive(false);
        if (poolDic.ContainsKey(name))
        {
    
    
            poolDic[name].Add(obj);
        }
        else
        {
    
    
            poolDic.Add(name, new List<GameObject>() {
    
     obj });
        }
    }

}

取(放摄像机)

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

public class Test : MonoBehaviour
{
    
    
    // Start is called before the first frame update
    void Start()
    {
    
    
        NewBehaviourScript.GetInstance().Test();
    }

    // Update is called once per frame
    void Update()
    {
    
    
        if (Input.GetMouseButtonDown(0))
        {
    
    
            PoolMgr.GetInstance().GetObj("Profab/Cube");
        }
        if (Input.GetMouseButtonDown(1))
        {
    
    
            PoolMgr.GetInstance().GetObj("Profab/Sphere");
        }
    }
}

放(给预制体)

注意预制体父级目录放Resource文件夹下

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

public class DelayPush : MonoBehaviour
{
    
    
    //对象激活时会使用的生命周期函数
    void OnEnable()
    {
    
    
        Invoke("Push", 1);
    }


    void Push()
    {
    
    
        PoolMgr.GetInstance().PushObj(this.gameObject.name, this.gameObject);
    }
}

测试结果

在这里插入图片描述

Guess you like

Origin blog.csdn.net/memory_MM_forever/article/details/113825833