C# 对象池应用

C# 对象池应用

对象池是游戏编程中非常常用的优化策略以及设计模式。

游戏中,我们常常会遇到频繁地创建销毁大量相同对象的场景。频繁的创建对象会造成GC[1]压力,可能导致卡顿,进而影响游戏体验。

核心思想

将需要重复创建的对象先缓存下来,需要时激活,不需要时停用,从而避免频繁创建对象。

原理

当创建对象时,对象池将对象放入池管理的某种内存连续的数据结构中(数组或者栈等)。当不需要对象时,对象池并不销毁对象,而是将对象回收到池中,下次需要的时候再次从池中拿出来。
因为,对象储存在内存连续的数据结构中,所以解决了内存碎片的问题。
因为,对象每次用完以后就放回池中循环利用而不是再次创建和销毁,这样就解决了频繁的内存分配和销毁的问题。

实例:

/// <summary>
/// 对象池本体
/// </summary>
public List<GameObject> pooledObjects;
/// <summary>
/// 对象池要管理的对象
/// </summary>
public GameObject objectToPool;
/// <summary>
/// 对象池中需要初始化对象的个数
/// </summary>
public int amountToPool;

void Start()
{
    PoolStart();        // 初始化对象池
}

/// <summary>
/// 初始化对象池,克隆对象并将它们添加到列表中
/// </summary>
void PoolStart()
{
    pooledObjects = new List<GameObject>();
    for (int i = 0; i < amountToPool; i++)
    {
        GameObject obj = (GameObject)Instantiate(objectToPool);
        obj.SetActive(false);
        pooledObjects.Add(obj);
        obj.transform.SetParent(this.transform); // 设置其父对象是 脚本所附加对象
    }
}

GameObject GetPooledObject()
{
    // For as many objects as are in the pooledObjects list
    for (int i = 0; i < pooledObjects.Count; i++)
    {
        // if the pooled objects is NOT active, return that object 
        if (!pooledObjects[i].activeInHierarchy)
        {
            return pooledObjects[i];
        }
    }
    // otherwise, return null   
    return null;
}

参考资料

  1. 对象池_百度百科 (baidu.com)
  2. [游戏编程技巧]-对象池 - 知乎 (zhihu.com)
  3. 对象池(Object Pool) - 知乎 (zhihu.com)

  1. Garbage Collection,垃圾回收 ↩︎

posted @ 2022-10-20 16:54  星幕·云影  阅读(263)  评论(0编辑  收藏  举报