agentsclimarketplace

Unity ai navigation

Skill IdoCohen560/claude-unity-game-studio/examples/my-first-game/.claude/skills/unity-ai-navigation

AI-powered Unity game development studio for Claude Code - 49 agents, 120+ skills, and a full studio hierarchy that turns a single AI session into a coordinated game dev team. View more about me in my portfolio.

Install
npx -y skills add IdoCohen560/claude-unity-game-studio --skill unity-ai-navigation

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 8 stars8 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Unity 6 AI and navigation guide. Use when working with NavMesh, pathfinding, NavMeshAgent, NavMeshSurface, NavMeshObstacle, off-mesh links, or Unity Sentis (ML model inference). Covers AI navigation package, runtime NavMesh baking, and common AI patterns like state machines and behavior trees. Based on Unity 6.3 LTS documentation.

SKILL.md

15.1 KB, as published. Nobody here has run it

Unity 6 AI and Navigation Guide

Source: Unity 6.3 LTS Documentation (6000.3)

AI Navigation Overview

Package: com.unity.ai.navigation (v2.0.11 for Unity 6000.3)

The AI Navigation package is a high-level component system that enables NavMesh-based navigation and pathfinding. It supports runtime and edit-time NavMesh construction, dynamic obstacle management, and link systems for specialized actions (jumping, doors).

Core Components

ComponentPurpose
NavMeshSurfaceDefines and builds NavMesh for a specific agent type
NavMeshAgentCharacter pathfinding and movement
NavMeshObstacleDynamic obstacle avoidance
NavMeshModifierAffects NavMesh generation based on transform hierarchy
NavMeshModifierVolumeAffects NavMesh generation based on volume
NavMeshLinkConnects same or different NavMesh surfaces

NavMesh Setup

Baking a NavMesh

  1. Add a NavMeshSurface component to a GameObject
  2. Configure the Agent Type (determines which agents can use this surface)
  3. Set Use Geometry to Render Meshes or Physics Colliders
  4. Configure Collect Objects mode (All, Volume, Current Hierarchy, NavMeshModifier only)
  5. Click Bake or call BuildNavMesh() at runtime

NavMeshSurface Properties

PropertyDescription
Agent TypeWhich NavMesh Agent configuration can use this surface
Default AreaWalkable (default), Not Walkable, Jump, plus 29 custom types
Use GeometryRender Meshes or Physics Colliders (colliders allow closer edge navigation)
Generate LinksAuto-creates connections between collected GameObjects during bake
Collect ObjectsAll GameObjects, Volume, Current Hierarchy, NavMeshModifier only
Include LayersFilters GameObjects by layer (default: Everything)

Advanced Baking Parameters

ParameterDescription
Override Voxel SizePrecision (default: 3 voxels per agent radius)
Override Tile SizeTile dimensions (default: 256 voxels); smaller = better carving
Minimum Region AreaRemoves disconnected mesh segments below threshold
Build Height MeshGenerates elevation data for character placement

The system excludes GameObjects with NavMeshAgent or NavMeshObstacle during baking.

Runtime NavMesh Baking

using UnityEngine;
using Unity.AI.Navigation;

public class RuntimeNavMeshBaker : MonoBehaviour
{
    NavMeshSurface surface;

    void Start()
    {
        surface = GetComponent<NavMeshSurface>();
        surface.BuildNavMesh();
    }

    public void RebakeNavMesh()
    {
        surface.UpdateNavMesh(surface.navMeshData);
    }
}

NavMeshAgent

The NavMeshAgent component handles both pathfinding and movement control.

Add via: Add Component > Navigation > NavMesh Agent

Basic Movement

using UnityEngine;
using UnityEngine.AI;

public class MoveTo : MonoBehaviour
{
    public Transform goal;

    void Start()
    {
        NavMeshAgent agent = GetComponent<NavMeshAgent>();
        agent.destination = goal.position;
    }
}

Agent Properties

Steering: Speed, Angular Speed, Acceleration, Stopping Distance, Auto Braking

Obstacle Avoidance: Radius, Height, Quality (None to High), Priority (0-99; lower = higher)

Agents avoid others of higher priority and ignore those of lower priority.

Pathfinding: Auto Traverse OffMesh Link, Auto Repath, Area Mask

Agent Scripting Patterns

using UnityEngine;
using UnityEngine.AI;

public class AIController : MonoBehaviour
{
    NavMeshAgent agent;

    void Start() { agent = GetComponent<NavMeshAgent>(); }

    public void MoveToTarget(Vector3 target) { agent.SetDestination(target); }

    bool HasReachedDestination()
    {
        if (!agent.pathPending
            && agent.remainingDistance <= agent.stoppingDistance
            && (!agent.hasPath || agent.velocity.sqrMagnitude == 0f))
            return true;
        return false;
    }

    public void StopMoving() { agent.isStopped = true; }
    public void ResumeMoving() { agent.isStopped = false; }
    public void WarpTo(Vector3 position) { agent.Warp(position); }
}

