using BaseGames.Core.Events; using UnityEngine; namespace BaseGames.World { /// /// 房间传送点。玩家进入触发器或按交互键时,广播 , /// 由 SceneLoader 监听并执行 Additive 场景加载/卸载。 /// [RequireComponent(typeof(Collider2D))] public class RoomTransition : MonoBehaviour, IInteractable { [Header("本传送门标识")] [SerializeField] private string _transitionId; // 本出口唯一 ID(供 SceneLoader 写入复活点) [Header("目标")] [SerializeField] private string _targetSceneAddress; // Addressable key(目标场景) [SerializeField] private string _targetTransitionId; // 目标房间出生点 ID [Header("触发方式")] [SerializeField] private bool _autoTrigger = true; // true = 玩家进入触发器自动触发 [Header("钥匙物品校验")] [SerializeField] private bool _requiresKeyItem; // 是否需要持有指定钥匙物品 [SerializeField] private string _requiredItemId; // 钥匙物品 ID(_requiresKeyItem = true 时生效) [Header("事件频道")] [SerializeField] private SceneLoadRequestEventChannelSO _onSceneLoadRequest; [Header("世界状态")] [SerializeField] private WorldStateRegistry _worldState; // ── IInteractable ───────────────────────────────────────────────────── public bool CanInteract => !_autoTrigger; public string InteractPrompt => "前往下一区域"; public void Interact(Transform player) => RequestTransition(); public void OnPlayerEnterRange(Transform player) { } public void OnPlayerExitRange() { } // ── Auto Trigger ────────────────────────────────────────────────────── private void OnTriggerEnter2D(Collider2D other) { if (!_autoTrigger) return; if (!other.CompareTag("Player")) return; RequestTransition(); } private void RequestTransition() { if (_requiresKeyItem && !HasItem(_requiredItemId)) return; _onSceneLoadRequest?.Raise(new SceneLoadRequest { SceneName = _targetSceneAddress, EntryTransitionId = _targetTransitionId, ShowLoadingScreen = true, IsRespawn = false, }); } /// 检查玩家是否持有指定物品(通过 WorldStateRegistry.IsCollected 检查)。 private bool HasItem(string itemId) { if (string.IsNullOrEmpty(itemId)) return true; if (_worldState == null) { Debug.LogWarning($"[RoomTransition] WorldStateRegistry 未配置,销 {itemId} 检查跳过"); return false; } return _worldState.IsCollected(itemId); } private void OnDrawGizmos() { Gizmos.color = new Color(0f, 1f, 0.5f, 0.6f); var col = GetComponent(); if (col != null) Gizmos.DrawWireCube(transform.position, col.bounds.size); } } }