mirror of
https://github.com/Donchitos/Claude-Code-Game-Studios
synced 2026-04-26 23:57:15 +00:00
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>
351 lines
7.4 KiB
Markdown
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/
|