unity对象池
程序员文章站
2022-07-13 15:01:09
...
避免了重复创建对象,而将对象放入一个List中(池里面),获取显示隐藏等方法来处理,提高执行效率
大概截图:类似捕鱼达人的demo
1 创建脚本,旋转大炮,按钮按下,调用对象池开始操作创建对象,显示隐藏对象
using UnityEngine;
using System.Collections;
public class SpawnFire : MonoBehaviour {
public float time = 0;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
time -= Time.deltaTime;
if (time < 0) {
time = 0.1f;
Vector3 mousepos = Input.mousePosition;
mousepos = Camera.main.ScreenToWorldPoint(mousepos); //鼠标按下的坐标
Vector3 ownPos = this.transform.position; // 大炮的位置
if (Input.GetMouseButton(0)) {
Vector3 angelV = mousepos - ownPos;
float angele = Vector2.Angle(angelV,Vector3.up); // 一直正的,二维向量夹角
//Debug.Log(angele);
if (mousepos.x > ownPos.x)
angele = -angele;
this.transform.eulerAngles = new Vector3(0,0,angele);
GameObject go = (GameObject)Resources.Load("fire");// 创建
// Fire.CreateFire(go, this.transform.TransformPoint(0,1,0),new Vector3(0, 0, angele));
FishPool._instance.CreateObj(go,this.transform.TransformPoint(0,1,0),new Vector3(0,0,angele));// 将位置角度传入对象池脚本
}
}
}
}
2 对象池脚本,如果list为空,这创建gameobject,等子弹消失后,Add进list,同时将对象active设置成false,如果list不为空,取出ist的第一个元素,remove出list,同时将对象active设置成true
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class FishPool : MonoBehaviour
{
// Use this for initialization
public static FishPool _instance;
public List<GameObject> list=new List<GameObject>();
int a = 0;
private void Awake()
{
_instance = this;
}
void Start () {
}
public static FishPool GetInstance() {
if (_instance == null)
_instance = new FishPool();
return _instance;
}
// Update is called once per frame
void Update () {
}
public void CreateObj(GameObject prefab,Vector3 pos,Vector3 angel) {
if (list.Count == 0)
{
GameObject go = (GameObject)Instantiate(prefab, pos, Quaternion.Euler(angel));
go.name = "--------------";
go.AddComponent<Fire>();
StartCoroutine(Fly(go));
}
else
{
Debug.Log("list cout "+list.Count);
GameObject go = list[0];
go.active = true;
go.transform.position = pos;
go.transform.eulerAngles = angel;
list.Remove(go);
StartCoroutine(Fly(go));
}
}
IEnumerator Fly(GameObject go)
{
yield return new WaitForSeconds(1f);
go.active = false;
list.Add(go);
}
}
最后绑定在子弹上的移动脚本,其实文章开头连接文章是将显示隐藏放在子弹的脚本里面,然后在对象池的脚本对外开放一个方法,让外面来操作里面的list,这个比较好
void Update () {
this.transform.Translate(new Vector3(0,Time.deltaTime*speed,0));
}
BUG再现,警示作用
结合单例模式
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class FishPool : MonoBehaviour
{
// Use this for initialization
public static FishPool _instance;
public List<GameObject> list=new List<GameObject>();
int a = 0;
private void Awake()
{
_instance = this;
}
void Start () {
}
public static FishPool GetInstance() {
Debug.Log("hehe");
if (_instance == null)
_instance = new FishPool();
Debug.Log("haha");
return _instance;
}
// Update is called once per frame
void Update () {
}
public void CreateObj() {
Debug.Log("a "+a++);
}
}
FishPool._instance.CreateObj());类继承MonoBehaviour,但是这个类没有绑到物体上,那么由于没有绑到物体,Awake就不会执行,需要手动创建返回静态对象的方法,然后就是继承MonoBehavior后,导致单例模式失效,该情况下每次都会实例化一个instance ,Debug语句会一直是0
类继承MonoBehaviour,但是这个类有绑到物体上,单例模式正常,a会一累加,同时可以在Awake中初始化
类不继承Monobehaviour,单例模式正常,a会一累加