提供对象缓存池的功能,避免频繁地创建和销毁各种游戏对象,提高游戏性能。除了 Game Framework 自身使用了对象池,用户还可以很方便地创建和管理自己的对象池。

E神

就Unity游戏开发来说,对象池是一个非常重要的资源管理手段

伪代码结构参照https://blog.csdn.net/yupu56/article/details/110206648?spm=1001.2014.3001.5501

伪代码

ObjectPoolManager

ObjectPoolManager 是管理不同对象池的总类 对象池的具体对象管理逻辑会在ObjectPool里面

public class ObjectPoolManager 

{

    private const int DefaultCapacity = int.MaxValue;//默认容量

    private const float DefaultExpireTime = float.MaxValue;//默认释放时间

    private const int DefaultPriority = 0;//默认优先级



    private readonly Dictionary m_ObjectPools;

    private readonly List m_CachedAllObjectPools;

    private readonly Comparison m_ObjectPoolComparer;



    /// 
    /// 初始化对象池管理器的新实例。
    /// 
    public ObjectPoolManager()

    {

        m_ObjectPools = new Dictionary();

        m_CachedAllObjectPools = new List();

        m_ObjectPoolComparer = ObjectPoolComparer;

    }



    public int Priority;/// 获取游戏框架模块优先级。优先级较高的模块会优先轮询,并且关闭操作会后进行
    public int Count;/// 获取对象池数量。


    /// 
    /// 对象池管理器轮询。
    /// 
    /// 逻辑流逝时间,以秒为单位。
    /// 真实流逝时间,以秒为单位。
    internal override void Update(float elapseSeconds, float realElapseSeconds)
    {
        foreach (KeyValuePair objectPool in m_ObjectPools)
        {
            objectPool.Value.Update(elapseSeconds, realElapseSeconds);
        }
    }

    /// 
    /// 获取对象池。
    /// 
    /// 对象类型。
    /// 要获取的对象池。
    public IObjectPool GetObjectPool() where T : ObjectBase
    {
        return (IObjectPool)InternalGetObjectPool(new TypeNamePair(typeof(T)));
    }

    /// 
    /// 创建允许单次获取的对象池。
    /// 
    /// 对象类型。
    /// 要创建的允许单次获取的对象池。
    public IObjectPool CreateSingleSpawnObjectPool() where T : ObjectBase
    {
        return InternalCreateObjectPool(string.Empty, false, DefaultExpireTime, DefaultCapacity, DefaultExpireTime, DefaultPriority);
    }

    /// 
    /// 创建允许多次获取的对象池。
    /// 
    /// 对象类型。
    /// 要创建的允许多次获取的对象池。
    public ObjectPoolBase CreateMultiSpawnObjectPool()
    {
        return InternalCreateObjectPool(string.Empty, true, DefaultExpireTime, DefaultCapacity, DefaultExpireTime, DefaultPriority);
    }
}

ObjectPool

可以看到 ObjectPool 对泛型Object类型进行管理

提供了对象获取,回收与释放方法

提供了对象定时自动释放功能

/// 
/// 泛型T的对象池。
/// 
/// 对象类型。
private sealed class ObjectPool : ObjectPoolBase, IObjectPool where T : ObjectBase
{
    private readonly GameFrameworkMultiDictionary> m_Objects;
    private readonly Dictionary> m_ObjectMap;
    private readonly List m_CachedCanReleaseObjects;
    private readonly List m_CachedToReleaseObjects;

    public override Type ObjectType/// 获取对象池对象类型。

    public override int Count/// 获取对象池中对象的数量。
    public override int CanReleaseCount/// 获取对象池中能被释放的对象的数量。
    public override bool AllowMultiSpawn/// 获取是否允许对象被多次获取。
    public override float AutoReleaseInterval/// 获取或设置对象池自动释放可释放对象的间隔秒数。
    public override int Capacity/// 获取或设置对象池的容量。
    public override float ExpireTime/// 获取或设置对象池对象过期秒数。
    public override int Priority/// 获取或设置对象池的优先级。

    /// 
    /// 创建对象。
    /// 
    /// 对象。
    /// 对象是否已被获取。
    public void Register(T obj, bool spawned)
    {
        if (obj == null)
        {
            throw new GameFrameworkException("Object is invalid.");
        }

        Object internalObject = Object.Create(obj, spawned);
        m_Objects.Add(obj.Name, internalObject);
        m_ObjectMap.Add(obj.Target, internalObject);

        if (Count > m_Capacity)
        {
            Release();
        }
    }

