组件池管理

对于一些频繁要创建销毁的组件,也可以进行进行对象池管理,但是这里是以组件为主体来进行对象管理的,实际上存放的仍然是预制体。

一下是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 : BaseComponentPool where T : Component
{
private Queue pool = new 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("BulletRigidbodies");

    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. 优化内存使用:高频组件预分配更多实例
  2. 提高访问效率:核心组件独立管理
  3. 实现优先级控制:重要组件优先分配
  4. 隔离影响域:避免不同类型组件互相干扰

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:远程调用处理器

posted @ 2025-06-11 16:41  木土无心  阅读(16)  评论(0)    收藏  举报