145 lines
4.0 KiB
C#
145 lines
4.0 KiB
C#
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
|
|
public class PlayerStats : MonoBehaviour
|
|
{
|
|
[Header("Health")]
|
|
public float maxHealth = 100f;
|
|
public float currentHealth;
|
|
|
|
[Header("Mana")]
|
|
public float maxMana = 100f;
|
|
public float currentMana;
|
|
|
|
[Header("Stamina")]
|
|
public float maxStamina = 100f;
|
|
public float currentStamina;
|
|
public float staminaRegenRate = 15f;
|
|
public float staminaRegenDelay = 1.5f;
|
|
|
|
[Header("Events")]
|
|
public UnityEvent onDeath;
|
|
|
|
private float _lastStaminaUseTime;
|
|
private bool _isDead;
|
|
|
|
private void Awake()
|
|
{
|
|
currentHealth = maxHealth;
|
|
currentMana = maxMana;
|
|
currentStamina = maxStamina;
|
|
}
|
|
|
|
public float sprintStaminaDrainRate = 10f;
|
|
[Tooltip("Optional: Drag the InputReader here to automatically drain stamina when sprinting")]
|
|
public Synty.AnimationBaseLocomotion.Samples.InputSystem.InputReader inputReader;
|
|
|
|
private bool _isSprinting;
|
|
|
|
private float _regenPauseEndTime;
|
|
[HideInInspector] public float staminaRegenMultiplier = 1f;
|
|
|
|
public void PauseStaminaRegen(float seconds)
|
|
{
|
|
_regenPauseEndTime = Time.time + seconds;
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
if (inputReader != null)
|
|
{
|
|
inputReader.onSprintActivated += HandleSprintStart;
|
|
inputReader.onSprintDeactivated += HandleSprintStop;
|
|
}
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
if (inputReader != null)
|
|
{
|
|
inputReader.onSprintActivated -= HandleSprintStart;
|
|
inputReader.onSprintDeactivated -= HandleSprintStop;
|
|
}
|
|
}
|
|
|
|
private void HandleSprintStart() => _isSprinting = true;
|
|
private void HandleSprintStop() => _isSprinting = false;
|
|
|
|
private void Update()
|
|
{
|
|
if (_isDead) return;
|
|
|
|
// Drain stamina if sprinting and moving
|
|
if (_isSprinting && inputReader != null && inputReader._movementInputDetected)
|
|
{
|
|
UseStamina(sprintStaminaDrainRate * Time.deltaTime);
|
|
|
|
// If we run out of stamina while sprinting, you might want to force walk here
|
|
if (currentStamina <= 0)
|
|
{
|
|
// Force sprint off via the reader
|
|
_isSprinting = false;
|
|
// Note: To perfectly force the Synty controller to stop running,
|
|
// you would normally call a method on the SamplePlayerAnimationController.
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Regenerate stamina if we haven't used it recently and not paused
|
|
if (Time.time > _lastStaminaUseTime + staminaRegenDelay && Time.time > _regenPauseEndTime)
|
|
{
|
|
if (currentStamina < maxStamina)
|
|
{
|
|
currentStamina += (staminaRegenRate * staminaRegenMultiplier) * Time.deltaTime;
|
|
currentStamina = Mathf.Clamp(currentStamina, 0f, maxStamina);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
[HideInInspector] public bool isBlocking = false;
|
|
[HideInInspector] public float currentBlockReduction = 0f;
|
|
|
|
public void TakeDamage(float amount)
|
|
{
|
|
if (_isDead) return;
|
|
|
|
currentHealth -= amount;
|
|
currentHealth = Mathf.Clamp(currentHealth, 0f, maxHealth);
|
|
|
|
if (currentHealth <= 0)
|
|
{
|
|
Die();
|
|
}
|
|
}
|
|
|
|
public void Heal(float amount)
|
|
{
|
|
if (_isDead) return;
|
|
currentHealth += amount;
|
|
currentHealth = Mathf.Clamp(currentHealth, 0f, maxHealth);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Attempts to use stamina.
|
|
/// </summary>
|
|
public void UseStamina(float amount)
|
|
{
|
|
currentStamina -= amount;
|
|
currentStamina = Mathf.Clamp(currentStamina, 0f, maxStamina);
|
|
_lastStaminaUseTime = Time.time;
|
|
}
|
|
|
|
public bool HasStaminaPercentage(float percentage)
|
|
{
|
|
return currentStamina >= (maxStamina * percentage);
|
|
}
|
|
|
|
private void Die()
|
|
{
|
|
_isDead = true;
|
|
Debug.Log("Player has died!");
|
|
onDeath?.Invoke();
|
|
}
|
|
}
|