1.简介
就是将对象存储在一个池子中,当需要时再次使用,而不是每次都实例化一个新的对象。
2.具体使用
通过一个简单的小案例了解对象池的使用
1.对象池脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ObjectScript : MonoBehaviour
{
public static ObjectScript bulletsPoolInstance;//单例脚本
public GameObject bulletObj;//子弹预制体
public int pooledAmount = 5;//对象池大小
public bool lockPoolSize = false;
private List<GameObject> pooledObjects;//对象池链表
private int currentIndex = 0;
private void Awake()
{
bulletsPoolInstance = this;
}
// Start is called before the first frame update
void Start()
{
pooledObjects = new List<GameObject>();
for (int i = 0; i < pooledAmount; i++)
{
GameObject obj = Instantiate(bulletObj);//初始化对象池
obj.SetActive(false);
pooledObjects.Add(obj);//加入链表
}
}
public GameObject GetPooledObject()
{
for (int i = 0; i < pooledObjects.Count; ++i)
{
int teml = (currentIndex + i) % pooledObjects.Count;
if (!pooledObjects[teml].activeInHierarchy)
{
currentIndex = (teml + 1) % pooledObjects.Count;
return pooledObjects[teml];
}
}
if (!lockPoolSize)
{
GameObject obj = Instantiate(bulletObj);
pooledObjects.Add(obj);
return obj;
}
return null;
}
// Update is called once per frame
void Update()
{
}
}
2.通过点击显示子弹
if (Input.GetMouseButtonDown(0))
{
//nextFire = Time.time + fireRate;
GameObject bullet = ObjectScript.bulletsPoolInstance.GetPooledObject();
//bullet.transform.Translate(new Vector3(0, 0, 10));
if (bullet!=null)
{
bullet.SetActive(true);
bullet.transform.position = shotSpawn.transform.position;
//bullet.GetComponent<Rigidbody>().AddForce(new Vector3(0, 0, 10));
}
}
3.子弹撞击地面隐藏不销毁
private void OnTriggerExit(Collider other)
{
other.gameObject.SetActive(false);//碰到就失效
}
4.演示
1)开始运行直接实例化子弹但不显示
2)点击鼠标将子弹显示,根据重力子弹下落,低级次数决定子弹数量,子弹撞击地板不销毁,重新回到初始位置
3.总结
对象池也是一种对游戏的优化,游戏中大量的子弹或特效会占用过多的内存,使用对象池可以减少内存的占用,实现优化。