using System.Collections.Generic;
using UnityEngine;
///
/// 鱼对象池 - 复用鱼对象避免频繁 Instantiate/Destroy
///
public class FishObjectPool : MonoBehaviour
{
public static FishObjectPool Instance { get; private set; }
[System.Serializable]
public class PoolConfig
{
public FishType fishType;
public int initialSize = 5; // 初始池大小
public int maxSize = 20; // 最大池大小
}
[Header("对象池配置")]
public List poolConfigs = new List();
// 对象池字典:FishType -> 对象队列
private Dictionary> fishPools = new Dictionary>();
private Dictionary configMap = new Dictionary();
// 记录从池中取出的对象,用于回收时识别类型
private Dictionary activeFishMap = new Dictionary();
void Awake()
{
Instance = this;
}
///
/// 初始化对象池 - 在游戏开始前调用
///
public void InitializePools()
{
// 构建配置映射
foreach (var config in poolConfigs)
{
configMap[config.fishType] = config;
}
// 为每种配置的鱼创建初始池
foreach (var config in poolConfigs)
{
CreatePool(config.fishType, config.initialSize);
}
Debug.Log($"[FishObjectPool] 对象池初始化完成,共 {poolConfigs.Count} 种鱼类型");
}
///
/// 创建指定类型的对象池
///
void CreatePool(FishType fishType, int size)
{
fishPools[fishType] = new Queue();
int fishId = (int)fishType;
GameObject prefab = GameManager.Ins.GetFishPre(fishId - 1);
if (prefab == null)
{
Debug.LogError($"[FishObjectPool] 找不到鱼预制体: {fishType}");
return;
}
// 预创建对象
for (int i = 0; i < size; i++)
{
GameObject fish = Instantiate(prefab, transform);
// 禁用 SplineController,防止在隐藏状态下运行并报错
var splineController = fish.GetComponent();
if (splineController != null)
{
splineController.enabled = false;
}
fish.SetActive(false);
fishPools[fishType].Enqueue(fish);
}
}
///
/// 从对象池获取鱼
///
public GameObject GetFish(FishType fishType)
{
// 确保池存在
if (!fishPools.ContainsKey(fishType))
{
// 如果没有配置,使用默认配置创建
var config = new PoolConfig { fishType = fishType, initialSize = 3, maxSize = 10 };
configMap[fishType] = config;
CreatePool(fishType, config.initialSize);
}
var pool = fishPools[fishType];
GameObject fish = null;
// 从池中取出一个可用的对象
while (pool.Count > 0)
{
fish = pool.Dequeue();
if (fish != null) // 防止对象已被销毁
{
break;
}
}
// 池为空则创建新对象
if (fish == null)
{
int fishId = (int)fishType;
GameObject prefab = GameManager.Ins.GetFishPre(fishId - 1);
if (prefab != null)
{
fish = Instantiate(prefab);
Debug.Log($"[FishObjectPool] 池为空,创建新对象: {fishType}");
}
}
if (fish != null)
{
// 在激活前确保 SplineController 被禁用
// 防止在 Init 设置 Spline 之前 Update 运行
var splineController = fish.GetComponent();
if (splineController != null)
{
splineController.enabled = false;
}
fish.SetActive(true);
activeFishMap[fish] = fishType;
}
return fish;
}
///
/// 回收鱼到对象池
///
public void ReturnFish(GameObject fish)
{
if (fish == null) return;
// 获取鱼的类型
if (!activeFishMap.TryGetValue(fish, out FishType fishType))
{
// 如果找不到类型映射,尝试从 Fish 组件获取
var fishComponent = fish.GetComponent();
if (fishComponent != null && fishComponent.Data != null)
{
fishType = (FishType)fishComponent.Data.FishId;
}
else
{
// 无法识别类型,直接销毁
Destroy(fish);
return;
}
}
// 从活跃映射中移除
activeFishMap.Remove(fish);
// 确保池存在
if (!fishPools.ContainsKey(fishType))
{
fishPools[fishType] = new Queue();
}
var pool = fishPools[fishType];
var config = configMap.ContainsKey(fishType) ? configMap[fishType] : null;
// 如果池未满,回收对象
if (config == null || pool.Count < config.maxSize)
{
// 重置对象状态
fish.SetActive(false);
fish.transform.SetParent(transform);
fish.transform.localPosition = Vector3.zero;
// 重置 Fish 组件状态
var fishComponent = fish.GetComponent();
if (fishComponent != null)
{
fishComponent.ResetForPool();
}
pool.Enqueue(fish);
}
else
{
// 池已满,销毁对象
Destroy(fish);
}
}
///
/// 清空所有对象池
///
public void ClearAllPools()
{
foreach (var pool in fishPools.Values)
{
while (pool.Count > 0)
{
var fish = pool.Dequeue();
if (fish != null)
{
Destroy(fish);
}
}
}
fishPools.Clear();
activeFishMap.Clear();
}
///
/// 获取池状态信息(调试用)
///
public string GetPoolStatus()
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.AppendLine("[FishObjectPool] 对象池状态:");
foreach (var pair in fishPools)
{
sb.AppendLine($" {pair.Key}: {pair.Value.Count} 个可用");
}
return sb.ToString();
}
}