我是写不出来,但是我看了他们的我就能写出来了。
相信你看了也肯定知道你自己的框架怎么搭建出来。
Unity3D内存管理——对象池(Object Pool)
Object Pooling in Unity
Unity3d中对象池(ObjectPool)的实现
我觉得有些对象可以自动回收,有些常驻的需要手动。
下面是我看了他们的文章写出来的对象池,在我自购的框架中。
using System.Collections.Generic;
using System;
using UnityEngine;
namespace Pool
{
/// <summary>
/// 属于场景
/// 不同的场景共享不同的对象集合
/// 我的对象池使用标签来进行管理,注意要让标签和对象资源的名称相同
/// </summary>
public class PoolManager:MonoBehaviour
{
//共享单例
public static PoolManager SharedInstance;
//检测自动释放时间
private int AutoReleaseTime = 10;
private List<ObjectPool> m_PoolList = new List<ObjectPool>();
private List<IPoolableObject> m_HideObjs = new List<IPoolableObject>();
private void Awake()
{
SharedInstance = this;
}
private void Start()
{
//对象池初始化
for (int i = 0; i < m_PoolList.Count; i++)
{
for (int j = 0; j < m_PoolList[i].InitialBufferSize; j++)
{
IPoolableObject o = New(m_PoolList[i].ResName);
RecycleObject(o);
}
}
//开启自动回收
InvokeRepeating("AutoRelease", AutoReleaseTime, AutoReleaseTime);
}
/// <summary>
/// 处理对象资源的隐藏时间
/// </summary>
private void Update()
{
for (int i = 0; i < m_HideObjs.Count; i++)
{
m_HideObjs[i].HideTime += Time.deltaTime;
}
}
/// <summary>
/// New新物体
/// </summary>
/// <param name="tag">物体的Tag=物体资源名称</param>
/// <returns></returns>
public IPoolableObject New(string tag)
{
//如果池子里面存在需要的对象
for (int i = 0; i < m_PoolList.Count; i++)
{
if(m_PoolList[i].ResName==tag)
{
if(m_PoolList[i].NextAvailableIndex<m_PoolList.Count)
{
IPoolableObject o = m_PoolList[i].PoolObjects[m_PoolList[i].NextAvailableIndex++];
return o;
}
else
{
//新增物体
if (m_PoolList[i].ShouldExpand)
{
for (int j = 0; j < m_PoolList[i].ExpandSize; j++)
{
GameObject obj = (GameObject)Instantiate(GameManager.Instance.LoadObject<GameObject>(m_PoolList[i].ResName));
obj.SetActive(false);
IPoolableObject o = obj.GetComponent<IPoolableObject>();
m_PoolList[i].PoolObjects.Add(o);
}
//补全占满
m_PoolList[i].NextAvailableIndex++;
return m_PoolList[i].PoolObjects[m_PoolList[i].NextAvailableIndex-1];
}
else
{
Debug.LogError(tag + "对象池已经占满,而且不允许拓展!");
return null;
}
}
}
}
Debug.LogError(tag + "的物体在该场景中不由对象池进行管理!");
return null;
}
/// <summary>
/// 回收一个物体
/// </summary>
/// <param name="o">物体</param>
public void RecycleObject(IPoolableObject o)
{
//更新活动指针
for (int i = 0; i < m_PoolList.Count; i++)
{
if(m_PoolList[i].ResName==o.tag)
{
m_PoolList[i].PoolObjects.Remove(o);
m_PoolList[i].PoolObjects.Add(o);
}
}
o.gameObject.SetActive(false);
m_HideObjs.Add(o);
}
/// <summary>
/// 卸载释放一个对象(从对象池中)
/// </summary>
/// <param name="o">对象</param>
private void ReleaseObject(IPoolableObject o)
{
//总池删除
for (int i = 0; i < m_PoolList.Count; i++)
{
if(m_PoolList[i].ResName==o.tag)
{
m_PoolList[i].PoolObjects.Remove(o);
}
}
//隐藏池删除
if (m_HideObjs.Contains(o))
m_HideObjs.Remove(o);
Destroy(o.gameObject);
}
/// <summary>
/// 全部卸载
/// </summary>
public void ReleaseAll()
{
//取消回调
CancelInvoke();
//内存释放
m_HideObjs.Clear();
m_PoolList.Clear();
//单例释放
SharedInstance = null;
}
/// <summary>
/// 自动回收
/// </summary>
private void AutoRelease()
{
for (int i = 0; i < m_PoolList.Count; i++)
{
for (int j = 0; j < m_PoolList[i].PoolObjects.Count; j++)
{
if(m_PoolList[i].IsAutoRecycle)
{
if(m_PoolList[i].PoolObjects[j].HideTime>m_PoolList[i].MaxHideTime)
{
ReleaseObject(m_PoolList[i].PoolObjects[j]);
}
}
}
}
}
}
}
using UnityEngine;
using System.Collections.Generic;
namespace Pool
{
/// <summary>
/// 需要经由对象池加载的Prefab
/// </summary>
[System.Serializable]
public class ObjectPool
{
//初始化最大数量
public int InitialBufferSize;
//预制体资源的名称,由AB包进行一个加载
public string ResName;
//是否允许扩展
public bool ShouldExpand;
//每次扩展个数
public int ExpandSize;
//下一个可用GO的索引
public int NextAvailableIndex = 0;
//池内资源是否自动释放
public bool IsAutoRecycle = true;
//这种资源的最大隐藏时间
public int MaxHideTime;
[System.NonSerialized]
//对象集合
public List<IPoolableObject> PoolObjects;
}
}
using UnityEngine;
namespace Pool
{
public abstract class IPoolableObject : MonoBehaviour
{
//隐藏时间超过就自动释放
public float HideTime;
}
}