Component attached to a player entity that manages health, death and respawn. It tracks MaxHealth and CurrentHealth, applies damage and healing, disables renderers/controllers on death, spawns a ragdoll impulse, updates a score manager, and restores components and position on respawn.
using Sandbox;
using System;
using System.Linq;
public sealed class PlayerHealth : Component
{
[Property] public float MaxHealth { get; set; } = 100f;
[Property] public float CurrentHealth { get; private set; } = 100f;
public bool IsDead => CurrentHealth <= 0f;
public float RespawnTimer { get; private set; } = 0f;
public float RespawnDuration { get; set; } = 3f;
private Vector3 _lastDamageDirection = Vector3.Zero;
protected override void OnStart()
{
CurrentHealth = MaxHealth;
}
protected override void OnUpdate()
{
if ( IsDead )
{
RespawnTimer -= Time.Delta;
if ( RespawnTimer <= 0f )
{
Respawn();
}
}
}
public void TakeDamage( float damage )
{
TakeDamage( damage, Vector3.Zero );
}
public void TakeDamage( float damage, Vector3 direction )
{
if ( IsDead ) return;
_lastDamageDirection = direction;
CurrentHealth = MathX.Clamp( CurrentHealth - damage, 0f, MaxHealth );
if ( CurrentHealth <= 0f )
{
Die();
}
}
public void Heal( float amount )
{
if ( IsDead ) return;
CurrentHealth = MathX.Clamp( CurrentHealth + amount, 0f, MaxHealth );
}
private void Die()
{
RespawnTimer = RespawnDuration;
if ( ScoreManager.Instance != null )
{
ScoreManager.Instance.AddDeath();
}
var ragdoll = Components.Get<PlayerRagdoll>();
if ( ragdoll.IsValid() )
{
ragdoll.SpawnRagdoll( _lastDamageDirection * 2500f );
}
var skm = Components.Get<SkinnedModelRenderer>();
if ( skm.IsValid() ) skm.Enabled = false;
var mr = Components.Get<ModelRenderer>();
if ( mr.IsValid() ) mr.Enabled = false;
var cc = Components.Get<CharacterController>();
if ( cc.IsValid() ) cc.Enabled = false;
var rb = Components.Get<Rigidbody>();
if ( rb.IsValid() ) rb.Enabled = false;
CameraJuice.Instance?.Shake( 30f, 6f );
Log.Info( "[PlayerHealth] Игрок погиб!" );
}
public void Respawn()
{
CurrentHealth = MaxHealth;
var skm = Components.Get<SkinnedModelRenderer>();
if ( skm.IsValid() ) skm.Enabled = true;
var mr = Components.Get<ModelRenderer>();
if ( mr.IsValid() ) mr.Enabled = true;
var cc = Components.Get<CharacterController>();
if ( cc.IsValid() ) cc.Enabled = true;
var rb = Components.Get<Rigidbody>();
if ( rb.IsValid() ) rb.Enabled = true;
var spawnPoint = Scene.GetAllComponents<SpawnPoint>().FirstOrDefault();
if ( spawnPoint.IsValid() )
{
Transform.World = spawnPoint.Transform.World;
}
else
{
Transform.LocalPosition = Vector3.Up * 50f;
}
Log.Info( "[PlayerHealth] Игрок возродился!" );
}
}