Files
FORT-BO/Assets/CONTENT/FEATURES/MapRadar/NetworkBaseHealth.cs
T

80 lines
2.1 KiB
C#

using System;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Events;
[DisallowMultipleComponent]
[RequireComponent(typeof(NetworkObject))]
public sealed class NetworkBaseHealth : NetworkBehaviour
{
[SerializeField, Min(1)] private int maximumHealth = 10;
[SerializeField] private UnityEvent<int> healthChanged;
[SerializeField] private UnityEvent depleted;
private readonly NetworkVariable<int> currentHealth = new(
0,
NetworkVariableReadPermission.Everyone,
NetworkVariableWritePermission.Server);
public int MaximumHealth => Mathf.Max(1, maximumHealth);
public int CurrentHealth => currentHealth.Value;
public bool IsDepleted => CurrentHealth <= 0;
public event Action<int> Changed;
public event Action Depleted;
private void OnValidate() => maximumHealth = Mathf.Max(1, maximumHealth);
public override void OnNetworkSpawn()
{
currentHealth.OnValueChanged += HandleHealthChanged;
if (IsServer)
currentHealth.Value = MaximumHealth;
ApplyState(currentHealth.Value, false);
}
public override void OnNetworkDespawn()
{
currentHealth.OnValueChanged -= HandleHealthChanged;
}
public bool ApplyDamage(int amount)
{
if (!IsServer || !IsSpawned || amount <= 0 || IsDepleted)
return false;
currentHealth.Value = Mathf.Max(0, CurrentHealth - amount);
return true;
}
public void ResetHealth()
{
if (IsServer && IsSpawned)
currentHealth.Value = MaximumHealth;
}
[ContextMenu("Debug/Apply One Damage (Server Play Mode)")]
private void ApplyDebugDamage()
{
if (Application.isPlaying)
ApplyDamage(1);
}
private void HandleHealthChanged(int previous, int current) =>
ApplyState(current, previous > 0 && current <= 0);
private void ApplyState(int health, bool becameDepleted)
{
Changed?.Invoke(health);
healthChanged?.Invoke(health);
if (!becameDepleted)
return;
Depleted?.Invoke();
depleted?.Invoke();
}
}