mirror of
https://github.com/Donchitos/Claude-Code-Game-Studios
synced 2026-04-29 17:07:18 +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>
330 lines
7.1 KiB
Markdown
330 lines
7.1 KiB
Markdown
# Unity 6.3 — Navigation Module Reference
|
|
|
|
**Last verified:** 2026-02-13
|
|
**Knowledge Gap:** Unity 6 NavMesh improvements
|
|
|
|
---
|
|
|
|
## Overview
|
|
|
|
Unity 6 navigation systems:
|
|
- **NavMesh**: Built-in pathfinding for AI agents
|
|
- **NavMeshComponents**: Package for runtime NavMesh building
|
|
|
|
---
|
|
|
|
## NavMesh Basics
|
|
|
|
### Bake Navigation Mesh
|
|
|
|
1. Mark walkable surfaces:
|
|
- Select GameObject (floor/terrain)
|
|
- Inspector > Navigation > Object tab
|
|
- Check "Navigation Static"
|
|
|
|
2. Bake NavMesh:
|
|
- `Window > AI > Navigation`
|
|
- Bake tab
|
|
- Click "Bake"
|
|
|
|
3. Configure settings:
|
|
- **Agent Radius**: How wide the agent is (0.5m default)
|
|
- **Agent Height**: How tall the agent is (2m default)
|
|
- **Max Slope**: Maximum walkable slope (45° default)
|
|
- **Step Height**: Maximum climbable step (0.4m default)
|
|
|
|
---
|
|
|
|
## NavMeshAgent (AI Movement)
|
|
|
|
### Basic Agent Setup
|
|
|
|
```csharp
|
|
using UnityEngine;
|
|
using UnityEngine.AI;
|
|
|
|
public class Enemy : MonoBehaviour {
|
|
private NavMeshAgent agent;
|
|
public Transform target;
|
|
|
|
void Start() {
|
|
agent = GetComponent<NavMeshAgent>();
|
|
}
|
|
|
|
void Update() {
|
|
// ✅ Move to target
|
|
agent.SetDestination(target.position);
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### NavMeshAgent Properties
|
|
|
|
```csharp
|
|
NavMeshAgent agent = GetComponent<NavMeshAgent>();
|
|
|
|
// Speed
|
|
agent.speed = 3.5f;
|
|
|
|
// Acceleration
|
|
agent.acceleration = 8f;
|
|
|
|
// Stopping distance
|
|
agent.stoppingDistance = 2f; // Stop 2m before destination
|
|
|
|
// Auto-braking (slow down at destination)
|
|
agent.autoBraking = true;
|
|
|
|
// Rotation speed
|
|
agent.angularSpeed = 120f; // Degrees per second
|
|
|
|
// Obstacle avoidance
|
|
agent.obstacleAvoidanceType = ObstacleAvoidanceType.HighQualityObstacleAvoidance;
|
|
```
|
|
|
|
---
|
|
|
|
### Check Path Status
|
|
|
|
```csharp
|
|
void Update() {
|
|
agent.SetDestination(target.position);
|
|
|
|
// Check if agent has a path
|
|
if (agent.hasPath) {
|
|
// Check if path is complete
|
|
if (agent.pathStatus == NavMeshPathStatus.PathComplete) {
|
|
Debug.Log("Valid path");
|
|
} else if (agent.pathStatus == NavMeshPathStatus.PathPartial) {
|
|
Debug.Log("Partial path (destination unreachable)");
|
|
} else {
|
|
Debug.Log("Invalid path");
|
|
}
|
|
}
|
|
|
|
// Check if agent reached destination
|
|
if (!agent.pathPending && agent.remainingDistance <= agent.stoppingDistance) {
|
|
Debug.Log("Reached destination");
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Calculate Path (Don't Move Yet)
|
|
|
|
```csharp
|
|
NavMeshPath path = new NavMeshPath();
|
|
agent.CalculatePath(targetPosition, path);
|
|
|
|
if (path.status == NavMeshPathStatus.PathComplete) {
|
|
// Valid path exists
|
|
agent.SetPath(path); // Apply the path
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## NavMesh Areas (Walkable Costs)
|
|
|
|
### Define Areas
|
|
`Window > AI > Navigation > Areas tab`
|
|
- **Walkable**: Cost 1 (default)
|
|
- **Not Walkable**: Unwalkable
|
|
- **Jump**: Cost 2 (prefer other routes)
|
|
- **Custom**: Define your own
|
|
|
|
### Assign Area Costs
|
|
|
|
```csharp
|
|
// Prefer shorter paths over low-cost paths
|
|
agent.areaMask = NavMesh.AllAreas; // Walk on all areas
|
|
|
|
// Only walk on "Walkable" area (avoid "Jump")
|
|
agent.areaMask = 1 << NavMesh.GetAreaFromName("Walkable");
|
|
```
|
|
|
|
---
|
|
|
|
## NavMesh Obstacles (Dynamic Obstacles)
|
|
|
|
### NavMeshObstacle Component
|
|
|
|
```csharp
|
|
// Add: GameObject > Add Component > NavMesh Obstacle
|
|
|
|
// Carve: Create hole in NavMesh (agents avoid)
|
|
// Don't Carve: Agent pushes through (local avoidance)
|
|
```
|
|
|
|
### Dynamic Carving (Moving Obstacles)
|
|
|
|
```csharp
|
|
NavMeshObstacle obstacle = GetComponent<NavMeshObstacle>();
|
|
obstacle.carving = true; // Create dynamic hole in NavMesh
|
|
```
|
|
|
|
---
|
|
|
|
## Off-Mesh Links (Jumps, Teleports)
|
|
|
|
### Create Off-Mesh Link
|
|
|
|
1. `GameObject > Create Empty` (at jump start)
|
|
2. Add `Off Mesh Link` component
|
|
3. Set Start/End transforms
|
|
4. Configure:
|
|
- **Bi-Directional**: Can traverse both ways
|
|
- **Cost Override**: Path cost for this link
|
|
|
|
### Detect Off-Mesh Link Traversal
|
|
|
|
```csharp
|
|
void Update() {
|
|
// Check if agent is on an off-mesh link
|
|
if (agent.isOnOffMeshLink) {
|
|
// Manually traverse (e.g., play jump animation)
|
|
StartCoroutine(TraverseOffMeshLink());
|
|
}
|
|
}
|
|
|
|
IEnumerator TraverseOffMeshLink() {
|
|
OffMeshLinkData data = agent.currentOffMeshLinkData;
|
|
Vector3 startPos = agent.transform.position;
|
|
Vector3 endPos = data.endPos;
|
|
|
|
float duration = 0.5f;
|
|
float elapsed = 0f;
|
|
|
|
while (elapsed < duration) {
|
|
agent.transform.position = Vector3.Lerp(startPos, endPos, elapsed / duration);
|
|
elapsed += Time.deltaTime;
|
|
yield return null;
|
|
}
|
|
|
|
agent.CompleteOffMeshLink(); // Resume normal pathfinding
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## NavMeshComponents Package (Runtime Baking)
|
|
|
|
### Installation
|
|
1. `Window > Package Manager`
|
|
2. Add from Git URL: `com.unity.ai.navigation`
|
|
|
|
### Runtime NavMesh Baking
|
|
|
|
```csharp
|
|
using Unity.AI.Navigation;
|
|
|
|
public class NavMeshBuilder : MonoBehaviour {
|
|
public NavMeshSurface surface;
|
|
|
|
void Start() {
|
|
// Bake NavMesh at runtime
|
|
surface.BuildNavMesh();
|
|
}
|
|
|
|
void UpdateNavMesh() {
|
|
// Update NavMesh after terrain changes
|
|
surface.UpdateNavMesh(surface.navMeshData);
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Common Patterns
|
|
|
|
### Patrol Between Waypoints
|
|
|
|
```csharp
|
|
public Transform[] waypoints;
|
|
private int currentWaypoint = 0;
|
|
|
|
void Update() {
|
|
if (!agent.pathPending && agent.remainingDistance < 0.5f) {
|
|
// Reached waypoint, move to next
|
|
currentWaypoint = (currentWaypoint + 1) % waypoints.Length;
|
|
agent.SetDestination(waypoints[currentWaypoint].position);
|
|
}
|
|
}
|
|
```
|
|
|
|
### Chase Player
|
|
|
|
```csharp
|
|
public Transform player;
|
|
public float chaseRange = 10f;
|
|
|
|
void Update() {
|
|
float distance = Vector3.Distance(transform.position, player.position);
|
|
|
|
if (distance <= chaseRange) {
|
|
agent.SetDestination(player.position);
|
|
} else {
|
|
agent.ResetPath(); // Stop moving
|
|
}
|
|
}
|
|
```
|
|
|
|
### Flee from Player
|
|
|
|
```csharp
|
|
public Transform player;
|
|
public float fleeRange = 5f;
|
|
|
|
void Update() {
|
|
float distance = Vector3.Distance(transform.position, player.position);
|
|
|
|
if (distance <= fleeRange) {
|
|
// Run away from player
|
|
Vector3 fleeDirection = transform.position - player.position;
|
|
Vector3 fleeTarget = transform.position + fleeDirection.normalized * 10f;
|
|
|
|
agent.SetDestination(fleeTarget);
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Debugging
|
|
|
|
### NavMesh Visualization
|
|
- `Window > AI > Navigation > Bake tab`
|
|
- Check "Show NavMesh" to visualize walkable areas
|
|
|
|
### Agent Path Gizmos
|
|
|
|
```csharp
|
|
void OnDrawGizmos() {
|
|
if (agent != null && agent.hasPath) {
|
|
Gizmos.color = Color.green;
|
|
Vector3[] corners = agent.path.corners;
|
|
|
|
for (int i = 0; i < corners.Length - 1; i++) {
|
|
Gizmos.DrawLine(corners[i], corners[i + 1]);
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Performance Tips
|
|
|
|
- **Limit Obstacle Avoidance Quality**: Use `LowQualityObstacleAvoidance` for distant agents
|
|
- **Update Frequency**: Don't call `SetDestination()` every frame if target hasn't moved
|
|
- **Area Masks**: Limit walkable areas to reduce pathfinding search space
|
|
- **NavMesh Tiles**: Use tiled NavMesh for large worlds (NavMeshComponents package)
|
|
|
|
---
|
|
|
|
## Sources
|
|
- https://docs.unity3d.com/6000.0/Documentation/Manual/Navigation.html
|
|
- https://docs.unity3d.com/Packages/com.unity.ai.navigation@2.0/manual/index.html
|