Claude
Skills
Sign in
Back

navmesh

Included with Lifetime
$97 forever

Navigation mesh generation and pathfinding skill for game AI. Enables creation and configuration of navigation meshes, pathfinding queries, dynamic obstacles, and navigation agent setup across Unity, Unreal, and Godot engines.

AI Agents

What this skill does


# Navigation Mesh Skill

Comprehensive navigation mesh generation and pathfinding implementation for game AI systems across multiple engines.

## Overview

This skill provides capabilities for creating, configuring, and utilizing navigation meshes for AI pathfinding. It covers navmesh generation, agent configuration, dynamic obstacles, off-mesh links, and runtime navigation queries.

## Capabilities

### NavMesh Generation
- Configure navmesh build settings
- Define walkable areas and surfaces
- Set up area types with costs
- Generate runtime navmeshes

### Agent Configuration
- Configure agent radius and height
- Set movement parameters
- Define avoidance priorities
- Configure step height and slopes

### Pathfinding
- Query paths between points
- Handle partial paths
- Implement path smoothing
- Support hierarchical pathfinding

### Dynamic Navigation
- Handle dynamic obstacles
- Implement navmesh carving
- Update navmesh at runtime
- Handle moving platforms

### Off-Mesh Links
- Create jump links
- Configure drop connections
- Handle ladders and teleports
- Set up one-way paths

## Prerequisites

### Unity
```csharp
// Built-in: Package Manager > AI Navigation
// Install: com.unity.ai.navigation
```

### Unreal Engine
```cpp
// Enable NavigationSystem module in Build.cs
PublicDependencyModuleNames.AddRange(new string[] {
    "NavigationSystem",
    "AIModule"
});
```

### Godot
```
# Enable NavigationServer2D/3D in project settings
# Use NavigationRegion2D/3D and NavigationAgent2D/3D nodes
```

## Usage Patterns

### Unity Navigation Setup

```csharp
// NavMeshAgent configuration
using UnityEngine;
using UnityEngine.AI;

public class AINavigation : MonoBehaviour
{
    [Header("Navigation Settings")]
    [SerializeField] private float moveSpeed = 3.5f;
    [SerializeField] private float angularSpeed = 120f;
    [SerializeField] private float stoppingDistance = 0.5f;

    private NavMeshAgent _agent;
    private Transform _target;

    private void Awake()
    {
        _agent = GetComponent<NavMeshAgent>();
        ConfigureAgent();
    }

    private void ConfigureAgent()
    {
        _agent.speed = moveSpeed;
        _agent.angularSpeed = angularSpeed;
        _agent.stoppingDistance = stoppingDistance;
        _agent.autoBraking = true;
    }

    public void SetDestination(Vector3 destination)
    {
        if (NavMesh.SamplePosition(destination, out NavMeshHit hit, 2f, NavMesh.AllAreas))
        {
            _agent.SetDestination(hit.position);
        }
    }

    public void SetTarget(Transform target)
    {
        _target = target;
    }

    private void Update()
    {
        if (_target != null)
        {
            SetDestination(_target.position);
        }
    }

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

    public bool IsPathValid()
    {
        return _agent.hasPath && _agent.pathStatus == NavMeshPathStatus.PathComplete;
    }
}

// Dynamic NavMesh Obstacle
using UnityEngine;
using UnityEngine.AI;

public class DynamicObstacle : MonoBehaviour
{
    private NavMeshObstacle _obstacle;

    private void Awake()
    {
        _obstacle = GetComponent<NavMeshObstacle>();
        _obstacle.carving = true;
        _obstacle.carvingMoveThreshold = 0.1f;
        _obstacle.carvingTimeToStationary = 0.5f;
    }

    public void EnableCarving(bool enable)
    {
        _obstacle.carving = enable;
    }
}

// Off-Mesh Link Setup
using UnityEngine;
using UnityEngine.AI;

public class JumpLink : MonoBehaviour
{
    [SerializeField] private Transform startPoint;
    [SerializeField] private Transform endPoint;
    [SerializeField] private bool bidirectional = false;

    private OffMeshLink _link;

    private void Awake()
    {
        _link = gameObject.AddComponent<OffMeshLink>();
        _link.startTransform = startPoint;
        _link.endTransform = endPoint;
        _link.biDirectional = bidirectional;
        _link.autoUpdatePositions = true;
    }
}

// NavMesh Surface Runtime Baking
using UnityEngine;
using Unity.AI.Navigation;

public class RuntimeNavMesh : MonoBehaviour
{
    private NavMeshSurface _surface;

    private void Awake()
    {
        _surface = GetComponent<NavMeshSurface>();
    }

    public void RebuildNavMesh()
    {
        _surface.BuildNavMesh();
    }

    public void UpdateNavMesh()
    {
        _surface.UpdateNavMesh(_surface.navMeshData);
    }
}
```

