using UnityEngine;
namespace MegaKoop.Game.Networking
{
[DisallowMultipleComponent]
public class NetworkIdentity : MonoBehaviour
{
[SerializeField] private int networkId;
[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 (networkId != 0)
{
Register();
}
}
private void OnDestroy()
{
if (networkId != 0)
{
if (NetworkIdAllocator.IsEnemyId(networkId))
{
NetworkIdAllocator.ReleaseEnemyId(networkId);
}
NetworkIdRegistry.Unregister(networkId);
networkId = 0;
}
}
private void Register()
{
if (networkId == 0)
{
return;
}
if (NetworkIdAllocator.IsEnemyId(networkId))
{
NetworkIdAllocator.SyncEnemyCursor(networkId);
}
if (!NetworkIdRegistry.TryRegister(this))
{
Debug.LogError($"[NetworkIdentity] Failed to register {name} with ID {networkId}. " +
"This object will not be synchronized correctly!");
}
}
///
/// Retrieves a NetworkIdentity by its ID using the centralized registry.
///
public static bool TryGet(int id, out NetworkIdentity identity)
{
identity = NetworkIdRegistry.GetById(id);
return identity != null;
}
///
/// Allows deterministic assignment so IDs match across clients.
/// This should be called before the object is used in network communication.
///
public void SetNetworkId(int id)
{
if (id == 0)
{
Debug.LogError("[NetworkIdentity] Cannot assign network id 0.");
return;
}
if (networkId == id)
{
return;
}
// Unregister old ID if it was registered
if (networkId != 0)
{
if (NetworkIdAllocator.IsEnemyId(networkId))
{
NetworkIdAllocator.ReleaseEnemyId(networkId);
}
NetworkIdRegistry.Unregister(networkId);
}
networkId = id;
if (NetworkIdAllocator.IsEnemyId(networkId))
{
NetworkIdAllocator.SyncEnemyCursor(networkId);
}
// 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!");
}
}
///
/// Gets the current network ID without triggering registration.
///
public int GetNetworkId() => networkId;
///
/// Clears the current network ID and unregisters without emitting duplicate warnings.
///
public void ClearNetworkId()
{
if (networkId == 0)
{
return;
}
int id = networkId;
NetworkIdRegistry.Unregister(id);
if (NetworkIdAllocator.IsEnemyId(id))
{
NetworkIdAllocator.ReleaseEnemyId(id);
}
networkId = 0;
}
}
}