# Unity 6.3 — Networking Module Reference **Last verified:** 2026-02-13 **Knowledge Gap:** Unity 6 uses Netcode for GameObjects (UNet deprecated) --- ## Overview Unity 6 networking options: - **Netcode for GameObjects** (RECOMMENDED): Official Unity multiplayer framework - **Mirror**: Community-driven (UNet successor) - **Photon**: Third-party service (PUN2) - **Custom**: Low-level sockets **UNet (Legacy)**: Deprecated, do not use. --- ## Netcode for GameObjects ### Installation 1. `Window > Package Manager` 2. Search "Netcode for GameObjects" 3. Install `com.unity.netcode.gameobjects` --- ## Basic Setup ### NetworkManager ```csharp // Add to scene: GameObject > Add Component > NetworkManager // Or create custom NetworkManager: using Unity.Netcode; public class CustomNetworkManager : MonoBehaviour { void Start() { NetworkManager.Singleton.StartHost(); // Server + client // OR NetworkManager.Singleton.StartServer(); // Dedicated server // OR NetworkManager.Singleton.StartClient(); // Client only } } ``` --- ## NetworkObject (Networked GameObjects) ### Mark GameObject as Networked 1. Add `NetworkObject` component to GameObject 2. Must be in root of prefab (not nested) 3. Register prefab in `NetworkManager > NetworkPrefabs List` ### Spawn Network Objects ```csharp using Unity.Netcode; public class GameManager : NetworkBehaviour { public GameObject playerPrefab; [ServerRpc(RequireOwnership = false)] public void SpawnPlayerServerRpc(ulong clientId) { GameObject player = Instantiate(playerPrefab); player.GetComponent().SpawnAsPlayerObject(clientId); } } ``` --- ## NetworkBehaviour (Networked Scripts) ### NetworkBehaviour Base Class ```csharp using Unity.Netcode; public class Player : NetworkBehaviour { // Called when spawned on network public override void OnNetworkSpawn() { if (IsOwner) { // Only run on owner's client GetComponent().enabled = true; } } void Update() { if (!IsOwner) return; // Only owner can control // Handle input if (Input.GetKey(KeyCode.W)) { MoveServerRpc(Vector3.forward); } } [ServerRpc] void MoveServerRpc(Vector3 direction) { // Runs on server transform.position += direction * Time.deltaTime; } } ``` --- ## Network Variables (Synchronized State) ### NetworkVariable ```csharp using Unity.Netcode; public class Player : NetworkBehaviour { // ✅ Auto-synced across clients private NetworkVariable health = new NetworkVariable(100); public override void OnNetworkSpawn() { // Subscribe to value changes health.OnValueChanged += OnHealthChanged; } void OnHealthChanged(int oldValue, int newValue) { Debug.Log($"Health changed: {oldValue} -> {newValue}"); UpdateHealthUI(newValue); } [ServerRpc] public void TakeDamageServerRpc(int damage) { // Only server can modify NetworkVariable health.Value -= damage; } } ``` ### NetworkVariable Permissions ```csharp // Server can write, clients read-only (default) private NetworkVariable score = new NetworkVariable(); // Owner can write private NetworkVariable ammo = new NetworkVariable( default, NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Owner ); ``` --- ## RPCs (Remote Procedure Calls) ### ServerRpc (Client → Server) ```csharp // Client calls, server executes [ServerRpc] void FireWeaponServerRpc() { // Runs on server Debug.Log("Server: Weapon fired"); } // Call from client: if (IsOwner && Input.GetKeyDown(KeyCode.Space)) { FireWeaponServerRpc(); } ``` ### ClientRpc (Server → All Clients) ```csharp // Server calls, all clients execute [ClientRpc] void PlayExplosionClientRpc(Vector3 position) { // Runs on all clients Instantiate(explosionPrefab, position, Quaternion.identity); } // Call from server: [ServerRpc] void ExplodeServerRpc(Vector3 position) { // Server logic DealDamageToNearbyPlayers(position); // Notify all clients PlayExplosionClientRpc(position); } ``` ### RPC Parameters ```csharp // ✅ Supported: Primitives, structs, strings, arrays [ServerRpc] void SetNameServerRpc(string playerName) { } [ClientRpc] void UpdateScoresClientRpc(int[] scores) { } // ❌ Not supported: MonoBehaviour, GameObject (use NetworkObjectReference) ``` --- ## Network Ownership ### Check Ownership ```csharp if (IsOwner) { // This client owns this NetworkObject } if (IsServer) { // Running on server } if (IsClient) { // Running on client } if (IsLocalPlayer) { // This is the local player object } ``` ### Transfer Ownership ```csharp // Server transfers ownership NetworkObject netObj = GetComponent(); netObj.ChangeOwnership(newOwnerClientId); ``` --- ## NetworkObjectReference (Pass GameObjects in RPCs) ```csharp using Unity.Netcode; [ServerRpc] void AttackTargetServerRpc(NetworkObjectReference targetRef) { if (targetRef.TryGet(out NetworkObject target)) { // Got the target object target.GetComponent().TakeDamage(10); } } // Call: NetworkObject targetNetObj = target.GetComponent(); AttackTargetServerRpc(targetNetObj); ``` --- ## Client-Server Architecture ### Server-Authoritative Pattern (RECOMMENDED) ```csharp public class Player : NetworkBehaviour { private NetworkVariable position = new NetworkVariable(); void Update() { if (IsOwner) { // Client: Send input to server Vector3 input = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")); MoveServerRpc(input); } // All clients: Sync to networked position transform.position = position.Value; } [ServerRpc] void MoveServerRpc(Vector3 input) { // Server: Validate and apply movement position.Value += input * Time.deltaTime * moveSpeed; } } ``` --- ## Network Transport ### Unity Transport (Default) ```csharp // Configured in NetworkManager: // - Transport: Unity Transport // - Address: 127.0.0.1 (localhost) or server IP // - Port: 7777 (default) ``` ### Connection Events ```csharp void Start() { NetworkManager.Singleton.OnClientConnectedCallback += OnClientConnected; NetworkManager.Singleton.OnClientDisconnectCallback += OnClientDisconnected; } void OnClientConnected(ulong clientId) { Debug.Log($"Client {clientId} connected"); } void OnClientDisconnected(ulong clientId) { Debug.Log($"Client {clientId} disconnected"); } ``` --- ## Performance Tips ### Reduce Network Traffic - Use `NetworkVariable` for state that changes infrequently - Batch multiple changes before syncing - Use delta compression for large data ### Prediction & Reconciliation - Run movement locally for responsiveness - Reconcile with server authoritative state - Use interpolation for smooth movement --- ## Debugging ### Network Profiler - `Window > Analysis > Network Profiler` - Monitor bandwidth, RPC calls, variable updates ### Network Simulator (Test Latency/Packet Loss) - `NetworkManager > Network Simulator` - Add artificial lag and packet loss for testing --- ## Sources - https://docs-multiplayer.unity3d.com/netcode/current/about/ - https://docs-multiplayer.unity3d.com/netcode/current/learn/bossroom/