unity对象池

来源:互联网 发布:专业校色软件 编辑:程序博客网 时间:2024/05/23 18:13

参考另一篇

避免了重复创建对象,而将对象放入一个List中(池里面),获取显示隐藏等方法来处理,提高执行效率

大概截图:类似捕鱼达人的demo


1 创建脚本,旋转大炮,按钮按下,调用对象池开始操作创建对象,显示隐藏对象

using UnityEngine;using System.Collections;public class SpawnFire : MonoBehaviour {    public float time = 0;// Use this for initializationvoid Start () {}// Update is called once per framevoid 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 framevoid 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 framevoid Update () {}    public void CreateObj() {              Debug.Log("a "+a++);            }}
 FishPool._instance.CreateObj());
类继承MonoBehaviour,但是这个类没有绑到物体上,那么由于没有绑到物体,Awake就不会执行,需要手动创建返回静态对象的方法,然后就是继承MonoBehavior后,导致单例模式失效,该情况下每次都会实例化一个instance ,Debug语句会一直是0

类继承MonoBehaviour,但是这个类有绑到物体上,单例模式正常,a会一累加,同时可以在Awake中初始化

类不继承Monobehaviour,单例模式正常,a会一累加