This commit is contained in:
Dominik G.
2025-10-24 19:28:42 +02:00
parent e1abeeb547
commit 33d34c251b
4 changed files with 316 additions and 55 deletions

View File

@@ -1,4 +1,3 @@
using System.Collections.Generic;
using UnityEngine;
namespace MegaKoop.Game.Networking
@@ -6,19 +5,19 @@ namespace MegaKoop.Game.Networking
[DisallowMultipleComponent]
public class NetworkIdentity : MonoBehaviour
{
private static readonly Dictionary<int, NetworkIdentity> registry = new();
private static int nextId = 1;
[SerializeField] private int networkId;
[SerializeField] private bool assignOnAwake = true;
[SerializeField] private bool assignOnAwake = false; // Changed default to false - IDs should be assigned deterministically
public int NetworkId => networkId;
private void Awake()
{
// Note: Auto-increment removed in favor of deterministic ID generation
// IDs should be assigned via SetNetworkId() before or during Awake
if (assignOnAwake && networkId == 0)
{
networkId = nextId++;
Debug.LogWarning($"[NetworkIdentity] {name} has assignOnAwake=true but no ID assigned. " +
"Use DeterministicIdGenerator or manually call SetNetworkId().");
}
Register();
@@ -26,10 +25,7 @@ namespace MegaKoop.Game.Networking
private void OnDestroy()
{
if (registry.TryGetValue(networkId, out NetworkIdentity existing) && existing == this)
{
registry.Remove(networkId);
}
NetworkIdRegistry.Unregister(networkId);
}
private void Register()
@@ -40,24 +36,31 @@ namespace MegaKoop.Game.Networking
return;
}
if (registry.TryGetValue(networkId, out NetworkIdentity existing) && existing != this)
if (!NetworkIdRegistry.TryRegister(this))
{
Debug.LogWarning($"[NetworkIdentity] Duplicate network id {networkId} detected. Overwriting reference.");
Debug.LogError($"[NetworkIdentity] Failed to register {name} with ID {networkId}. " +
"This object will not be synchronized correctly!");
}
registry[networkId] = this;
}
public static bool TryGet(int id, out NetworkIdentity identity) => registry.TryGetValue(id, out identity);
/// <summary>
/// Retrieves a NetworkIdentity by its ID using the centralized registry.
/// </summary>
public static bool TryGet(int id, out NetworkIdentity identity)
{
identity = NetworkIdRegistry.GetById(id);
return identity != null;
}
/// <summary>
/// Allows deterministic assignment so IDs match across clients.
/// This should be called before the object is used in network communication.
/// </summary>
public void SetNetworkId(int id)
{
if (id == 0)
{
Debug.LogWarning("[NetworkIdentity] Cannot assign network id 0.");
Debug.LogError("[NetworkIdentity] Cannot assign network id 0.");
return;
}
@@ -66,13 +69,25 @@ namespace MegaKoop.Game.Networking
return;
}
if (registry.TryGetValue(networkId, out NetworkIdentity existing) && existing == this)
// Unregister old ID if it was registered
if (networkId != 0)
{
registry.Remove(networkId);
NetworkIdRegistry.Unregister(networkId);
}
networkId = id;
Register();
// Register with new ID
if (!NetworkIdRegistry.TryRegister(this))
{
Debug.LogError($"[NetworkIdentity] Failed to set network ID {id} for {name}. " +
"ID may already be in use!");
}
}
/// <summary>
/// Gets the current network ID without triggering registration.
/// </summary>
public int GetNetworkId() => networkId;
}
}