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();
}
}
}