【Unity】对象池技术
2023-12-24 23:38:05
【Unity】对象池技术
1.简介
对象池(Object Pooling)技术是一种用于优化游戏性能和内存管理的技术。
对象池可以用于各种需要频繁实例化和销毁游戏对象的场景,例如子弹、敌人、玩家等。其主要目标是减少频繁的内存分配和垃圾回收的次数,提高游戏的运行效率,从而提高性能和降低延迟。
在对象池中查找池中隐藏的游戏对象,将其显示出来,以避免一直实例化新的游戏对象,导致游戏性能受到影响。
2.实现
一般地,游戏会需要频繁实例化多种预制体,所以需要先将每种预制体存在各个小池中,接着通过大池进行管理,之后直接从大池中拿取和放回。
小池子(SubPool)代码
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);
}
}
}
大池子(ObjectPool)代码
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();
}
}
}
因为作者精力有限,文章中难免出现一些错漏,敬请广大专家和网友批评、指正。
文章来源:https://blog.csdn.net/qq_46051312/article/details/135188264
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!