### Unreal Engine Navigation Setup

```cpp
// AINavigationComponent.h
#pragma once

#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "NavigationSystem.h"
#include "AINavigationComponent.generated.h"

UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
class MYGAME_API UAINavigationComponent : public UActorComponent
{
    GENERATED_BODY()

public:
    UAINavigationComponent();

    UFUNCTION(BlueprintCallable, Category = "Navigation")
    bool MoveToLocation(FVector Destination);

    UFUNCTION(BlueprintCallable, Category = "Navigation")
    bool MoveToActor(AActor* TargetActor);

    UFUNCTION(BlueprintCallable, Category = "Navigation")
    void StopMovement();

    UFUNCTION(BlueprintCallable, Category = "Navigation")
    bool HasReachedDestination() const;

    UFUNCTION(BlueprintCallable, Category = "Navigation")
    FVector GetRandomReachablePoint(float Radius) const;

protected:
    virtual void BeginPlay() override;

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Navigation")
    float AcceptanceRadius = 50.0f;

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Navigation")
    bool bStopOnOverlap = true;

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Navigation")
    bool bUsePathfinding = true;

private:
    class AAIController* AIController;
    class UNavigationSystemV1* NavSystem;
};

// AINavigationComponent.cpp
#include "AINavigationComponent.h"
#include "AIController.h"
#include "NavigationSystem.h"
#include "NavFilters/NavigationQueryFilter.h"

UAINavigationComponent::UAINavigationComponent()
{
    PrimaryComponentTick.bCanEverTick = false;
}

void UAINavigationComponent::BeginPlay()
{
    Super::BeginPlay();

    APawn* Pawn = Cast<APawn>(GetOwner());
    if (Pawn)
    {
        AIController = Cast<AAIController>(Pawn->GetController());
    }

    NavSystem = FNavigationSystem::GetCurrent<UNavigationSystemV1>(GetWorld());
}

bool UAINavigationComponent::MoveToLocation(FVector Destination)
{
    if (!AIController) return false;

    FAIMoveRequest MoveRequest;
    MoveRequest.SetGoalLocation(Destination);
    MoveRequest.SetAcceptanceRadius(AcceptanceRadius);
    MoveRequest.SetStopOnOverlap(bStopOnOverlap);
    MoveRequest.SetUsePathfinding(bUsePathfinding);

    FNavPathSharedPtr Path;
    AIController->MoveTo(MoveRequest, &Path);

    return Path.IsValid();
}

bool UAINavigationComponent::MoveToActor(AActor* TargetActor)
{
    if (!AIController || !TargetActor) return false;

    FAIMoveRequest MoveRequest;
    MoveRequest.SetGoalActor(TargetActor);
    MoveRequest.SetAcceptanceRadius(AcceptanceRadius);
    MoveRequest.SetStopOnOverlap(bStopOnOverlap);
    MoveRequest.SetUsePathfinding(bUsePathfinding);

    FNavPathSharedPtr Path;
    AIController->MoveTo(MoveRequest, &Path);

    return Path.IsValid();
}

void UAINavigationComponent::StopMovement()
{
    if (AIController)
    {
        AIController->StopMovement();
    }
}

bool UAINavigationComponent::HasReachedDestination() const
{
    if (!AIController) return false;

    return AIController->GetMoveStatus() == EPathFollowingStatus::Idle;
}

FVector UAINavigationComponent::GetRandomReachablePoint(float Radius) const
{
    FNavLocation RandomPoint;
    if (NavSystem && NavSystem->GetRandomReac

Related in AI Agents