复习一(对象池)

为什么使用对象池

当一个游戏需要频繁的创建和销毁对象时,为了不增加GC的性能消耗,可以考虑使用回收对象来打到复用的目的。(适用于飞机大战类,消除类,射击类,moba类等游戏)

什么是对象池

为了回收和复用对象,我们使用一个集合来存储不使用的对象,当需要使用该对象时,再从集合中取出,这样一个工具类称之为对象池。

对象池的实现

ObjectPool:对存储对象的集合进行了适当的封装,用于单个游戏对象(预制体)的回收和复用。
PoolManager:对ObjectPool单个游戏对象的进一步封装,可以用于创建多个对象(预制体)的回收和复用,可以更方便的使用对象池。(对象池模块化)
IPoolRelease:对象池回收对象时的还原接口,继承后对象自动还原初始值。

代码

using UnityEngine;
using System.Collections.Generic;

/// <summary>
/// 二十四种设计模式
/// 对象池
/// </summary>
public class ObjectPool//子弹对象池//可以不继承  MonoBehaviour
{
    public GameObject prefab;//预制体
    private Stack<GameObject> pool = new Stack<GameObject>();//开辟占

    public ObjectPool(GameObject _prefab)
    {
        prefab = _prefab;
    }
    //取对象
    public GameObject Get()
    {
        if (pool.Count > 0)//判断是否有对象
        {
            GameObject go = pool.Pop();
            go.SetActive(true);//取得时候激活对象
            return go;
        }
        else
        {
            GameObject go = GameObject.Instantiate(prefab);//如果没有则克隆一个对象
            return go;
        }
    }
    //回收存对象
    public void Save(GameObject go)
    {
        go.SetActive(false);//收回的时候不激活对象
        pool.Push(go);
    }
}

对象池管理器

using UnityEngine;
using System.Collections.Generic;

public class PoolManager : MonoBehaviour//对象池管理器脚本
{
    /// <summary>
    /// 二十四种设计模式
    /// 单例模式
    /// </summary>
    public static PoolManager _instance = null;//对象池该为静态,//私有的静态实例
    public static PoolManager Instance//共有的唯一的,全局访问点
    {
        get
        {
            if (_instance == null)
            {
                _instance = GameObject.FindObjectOfType<PoolManager>();
            }
            if (_instance == null)//如果为空的话
            {
                GameObject go = new GameObject("PoolManager");//创造一个对象池
                _instance = go.AddComponent<PoolManager>();
            }
            return _instance;
        }
    }
    public GameObject[] prePrefabs;
    void Awake()
    {
        if (_instance == null)
            _instance = this;
        else
            Destroy(gameObject);
        InitPool();
    }

    private Dictionary<string, ObjectPool> dic = new Dictionary<string, ObjectPool>();

    void InitPool()
    {
        //提前初始化的对象池
        foreach (var prefab in prePrefabs)
        {
            CreatPool(prefab.name, prefab);
        }
    }
    /// <summary>
    /// 创建对象池
    /// </summary>
    /// <param name="poolName">对象池名字</param>
    /// <param name="prefab">对象池对应的预制体</param>
    public void CreatPool(string poolName, GameObject prefab)
    {
        if (!dic.ContainsKey(poolName))
        {
            dic[poolName] = new ObjectPool(prefab);
        }
    }
    /// <summary>
    /// 获取对象池对象
    /// </summary>
    /// <param name="poolName">对象池名字</param>
    /// <returns></returns>
    public GameObject Get(string poolName)//取对象
    {
        ObjectPool pool;
        if (dic.TryGetValue(poolName, out pool))//如果对象池中有的话
        {
            return pool.Get();//取这个对象
        }
        else
        {
            Debug.LogError("对象池:" + poolName + "不存在!!!");
            return null;
        }
    }
    /// <summary>
    /// 回收对象
    /// </summary>
    /// <param name="poolName">对象池的名字</param>
    /// <param name="go">对象</param>
    public void Save(string poolName, GameObject go)
    {
        ObjectPool pool;
        if (dic.TryGetValue(poolName, out pool))//如果对象池中有的话
        {
            pool.Save(go);
        }
        else
        {
            Debug.Log("对象池:" + poolName + "不存在!!!");
        }
    }
}


猜你喜欢

转载自blog.csdn.net/qq_41996509/article/details/80823994
今日推荐