对象池总结

using System.Collections.Generic;
using UnityEngine;

public class BulletsPool : MonoBehaviour
{
    public static BulletsPool bulletsPoolInstance;      //子弹池单例
    public GameObject bulletObj;                        //子弹perfabs
    public int pooledAmount = 5;                        //子弹池初始大小
    public bool lockPoolSize = false;                   //是否锁定子弹池大小

    private List<GameObject> pooledObjects;             //子弹池链表

    private int currentIndex = 0;                       //当前指向链表位置索引

    void Awake()
    {
        bulletsPoolInstance = this;                     //把本对象作为实例。
    }

    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)   //把对象池遍历一遍
        {
            //这里简单优化了一下,每一次遍历都是从上一次被使用的子弹的下一个,而不是每次遍历从0开始。
            //例如上一次获取了第4个子弹,currentIndex就为5,这里从索引5开始遍历,这是一种贪心算法。
            int temI = (currentIndex + i) % pooledObjects.Count;
            if (!pooledObjects[temI].activeInHierarchy) //判断该子弹是否在场景中激活。
            {
                currentIndex = (temI + 1) % pooledObjects.Count;
                return pooledObjects[temI];             //找到没有被激活的子弹并返回
            }
        }


        //如果遍历完一遍子弹库发现没有可以用的,执行下面
        if (!lockPoolSize)                               //如果没有锁定对象池大小,创建子弹并添加到对象池中。
        {
            GameObject obj = Instantiate(bulletObj);
            pooledObjects.Add(obj);
            return obj;
        }

        //如果遍历完没有而且锁定了对象池大小,返回空。
        return null;
    }

}

```csharp
using UnityEngine;

public class AutoFire : MonoBehaviour
{
    //传统创建子弹方法需要的子弹perfabs
    //public GameObject shotObj;

    public GameObject shotSpawn;                //子弹发射的初始化位置

    public float fireRate = 0.2f;               //每次发射子弹事件间隔

    private float nextFire;                     //下一次发射子弹的时间

    void Update()
    {
        if (Time.time > nextFire)               //可以发射子弹时间
        {
            nextFire = Time.time + fireRate;

            //传统创建子弹方法
            //Instantiate(shotObj, shotSpawn.transform.position, shotSpawn.transform.rotation);

            //获取对象池中的子弹
            GameObject bullet = BulletsPool.bulletsPoolInstance.GetPooledObject();
            if (bullet != null)                  //不为空时执行
            {
                bullet.SetActive(true);         //
                if (bullet.GetComponent<MoveSpeed>()==null) 
                {
                    bullet.AddComponent<MoveSpeed>();
                }
                bullet.transform.position = shotSpawn.transform.position;
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值