Claude-Code-Game-Studios/docs/engine-reference/unity/current-best-practices.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

334 lines
7.6 KiB
Markdown

# Unity 6.3 LTS — Current Best Practices
**Last verified:** 2026-02-13
Modern Unity 6 patterns that may not be in the LLM's training data.
These are production-ready recommendations as of Unity 6.3 LTS.
---
## Project Setup
### Use Unity 6.3 LTS for Production
- **Tech Stream** (6.4+): Latest features, less stable
- **LTS** (6.3): Production-ready, 2-year support (until Dec 2027)
### Choose the Right Render Pipeline
- **URP (Universal)**: Mobile, cross-platform, good performance ✅ Recommended for most games
- **HDRP (High Definition)**: High-end PC/console, photorealistic
- **Built-in**: Deprecated, avoid for new projects
---
## Scripting
### Use C# 9+ Features (Unity 6 Supports C# 9)
```csharp
// ✅ Record types for data
public record PlayerData(string Name, int Level, float Health);
// ✅ Init-only properties
public class Config {
public string GameMode { get; init; }
}
// ✅ Pattern matching
var result = enemy switch {
Boss boss => boss.Enrage(),
Minion minion => minion.Flee(),
_ => null
};
```
### Async/Await for Asset Loading
```csharp
// ✅ Modern async pattern
public async Task<GameObject> LoadEnemyAsync(string key) {
var handle = Addressables.LoadAssetAsync<GameObject>(key);
return await handle.Task;
}
```
### Use Source Generators for Serialization (Unity 6+)
```csharp
// ✅ Source-generated serialization (faster, less reflection)
[GenerateSerializer]
public partial struct PlayerStats : IComponentData {
public int Health;
public int Mana;
}
```
---
## DOTS/ECS (Production-Ready in Unity 6.3 LTS)
### Use ISystem (Not ComponentSystem)
```csharp
// ✅ Modern unmanaged ISystem (Burst-compatible)
public partial struct MovementSystem : ISystem {
public void OnCreate(ref SystemState state) { }
public void OnUpdate(ref SystemState state) {
foreach (var (transform, speed) in
SystemAPI.Query<RefRW<LocalTransform>, RefRO<MoveSpeed>>()) {
transform.ValueRW.Position += speed.ValueRO.Value * SystemAPI.Time.DeltaTime;
}
}
}
```
### Use IJobEntity for Parallel Jobs
```csharp
// ✅ IJobEntity (replaces IJobForEach)
[BurstCompile]
public partial struct DamageJob : IJobEntity {
public float DeltaTime;
void Execute(ref Health health, in DamageOverTime dot) {
health.Value -= dot.DamagePerSecond * DeltaTime;
}
}
// Schedule it
var job = new DamageJob { DeltaTime = SystemAPI.Time.DeltaTime };
job.ScheduleParallel();
```
---
## Input
### Use Input System Package (Not Legacy Input)
```csharp
// ✅ Input Actions (rebindable, cross-platform)
using UnityEngine.InputSystem;
public class PlayerInput : MonoBehaviour {
private PlayerControls controls;
void Awake() {
controls = new PlayerControls();
controls.Gameplay.Jump.performed += ctx => Jump();
}
void OnEnable() => controls.Enable();
void OnDisable() => controls.Disable();
}
```
Create Input Actions asset in editor, generate C# class via inspector.
---
## UI
### Use UI Toolkit for Runtime UI (Production-Ready in Unity 6)
```csharp
// ✅ UI Toolkit (replaces UGUI for new projects)
using UnityEngine.UIElements;
public class MainMenu : MonoBehaviour {
void OnEnable() {
var root = GetComponent<UIDocument>().rootVisualElement;
var playButton = root.Q<Button>("play-button");
playButton.clicked += StartGame;
var scoreLabel = root.Q<Label>("score");
scoreLabel.text = $"High Score: {PlayerPrefs.GetInt("HighScore")}";
}
}
```
**UXML** (UI structure) + **USS** (styling) = HTML/CSS-like workflow.
---
## Asset Management
### Use Addressables (Not Resources)
```csharp
// ✅ Addressables (async, memory-efficient)
using UnityEngine.AddressableAssets;
public async Task SpawnEnemyAsync(string enemyKey) {
var handle = Addressables.InstantiateAsync(enemyKey);
var enemy = await handle.Task;
// Cleanup: release when destroyed
Addressables.ReleaseInstance(enemy);
}
```
**Benefits:** Async loading, remote content delivery, better memory control.
---
## Rendering
### Use RenderGraph API for Custom Passes (URP/HDRP)
```csharp
// ✅ RenderGraph API (Unity 6+)
public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) {
using (var builder = renderGraph.AddRasterRenderPass<PassData>("My Pass", out var passData)) {
// Setup pass
builder.SetRenderFunc((PassData data, RasterGraphContext context) => {
// Execute commands
});
}
}
```
**Replaces:** Old `CommandBuffer.Execute()` pattern.
---
## Performance
### Use Burst Compiler + Jobs System
```csharp
// ✅ Burst-compiled job (massive performance gain)
[BurstCompile]
struct ParticleUpdateJob : IJobParallelFor {
public NativeArray<float3> Positions;
public NativeArray<float3> Velocities;
public float DeltaTime;
public void Execute(int index) {
Positions[index] += Velocities[index] * DeltaTime;
}
}
// Schedule
var job = new ParticleUpdateJob {
Positions = positions,
Velocities = velocities,
DeltaTime = Time.deltaTime
};
job.Schedule(positions.Length, 64).Complete();
```
**20-100x faster** than equivalent C# code.
---
### Use GPU Instancing for Repeated Objects
```csharp
// ✅ GPU Instancing (thousands of objects, minimal draw calls)
Graphics.RenderMeshInstanced(
new RenderParams(material),
mesh,
0,
matrices // NativeArray<Matrix4x4>
);
```
---
## Memory Management
### Use NativeContainers (Not Managed Arrays in Jobs)
```csharp
// ✅ NativeArray (no GC, Burst-compatible)
NativeArray<int> data = new NativeArray<int>(1000, Allocator.TempJob);
// ... use in job
data.Dispose(); // Manual cleanup required
// ✅ Or use using statement
using var data = new NativeArray<int>(1000, Allocator.TempJob);
// Auto-disposed
```
---
## Multiplayer
### Use Netcode for GameObjects (Official)
```csharp
// ✅ Unity's official netcode
using Unity.Netcode;
public class Player : NetworkBehaviour {
private NetworkVariable<int> health = new NetworkVariable<int>(100);
[ServerRpc]
public void TakeDamageServerRpc(int damage) {
health.Value -= damage;
}
}
```
**Replaces:** UNet (deprecated), MLAPI (renamed to Netcode for GameObjects).
---
## Testing
### Use Unity Test Framework (NUnit-based)
```csharp
// ✅ Play Mode Test
[UnityTest]
public IEnumerator Player_TakesDamage_HealthDecreases() {
var player = new GameObject().AddComponent<Player>();
player.Health = 100;
player.TakeDamage(25);
yield return null; // Wait one frame
Assert.AreEqual(75, player.Health);
}
```
---
## Debugging
### Use Logging Best Practices
```csharp
// ✅ Structured logging (Unity 6+)
using UnityEngine;
Debug.Log($"Player {playerName} scored {score} points");
// ✅ Conditional compilation for debug code
#if UNITY_EDITOR || DEVELOPMENT_BUILD
Debug.DrawRay(transform.position, direction, Color.red);
#endif
```
---
## Summary: Unity 6 Tech Stack
| Feature | Use This (2026) | Avoid This (Legacy) |
|---------|------------------|----------------------|
| **Input** | Input System package | `Input` class |
| **UI** | UI Toolkit | UGUI (Canvas) |
| **ECS** | ISystem + IJobEntity | ComponentSystem |
| **Rendering** | URP + RenderGraph | Built-in pipeline |
| **Assets** | Addressables | Resources |
| **Jobs** | Burst + IJobParallelFor | Coroutines for heavy work |
| **Multiplayer** | Netcode for GameObjects | UNet |
---
**Sources:**
- https://docs.unity3d.com/6000.0/Documentation/Manual/BestPracticeGuides.html
- https://docs.unity3d.com/Packages/com.unity.entities@1.3/manual/index.html
- https://docs.unity3d.com/Packages/com.unity.inputsystem@1.11/manual/index.html