Multiplayer Engineering • Unity

Getting Started with Unity Netcode (NGO): The Ultimate Guide

Written by Sudhishkumar K • Dec 2026 • 25 Min Read

Multiplayer game development used to be a dark art. For years, Unity developers struggled with the deprecated UNet system, third-party solutions like Photon (PUN), or low-level socket programming.

But in 2026, the standard is clear: Netcode for GameObjects (NGO).

NGO is Unity's official, robust, first-party solution for building multiplayer games. It handles the heavy lifting of state synchronization, connection management, and latency compensation. However, shifting from single-player to multiplayer requires a fundamental rewiring of your brain. You are no longer writing code for one computer; you are writing code for a distributed system.

In this guide, we will break down the core pillars of NGO: The Server-Authoritative Model, NetworkVariables, RPCs, and Object Spawning.

1. The Golden Rule: Server Authority

Before writing a single line of code, you must understand the architecture. NGO uses a Server-Authoritative model.

[Image of Server-Client Architecture Diagram]

Why? Security. If the client calculated their own health, a hacker could simply send "Health = 99999" to the server. In NGO, the client can only ask: "I took damage." The server decides: "Yes, you did. Your health is now 90."

2. Setting Up the Environment

To start, install the package com.unity.netcode.gameobjects from the Package Manager.

Every multiplayer scene needs a NetworkManager.

  1. Create an Empty GameObject named "NetworkManager".
  2. Add the NetworkManager component.
  3. Select "UnityTransport" as the Transport.
  4. Drag your Player Prefab into the "Player Prefab" slot. (Note: Your player prefab must have a NetworkObject component).

3. NetworkVariables: Syncing State

In single-player, if you want to store health, you write:
public int health = 100;

In multiplayer, if you change that integer on the Server, the Client won't know. The variable is local to the machine. To sync it, we use NetworkVariable<T>.


using Unity.Netcode;

public class PlayerHealth : NetworkBehaviour {
    // 1. Define the variable
    // ReadPermission: Everyone can see the health.
    // WritePermission: Only Server can change it.
    public NetworkVariable Health = new NetworkVariable(
        100, 
        NetworkVariableReadPermission.Everyone, 
        NetworkVariableWritePermission.Server
    );

    public override void OnNetworkSpawn() {
        // 2. Subscribe to changes
        // This fires on ALL clients whenever the value changes
        Health.OnValueChanged += (oldValue, newValue) => {
            UpdateHealthUI(newValue);
        };
    }

    // Example of taking damage (Server Side Logic)
    public void TakeDamage(int amount) {
        if (!IsServer) return; // Safety check
        
        Health.Value -= amount; // This syncs automatically!
    }
}
            

Supported Types

You cannot use standard classes in NetworkVariables. You must use "Value Types" (int, float, bool, Vector3) or structs that implement `INetworkSerializable`. This ensures the data is small enough to travel over the internet efficiently.

4. RPCs: Messaging System

Variables are great for State (Health, Ammo, Position). But what about Events?
Example: "Play a Gunshot Sound." You don't want to store a "IsSoundPlaying" variable. You want to fire an event once.

We use Remote Procedure Calls (RPCs).

ServerRpc Direction: Client -> Server
Use Case: "I pressed the shoot button." "I want to pick up this item."
Naming: Must end in `ServerRpc`.
ClientRpc Direction: Server -> Clients
Use Case: "Play this particle effect." "Show the Game Over screen."
Naming: Must end in `ClientRpc`.

// 1. Client asks to shoot
void Update() {
    if (Input.GetButtonDown("Fire1") && IsOwner) {
        RequestShootServerRpc();
    }
}

// 2. Server validates and tells everyone
[ServerRpc]
void RequestShootServerRpc() {
    if (Ammo.Value > 0) {
        Ammo.Value--;
        // Tell all clients to play the sound/FX
        PlayEffectsClientRpc(); 
    }
}

// 3. All clients (including the shooter) play the effect
[ClientRpc]
void PlayEffectsClientRpc() {
    audioSource.PlayOneShot(shootClip);
    particleSystem.Play();
}
            

5. Movement and NetworkTransform

Syncing position is the hardest part of multiplayer. If you just use a `NetworkVariable` for position, the player will "teleport" every time the network updates (e.g., 10 times a second). It looks choppy.

Unity provides the NetworkTransform component.

6. Spawning Objects Dynamically

You cannot just use `Instantiate()` for a bullet. If you do, it will only appear on the Server's machine, not the Clients.

To spawn an object across the network:

  1. The prefab must have a NetworkObject component.
  2. The prefab must be registered in the "Network Prefab List" inside the NetworkManager.
  3. You must call Spawn() on the instantiated object.

[ServerRpc]
void FireBulletServerRpc() {
    // 1. Standard Instantiate
    GameObject bullet = Instantiate(bulletPrefab, spawnPoint.position, spawnPoint.rotation);
    
    // 2. Get the Netcode component
    NetworkObject netObj = bullet.GetComponent();
    
    // 3. Tell the network to spawn it on all clients
    netObj.Spawn(); 
}
            

7. Testing with ParrelSync

Building a standalone executable every time you want to test multiplayer is painful.

Install the open-source tool ParrelSync. It allows you to open two Unity Editors at the same time using the same project.
Editor A: Click "Start Host".
Editor B: Click "Start Client".
You can now debug Client and Server logic simultaneously in real-time.

Conclusion

Unity NGO is a powerful toolset. While the learning curve is steep, mastering the distinction between Server Logic and Client Logic is the key to success.

Start small. Build a cube that can move. Then sync the movement. Then add a button to change its color. Once you understand the flow of data, you can build anything from a co-op puzzle game to a battle royale.


Frequently Asked Questions (FAQ)

Q: What is the difference between Host and Server?
A: A Dedicated Server has no player; it is just a simulation running in the cloud. A Host is a player who also acts as the server. Their machine simulates the game for everyone else. NGO supports both.

Q: Is NGO free?
A: Yes, the package is free. However, if you use Unity Relay or Lobby services to connect players over the internet (without port forwarding), you may incur costs after a certain number of concurrent users.

Q: Can I use physics?
A: Yes, but use `NetworkRigidbody`. Physics simulations are non-deterministic, so syncing them perfectly is hard. NetworkRigidbody helps sync the results of the physics simulation from Server to Client.