Unity简单的对象池

对象池理解: 在场景中需要经常生成和销毁物体时,直接使用实例化和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;
        }
        //屏幕检测

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Unity中,虽然没有内置的对象池类,但是可以通过自定义脚本来实现对象池的功能。下面是一个简单的示例代码,展示了如何创建一个基本的对象池: ```csharp using System.Collections.Generic; using UnityEngine; public class ObjectPool : MonoBehaviour { public GameObject prefab; // 预制体 public int poolSize; // 对象池大小 private List<GameObject> objectPool; void Start() { objectPool = new List<GameObject>(); for (int i = 0; i < poolSize; i++) { GameObject obj = Instantiate(prefab); obj.SetActive(false); objectPool.Add(obj); } } public GameObject GetObjectFromPool() { for (int i = 0; i < objectPool.Count; i++) { if (!objectPool[i].activeInHierarchy) { objectPool[i].SetActive(true); return objectPool[i]; } } // 如果对象池中没有可用对象,则动态创建一个新对象 GameObject newObj = Instantiate(prefab); objectPool.Add(newObj); return newObj; } public void ReturnObjectToPool(GameObject obj) { obj.SetActive(false); } } ``` 在上述代码中,我们创建了一个名为ObjectPool的脚本。在Start方法中,我们初始化了对象池,根据poolSize的值来创建一定数量的对象,并将它们存储在objectPool列表中。 GetObjectFromPool方法用于从对象池中获取一个可用的对象。我们遍历objectPool列表,寻找第一个处于非激活状态的对象,并将其设置为激活状态,然后返回该对象。如果对象池中没有可用对象,则动态创建一个新对象,并将其添加到objectPool列表中。 ReturnObjectToPool方法用于将使用完的对象返回到对象池中。我们将传入的对象设置为非激活状态,以便下次复用。 通过这样的自定义脚本,你可以在Unity中实现对象池的功能,以提高游戏的性能和效率。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值