Map mehanic ready to multiplayer
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user