Files
zeling_v2/Assets/_Game/Scripts/World/RoomTransition.cs

84 lines
3.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using BaseGames.Core.Events;
using UnityEngine;
namespace BaseGames.World
{
/// <summary>
/// 房间传送点。玩家进入触发器或按交互键时,广播 <see cref="SceneLoadRequest"/>
/// 由 SceneLoader 监听并执行 Additive 场景加载/卸载。
/// </summary>
[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,
});
}
/// <summary>检查玩家是否持有指定物品(通过 WorldStateRegistry.IsCollected 检查)。</summary>
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<Collider2D>();
if (col != null)
Gizmos.DrawWireCube(transform.position, col.bounds.size);
}
}
}