Unity超简易对象池

目录

用途

原理

代码

实例


用途

避免频繁地创建和销毁对象

原理

使用时从对象池内取对象,如果没有再生成;不用时,隐藏后放入对象池,而不是直接销毁;

用对象池的方法GetObject代替 GameObject.Instantiate,获取对象;

用对象池的方法SetObjectToPool代替Destory,回收对象

代码

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class ObjectPool : MonoBehaviour
{
    //单例脚本
    public static ObjectPool _instance;
    private ObjectPool() { }//私有构造

    //对象池数据结构
    public Dictionary> pool;

    public GameObject xiguaPrefab;
    public GameObject xiguaLeftPrefab;
    public GameObject xiguaRightPrefab;
    //根据需要在这里添加预设体

    //存储所以可以放入该对象池里的对象的预设体
    public Dictionary staples;

    void Awake()
    {
        _instance = this;
        pool = new Dictionary>();//实例化
        staples = new Dictionary();
        //添加进来Demo里面的预设体
        staples.Add(xiguaPrefab.name, xiguaPrefab);
        staples.Add(xiguaLeftPrefab.name, xiguaLeftPrefab);
        staples.Add(xiguaRightPrefab.name, xiguaRightPrefab);
        //使用之前要先在这里注册
    }

    /// 
    /// 获取对象池中的对象
    /// 
    /// 对象的名称
    /// 对象的位置
    /// 对象的旋转
    /// 对象的旋转
    /// 返回要获取的对象
    public GameObject GetObject(string objectName, Vector3 objectPosition, Quaternion objectRotation)
    {
        GameObject willGetObject;
        string objName = objectName + "(Clone)";
        //如果对象池有该类型的对象,且该类型的对象池不为空(有可以使用的对象)
        if (pool.ContainsKey(objName) && pool[objName].Count > 0)
        {
            //获取池子里第一个对象
            willGetObject = pool[objName][0];
            //设置位置和旋转
            willGetObject.transform.position = objectPosition;
            willGetObject.transform.rotation = objectRotation;
            //设置为激活状态
            willGetObject.SetActive(true);
            //从集合中删除该对象
            pool[objName].Remove(willGetObject);
        }
        else
        {
            willGetObject = Instantiate(staples[objectName], objectPosition, objectRotation) as GameObject;
            willGetObject.transform.SetParent(this.transform);
        }
        Rigidbody rb = willGetObject.GetComponent();
        if (rb != null)
            rb.velocity = Vector3.zero;
        return willGetObject;
    }

    /// 
    /// 将用完的对象放到对象池里
    /// 
    /// 需要放的对象
    public void SetObjectToPool(GameObject willSetObject)
    {
        //将活跃状态设置为False
        willSetObject.SetActive(false);
        //获取对象的名称
        string objName = willSetObject.name;
        //如果字典中包含该Key值对象
        if (pool.ContainsKey(objName))
        {
            //将对象放入盒子中
            pool[objName].Add(willSetObject);
        }
        else
        {
            //否则没有该key的盒子,创建该key值的盒子,并把对象放进盒子中
            pool.Add(objName, new List { willSetObject });
        }
    }
}

实例

//生成实例,通过名字即可
public GameObject right;
ObjectPool._instance.GetObject(right.name, transform.position, right.transform.rotation) as GameObject;

//回收
ObjectPool._instance.SetObjectToPool(gameObject);

 

你可能感兴趣的:(Unity基础)