对象池理解: 在场景中需要经常生成和销毁物体时,直接使用实例化和destroy会十分损耗性能。这个时候可以创建一个对象池。将这些东西生成后存入池子中,使用时取出,不使用则放回。通过控制其setActive属性来实现生成和销毁的效果。
创建一个对象池一般需要用到创建一个表,可以是list,queue,stack,Dictionary等数据结构。
这里使用Queue先进先出的特性,创建对象池,实现发射子弹的小功能。
using System.Collections.Generic;
using UnityEngine;
public class PoolTest : MonoBehaviour
{
public static PoolTest _instance;//创建单例模式
public Queue<GameObject> list = new Queue<GameObject>();//对象池
public GameObject prefab;//子弹预设体
public int maxCount = 10;//子弹个数
private void Start()
{
FillPool();
}
private void Awake()
{
_instance = this;
}
public void FillPool()
{
for (int i = 0; i < maxCount; i++)//实例化预设体(子弹)
{
var go= Instantiate(prefab);
go.transform.SetParent(transform);
ReturnPool(go);
}
}
public void ReturnPool(GameObject go)//将预设体放入池子并隐藏,也就是放回池子的方法
{
list.Enqueue(go);
go.SetActive(false);
go.transform.position = this.transform.position;
}
public GameObject GetFormPool()//定义一个GameObject方法用来取出子弹
{
var outBullt = list.Dequeue();
outBullt.SetActive(true);
return outBullt;
}
}
创建出池子后,只需要在另外的脚本中调用取出和放入的方法即可。
比如实现左键按下发射子弹
if (Input.GetMouseButtonDown(0)&&bullet>0)
{
PoolTest._instance.GetFormPool();
}
子弹的销毁判断采用的方法是当子弹离开屏幕范围时
if (!isinCamera(this.transform.position))
{
pool.GetComponent<PoolTest>().ReturnPool(this.gameObject);
}//调用放回池子
public bool isinCamera(Vector2 worldpos)
{
var pos = Camera.main.WorldToViewportPoint(worldpos);//将物体坐标转换成屏幕坐标
if (pos.x > 0 && pos.x < 1 && pos.y < 1 && pos.y > 0)
{
return true;
}
else
return false;
}
//屏幕检测