unity对象池

参考另一篇

避免了重复创建对象,而将对象放入一个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会一累加


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值