Partial Paths

When a destination is unreachable, the agent generates a partial path to the nearest reachable location:

if (agent.pathStatus == NavMeshPathStatus.PathPartial)
    Debug.Log("Destination unreachable, using partial path");
else if (agent.pathStatus == NavMeshPathStatus.PathInvalid)
    Debug.Log("No valid path found");

NavMeshObstacle

Defines dynamic obstacles that agents avoid. Add via: Add Component > Navigation > NavMesh Obstacle

Shapes: Box (Center + Size) or Capsule (Center + Radius + Height)

Carving

PropertyDescription
Move ThresholdDistance triggering update for moving obstacles
Time To StationarySeconds before classified as stationary
Carve Only StationaryOnly carve when not moving
  • Carved: Dynamically modify NavMesh topology (barrels, crates, doors)
  • Non-carved: Exclusion zones without mesh modification (moving characters)
using UnityEngine;
using UnityEngine.AI;

public class DynamicObstacle : MonoBehaviour
{
    NavMeshObstacle obstacle;

    void Start()
    {
        obstacle = GetComponent<NavMeshObstacle>();
        obstacle.carving = true;
        obstacle.carveOnlyStationary = true;
    }

    public void SetBlocking(bool blocking) { obstacle.enabled = blocking; }
}

Off-Mesh Links (NavMeshLink)

Connects separate NavMesh surfaces. Use for doors, jump points, ledges, ladders.

Add via: GameObject > AI > NavMesh Link or Add Component > Navigation > NavMesh Link

PropertyDescription
Agent TypeWhich agent type can traverse
Start/End TransformGameObjects at link edges
WidthLink span width
BidirectionalTwo-way traversal
Area TypeWalkable, Not Walkable, or Jump
ActivatedControls link usability

Custom Link Traversal

using UnityEngine;
using UnityEngine.AI;
using System.Collections;

public class CustomLinkTraversal : MonoBehaviour
{
    NavMeshAgent agent;

    void Start()
    {
        agent = GetComponent<NavMeshAgent>();
        agent.autoTraverseOffMeshLink = false;
    }

    void Update()
    {
        if (agent.isOnOffMeshLink) StartCoroutine(TraverseLink());
    }

    IEnumerator TraverseLink()
    {
        OffMeshLinkData linkData = agent.currentOffMeshLinkData;
        Vector3 startPos = agent.transform.position;
        Vector3 endPos = linkData.endPos + Vector3.up * agent.baseOffset;
        float elapsed = 0f, duration = 0.5f;

        while (elapsed < duration)
        {
            float t = elapsed / duration;
            agent.transform.position = Vector3.Lerp(startPos, endPos, t)
                + Vector3.up * Mathf.Sin(t * Mathf.PI) * 2f;
            elapsed += Time.deltaTime;
            yield return null;
        }
        agent.CompleteOffMeshLink();
    }
}

Unity Sentis Overview

Package: com.unity.sentis (v2.1) -- now renamed Inference Engine (com.unity.ai.inference)

Neural network inference library for running ONNX models (opset 7-15) on GPU/CPU across all Unity platforms.

Core Workflow

using UnityEngine;
using Unity.Sentis;

public class MLInference : MonoBehaviour
{
    public ModelAsset modelAsset;
    Model runtimeModel;
    Worker worker;

    void Start()
    {
        runtimeModel = ModelLoader.Load(modelAsset);
        worker = new Worker(runtimeModel, BackendType.GPUCompute);
    }

    void RunInference()
    {
        Tensor<float> input = TextureConverter.ToTensor(
            Resources.Load("image") as Texture2D);
        worker.Schedule(input);
        Tensor<float> output = worker.PeekOutput() as Tensor<float>;
        input.Dispose();
    }

    void OnDestroy() { worker?.Dispose(); }
}

Backend Types

BackendPerformanceNotes
GPUComputeFastest (GPU)Check SystemInfo.supportsComputeShaders
CPUFastest (CPU)Slow on WebGL (Burst to WASM)
GPUPixelSlowerFallback without compute shaders

See skills/unity-ai-navigation/references/sentis-ml.md for full API details.

Common AI Patterns

Simple State Machine

using UnityEngine;
using UnityEngine.AI;

public enum AIState { Idle, Patrol, Chase, Attack }

public class AIStateMachine : MonoBehaviour
{
    public AIState currentState = AIState.Idle;
    public Transform[] patrolPoints;
    public float chaseRange = 10f, attackRange = 2f;
    NavMeshAgent agent;
    Transform player;
    int patrolIndex;

    void Start()
    {
        agent = GetComponent<NavMeshAgent>();
        player = GameObject.FindWithTag("Player").transform;
    }

