1、对象池经常用到Unity对内存的优化,它的作用在于可以减少创建每个对象的系统开销。
2、比如在射击游戏中,玩家和敌人都需要大量的创建子弹,而这些子弹在打到敌人或则在经过一段时间后会销毁,当玩家再次射击的时候又会大量的克隆子弹,这样对系统而言造成了很大的内存开销。
3、那现在的对象池就可以起到在大量克隆相同的GameObject时对内存起到优化的作用。
4、介绍一下对象池是怎么优化内存的,在射击游戏中,我们发射的子弹都是克隆出来的,当打到敌人之后立即会Destroy掉,下次需要子弹的时候,会继续克隆,然后继续Destroy。
而对象池起的作用就是 我们创建的子弹不进行Destroy ,当不需要的时候只是SetActive(false)进行隐藏,放我们发射子弹的时候从我们存放子弹的字典中取出来,取的时候需要对字典中的数据进行遍历,如果该物体在场景中处于SetActive(true)的状态,则接着往下遍历,如果处于SetActive(false)的状态就return该物体,之后进行相应的操作。
5、如果我们在字典里遍历了一遍,全部的数据都在使用,这个时候我们就可以继续克隆新的物体存放到字典里面,进行return。(好吧可能说的有点乱 下面直接上代码········)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 对象池
/// 存放多种不同游戏对象
/// </summary>
public class GameObjectPools : MonoSingleton<GameObjectPools>
{
/// <summary>可能存放多个种类的对象,每个种类有多个对象 </summary>
private Dictionary<string, List<GameObject>> cache = new Dictionary<string, List<GameObject>>();
/// <summary>增加物体进入池(按类别增加)</summary>
public void Add(string key, GameObject go)
{
//1.如果key在容器中存在,则将go加入对应的列表
//2.如果key在容器中不存在,是先创建一个列表,再加入
if (!cache.ContainsKey(key))
cache.Add(key, new List<GameObject>());
cache[key].Add(go);
}
/// <summary>销毁物体(将对象隐藏)</summary>
public void MyDestory(GameObject destoryGo)
{
//设置destoryGo隐藏
destoryGo.SetActive(false);
}
/// <summary>将对象归入池中<summary>
public void MyDestory(GameObject tempGo, float delay)
{
//开启一个协程
StartCoroutine(DelayDestory(tempGo, delay));
}
/// <summary>延迟销毁</summary>
private IEnumerator DelayDestory(GameObject destoryGO, float delay)
{
//等待一个延迟的时间
yield return new WaitForSeconds(delay);
MyDestory(destoryGO);
}
/// <summary>取出可用的物体(已经隐藏的)</summary>
public GameObject FindUsable(string key)
{
//1.在容器中找出key对应的列表,从列表中找出已经为隐藏状态的对象,返回
if (cache.ContainsKey(key))
foreach (GameObject item in cache[key])
{
if (!item.activeSelf)
return item;
}
return null;
}
/// <summary>创建一个游戏物体到场景 </summary>
public GameObject CreateObject(string key, GameObject go, Vector3 position, Quaternion quaternion)
{
//先找是否有可用的,如果没有则创建,如果有找到后设置好位置,朝向再返回
GameObject tempGo = FindUsable(key);
if (tempGo != null)
{
tempGo.transform.position = position; //位置自定义
tempGo.transform.rotation = quaternion;
tempGo.SetActive(true);
}
else
{
tempGo = GameObject.Instantiate(go, position, quaternion) as GameObject;
Add(key, tempGo);
}
return tempGo;
}
/// <summary>清空某类游戏对象</summary>
public void Clear(string key)
{
cache.Remove(key);
}
/// <summary>清空池中所有游戏对象</summary>
public void ClearAll()
{
cache.Clear();
}
}