组件池管理
对于一些频繁要创建销毁的组件,也可以进行进行对象池管理,但是这里是以组件为主体来进行对象管理的,实际上存放的仍然是预制体。
一下是ds给的流程图和具体实现:
未实践
组件池管理系统流程图

具体实现
核心架构设计
`
using System;
using System.Collections.Generic;
using UnityEngine;
// 通用组件池基类
public abstract class BaseComponentPool
{
public abstract void ReturnComponent(Component component);
public abstract Type ComponentType { get; }
}
// 泛型组件池
public class ComponentPool
{
private Queue
private GameObject prefab;
private Transform parent;
public override Type ComponentType => typeof(T);
public ComponentPool(GameObject prefab, int initialSize, Transform parent = null)
{
this.prefab = prefab;
this.parent = parent;
for (int i = 0; i < initialSize; i++)
{
CreateComponent();
}
}
// ... (Get/Return方法实现同前)
private T CreateComponent()
{
GameObject obj = Object.Instantiate(prefab, parent);
T component = obj.GetComponent<T>();
obj.SetActive(false);
pool.Enqueue(component);
return component;
}
public T Get()
{
if (pool.Count == 0)
{
CreateComponent();
}
T component = pool.Dequeue();
component.gameObject.SetActive(true);
return component;
}
public void Return(T component)
{
component.gameObject.SetActive(false);
// 重置组件状态
ResetComponent(component);
pool.Enqueue(component);
}
protected virtual void ResetComponent(T component)
{
// 可被子类重写的重置逻辑
}
}
// 通用组件池管理器
public class ComponentPoolManager : MonoBehaviour
{
[System.Serializable]
public class PoolConfig
{
public string poolName;
public GameObject prefab;
public Type componentType; // 存储组件类型
public int initialSize = 10;
}
private static ComponentPoolManager _instance;
public static ComponentPoolManager Instance => _instance;
[SerializeField] private List<PoolConfig> poolConfigs;
private Dictionary<string, BaseComponentPool> pools = new Dictionary<string, BaseComponentPool>();
private Dictionary<Type, List<string>> typeToPoolMap = new Dictionary<Type, List<string>>();
void Awake()
{
if (_instance != null && _instance != this)
{
Destroy(gameObject);
return;
}
_instance = this;
DontDestroyOnLoad(gameObject);
InitializePools();
}
private void InitializePools()
{
foreach (var config in poolConfigs)
{
// 使用反射创建泛型池
Type poolType = typeof(ComponentPool<>).MakeGenericType(config.componentType);
BaseComponentPool pool = (BaseComponentPool)Activator.CreateInstance(
poolType,
config.prefab,
config.initialSize,
transform
);
pools.Add(config.poolName, pool);
// 建立类型到池名的映射
if (!typeToPoolMap.ContainsKey(config.componentType))
{
typeToPoolMap[config.componentType] = new List<string>();
}
typeToPoolMap[config.componentType].Add(config.poolName);
}
}
// 获取指定类型的组件
public T GetFromPool<T>(string poolName) where T : Component
{
if (pools.TryGetValue(poolName, out BaseComponentPool basePool))
{
if (basePool is ComponentPool<T> typedPool)
{
return typedPool.Get();
}
}
Debug.LogError($"Pool {poolName} doesn't contain type {typeof(T)}");
return null;
}
// 通用归还方法
public void ReturnToPool(Component component, string poolName = null)
{
Type componentType = component.GetType();
// 自动检测所属池
if (string.IsNullOrEmpty(poolName))
{
if (typeToPoolMap.TryGetValue(componentType, out var possiblePools))
{
if (possiblePools.Count == 1)
{
poolName = possiblePools[0];
}
else
{
Debug.LogError($"Multiple pools exist for type {componentType}. Specify pool name.");
return;
}
}
else
{
Debug.LogError($"No pool registered for type {componentType}");
return;
}
}
if (pools.TryGetValue(poolName, out var pool))
{
pool.ReturnComponent(component);
}
}
// 编辑器友好方法:添加池配置
public void AddPoolConfig(string name, GameObject prefab, Type componentType, int size = 10)
{
#if UNITY_EDITOR
if (!Application.isPlaying)
{
poolConfigs.Add(new PoolConfig
{
poolName = name,
prefab = prefab,
componentType = componentType,
initialSize = size
});
return;
}
#endif
// 运行时动态添加池
Type poolType = typeof(ComponentPool<>).MakeGenericType(componentType);
BaseComponentPool pool = (BaseComponentPool)Activator.CreateInstance(
poolType,
prefab,
size,
transform
);
pools.Add(name, pool);
if (!typeToPoolMap.ContainsKey(componentType))
{
typeToPoolMap[componentType] = new List<string>();
}
typeToPoolMap[componentType].Add(name);
}
}`
专用组件池实现(以CharacterController为例)
`public class CharacterControllerPool : ComponentPool
{
public CharacterControllerPool(GameObject prefab, int size, Transform parent)
: base(prefab, size, parent) { }
protected override void ResetComponent(CharacterController controller)
{
// 重置CharacterController状态
controller.enabled = false;
controller.transform.position = Vector3.zero;
controller.transform.rotation = Quaternion.identity;
controller.enabled = true;
}
}`
编辑器扩展(使配置更友好)
`#if UNITY_EDITOR
[CustomEditor(typeof(ComponentPoolManager))]
public class ComponentPoolManagerEditor : Editor
{
private SerializedProperty poolConfigs;
void OnEnable()
{
poolConfigs = serializedObject.FindProperty("poolConfigs");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(poolConfigs);
if (GUILayout.Button("Add New Pool"))
{
ComponentPoolManager manager = (ComponentPoolManager)target;
manager.AddPoolConfig("NewPool", null, typeof(MonoBehaviour), 10);
}
serializedObject.ApplyModifiedProperties();
}
}
endif`
使用示例
`// 初始化多种类型的池
public class GameInitializer : MonoBehaviour
{
public GameObject playerPrefab;
public GameObject bulletPrefab;
public GameObject effectPrefab;
void Start()
{
ComponentPoolManager.Instance.AddPoolConfig(
"PlayerControllers",
playerPrefab,
typeof(CharacterController),
5
);
ComponentPoolManager.Instance.AddPoolConfig(
"BulletRigidbodies",
bulletPrefab,
typeof(Rigidbody),
50
);
ComponentPoolManager.Instance.AddPoolConfig(
"ExplosionEffects",
effectPrefab,
typeof(ParticleSystem),
20
);
}
}
// 在游戏中使用
public class PlayerShooting : MonoBehaviour
{
void Fire()
{
// 获取子弹刚体组件
Rigidbody bulletRb = ComponentPoolManager.Instance
.GetFromPool
bulletRb.transform.position = gunBarrel.position;
bulletRb.velocity = transform.forward * bulletSpeed;
// 获取爆炸效果
ParticleSystem explosion = ComponentPoolManager.Instance
.GetFromPool<ParticleSystem>("ExplosionEffects");
explosion.transform.position = targetPosition;
explosion.Play();
}
void OnHit()
{
// 归还组件(自动检测类型)
ComponentPoolManager.Instance.ReturnToPool(GetComponent<CharacterController>());
}
}`
智能组件归还
`// 不需要指定池名(自动检测)
ComponentPoolManager.Instance.ReturnToPool(myComponent);
// 明确指定池名
ComponentPoolManager.Instance.ReturnToPool(myComponent, "PlayerControllers");`
预制体复用系统
`public class MultiComponentPool
{
private Dictionary<Type, BaseComponentPool> subPools = new Dictionary<Type, BaseComponentPool>();
public MultiComponentPool(GameObject prefab, Transform parent)
{
// 自动为预制体上的所有组件创建子池
foreach (var component in prefab.GetComponents<Component>())
{
Type type = component.GetType();
if (!subPools.ContainsKey(type))
{
Type poolType = typeof(ComponentPool<>).MakeGenericType(type);
subPools[type] = (BaseComponentPool)Activator.CreateInstance(
poolType, prefab, 0, parent);
}
}
}
public T Get<T>() where T : Component
{
if (subPools.TryGetValue(typeof(T), out var pool))
{
return ((ComponentPool<T>)pool).Get();
}
return null;
}
}`
性能优化策略
类型缓存系统:
`private static Dictionary<Type, Type> poolTypeCache = new Dictionary<Type, Type>();
private Type GetPoolType(Type componentType)
{
if (!poolTypeCache.TryGetValue(componentType, out Type poolType))
{
poolType = typeof(ComponentPool<>).MakeGenericType(componentType);
poolTypeCache.Add(componentType, poolType);
}
return poolType;
}`
批处理初始化:
IEnumerator InitializePoolsCoroutine() { foreach (var config in poolConfigs) { // 每帧初始化一个池 AddPoolConfig(config.poolName, config.prefab, config.componentType, config.initialSize); yield return null; } }
内存监控与清理:
void Update() { // 每60帧清理一次未使用组件 if (Time.frameCount % 60 == 0) { foreach (var pool in pools.Values) { if (pool is IDisposable disposablePool) { disposablePool.CleanUnused(Time.unscaledTime - 10f); // 清理10秒未使用的 } } } }
常用组件预配置:
// 在编辑器中预配置常用池 [SerializeField] private ComponentPoolManager.PoolConfig[] defaultPools = { new() { poolName = "MainPlayer", prefab = playerPrefab, componentType = typeof(CharacterController) }, new() { poolName = "Enemies", prefab = enemyPrefab, componentType = typeof(AIController)) } };
根据组件的功能类别、性能特征或使用频率将组件池划分为不同层次的管理策略
那就是分层池管理

- 优化内存使用:高频组件预分配更多实例
- 提高访问效率:核心组件独立管理
- 实现优先级控制:重要组件优先分配
- 隔离影响域:避免不同类型组件互相干扰
1. 核心组件层 (Critical Layer)
定位:游戏运行必需的基础组件
特点:
高优先级
常驻内存
严格的生命周期管理
典型组件:
CharacterController:角色移动控制
Rigidbody:物理模拟
NavMeshAgent:AI导航
2. 特效组件层 (VFX Layer)
定位:视觉/听觉特效组件
特点:
瞬时爆发性使用
生命周期短
允许延迟创建
典型组件:
ParticleSystem:粒子特效
AudioSource:音效播放
TrailRenderer:拖尾效果
3. UI组件层 (UI Layer)
定位:用户界面相关组件
特点:
常与Canvas耦合
状态重置复杂
需要布局管理
典型组件:
Image:UI图片
TextMeshProUGUI:文本组件
ScrollRect:滚动视图
4. 网络组件层 (Network Layer)
定位:网络同步相关组件
特点:
需要跨帧状态管理
数据序列化支持
带宽优化要求
典型组件:
NetworkTransform:网络位置同步
NetworkAnimator:网络动画同步
RpcHandler:远程调用处理器
浙公网安备 33010602011771号