using UnityEngine; namespace BaseGames.Enemies { /// /// 竞技场锚点集合:Boss 定点走位(跳到悬空平台、传送到房间固定角落)的坐标来源。 /// 挂在 Boss 上;锚点物体本身放在场景里(随房间布局走,不进 SO)。 /// /// AI 图不直接持有本组件——坐标经 取得 /// (图的 lambda 不得闭包捕获实例)。BossBase 在 Awake 解析本组件并转发。 /// public sealed class BossArenaAnchors : MonoBehaviour { [Tooltip("锚点物体(顺序即下标,AI 图按下标引用)")] [SerializeField] private Transform[] _anchors; public int Count => _anchors != null ? _anchors.Length : 0; /// 取第 index 个锚点坐标。下标越界或漏配即抛——不静默回退到自身位置。 public Vector2 At(int index) { if (_anchors == null || index < 0 || index >= _anchors.Length) throw new System.IndexOutOfRangeException( $"[BossArenaAnchors] {name} 请求锚点下标 {index},但只配了 {Count} 个。" + "请在 Inspector 补齐锚点,或修正 AI 图里的下标。"); var t = _anchors[index]; if (t == null) throw new System.InvalidOperationException( $"[BossArenaAnchors] {name} 第 {index} 个锚点为空引用。请在 Inspector 指定。"); return t.position; } #if UNITY_EDITOR private void OnValidate() { if (_anchors == null) return; for (int i = 0; i < _anchors.Length; i++) if (_anchors[i] == null) Debug.LogError($"[BossArenaAnchors] {name} 第 {i} 个锚点未指定。", this); } private void OnDrawGizmosSelected() { if (_anchors == null) return; Gizmos.color = new Color(1f, 0.8f, 0.2f, 0.9f); for (int i = 0; i < _anchors.Length; i++) { if (_anchors[i] == null) continue; Gizmos.DrawWireSphere(_anchors[i].position, 0.35f); UnityEditor.Handles.Label(_anchors[i].position, $"anchor {i}"); } } #endif } }