对象池(Object Pooling)技术是一种用于优化游戏性能和内存管理的技术。
对象池可以用于各种需要频繁实例化和销毁游戏对象的场景,例如子弹、敌人、玩家等。其主要目标是减少频繁的内存分配和垃圾回收的次数,提高游戏的运行效率,从而提高性能和降低延迟。
在对象池中查找池中隐藏的游戏对象,将其显示出来,以避免一直实例化新的游戏对象,导致游戏性能受到影响。
一般地,游戏会需要频繁实例化多种预制体,所以需要先将每种预制体存在各个小池中,接着通过大池进行管理,之后直接从大池中拿取和放回。
using UnityEngine;
using System.Collections.Generic;
public class SubPool
{
//预制体
private GameObject m_prefab;
//父对象
private Transform m_parent;
//小池中所有存在场景的对象
private List<GameObject> m_objects = new List<GameObject>();
/// <summary>
/// 构造函数
/// </summary>
/// <param name="parent">父对象</param>
/// <param name="prefab">预制体</param>
public SubPool(Transform parent, GameObject prefab)
{
m_parent = parent;
m_prefab = prefab;
}
/// <summary>
/// 预制体名字
/// </summary>
public string Name
{
get
{
return m_prefab.name;
}
}
/// <summary>
/// 生成
/// </summary>
/// <returns>生成的对象</returns>
public GameObject Spawn()
{
GameObject go = null;
foreach(GameObject obj in m_objects)
{
if (!obj.activeSelf)
{
go = obj;
break;
}
}
if(go == null)
{
go = GameObject.Instantiate(m_prefab);
go.transform.parent = m_parent;
m_objects.Add(go);
}
go.SetActive(true);
return go;
}
/// <summary>
/// 是否存在小池中
/// </summary>
/// <param name="go">判断的对象</param>
/// <returns></returns>
public bool Contains(GameObject go)
{
return m_objects.Contains(go);
}
/// <summary>
/// 回收
/// </summary>
/// <param name="go">回收的对象</param>
public void UnSpawn(GameObject go)
{
if(Contains(go))
{
go.SetActive(false);
}
}
/// <summary>
/// 回收全部
/// </summary>
public void UnSpawnAll()
{
foreach(GameObject obj in m_objects)
{
UnSpawn(obj);
}
}
}
using System.Collections.Generic;
using UnityEngine;
public class ObjectPool : MonoBehaviour
{
//存放预制体的文件名
public string FileName = "prefab";
//名字-小池子字典
private Dictionary<string, SubPool> m_pools = new Dictionary<string, SubPool>();
/// <summary>
/// 生成
/// </summary>
/// <param name="name">名字</param>
/// <param name="parent">父对象</param>
/// <returns>生成的对象</returns>
public GameObject Spawn(string name, Transform parent)
{
SubPool pool = null;
if(!m_pools.ContainsKey(name))
{
RegisterNewPool(name, parent);
}
pool = m_pools[name];
return pool.Spawn();
}
/// <summary>
/// 注册新的小池子
/// </summary>
/// <param name="name">名字</param>
/// <param name="parent">父对象</param>
private void RegisterNewPool(string name, Transform parent)
{
string path = FileName + "/" + name;
GameObject go = Resources.Load<GameObject>(path);
if(go != null)
{
SubPool pool = new SubPool(parent, go);
m_pools.Add(pool.Name, pool);
}
else
{
Debug.Log("未找到" + path + "的预制体");
}
}
/// <summary>
/// 回收
/// </summary>
/// <param name="go">被回收的游戏对象</param>
public void UnSpawn(GameObject go)
{
SubPool pool = null;
foreach(SubPool p in m_pools.Values)
{
if(p.Contains(go))
{
pool = p;
break;
}
}
if(pool != null)
{
pool.UnSpawn(go);
}
}
/// <summary>
/// 回收全部
/// </summary>
public void UnSpawnAll()
{
foreach(SubPool p in m_pools.Values)
{
p.UnSpawnAll();
}
}
}
因为作者精力有限,文章中难免出现一些错漏,敬请广大专家和网友批评、指正。