Unity对象池技术

发表于2018-03-21
评论0 1.4k浏览
在游戏中,会出现对游戏对象进行反复的创建销毁的情况,比如游戏中的子弹,敌人等,但反复的创建与销毁会浪费一定的系统资源,此种情况下一般会引入对象池技术,可以将暂时不需要用到游戏对象放在对象池(缓冲区),当需要使用到时再从对象池中提取。下面就通过一个简单的项目DEMO,帮助大家去学习了解关于对象池的知识。

代码如下:
using UnityEngine;  
using System.Collections.Generic;  
public class PoolManager : MonoBehaviour   
{  
    /// <summary>  
    ///当游戏中只有一个对象需要用到对象池  
    /// </summary>  
    public List<GameObject> singlePool;  
    /// <summary>  
    /// 当游戏中有多个游戏对象需要用到对象池  
    /// </summary>  
    public Dictionary<int, List<GameObject>> mostPool;  
    /// <summary>  
    /// 单例模式  
    /// </summary>  
    public static PoolManager manager;  
    public static PoolManager GetInstance()  
    {  
        if (manager != null)  
        {  
            manager = new PoolManager();  
        }  
        return manager;  
    }  
    /// <summary>  
    /// 从对象池中创建单个游戏对象  
    /// </summary>  
    public GameObject CreateSingleGameobject(GameObject obj,Vector3 position,Quaternion rotation)  
    {  
        if(singlePool.Count>0)  
        {  
            GameObject m_obj=singlePool[0];  
            singlePool.Remove(m_obj);  
            m_obj.SetActive(true);  
            m_obj.transform.position = position;  
            m_obj.transform.rotation = rotation;  
            return m_obj;  
        }  
        return GameObject.Instantiate(obj, position, rotation) as GameObject;  
    }  
    /// <summary>  
    /// 将游戏对象取消激活,隐藏起来  
    /// 并将其添加到对象池中,为了减少资源的浪费,不需要进行销毁  
    /// </summary>  
    /// <param name="obj"></param>  
    public void HideSingleGameobject(GameObject obj)  
    {  
        //使其处于未机会隐藏状态  
        obj.SetActive(false);  
        //将其添加到对象池中  
        singlePool.Add(obj);  
    }  
    /// <summary>  
    /// 当游戏中有多个游戏对象需要在对象池中创建时  
    /// </summary>  
    /// <param name="obj">需要激活的游戏对象</param>  
    /// <param name="position"></param>  
    /// <param name="rotation"></param>  
    /// <returns></returns>  
    public GameObject CreateMostGameobject(GameObject obj,Vector3 position,Quaternion rotation)  
    {  
        int objID = obj.GetInstanceID();  
        if (mostPool.ContainsKey(objID))  
        {  
            if (mostPool[objID].Count > 0)  
            {  
                GameObject m_obj = mostPool[objID][0];  
                mostPool[objID].Remove(m_obj);  
                m_obj.SetActive(true);  
                m_obj.transform.position = position;  
                m_obj.transform.rotation = rotation;  
                return m_obj;  
            }  
        }    
        //如果对象池中没有该游戏对象,实例化一个游戏对象  
        GameObject n_obj = GameObject.Instantiate(obj, position, rotation) as GameObject;  
        return n_obj;  
    }  
    public void HideMostGameobject(GameObject obj)  
    {  
        int key = obj.GetInstanceID();  
        if (!mostPool.ContainsKey(key))  
        {  
            mostPool.Add(key, new List<GameObject>());  
        }  
        mostPool[key].Add(obj);  
        obj.SetActive(false);  
    }  
}  

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引