using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.SceneManagement; public class PlayerHealth : Singleton { public bool isDead { get; private set; } [SerializeField] private int maxHealth = 7; // Maximum health of the player [SerializeField] private float knockBackThrustAmount = 10f; // Force applied to the player when knocked back [SerializeField] private float damageRecoveryTime = 1f; // Time during which the player cannot take damage after being hit private Slider healthSlider; // UI Slider to display player's health private int currentHealth; // Current health of the player private bool canTakeDamage = true; // Flag to check if player can take damage private Knockback knockback; // Reference to Knockback component private Flash flash; // Reference to Flash component // The default starting position of the player private Vector3 defaultPosition; // Constants for UI and animation management const string HEALTH_SLIDER_TEXT = "Health Slider"; // Name of the health slider in the scene const string TOWN_TEXT = "End"; // Name of the scene to load when the player dies readonly int DEATH_HASH = Animator.StringToHash("Death"); // Hash for the "Death" animation trigger // Initialization of components and setting up the player's default position protected override void Awake() { base.Awake(); flash = GetComponent(); knockback = GetComponent(); // Set the default position to wherever you want the character to start defaultPosition = transform.position; } // Subscribe to scene load events when the script is enabled void OnEnable() { SceneManager.sceneLoaded += OnSceneLoaded; } // Unsubscribe from scene load events when the script is disabled void OnDisable() { SceneManager.sceneLoaded -= OnSceneLoaded; } // Resets the player's health and position when a specific scene is loaded void OnSceneLoaded(Scene scene, LoadSceneMode mode) { if (scene.name == "End") { ResetHealth(); } } // Resets the player's position to the default position public void ResetCharacterPosition() { transform.position = defaultPosition; } // Resets the player's health to the maximum value, updates the UI, and resets the animator and position public void ResetHealth() { isDead = false; currentHealth = maxHealth; UpdateHealthSlider(); // Reset the animator to the default state Animator animator = GetComponent(); if (animator != null) { animator.ResetTrigger(DEATH_HASH); // Reset the death trigger animator.Play("Idle"); // Play the idle animation } ResetCharacterPosition(); // Reset position when health is reset } // Sets initial values for the player's health and updates the health UI at the start of the game private void Start() { isDead = false; currentHealth = maxHealth; UpdateHealthSlider(); } // Handles damage when the player collides with an enemy and applies knockback private void OnCollisionStay2D(Collision2D other) { EnemyAI enemy = other.gameObject.GetComponent(); if (enemy) { TakeDamage(1, other.transform); } } // Heals the player by one health point if not already at max health, and updates the UI public void HealPlayer() { if (currentHealth < maxHealth) { currentHealth += 1; UpdateHealthSlider(); } } // Manages the process of taking damage, including knockback, screen flash, and health deduction public void TakeDamage(int damageAmount, Transform hitTransform) { if (!canTakeDamage) { return; } knockback.GetKnockedBack(hitTransform, knockBackThrustAmount); // Apply knockback StartCoroutine(flash.FlashRoutine()); // Trigger the flash effect canTakeDamage = false; // Temporarily disable taking further damage currentHealth -= damageAmount; // Deduct health StartCoroutine(DamageRecoveryRoutine()); // Start recovery process UpdateHealthSlider(); // Update health UI CheckIfPlayerDeath(); // Check if player is dead and handle it } // Checks if the player's health is 0 or less, and triggers the death sequence if true private void CheckIfPlayerDeath() { if (currentHealth <= 0 && !isDead) { isDead = true; currentHealth = 0; GetComponent().SetTrigger(DEATH_HASH); // Trigger the death animation StartCoroutine(DeathLoadSceneRoutine()); // Load the death scene after a delay } } // Coroutine that handles loading the death scene after a short delay private IEnumerator DeathLoadSceneRoutine() { yield return new WaitForSeconds(2f); SceneManager.LoadScene(TOWN_TEXT); // Load the end scene } // Coroutine that manages the recovery period during which the player cannot take damage private IEnumerator DamageRecoveryRoutine() { yield return new WaitForSeconds(damageRecoveryTime); canTakeDamage = true; // Re-enable taking damage after the recovery period } // Updates the health slider UI to reflect the player's current health private void UpdateHealthSlider() { if (healthSlider == null) { healthSlider = GameObject.Find(HEALTH_SLIDER_TEXT).GetComponent(); } healthSlider.maxValue = maxHealth; // Set the max value of the slider healthSlider.value = currentHealth; // Update the slider to the current health } }