feat(world): 检查点复活位置由 RespawnPoint 子节点显式配置
CheckpointMarker 新增 _respawnPoint 引用,注册的检查点位置改为 该子节点的位置——触发区与出生点解耦,触发区可横跨通道、出生点 精确落在安全平台上。漏配时 Awake 显式报错且不注册(不以标记 自身位置兜底)。Gizmos 增画复活点(青色)与触发区连线,漏配 画红叉警示。PlaceCheckpointMarker 脚手架自动创建并绑定 RespawnPoint 子节点。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -13,6 +13,8 @@ namespace BaseGames.World
|
||||
/// - 激活状态仅存于运行时,不持久化,换房间后重置
|
||||
/// - 闩锁按接触周期:进入时注册并广播一次,离开触发区后重置,
|
||||
/// 同一次接触内不重复结算
|
||||
/// - 触发区与出生位置解耦:注册的是 _respawnPoint 子节点的位置,
|
||||
/// 触发区可横跨通道,出生点精确落在安全平台上
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(Collider2D))]
|
||||
public class CheckpointMarker : MonoBehaviour
|
||||
@@ -21,6 +23,10 @@ namespace BaseGames.World
|
||||
[Tooltip("勾选 Player 层")]
|
||||
[SerializeField] private LayerMask _playerLayers;
|
||||
|
||||
[Header("复活点")]
|
||||
[Tooltip("玩家回溯时出现的位置(必配,脚手架自动创建 RespawnPoint 子节点)")]
|
||||
[SerializeField] private Transform _respawnPoint;
|
||||
|
||||
[Header("事件")]
|
||||
[Tooltip("EVT_CheckpointReached — 激活时广播,供 VFX/SFX 使用")]
|
||||
[SerializeField] private VoidEventChannelSO _onCheckpointReached;
|
||||
@@ -38,15 +44,20 @@ namespace BaseGames.World
|
||||
col.isTrigger = true;
|
||||
Debug.LogWarning($"[CheckpointMarker] {name}: Collider2D.isTrigger 已自动设为 true。", this);
|
||||
}
|
||||
|
||||
if (_respawnPoint == null)
|
||||
Debug.LogError($"[CheckpointMarker] {name}: _respawnPoint 未绑定,检查点无法注册。" +
|
||||
"请用脚手架(BaseGames/Scene/Place/Checkpoint Marker)创建,或手动补 RespawnPoint 子节点并绑定。", this);
|
||||
}
|
||||
|
||||
private void OnTriggerEnter2D(Collider2D other)
|
||||
{
|
||||
if (_isActivated) return;
|
||||
if ((_playerLayers.value & (1 << other.gameObject.layer)) == 0) return;
|
||||
if (_respawnPoint == null) return; // 漏配已在 Awake 报错,此处不以标记自身位置兜底
|
||||
|
||||
_isActivated = true;
|
||||
ServiceLocator.GetOrDefault<ICheckpointService>()?.RegisterCheckpoint(transform.position);
|
||||
ServiceLocator.GetOrDefault<ICheckpointService>()?.RegisterCheckpoint(_respawnPoint.position);
|
||||
_onCheckpointReached?.Raise();
|
||||
}
|
||||
|
||||
@@ -64,6 +75,23 @@ namespace BaseGames.World
|
||||
Gizmos.DrawWireSphere(transform.position, 0.4f);
|
||||
Gizmos.DrawLine(transform.position + Vector3.down * 0.4f,
|
||||
transform.position + Vector3.up * 0.8f);
|
||||
|
||||
// 复活点:青色小球 + 落点竖线 + 与触发区的连线;漏配画红叉警示
|
||||
if (_respawnPoint != null)
|
||||
{
|
||||
Gizmos.color = new Color(0f, 0.8f, 1f, 0.9f);
|
||||
Gizmos.DrawWireSphere(_respawnPoint.position, 0.25f);
|
||||
Gizmos.DrawLine(_respawnPoint.position + Vector3.down * 0.5f,
|
||||
_respawnPoint.position + Vector3.up * 0.5f);
|
||||
Gizmos.color = new Color(0f, 0.8f, 1f, 0.4f);
|
||||
Gizmos.DrawLine(transform.position, _respawnPoint.position);
|
||||
}
|
||||
else
|
||||
{
|
||||
Gizmos.color = Color.red;
|
||||
Gizmos.DrawLine(transform.position + new Vector3(-0.3f, -0.3f), transform.position + new Vector3(0.3f, 0.3f));
|
||||
Gizmos.DrawLine(transform.position + new Vector3(-0.3f, 0.3f), transform.position + new Vector3(0.3f, -0.3f));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user