using UnityEngine; using System.Collections.Generic; using TMPro; public class CheckpointSystem : MonoBehaviour { public static CheckpointSystem Instance { get; private set; } [Header("References")] public TeamCohesionManager cohesionManager; public Transform playerTransform; public GridMovement playerMovement; [Header("Settings")] public bool autoSaveOnCheckpoint = true; public float checkpointRadius = 3f; public Vector3 respawnRotation = new Vector3(0, 90, 0); // to look east at respawnss [Header("Respawn UI")] public TextMeshProUGUI respawnText; public CanvasGroup respawnCanvasGroup; public string respawnMessage = "Respawned at Checkpoint"; [Header("Fade Animation")] public float fadeDuration = 0.5f; public float displayDuration = 2f; private Vector3 savedPlayerPosition; private int savedFloorLevel; private List savedCharacters = new List(); private bool hasCheckpoint = false; [System.Serializable] private class SavedCharacterData { public CharacterInGroup character; public int hp; public int fatigue; public int mana; public int gridX; public int gridY; public SavedCharacterData(CharacterInGroup chara) { character = chara; hp = chara.currentHP; fatigue = chara.currentFatigue; mana = chara.currentMana; gridX = chara.gridX; gridY = chara.gridY; } } private void Awake() { if (Instance != null && Instance != this) { Destroy(gameObject); return; } Instance = this; } private void Start() { FindReferences(); SaveInitialCheckpoint(); } private void FindReferences() { if (cohesionManager == null) cohesionManager = FindFirstObjectByType(); if (playerTransform == null) { GameObject player = GameObject.FindGameObjectWithTag("Player"); if (player != null) playerTransform = player.transform; } if (playerMovement == null) playerMovement = FindFirstObjectByType(); } private void SaveInitialCheckpoint() { // Wait a frame to ensure all systems are initialized StartCoroutine(SaveInitialCheckpointDelayed()); } private System.Collections.IEnumerator SaveInitialCheckpointDelayed() { yield return new WaitForSeconds(0.5f); SaveCheckpoint(); } public void SaveCheckpoint() { if (playerTransform == null || cohesionManager == null) return; savedPlayerPosition = playerTransform.position; if (playerMovement != null) savedFloorLevel = playerMovement.currentFloorLevel; savedCharacters.Clear(); foreach (var character in cohesionManager.groupMembers) { savedCharacters.Add(new SavedCharacterData(character)); } hasCheckpoint = true; } public void SaveCheckpointAt(Vector3 position) { savedPlayerPosition = position; if (playerMovement != null) savedFloorLevel = playerMovement.currentFloorLevel; savedCharacters.Clear(); if (cohesionManager != null) { foreach (var character in cohesionManager.groupMembers) { savedCharacters.Add(new SavedCharacterData(character)); } } hasCheckpoint = true; } public void LoadCheckpoint() { if (!hasCheckpoint) return; if (playerTransform != null) { playerTransform.position = savedPlayerPosition; playerTransform.rotation = Quaternion.Euler(respawnRotation); } if (playerMovement != null) playerMovement.currentFloorLevel = savedFloorLevel; RestoreCharacters(); ShowRespawnMessage(); } private void RestoreCharacters() { if (cohesionManager == null) return; cohesionManager.groupMembers.Clear(); foreach (var saved in savedCharacters) { CharacterInGroup character = saved.character; character.currentHP = character.maxHP; character.currentFatigue = character.maxFatigue; character.currentMana = character.maxMana; character.gridX = saved.gridX; character.gridY = saved.gridY; cohesionManager.groupMembers.Add(character); } RecreatePartyUI(); } private void RecreatePartyUI() { PartyUIManager partyUI = FindFirstObjectByType(); if (partyUI != null) { partyUI.DisplayPartyUI(); } } private void OnTriggerEnter(Collider other) { if (other.CompareTag("Checkpoint") && autoSaveOnCheckpoint) { SaveCheckpoint(); } } public bool HasCheckpoint() => hasCheckpoint; public Vector3 GetCheckpointPosition() => savedPlayerPosition; private void ShowRespawnMessage() { if (respawnText != null && respawnCanvasGroup != null) { respawnText.text = respawnMessage; respawnText.gameObject.SetActive(true); StartCoroutine(FadeRespawnTextInOut()); } } private System.Collections.IEnumerator FadeRespawnTextInOut() { // Fade in from 0 to 1 float elapsed = 0f; while (elapsed < fadeDuration) { elapsed += Time.deltaTime; respawnCanvasGroup.alpha = Mathf.Lerp(0f, 1f, elapsed / fadeDuration); yield return null; } respawnCanvasGroup.alpha = 1f; // Display at full opacity yield return new WaitForSeconds(displayDuration); // Fade out from 1 to 0 elapsed = 0f; while (elapsed < fadeDuration) { elapsed += Time.deltaTime; respawnCanvasGroup.alpha = Mathf.Lerp(1f, 0f, elapsed / fadeDuration); yield return null; } respawnCanvasGroup.alpha = 0f; // Deactivate text object respawnText.gameObject.SetActive(false); } }