Claude-Code-Game-Studios/docs/engine-reference/unity/modules/networking.md
Donchitos ad540fe75d Game Studio Agent Architecture — complete setup (Phases 1-7)
48 coordinated Claude Code subagents for indie game development:
- 3 leadership agents (creative-director, technical-director, producer)
- 10 department leads (game-designer, lead-programmer, art-director, etc.)
- 23 specialist agents (gameplay, engine, AI, networking, UI, tools, etc.)
- 12 engine-specific agents (Godot, Unity, Unreal with sub-specialists)

Infrastructure:
- 34 skills (slash commands) for workflows, reviews, and team orchestration
- 8 hooks for commit validation, asset checks, session management
- 11 path-scoped rules enforcing domain-specific standards
- 28 templates for design docs, reports, and collaborative protocols

Key features:
- User-driven collaboration protocol (Question → Options → Decision → Draft → Approval)
- Engine version awareness with knowledge-gap detection (Godot 4.6 pinned)
- Phase gate system for development milestone validation
- CLAUDE.md kept under 80 lines with extracted doc imports

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 21:04:24 +11:00

351 lines
7.4 KiB
Markdown

# 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<NetworkObject>().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<Camera>().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<T>
```csharp
using Unity.Netcode;
public class Player : NetworkBehaviour {
// ✅ Auto-synced across clients
private NetworkVariable<int> health = new NetworkVariable<int>(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<int> score = new NetworkVariable<int>();
// Owner can write
private NetworkVariable<int> ammo = new NetworkVariable<int>(
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<NetworkObject>();
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<Health>().TakeDamage(10);
}
}
// Call:
NetworkObject targetNetObj = target.GetComponent<NetworkObject>();
AttackTargetServerRpc(targetNetObj);
```
---
## Client-Server Architecture
### Server-Authoritative Pattern (RECOMMENDED)
```csharp
public class Player : NetworkBehaviour {
private NetworkVariable<Vector3> position = new NetworkVariable<Vector3>();
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/