首页 学习日记正文

Unity对象池封装

阿沐 学习日记 2020-04-02 615 0 unity

Unity对象池封装

image.png

1、应用场景:

对一些游戏场景:需要多次创建和销毁的对象【如枪战游戏里的子弹、RPG游戏里的剧情小怪...】

2、为什么要使用对象池:

可以减少GC的次数,提高游戏性能

3、对象池原理:

    a、需要生成对象时,先判断容器里是否存在可用的该类型对象,存在则直接取,不存在就实例化

    b、将需要销毁的对象保存而不删除【设置不可见,保存在容器中】

4、具体实现:【将对象池比作为衣柜,衣柜里有好多抽屉,不同抽屉放置不同类型的衣服】

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

public class PoolObj : SingletonBase<PoolObj> {

    public Dictionary<string, List<GameObject>> poolDict = new Dictionary<string, List<GameObject>>();

    public GameObject GetObj(string name)
    {
        GameObject obj = null;
        //如果衣橱里有该类型抽屉 并且 该抽屉 有可用的衣服
        if (poolDict.ContainsKey(name) && poolDict[name].Count > 0)
        {
            //取出目标衣服,在抽屉里移除衣服
            obj = poolDict[name][0];
            poolDict[name].RemoveAt(0);
        }
        else
        {
            //创建衣服
            obj = GameObject.Instantiate(Resources.Load<GameObject>(name));
            obj.name = name;//将对象名字设置为 预制体 名字
        }
        obj.SetActive(true);
        return obj;
    }

    public void PushObj(string name,GameObject obj)
    {
        obj.SetActive(false);
        //如果衣柜里有该类型抽屉
        if (poolDict.ContainsKey(name))
        {
            //直接在相应抽屉里添加衣服
            poolDict[name].Add(obj);
        }
        else
        {
            //衣柜里没有该抽屉 则 创建抽屉
            poolDict.Add(name, new List<GameObject>() { obj});
        }
    }
}

预制体上挂上延迟销毁的代码:

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

public class delayPush : MonoBehaviour {

	void OnEnable()
    {
        Invoke("Push", 1);//延迟1秒放入对象池
	}

    void Push()//调用对象池 放入管理方法
    {
        PoolObj.GetInstance().PushObj(this.gameObject.name,this.gameObject);
    }
}

测试代码:

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

public class GameStart : MonoBehaviour {

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            PoolObj.GetInstance().GetObj("Pool/Cube");//预制体路径
        }
        if (Input.GetMouseButtonDown(1))
        {
            PoolObj.GetInstance().GetObj("Pool/Cube2");
        }


    }
}

效果:

打赏

评论

Music