v10 全量评审:修复 TD-06 至 TD-12(InputReader 移除资产扫描回退 / EmergencySave 解除 LocalFileStorage 直接依赖 / AccessibilityManager 注册 IAccessibilityService / HUDController HP/SpringIcon SetActive 复用 / MovingPlatform 缓存 WaitForSeconds / RewardSO IRewardTarget 解耦 Quest←Player 依赖 / CrashReporter 频率限制崩溃日志)

This commit is contained in:
2026-05-12 16:18:46 +08:00
parent ebbbb7332e
commit 9284278578
27 changed files with 1697 additions and 125 deletions

View File

@@ -1,16 +1,20 @@
using UnityEngine;
using BaseGames.Core;
using BaseGames.Core.Assets;
namespace BaseGames.World
{
/// <summary>
/// 可收集物生成器(静态工具类)。
/// 封装 Geo / 道具 Collectible 的实例化逻辑,供 LootResolver 等调用。
/// Prefab 引用通过 CollectibleSpawnerConfig SO 注入,避免 Resources.Load。
/// 封装 Geo / 道具 Collectible 的 Spawn 逻辑,供 LootResolver 等调用。
/// 优先通过 IObjectPoolService 从对象池取用(需预热 COL_Geo / COL_Item
/// 池服务不可用时退回 Object.Instantiate仅限编辑器 / 单元测试场景)。
/// Prefab 引用通过 CollectibleSpawnerConfig 注入,避免 Resources.Load。
/// </summary>
public static class CollectibleSpawner
{
/// <summary>
/// 全局配置引用(由 CollectibleSpawnerConfig.Initialize() 在游戏启动时设置)。
/// 全局配置引用(由 CollectibleSpawnerConfig.Awake() 注册)。
/// </summary>
private static CollectibleSpawnerConfig _config;
@@ -19,40 +23,42 @@ namespace BaseGames.World
/// <summary>
/// 在世界坐标生成 Geo 拾取物。
/// 若配置未注册则仅输出日志(编辑器 / 测试场景兜底)。
/// 优先从 GlobalObjectPool 取用key = AddressKeys.PrefabCollectibleGeo
/// 池服务不可用时退回 Object.Instantiate。
/// </summary>
public static void SpawnGeo(Vector2 position, int amount)
{
if (_config == null || _config.GeoPrefab == null)
{
Debug.LogWarning($"[CollectibleSpawner] GeoPrefab 未配置Geo x{amount} 无法生成 at {position}");
return;
}
var go = Object.Instantiate(_config.GeoPrefab, position, Quaternion.identity);
if (go.TryGetComponent<Collectible>(out var c))
{
var go = SpawnFromPool(AddressKeys.PrefabCollectibleGeo, position)
?? InstantiateFallback(_config?.GeoPrefab, position,
$"[CollectibleSpawner] GeoPrefab 未配置Geo x{amount} 无法生成 at {position}");
if (go != null && go.TryGetComponent<Collectible>(out var c))
c.SetGeo(amount);
}
}
/// <summary>
/// 在世界坐标生成道具拾取物(通过 itemId 广播 EVT_CollectiblePickup
/// 若配置未注册则仅输出日志。
/// 优先从 GlobalObjectPool 取用key = AddressKeys.PrefabCollectibleItem
/// 池服务不可用时退回 Object.Instantiate。
/// </summary>
public static void SpawnItem(Vector2 position, string itemId)
{
if (_config == null || _config.ItemPrefab == null)
{
Debug.LogWarning($"[CollectibleSpawner] ItemPrefab 未配置,物品 {itemId} 无法生成 at {position}");
return;
}
var go = Object.Instantiate(_config.ItemPrefab, position, Quaternion.identity);
if (go.TryGetComponent<Collectible>(out var c))
{
var go = SpawnFromPool(AddressKeys.PrefabCollectibleItem, position)
?? InstantiateFallback(_config?.ItemPrefab, position,
$"[CollectibleSpawner] ItemPrefab 未配置,物品 {itemId} 无法生成 at {position}");
if (go != null && go.TryGetComponent<Collectible>(out var c))
c.SetItem(itemId);
}
}
// ── 内部工具 ──────────────────────────────────────────────────────
private static GameObject SpawnFromPool(string key, Vector2 position)
=> ServiceLocator.GetOrDefault<IObjectPoolService>()
?.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);
}
}
}