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;
        }
        //屏幕检测

猜你喜欢

转载自blog.csdn.net/weixin_43821918/article/details/106095321