unity 对象池设计

设计缓存池 我们关注几个方面:

1.怎么将游戏对象保存到缓存池

2.怎么从缓存池中取出对象

3.怎么智能删除缓存池 

unity优秀的缓存池插件 PoolManager

 下面是一个简单地对象池类库

PoolManager

using UnityEngine;
using System.Collections.Generic;

public class PoolManager
{
    /// <summary>
    
/// 超时时间
    
/// </summary>
    public const int EXPIRE_TIME = 1 * 60;

    private static Dictionary<string, PoolItem> itemList;

    /// <summary>
    
/// 添加一条数据
    
/// </summary>
    
/// <param name="path">Path.</param>
    
/// <param name="maxSize">Max size.</param>
    public static void PushData(string path)
    {
        if (itemList == null) itemList = new Dictionary<string, PoolItem> ();
        if(!itemList.ContainsKey(path)) itemList.Add(path, new PoolItem(path));
    }
    
    /// <summary>
    
/// 添加 GameObject 对象
    
/// </summary>
    
/// <param name="path">Path.</param>
    
/// <param name="gameObject">Game object.</param>
    public static void PushObject(string path, GameObject gameObject)
    {
        if (itemList == null || !itemList.ContainsKey(path)) PushData(path);
        // 添加对象
        itemList [path].PushObject (gameObject);
    }

    /// <summary>
    
/// 移除一条数据
    
/// </summary>
    
/// <param name="path">Path.</param>
    public static void RemoveData(string path)
    {
        if (itemList == nullreturn;
        itemList.Remove (path);
    }

    /// <summary>
    
/// 移除 GameObject 对象
    
/// </summary>
    
/// <param name="path">Path.</param>
    
/// <param name="gameObject">Game object.</param>
    public static void RemoveObject(string path, GameObject gameObject)
    {
        if (itemList == null || !itemList.ContainsKey(path)) return;

        // 移除对象
        itemList [path].RemoveObject (gameObject);
    }

    /// <summary>
    
/// 获取缓存的对象
    
/// </summary>
    
/// <param name="path">Path.</param>
    public static GameObject GetObject(string path)
    {
        if (itemList == null || !itemList.ContainsKey (path)) return null;
        return itemList [path].GetObject ();
    }

    /// <summary>
    
/// 禁用对象
    
/// </summary>
    
/// <param name="path">Path.</param>
    
/// <param name="gameObject">Game object.</param>
    public static void DestoryObject(string path, GameObject gameObject)
    {
        if (itemList == null || !itemList.ContainsKey (path)) return;
        itemList [path].DestoryObject (gameObject);
    }

    /// <summary>
    
/// 处理超时的对象
    
/// </summary>
    public static void ExpireObject()
    {
        // 筛选符合条件的数据
        foreach (PoolItem poolItem in itemList.Values) 
        {
            poolItem.ExpireObject();
        }
    }

    /// <summary>
    
/// 销毁对象
    
/// </summary>
    public static void Destroy()
    {
        foreach (PoolItem poolItem in itemList.Values) 
        {
            poolItem.Destory();
        }
        itemList = null;
    }

} 

 PoolItem

 using UnityEngine;

using System.Collections.Generic;

/// <summary>
/// 池数据
/// </summary>
public class PoolItem
{
    /// <summary>
    
/// 路径,对象标识
    
/// </summary>
    public string path;

    /// <summary>
    
/// 对象列表
    
/// </summary>
    public Dictionary<int, PoolItemTime> objectList;

    public PoolItem(string path)
    {
        this.path = path;
        this.objectList = new Dictionary<int, PoolItemTime> ();
    }

    /// <summary>
    
/// 添加对象
    
/// </summary>
    
/// <param name="gameObject">Game object.</param>
    public void PushObject(GameObject gameObject)
    {
        int hashKey = gameObject.GetHashCode ();
        if(!this.objectList.ContainsKey(hashKey))
        {
            this.objectList.Add(hashKey, new PoolItemTime(gameObject)); 
        }else{
            this.objectList[hashKey].Active();
        }
    }

