基于Unity引擎的简单对象池

来源:互联网 发布:没有网络又可以玩游戏 编辑:程序博客网 时间:2024/06/02 03:45
对象池的基本定义大家基本了解了,我在这就进行简单的一句话概述。
通常情况下,当您实例化并销毁prefabs的实例,您在运行时不断创建新的对象和摧毁它们,这可能会导致运行时垃圾回收和偶尔的帧速率下降。对象池可以防止这种,通过预先实例化,而不是被摧毁然后重新生成对象!
本篇文章是关于unity内部的简单对象池实现,实现的基本功能就是,打死怪物后实例化金币,金币可以通过对象池一直复用。不需要重复的销毁金币和生成新的金币实例。

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

public class ObjectPool : MonoBehaviour
{
    public static ObjectPool intance;
    public static Dictionary<string, Stack> pool = new Dictionary<string, Stack> { };
    void Start()
    {
        intance = this;
    }
    //从对象池里拿到我们的对象
    public Object GetObject(string prefabName, Vector3 position, Quaternion rotation)
    {
        //prefabName为resources文件夹目录
        string key = "Instant_Coin" + "(Clone)";//目的是找到游戏内的对象,这里按需要处理
        Object o;
        if (pool.ContainsKey(key) && pool[key].Count > 0) 
        {
            Stack stack = pool[key];
            o = stack.Pop() as Object;
            ResetStartState(o, position, rotation);
        }
        else
        {
            o = Instantiate(Resources.Load(prefabName), position, rotation);

        }

        DelayDestroy dd = (o as GameObject).GetComponent<DelayDestroy>();//延时回收对象
        dd.Init();
        return o;

    }

    //重置对象初始状态,内部代码可以重写
    public void ResetStartState(Object tempObj,Vector3 pos,Quaternion rot)
    {
        (tempObj as GameObject).SetActive(true);
        (tempObj as GameObject).transform.position = pos;
        (tempObj as GameObject).transform.rotation = rot;
        Animation tempAni = (tempObj as GameObject).GetComponentInChildren<Animation>();
        if (tempAni != null)
        {
            tempAni.Play("drop");
        }
    }
    //根据不同需求重写,对象重置状态
    public void ResetStartState(Object tempObj)
    {

    }
    //回收对象时,调整回收对象状态
    public void ResetEndState(Object tempObj)
    {
        (tempObj as GameObject).SetActive(false);
    }
    //同样可以重写
    public void ResetEndState(Object tempObj)
    {
        (tempObj as GameObject).SetActive(false);
    }

    //把对象放回对象池,这个函数也是可以重写的函数
    public Object ReturnPool(GameObject o)
    {
        string key = o.name;
        if (pool.ContainsKey(key)) 
        {
            Stack stack = pool[key];
            stack.Push(o);
        }
        else
        {
            Stack tempStack = new Stack();
            tempStack.Push(o);
            pool[key] = tempStack;
        }
        ResetEndState(o);
        return o;
    }
}

//这个脚本是挂在回收对象上的,方便使用完成后回收对象
public class DelayCollectObject : MonoBehaviour
{

    private float DelayTime;
    public void Init()
    {
        DelayTime = 3f;
        StartCoroutine(ReturnToPool());
    }
    IEnumerator ReturnToPool()
    {
        yield return new WaitForSeconds(DelayTime);
        ObjectPool.intance.ReturnPool(this.gameObject);

    }
}

0 0
原创粉丝点击