加载中...

【Unity系列】游戏中对象太多卡成PPT?那你该用对象池 (Object Pool) 了

  • 2025-08-23
  • 游戏开发
  • unity教程 游戏开发
  • --

在游戏开发中,频繁创建和销毁对象会带来性能开销,尤其是子弹、特效、怪物等需要反复生成的对象。Unity在 Instantiate 和 Destroy 时会触发内存分配与垃圾回收 (GC),如果数量较多,可能导致帧率波动和卡顿。

对象池 (Object Pool)  的核心思想是:一次性创建对象,循环使用,避免反复销毁和分配

基础实现

最简单的对象池可以用一个 Queue 或 List 来管理。

using UnityEngine;
using System.Collections.Generic;
public class ObjectPool : MonoBehaviour{
    public GameObject prefab;
    public int initialSize = 10;    
    private Queue<GameObject> pool = new Queue<GameObject>();
    void Start() {
        for (int i = 0; i < initialSize; i++) {
            GameObject obj = Instantiate(prefab);
            obj.SetActive(false);
            pool.Enqueue(obj);
        }
    }
    public GameObject Get() {
        if (pool.Count > 0) {
            GameObject obj = pool.Dequeue();
            obj.SetActive(true);
            return obj;
        }
        // 池子不够时可选择扩容
        GameObject newObj = Instantiate(prefab);
        return newObj;
    }
    public void Release(GameObject obj) {
        obj.SetActive(false);
        pool.Enqueue(obj);
    }
}

使用时,可以通过 Get() 获取对象,使用完再调用 Release() 归还。

应用场景

  1. 子弹系统

    射击类游戏子弹数量巨大,使用对象池能避免频繁GC。

  2. 特效播放

    爆炸、击中特效往往短暂但数量多,适合对象池管理。

  3. 敌人或NPC生成

    在波次制游戏中,敌人重复出现,适合通过对象池复用。

优化思路

  1. 分组管理

    根据不同对象类型建立多个池,例如子弹池、特效池。

  2. 预扩容

    在加载关卡时预先生成对象,避免运行中卡顿。

  3. 回收策略

    对象池过大时,可以限制最大容量,超出部分销毁。

  4. 自动归还

   对象本身可在逻辑结束后自动调用 Release(),避免遗忘。

实战案例:子弹系统

public class Bullet : MonoBehaviour{
    private float lifeTime = 2f;
    private float timer;
    private ObjectPool pool;
    public void Init(ObjectPool p) {
        pool = p;
        timer = 0f;
    }
    void Update() {
        timer += Time.deltaTime;
        if (timer >= lifeTime) {
            pool.Release(gameObject);
        }
    }
}

发射子弹时:

GameObject bullet = bulletPool.Get();
bullet.transform.position = firePoint.position;
bullet.GetComponent<Bullet>().Init(bulletPool);

这样子弹生命周期结束时会自动回收,避免了手动管理的复杂性。

注意事项

  • 对象池管理的对象不宜过于复杂,否则初始化成本过高。

  • 在多人协作中要统一对象池接口,避免不同系统重复实现。

  • Unity自带的 Pooling 在UI系统中也有应用,例如 ScrollView 的元素复用,原理类似。

小结

对象池是Unity性能优化中最常见、最实用的技巧之一:

  • 避免频繁的 Instantiate 与 Destroy;

  • 适合高频、短生命周期的对象;

  • 可通过扩容、分组和自动归还机制进一步优化。

合理使用对象池,可以显著减少GC带来的卡顿,提高游戏运行的流畅度。下一篇我们将介绍 事件系统与观察者模式 ,它能进一步降低模块间耦合。

Maple
Maple
© 2025 by Maplezz 本文基于 CC BY-NC-SA 4.0 许可 CC 协议 必须注明创作者 仅允许将作品用于非商业用途 改编作品必须遵循相同条款进行共享 最后更新:2025/8/26