| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- using UnityEngine;
- using System.Collections.Generic;
- using TMPro;
- /// <summary>
- /// Manages checkpoint saving and loading for the respawn system.
- /// Automatically captures player's start position as fallback respawn point.
- /// </summary>
- 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<SavedCharacterData> savedCharacters = new List<SavedCharacterData>();
- private bool hasCheckpoint = false;
- [System.Serializable] // This class is used to save the characters data when the checkpoint is saved
- 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;
- }
- }
- #region Initialization
- 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<TeamCohesionManager>();
-
- if (playerTransform == null)
- {
- GameObject player = GameObject.FindGameObjectWithTag("Player");
- if (player != null)
- playerTransform = player.transform;
- }
-
- if (playerMovement == null)
- playerMovement = FindFirstObjectByType<GridMovement>();
- }
- 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);
-
- // Save the starting position as initial checkpoint
- SaveCheckpoint();
- Debug.Log("[CheckpointSystem] Initial checkpoint saved at start position");
- }
- #endregion
- #region Checkpoint Save
- public void SaveCheckpoint()
- {
- if (playerTransform == null || cohesionManager == null)
- {
- Debug.LogWarning("[CheckpointSystem] Cannot save checkpoint: missing references");
- 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;
-
- Debug.Log($"[CheckpointSystem] Checkpoint saved with {savedCharacters.Count} characters");
- }
- 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;
-
- Debug.Log($"[CheckpointSystem] Manual checkpoint saved at {savedPlayerPosition}");
- }
- #endregion
- #region Checkpoint Load
- public void LoadCheckpoint()
- {
- if (!hasCheckpoint)
- {
- Debug.LogWarning("[CheckpointSystem] No checkpoint available");
- return;
- }
- if (playerTransform != null)
- {
- playerTransform.position = savedPlayerPosition;
- playerTransform.rotation = Quaternion.Euler(respawnRotation);
- }
-
- if (playerMovement != null)
- playerMovement.currentFloorLevel = savedFloorLevel;
- RestoreCharacters();
-
- // Show respawn UI message
- 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<PartyUIManager>();
- if (partyUI != null)
- {
- partyUI.DisplayPartyUI();
- }
- }
- #endregion
- #region Checkpoint Triggers
- private void OnTriggerEnter(Collider other)
- {
- if (other.CompareTag("Checkpoint") && autoSaveOnCheckpoint)
- {
- SaveCheckpoint();
- }
- }
- #endregion
- #region Public API
- public bool HasCheckpoint() => hasCheckpoint;
- public Vector3 GetCheckpointPosition() => savedPlayerPosition;
- #endregion
-
- #region Respawn UI
-
- 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);
- }
-
- #endregion
- }
|