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; } } }