using System.Collections; using System.Threading.Tasks; using UnityEngine; using BaseGames.Core.Events; namespace BaseGames.Core { /// /// 死亡/复活流程服务接口。 /// public interface IDeathRespawnService { /// 玩家死亡时由 GameManager 调用,启动死亡演出流程。 IEnumerator StartDeathSequenceCoroutine(); /// DeathScreen 确认按钮点击后调用,执行复活流程。 IEnumerator StartRespawnCoroutine(); /// SteelSoul 模式:HP 归零后直接清档并返回主菜单。 IEnumerator StartGameOverCoroutine(); } /// /// 死亡/复活流程独立服务。 /// public class DeathRespawnService : MonoBehaviour, IDeathRespawnService { [Header("Config")] [SerializeField] private float _deathAnimDuration = 1.2f; [SerializeField] private float _deathScreenDelay = 0.5f; [SerializeField] private float _respawnFadeDuration = 0.4f; [Header("Event Channels - Raise")] [SerializeField] private VoidEventChannelSO _onRespawnStarted; [SerializeField] private VoidEventChannelSO _onRespawnCompleted; [SerializeField] private SceneLoadRequestEventChannelSO _onSceneLoadRequest; [Header("Event Channels - Listen")] [SerializeField] private VoidEventChannelSO _onDeathScreenConfirmed; public IEnumerator StartDeathSequenceCoroutine() { yield return new WaitForSeconds(_deathAnimDuration); yield return new WaitForSeconds(_deathScreenDelay); // 确认等待由 GameManager.DeathFlow 统一处理,此处仅负责动画延迟 } public IEnumerator StartRespawnCoroutine() { _onRespawnStarted?.Raise(); yield return new WaitForSeconds(_respawnFadeDuration); // 通过 SceneLoadRequest 频道触发场景重载,复用 SceneService / RoomTransition 路径 var sm = ServiceLocator.GetOrDefault(); _onSceneLoadRequest?.Raise(new SceneLoadRequest { SceneName = sm?.LastCheckpointScene, EntryTransitionId = sm?.LastCheckpointSpawnId, ShowLoadingScreen = true, IsRespawn = true, }); yield return new WaitForSeconds(_respawnFadeDuration); _onRespawnCompleted?.Raise(); } public IEnumerator StartGameOverCoroutine() { // 1. 删除当前存档槽 var saveManager = ServiceLocator.GetOrDefault(); if (saveManager != null) { var task = saveManager.DeleteSlotAsync(saveManager.ActiveSlot); yield return new WaitUntil(() => task.IsCompleted); } // 2. 返回主菜单 var sceneService = ServiceLocator.GetOrDefault(); if (sceneService != null) yield return sceneService.LoadMainMenuCoroutine(); } } }