    /// 
    /// 获取对象。
    /// 
    /// 要获取的对象。
    public T Spawn()
    {
        return Spawn(string.Empty);
    }



    /// 
    /// 回收对象。
    /// 
    /// 要回收的对象。
    public void Unspawn(T obj)
    {
        if (obj == null)
        {
            throw new GameFrameworkException("Object is invalid.");
        }

        Unspawn(obj.Target);
    }



    //对象池的自动释放机制

    internal override void Update(float elapseSeconds, float realElapseSeconds)

    {

        m_AutoReleaseTime += realElapseSeconds;

        if (m_AutoReleaseTime < m_AutoReleaseInterval)
        {

            return;
        }
        Release();

    }
    /// 
    /// 释放对象池中的可释放对象。
    /// 
    public override void Release()

    {

        Release(Count - m_Capacity, m_DefaultReleaseObjectFilterCallback);

    }
}

Object

Object相当于给T类型规定了共同的行为

/// 
/// 内部对象。
/// 
/// 对象类型。
private sealed class Object : IReference where T : ObjectBase

{

    private T m_Object;

    private int m_SpawnCount;



    /// 
    /// 创建内部对象。
    /// 
    /// 对象。
    /// 对象是否已被获取。
    /// 创建的内部对象。
    public static Object Create(T obj, bool spawned)

    {

        Object internalObject = ReferencePool.Acquire>();

        internalObject.m_Object = obj;

        internalObject.m_SpawnCount = spawned ? 1 : 0;

        if (spawned)

        {

            obj.OnSpawn();

        }



        return internalObject;

    }



    /// 
    /// 获取对象。
    /// 
    /// 对象。
    public T Spawn()

    {

        m_SpawnCount++;

        m_Object.LastUseTime = DateTime.Now;

        m_Object.OnSpawn();

        return m_Object;

    }



    /// 
    /// 回收对象。
    /// 
    public void Unspawn()

    {

        m_Object.OnUnspawn();

        m_Object.LastUseTime = DateTime.Now;

        m_SpawnCount--;

        if (m_SpawnCount < 0)

        {

            throw new GameFrameworkException(Utility.Text.Format("Object '{0}' spawn count is less than 0.", Name));

        }

    }



    /// 
    /// 释放对象。
    /// 
    /// 是否是关闭对象池时触发。
    public void Release(bool isShutdown)

    {

        m_Object.Release(isShutdown);

        ReferencePool.Release(m_Object);

    }

}

小结

GF对象池实现了对象池的基本功能

多个对象池的统一管理

对象的获取回收与释放,对象的复用

对象的自动释放机制

实际使用,简洁引用关系图

使用实践

using GameFramework;
using StarForce;
using GameFramework.Resource;
using GameFramework.ObjectPool;



public class TestNode:MonoBehaviour

{



    public GameObject testObj;
//Cube预制
    public List objlist=new List();



    private IObjectPool TestObjectPool = null;



    private void Awake()

    {

    

    }



    private void Start()

    {

        TestObjectPool = GameEntry.ObjectPool.CreateSingleSpawnObjectPool(5f);

    }



    private void Update()

    {

        if (Input.GetKeyDown(KeyCode.N))

        {

            GameObject obj;

            obj = Instantiate(testObj);

            objlist.Add(obj);

            TestObjectPool.Register(TestObject.Create(obj),true);

        }



        if (Input.GetKeyDown(KeyCode.M))

        {

            Debug.LogError("回收对象");

            objlist[0].SetActive(false);

            TestObjectPool.Unspawn(objlist[0]);

            objlist.RemoveAt(0);

        }

    }





}



public class TestObject : ObjectBase

{

    public static TestObject Create(object target)

    {

        Debug.LogError("创建对象");



        TestObject testObject = ReferencePool.Acquire();

        testObject.Initialize(target);

        return testObject;

    }



    protected override void Release(bool isShutdown)

    {



        

        GameObject testMonoObject = (GameObject)Target;

        if (testMonoObject == null)

        {

            return;

        }

        Debug.LogError("释放对象");


        Object.Destroy(testMonoObject.gameObject);

    }

}
运行结果