Files
megakoop/Game/Scripts/Networking/SteamHealthNetworkBridge.cs
2025-10-24 20:31:52 +02:00

139 lines
3.7 KiB
C#

using UnityEngine;
namespace MegaKoop.Game.Networking
{
[DisallowMultipleComponent]
public class SteamHealthNetworkBridge : MonoBehaviour
{
[SerializeField] private Combat.Health health;
[SerializeField] private NetworkIdentity identity;
private SteamCoopNetworkManager networkManager;
private bool isRegistered;
private bool hasPendingBroadcast;
private float pendingNormalizedHealth;
private void Awake()
{
if (health == null)
{
health = GetComponent<Combat.Health>();
}
if (identity == null)
{
identity = GetComponent<NetworkIdentity>();
}
}
private void OnEnable()
{
networkManager = SteamCoopNetworkManager.Instance;
if (networkManager != null)
{
networkManager.RegisterHandler(NetworkMessageType.HealthSync, HandleHealthSync);
isRegistered = true;
}
if (health != null)
{
health.NormalizedHealthChanged += OnHealthChanged;
}
if (health != null && identity != null && IsAuthority())
{
QueueBroadcast(health.CurrentHealth / health.MaxHealth);
}
FlushPendingBroadcast();
}
private void OnDisable()
{
if (isRegistered && networkManager != null)
{
networkManager.UnregisterHandler(NetworkMessageType.HealthSync, HandleHealthSync);
isRegistered = false;
}
if (health != null)
{
health.NormalizedHealthChanged -= OnHealthChanged;
}
networkManager = null;
}
private bool IsAuthority()
{
return networkManager == null || networkManager.IsHost;
}
private void OnHealthChanged(float normalized)
{
if (!IsAuthority() || identity == null)
{
return;
}
QueueBroadcast(normalized);
FlushPendingBroadcast();
}
private void HandleHealthSync(NetworkMessage message)
{
if (IsAuthority() || identity == null || health == null)
{
return;
}
HealthSyncMessage syncMessage = HealthSyncMessage.Deserialize(message.Payload);
if (syncMessage.NetworkId != identity.NetworkId)
{
return;
}
health.ForceSetNormalizedHealth(syncMessage.NormalizedHealth);
}
private void QueueBroadcast(float normalized)
{
pendingNormalizedHealth = normalized;
hasPendingBroadcast = true;
}
private void FlushPendingBroadcast()
{
if (!hasPendingBroadcast)
{
return;
}
networkManager ??= SteamCoopNetworkManager.Instance;
if (networkManager == null || identity == null)
{
return;
}
if (!IsAuthority())
{
hasPendingBroadcast = false;
return;
}
var message = new HealthSyncMessage(identity.NetworkId, pendingNormalizedHealth);
byte[] payload = HealthSyncMessage.Serialize(message);
networkManager.SendToAll(NetworkMessageType.HealthSync, payload, Steamworks.EP2PSend.k_EP2PSendReliable);
hasPendingBroadcast = false;
}
private void LateUpdate()
{
if (hasPendingBroadcast)
{
FlushPendingBroadcast();
}
}
}
}