using UnityEngine; using BaseGames.Core; using BaseGames.Core.Events; using BaseGames.World; namespace BaseGames.Challenge { /// /// 挑战房间入口触发物(架构 22_QuestChallengeModule §13)。 /// 实现 IInteractable,玩家交互后通过事件频道触发挑战场景加载。 /// ⚠️ SceneLoader 无 Instance;通过 EVT_SceneLoadRequest 频道触发加载(架构 03 §3)。 /// [RequireComponent(typeof(Collider2D))] public class ChallengeRoomTrigger : MonoBehaviour, IInteractable { [SerializeField] private ChallengeRoomSO _challengeData; [SerializeField] private string _challengeSceneName; [SerializeField] private SceneLoadRequestEventChannelSO _onSceneLoadRequest; // EVT_SceneLoadRequest // ── IInteractable ────────────────────────────────────────────────── public string InteractPrompt => _challengeData != null ? $"进入挑战:{_challengeData.displayName}" : "进入挑战"; public bool CanInteract => IsUnlocked(); public void Interact(Transform player) { if (!IsUnlocked()) return; _onSceneLoadRequest?.Raise(new SceneLoadRequest { SceneName = _challengeSceneName, EntryTransitionId = string.Empty, ShowLoadingScreen = false, IsRespawn = false, }); } public void OnPlayerEnterRange(Transform player) { } public void OnPlayerExitRange() { } // ── 私有 ───────────────────────────────────────────────────────── private bool IsUnlocked() { if (_challengeData?.prerequisiteBossIds == null) return true; var sm = ServiceLocator.GetOrDefault(); if (sm == null) return false; foreach (var bossId in _challengeData.prerequisiteBossIds) if (!sm.IsBossDefeated(bossId)) return false; return true; } } }