CheckpointSystem.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. using UnityEngine;
  2. using System.Collections.Generic;
  3. using TMPro;
  4. public class CheckpointSystem : MonoBehaviour
  5. {
  6. public static CheckpointSystem Instance { get; private set; }
  7. [Header("References")]
  8. public TeamCohesionManager cohesionManager;
  9. public Transform playerTransform;
  10. public GridMovement playerMovement;
  11. [Header("Settings")]
  12. public bool autoSaveOnCheckpoint = true;
  13. public float checkpointRadius = 3f;
  14. public Vector3 respawnRotation = new Vector3(0, 90, 0); // to look east at respawnss
  15. [Header("Respawn UI")]
  16. public TextMeshProUGUI respawnText;
  17. public CanvasGroup respawnCanvasGroup;
  18. public string respawnMessage = "Respawned at Checkpoint";
  19. [Header("Fade Animation")]
  20. public float fadeDuration = 0.5f;
  21. public float displayDuration = 2f;
  22. private Vector3 savedPlayerPosition;
  23. private int savedFloorLevel;
  24. private List<SavedCharacterData> savedCharacters = new List<SavedCharacterData>();
  25. private bool hasCheckpoint = false;
  26. [System.Serializable]
  27. private class SavedCharacterData
  28. {
  29. public CharacterInGroup character;
  30. public int hp;
  31. public int fatigue;
  32. public int mana;
  33. public int gridX;
  34. public int gridY;
  35. public SavedCharacterData(CharacterInGroup chara)
  36. {
  37. character = chara;
  38. hp = chara.currentHP;
  39. fatigue = chara.currentFatigue;
  40. mana = chara.currentMana;
  41. gridX = chara.gridX;
  42. gridY = chara.gridY;
  43. }
  44. }
  45. private void Awake()
  46. {
  47. if (Instance != null && Instance != this)
  48. {
  49. Destroy(gameObject);
  50. return;
  51. }
  52. Instance = this;
  53. }
  54. private void Start()
  55. {
  56. FindReferences();
  57. SaveInitialCheckpoint();
  58. }
  59. private void FindReferences()
  60. {
  61. if (cohesionManager == null)
  62. cohesionManager = FindFirstObjectByType<TeamCohesionManager>();
  63. if (playerTransform == null)
  64. {
  65. GameObject player = GameObject.FindGameObjectWithTag("Player");
  66. if (player != null)
  67. playerTransform = player.transform;
  68. }
  69. if (playerMovement == null)
  70. playerMovement = FindFirstObjectByType<GridMovement>();
  71. }
  72. private void SaveInitialCheckpoint()
  73. {
  74. // Wait a frame to ensure all systems are initialized
  75. StartCoroutine(SaveInitialCheckpointDelayed());
  76. }
  77. private System.Collections.IEnumerator SaveInitialCheckpointDelayed()
  78. {
  79. yield return new WaitForSeconds(0.5f);
  80. SaveCheckpoint();
  81. }
  82. public void SaveCheckpoint()
  83. {
  84. if (playerTransform == null || cohesionManager == null) return;
  85. savedPlayerPosition = playerTransform.position;
  86. if (playerMovement != null)
  87. savedFloorLevel = playerMovement.currentFloorLevel;
  88. savedCharacters.Clear();
  89. foreach (var character in cohesionManager.groupMembers)
  90. {
  91. savedCharacters.Add(new SavedCharacterData(character));
  92. }
  93. hasCheckpoint = true;
  94. }
  95. public void SaveCheckpointAt(Vector3 position)
  96. {
  97. savedPlayerPosition = position;
  98. if (playerMovement != null)
  99. savedFloorLevel = playerMovement.currentFloorLevel;
  100. savedCharacters.Clear();
  101. if (cohesionManager != null)
  102. {
  103. foreach (var character in cohesionManager.groupMembers)
  104. {
  105. savedCharacters.Add(new SavedCharacterData(character));
  106. }
  107. }
  108. hasCheckpoint = true;
  109. }
  110. public void LoadCheckpoint()
  111. {
  112. if (!hasCheckpoint) return;
  113. if (playerTransform != null)
  114. {
  115. playerTransform.position = savedPlayerPosition;
  116. playerTransform.rotation = Quaternion.Euler(respawnRotation);
  117. }
  118. if (playerMovement != null)
  119. playerMovement.currentFloorLevel = savedFloorLevel;
  120. RestoreCharacters();
  121. ShowRespawnMessage();
  122. }
  123. private void RestoreCharacters()
  124. {
  125. if (cohesionManager == null) return;
  126. cohesionManager.groupMembers.Clear();
  127. foreach (var saved in savedCharacters)
  128. {
  129. CharacterInGroup character = saved.character;
  130. character.currentHP = character.maxHP;
  131. character.currentFatigue = character.maxFatigue;
  132. character.currentMana = character.maxMana;
  133. character.gridX = saved.gridX;
  134. character.gridY = saved.gridY;
  135. cohesionManager.groupMembers.Add(character);
  136. }
  137. RecreatePartyUI();
  138. }
  139. private void RecreatePartyUI()
  140. {
  141. PartyUIManager partyUI = FindFirstObjectByType<PartyUIManager>();
  142. if (partyUI != null)
  143. {
  144. partyUI.DisplayPartyUI();
  145. }
  146. }
  147. private void OnTriggerEnter(Collider other)
  148. {
  149. if (other.CompareTag("Checkpoint") && autoSaveOnCheckpoint)
  150. {
  151. SaveCheckpoint();
  152. }
  153. }
  154. public bool HasCheckpoint() => hasCheckpoint;
  155. public Vector3 GetCheckpointPosition() => savedPlayerPosition;
  156. private void ShowRespawnMessage()
  157. {
  158. if (respawnText != null && respawnCanvasGroup != null)
  159. {
  160. respawnText.text = respawnMessage;
  161. respawnText.gameObject.SetActive(true);
  162. StartCoroutine(FadeRespawnTextInOut());
  163. }
  164. }
  165. private System.Collections.IEnumerator FadeRespawnTextInOut()
  166. {
  167. // Fade in from 0 to 1
  168. float elapsed = 0f;
  169. while (elapsed < fadeDuration)
  170. {
  171. elapsed += Time.deltaTime;
  172. respawnCanvasGroup.alpha = Mathf.Lerp(0f, 1f, elapsed / fadeDuration);
  173. yield return null;
  174. }
  175. respawnCanvasGroup.alpha = 1f;
  176. // Display at full opacity
  177. yield return new WaitForSeconds(displayDuration);
  178. // Fade out from 1 to 0
  179. elapsed = 0f;
  180. while (elapsed < fadeDuration)
  181. {
  182. elapsed += Time.deltaTime;
  183. respawnCanvasGroup.alpha = Mathf.Lerp(1f, 0f, elapsed / fadeDuration);
  184. yield return null;
  185. }
  186. respawnCanvasGroup.alpha = 0f;
  187. // Deactivate text object
  188. respawnText.gameObject.SetActive(false);
  189. }
  190. }