Files
Learning-UnityNGO/Assets/CONTENT/FEATURES/DEV-TEST/Scripts/PlayerHealth.cs
T

117 lines
2.7 KiB
C#

using UnityEngine;
using Unity.Netcode;
using TMPro;
using System;
public class PlayerHealth : NetworkBehaviour
{
[SerializeField] private int maxHealth = 100;
public NetworkVariable<int> currentHealth = new NetworkVariable<int>(
100,
NetworkVariableReadPermission.Everyone,
NetworkVariableWritePermission.Server
);
public NetworkVariable<bool> isDead = new NetworkVariable<bool>(false);
public event Action<int, int> HealthChanged;
public event Action Died;
private bool isServer;
public void Init(bool _isServer)
{
isServer = _isServer;
currentHealth.OnValueChanged += OnHealthChanged;
if(isServer)
{
currentHealth.Value = maxHealth;
}
HealthChanged?.Invoke(currentHealth.Value, maxHealth);
}
private void OnHealthChanged(int _previousValue, int _newValue)
{
HealthChanged?.Invoke(_newValue, maxHealth);
if(_newValue <= 0)
{
Die();
}
}
public void TakeDamage(int _damageAmount)
{
if (!isServer) return;
if(isDead.Value) return;
currentHealth.Value = Mathf.Max(0, currentHealth.Value - _damageAmount);
}
public override void OnNetworkDespawn()
{
currentHealth.OnValueChanged -= OnHealthChanged;
}
private void Die()
{
if(!isServer) return;
isDead.Value = true;
OnDiedClientRpc();
}
public void Respawn(Vector3 _spawnPosition)
{
if(!isServer) return;
isDead.Value = false;
currentHealth.Value = maxHealth;
RespawnClientRpc(_spawnPosition);
}
public void PushCurrentHealthValue()
{
HealthChanged?.Invoke(currentHealth.Value, maxHealth);
}
[ClientRpc]
private void OnDiedClientRpc()
{
Debug.Log($"Player {OwnerClientId} died");
SetPhysicsAndVisualsActive(false);
Died?.Invoke();
}
[ClientRpc]
private void RespawnClientRpc(Vector3 _spawnPosition)
{
SetPhysicsAndVisualsActive(true);
transform.position = _spawnPosition;
}
private void SetPhysicsAndVisualsActive(bool _isActive)
{
foreach (Collider collider in GetComponentsInChildren<Collider>())
collider.enabled = _isActive;
foreach (MeshRenderer meshRenderer in GetComponentsInChildren<MeshRenderer>())
meshRenderer.enabled = _isActive;
Rigidbody rigidbody = GetComponent<Rigidbody>();
if (rigidbody == null) return;
rigidbody.isKinematic = !_isActive;
if (_isActive)
{
rigidbody.linearVelocity = Vector3.zero;
rigidbody.angularVelocity = Vector3.zero;
}
}
}