摄像机区域的架构改动
This commit is contained in:
83
Assets/_Game/Scripts/World/RoomTransition.cs
Normal file
83
Assets/_Game/Scripts/World/RoomTransition.cs
Normal file
@@ -0,0 +1,83 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user