using UnityEngine; using BaseGames.Core; using BaseGames.Core.Assets; namespace BaseGames.World { /// /// 可收集物生成器(静态工具类)。 /// 封装 Geo / 道具 Collectible 的 Spawn 逻辑,供 LootResolver 等调用。 /// 优先通过 IObjectPoolService 从对象池取用(需预热 COL_Geo / COL_Item); /// 池服务不可用时退回 Object.Instantiate(仅限编辑器 / 单元测试场景)。 /// Prefab 引用通过 CollectibleSpawnerConfig 注入,避免 Resources.Load。 /// public static class CollectibleSpawner { /// /// 全局配置引用(由 CollectibleSpawnerConfig.Awake() 注册)。 /// private static CollectibleSpawnerConfig _config; /// 由 CollectibleSpawnerConfig.Awake() 注册自身。 internal static void Register(CollectibleSpawnerConfig config) => _config = config; /// /// 在世界坐标生成 Geo 拾取物。 /// 优先从 GlobalObjectPool 取用(key = AddressKeys.PrefabCollectibleGeo), /// 池服务不可用时退回 Object.Instantiate。 /// public static void SpawnGeo(Vector2 position, int amount) { var go = SpawnFromPool(AddressKeys.PrefabCollectibleGeo, position) ?? InstantiateFallback(_config?.GeoPrefab, position, $"[CollectibleSpawner] GeoPrefab 未配置,Geo x{amount} 无法生成 at {position}"); if (go != null && go.TryGetComponent(out var c)) c.SetGeo(amount); } /// /// 在世界坐标生成道具拾取物(通过 itemId 广播 EVT_CollectiblePickup)。 /// 优先从 GlobalObjectPool 取用(key = AddressKeys.PrefabCollectibleItem), /// 池服务不可用时退回 Object.Instantiate。 /// public static void SpawnItem(Vector2 position, string itemId) { var go = SpawnFromPool(AddressKeys.PrefabCollectibleItem, position) ?? InstantiateFallback(_config?.ItemPrefab, position, $"[CollectibleSpawner] ItemPrefab 未配置,物品 {itemId} 无法生成 at {position}"); if (go != null && go.TryGetComponent(out var c)) c.SetItem(itemId); } // ── 内部工具 ────────────────────────────────────────────────────── private static GameObject SpawnFromPool(string key, Vector2 position) => ServiceLocator.GetOrDefault() ?.Spawn(key, position, Quaternion.identity); private static GameObject InstantiateFallback(GameObject prefab, Vector2 position, string warnMsg) { if (prefab == null) { Debug.LogWarning(warnMsg); return null; } return Object.Instantiate(prefab, position, Quaternion.identity); } } }