    /// <summary>
    
/// 销毁对象
    
/// </summary>
    
/// <param name="gameObject">Game object.</param>
    public void DestoryObject(GameObject gameObject)
    {
        int hashKey = gameObject.GetHashCode ();
        if (this.objectList.ContainsKey (hashKey)) 
        {
            this.objectList[hashKey].Destory();
        }
    }

    /// <summary>
    
/// 获取未真正销毁的对象(池对象)
    
/// </summary>
    public GameObject GetObject()
    {
        if (this.objectList == null || this.objectList.Count == 0return null;

        foreach (PoolItemTime poolItemTime in this.objectList.Values)
        {
            if(poolItemTime.destoryStatus) return poolItemTime.Active();
        }

        return null;
    }

    /// <summary>
    
/// 移除并且销毁对象
    
/// </summary>
    
/// <param name="gameObject">Game object.</param>
    public void RemoveObject(GameObject gameObject)
    {
        int hashKey = gameObject.GetHashCode ();
        if (this.objectList.ContainsKey (hashKey)) 
        {
            GameObject.Destroy(gameObject);
            this.objectList.Remove(hashKey);
        }
    }
    
    /// <summary>
    
/// 销毁对象
    
/// </summary>
    public void Destory()
    {
        IList<PoolItemTime> poolList = new List<PoolItemTime> ();
        foreach (PoolItemTime poolItemTime in this.objectList.Values)
        {
            poolList.Add(poolItemTime);
        }
        while (poolList.Count > 0)
        {
            if(poolList[0] != null && poolList[0].gameObject != null)
            {
                GameObject.Destroy(poolList[0].gameObject);
                poolList.RemoveAt(0);
            }
        }
        this.objectList = new Dictionary<int, PoolItemTime> ();
    }

    /// <summary>
    
/// 超时检测
    
/// </summary>
    public void ExpireObject()
    {
        IList<PoolItemTime> expireList = new List<PoolItemTime> ();
        foreach (PoolItemTime poolItemTime in this.objectList.Values)
        {
            if(poolItemTime.IsExpire()) expireList.Add(poolItemTime);
        }
        int expireCount = expireList.Count;
        for(int index = 0; index < expireCount; index ++)
        {
            this.RemoveObject(expireList[index].gameObject);
        }
    }
}

 

 PoolItemTime

using UnityEngine;
using System.Collections;

/// <summary>
/// 对象超时数据,销毁的对象在多久之后自动销毁
/// </summary>
public class PoolItemTime
{
    /// <summary>
    
/// 对象
    
/// </summary>
    public GameObject gameObject;

    /// <summary>
    
/// 存取时间
    
/// </summary>
    public float expireTime;
    
    /// <summary>
    
/// 销毁状态,外部不要随便修改这什值
    
/// </summary>
    public bool destoryStatus;

    public PoolItemTime(GameObject gameObject)
    {
        this.gameObject = gameObject;
        this.destoryStatus = false;
    }

    /// <summary>
    
/// 激活对象
    
/// </summary>
    public GameObject Active()
    {
        this.gameObject.SetActive (true);
        this.destoryStatus = false;
        return this.gameObject;
    }

    /// <summary>
    
/// 销毁对象
    
/// </summary>
    public void Destory()
    {
        // 重置角色状态
        this.gameObject.SetActive (false);

        this.destoryStatus = true;
        this.expireTime = Time.time;
    }

    /// <summary>
    
/// 是否超时
    
/// </summary>
    
/// <value><c>true</c> if this instance is expire; otherwise, <c>false</c>.</value>
    public bool IsExpire() 
    {
        if (!this.destoryStatus) return false;
        if(Time.time - this.expireTime >= PoolManager.EXPIRE_TIME) return true;
        return false;
    }

} 

 

posted @ 2015-11-19 15:46  倾其一生  阅读(711)  评论(0)    收藏  举报