    void Update()
    {
        float dist = Vector3.Distance(transform.position, player.position);
        switch (currentState)
        {
            case AIState.Idle:
                if (dist < chaseRange) currentState = AIState.Chase;
                else if (patrolPoints.Length > 0) currentState = AIState.Patrol;
                break;
            case AIState.Patrol:
                agent.SetDestination(patrolPoints[patrolIndex].position);
                if (!agent.pathPending && agent.remainingDistance <= agent.stoppingDistance)
                    patrolIndex = (patrolIndex + 1) % patrolPoints.Length;
                if (dist < chaseRange) currentState = AIState.Chase;
                break;
            case AIState.Chase:
                agent.SetDestination(player.position);
                if (dist < attackRange) currentState = AIState.Attack;
                else if (dist > chaseRange * 1.5f) currentState = AIState.Patrol;
                break;
            case AIState.Attack:
                agent.isStopped = true;
                if (dist > attackRange) { agent.isStopped = false; currentState = AIState.Chase; }
                break;
        }
    }
}

Behavior Tree Nodes

public enum NodeState { Running, Success, Failure }

public abstract class BTNode { public abstract NodeState Evaluate(); }

public class Selector : BTNode
{
    BTNode[] children;
    public Selector(params BTNode[] children) { this.children = children; }
    public override NodeState Evaluate()
    {
        foreach (var child in children)
        {
            var result = child.Evaluate();
            if (result != NodeState.Failure) return result;
        }
        return NodeState.Failure;
    }
}

public class Sequence : BTNode
{
    BTNode[] children;
    public Sequence(params BTNode[] children) { this.children = children; }
    public override NodeState Evaluate()
    {
        foreach (var child in children)
        {
            var result = child.Evaluate();
            if (result != NodeState.Success) return result;
        }
        return NodeState.Success;
    }
}

NavMesh Queries

using UnityEngine;
using UnityEngine.AI;

public class NavMeshQueries : MonoBehaviour
{
    public Vector3 GetNearestNavMeshPoint(Vector3 pos, float maxDist)
    {
        NavMeshHit hit;
        return NavMesh.SamplePosition(pos, out hit, maxDist, NavMesh.AllAreas)
            ? hit.position : pos;
    }

    public bool IsOnNavMesh(Vector3 pos)
    {
        NavMeshHit hit;
        return NavMesh.SamplePosition(pos, out hit, 0.1f, NavMesh.AllAreas);
    }

    public bool CanReachTarget(Vector3 start, Vector3 end)
    {
        NavMeshPath path = new NavMeshPath();
        NavMesh.CalculatePath(start, end, NavMesh.AllAreas, path);
        return path.status == NavMeshPathStatus.PathComplete;
    }

    public Vector3 GetRandomNavMeshPoint(Vector3 center, float range)
    {
        Vector3 dir = Random.insideUnitSphere * range + center;
        NavMeshHit hit;
        return NavMesh.SamplePosition(dir, out hit, range, NavMesh.AllAreas)
            ? hit.position : center;
    }
}

Anti-Patterns

  • Baking NavMesh every frame -- BuildNavMesh() is expensive. Only call when geometry changes. Use UpdateNavMesh() for incremental updates.
  • Not checking pathStatus -- Always check agent.pathStatus. Partial or invalid paths cause agents to get stuck silently.
  • Setting destination in Update without guard -- Recalculating paths every frame wastes CPU. Only update when target moves significantly.
  • NavMeshObstacle on agents -- Do not add NavMeshObstacle to GameObjects that also have NavMeshAgent. Agents already avoid each other.
  • Forgetting area masks -- Agents without proper Area Mask may walk through restricted zones.
  • Carving everything -- Carving is expensive. Use non-carving obstacles for things agents can path around naturally.
  • Missing NavMeshSurface -- Without a NavMeshSurface, there is no NavMesh. Agents will not move.
  • Not disposing Sentis workers -- Always call worker.Dispose() in OnDestroy().
  • Using CPU backend on WebGL -- Burst compiles to WASM, resulting in very slow ML inference.

Key API Quick Reference

ClassNamespacePurpose
NavMeshAgentUnityEngine.AIPathfinding and movement
NavMeshObstacleUnityEngine.AIDynamic obstacle
NavMeshUnityEngine.AIStatic queries and sampling
NavMeshPathUnityEngine.AICalculated path data
NavMeshHitUnityEngine.AIRaycast/sample result
NavMeshSurfaceUnity.AI.NavigationNavMesh baking
NavMeshModifierUnity.AI.NavigationPer-object overrides
NavMeshModifierVolumeUnity.AI.NavigationVolume-based overrides
NavMeshLinkUnity.AI.NavigationSurface connections
ModelAssetUnity.SentisONNX model reference
ModelLoaderUnity.SentisRuntime model loading
WorkerUnity.SentisInference engine
BackendTypeUnity.SentisGPUCompute, CPU, GPUPixel
Tensor<T>Unity.SentisInput/output data

Related Skills

  • unity-foundations -- GameObject, components, scene hierarchy
  • unity-scripting -- C# scripting patterns, MonoBehaviour lifecycle
  • unity-physics -- Colliders, raycasting, physics integration with NavMesh

Additional Resources

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.