Files
Bombaleila/Assets/ThunderWire Studio/UHFPS/Content/Scripts/Runtime/Controllers/Player/PlayerHealth.cs
2026-03-03 05:27:03 +05:00

194 lines
6.4 KiB
C#

using UnityEngine;
using UHFPS.Tools;
using UHFPS.Rendering;
using static UHFPS.Runtime.GameManager;
namespace UHFPS.Runtime
{
public class PlayerHealth : BaseHealthEntity
{
public uint MaxHealth = 100;
public uint StartHealth = 100;
public bool UseHearthbeat;
public float LowHealthPulse = 5f;
public float HealthFadeTime = 0.1f;
public uint MinHealthFade = 20;
public float BloodDuration = 2f;
public float BloodFadeInSpeed = 2f;
public float BloodFadeOutSpeed = 1f;
public float CloseEyesTime = 2f;
public float CloseEyesSpeed = 2f;
public bool EnableFallDamage;
public MinMax FallDistance = new(5, 10);
public MinMaxInt FallDamage = new(0, 15);
public bool UseDamageSounds;
public AudioClip[] DamageSounds;
[Range(0f, 1f)]
public float DamageVolume = 1f;
public bool IsInvisibleToEnemies;
public bool IsInvisibleToAllies;
private PlayerStateMachine player;
private GameManager gameManager;
private EyeBlink eyeBlink;
private float targetHealth;
private float healthVelocity;
private float bloodWeight;
private float targetBlood;
private float bloodTime;
private float eyesTime;
private int lastDamageSound;
private Vector3 lastPosition;
private bool wasInAir;
private bool lastPosLoaded;
private void Awake()
{
gameManager = GameManager.Instance;
gameManager.HealthPPVolume.profile.TryGet(out eyeBlink);
player = GetComponent<PlayerStateMachine>();
if (!SaveGameManager.GameWillLoad || !SaveGameManager.GameStateExist)
InitHealth();
}
private void Update()
{
if (!lastPosLoaded)
{
lastPosition = transform.position;
lastPosLoaded = true;
}
if (gameManager.HealthBar != null)
{
float healthValue = gameManager.HealthBar.value;
healthValue = Mathf.SmoothDamp(healthValue, targetHealth, ref healthVelocity, HealthFadeTime);
gameManager.HealthBar.value = healthValue;
}
if (EntityHealth > MinHealthFade)
{
if (bloodTime > 0f) bloodTime -= Time.deltaTime;
else
{
targetBlood = 0f;
bloodTime = 0f;
}
}
bloodWeight = Mathf.MoveTowards(bloodWeight, targetBlood, Time.deltaTime * (bloodTime > 0 ? BloodFadeInSpeed : BloodFadeOutSpeed));
gameManager.HealthPPVolume.weight = bloodWeight;
if (IsDead && eyeBlink != null)
{
if (eyesTime < CloseEyesTime)
{
eyesTime += Time.deltaTime;
}
else
{
float blinkValue = eyeBlink.Blink.value;
eyeBlink.Blink.value = Mathf.MoveTowards(blinkValue, 1f, Time.deltaTime * CloseEyesSpeed);
}
}
if (!IsDead && EnableFallDamage)
{
if (player.StateGrounded)
{
if(!wasInAir) lastPosition = transform.position;
else
{
Vector3 dropPosition = transform.position;
float fallDistance = Mathf.Clamp(lastPosition.y - dropPosition.y, 0, Mathf.Infinity);
float fallModifier = Mathf.InverseLerp(FallDistance.RealMin, FallDistance.RealMax, fallDistance);
float fallDamage = 0f;
if (fallModifier > 0f) fallDamage = Mathf.Lerp(FallDamage.RealMin, FallDamage.RealMax, fallModifier);
if (fallDamage > 1f) OnApplyDamage(Mathf.RoundToInt(fallDamage));
wasInAir = false;
}
}
else if(!wasInAir)
{
wasInAir = true;
}
}
}
public void InitHealth()
{
InitializeHealth((int)StartHealth, (int)MaxHealth);
if (StartHealth <= MinHealthFade)
{
targetBlood = 1f;
bloodTime = BloodDuration;
}
}
public override void OnHealthChanged(int oldHealth, int newHealth)
{
gameManager.HealthPercent.text = newHealth.ToString();
targetHealth = (float)newHealth / MaxHealth;
if (UseHearthbeat)
{
Material hearthbeatMat = gameManager.Hearthbeat.material;
if (newHealth <= 0)
{
hearthbeatMat.EnableKeyword("ZERO_PULSE");
}
else
{
float pulse = GameTools.Remap(0f, MaxHealth, LowHealthPulse, 1f, newHealth);
hearthbeatMat.SetFloat("_PulseMultiplier", pulse);
hearthbeatMat.DisableKeyword("ZERO_PULSE");
}
}
}
public override void OnApplyDamage(int damage, Transform sender = null)
{
if (IsDead) return;
base.OnApplyDamage(damage, sender);
if (UseDamageSounds && DamageSounds.Length > 0)
{
int damageSound = GameTools.RandomUnique(0, DamageSounds.Length, lastDamageSound);
GameTools.PlayOneShot2D(transform.position, DamageSounds[damageSound], DamageVolume, "DamageSound");
lastDamageSound = damageSound;
}
targetBlood = 1f;
bloodTime = BloodDuration;
}
public override void OnApplyHeal(int healAmount)
{
base.OnApplyHeal(healAmount);
if(EntityHealth > MinHealthFade)
bloodTime = BloodDuration;
}
public override void OnHealthZero()
{
gameManager.ShowPanel(PanelType.DeadPanel);
gameManager.PlayerPresence.FreezePlayer(true, true);
gameManager.PlayerPresence.PlayerManager.PlayerItems.DeactivateCurrentItem();
targetBlood = 1f;
}
}
}