using System; using System.Collections.Generic; using System.Linq; using Sirenix.OdinInspector; using SLSUtilities.General; using UnityEngine; namespace Cielonos.MainGame.Map { public partial class ZoneManager : Singleton { [Title("Editor Tools")] [Button("Rebuild Spawn Points"), PropertyOrder(-100)] public void RebuildMapData() { if(spawnPointContainer == null) { Debug.LogWarning("[ZoneManager] Spawn Point Container is not assigned."); return; } spawnPoints.Clear(); // 1. 查找场景中所有生成点 SpawnPoint[] allPoints = spawnPointContainer.GetComponentsInChildren(true); // 2. 按 groupName 分组,并按 Hierarchy 顺序排序 (保证 Index 确定性) var grouped = allPoints .GroupBy(p => p.groupName) .OrderBy(g => g.Key); foreach (var group in grouped) { // 按在 Hierarchy 中的顺序排序列表 var list = group.OrderBy(p => p.transform.GetSiblingIndex()).ToList(); spawnPoints[group.Key] = list; // 3. 将计算好的 Index 写入到具体物体上(持久化) for (int i = 0; i < list.Count; i++) { list[i].SetData(i); // 调用子物体的方法设置数据 } } //Debug.Log($"[ZoneManager] Rebuilt map: Found {allPoints.Length} points in {spawnPoints.Count} groups."); } } // 继承 Singleton 保持运行时单例特性 public partial class ZoneManager { // 运行时查找用的字典 [Title("Runtime Data")] [Required] public GameObject spawnPointContainer; public Dictionary> spawnPoints = new Dictionary>(); protected override void Awake() { base.Awake(); RebuildMapData(); } public void SetupZone(ZoneData data) { // 生成敌人 if (data.enemySpawns != null) { foreach (KeyValuePair enemySpawn in data.enemySpawns) { string group = enemySpawn.Key.group; int index = enemySpawn.Key.index; if (spawnPoints.TryGetValue(group, out List points)) { SpawnPoint point = points[index]; point.GetTransform(out Vector3 position, out Quaternion rotation); GameObject enemyPrefab = MapBaseCollection.Enemies[enemySpawn.Value]; Instantiate(enemyPrefab, position, rotation); } } } // 生成交互物体 SpawnInteractables(data); } /// /// 仅生成交互物体,跳过敌人生成。用于重入已完成的战斗节点。 /// public void SetupZoneWithoutEnemies(ZoneData data) { SpawnInteractables(data); } /// /// 根据 ZoneData 中配置的 interactableSpawns 动态生成所有配置的交互物体。 /// private void SpawnInteractables(ZoneData data) { if (data.interactableSpawns == null) return; // 遍历关卡数据中配置的每一种交互物定义 foreach (var def in data.interactableSpawns) { // 从全局配置合集查找对应的交互物预制体 if (!MapBaseCollection.Interactables.TryGetValue(def.interactableId, out GameObject prefab)) { Debug.LogWarning($"[ZoneManager] 交互物体 '{def.interactableId}' 在 MapBaseCollection.Interactables 中未找到。"); continue; } // 遍历该类型交互物在场景里的所有生成点,逐个进行实例化 foreach (ZoneData.SpawnPointKey key in def.spawnPoints) { if (spawnPoints.TryGetValue(key.group, out List points) && key.index < points.Count) { SpawnPoint point = points[key.index]; point.GetTransform(out Vector3 position, out Quaternion rotation); Instantiate(prefab, position, rotation); } else { Debug.LogWarning($"[ZoneManager] 生成点 '{key.group}_{key.index}' 不存在,跳过 '{def.interactableId}' 的生成。"); } } } } } }