Skip to content
Development
Skill

/ai-navigation

Use when implementing AI movement — NavigationAgent2D/3D, steering behaviors, behavior trees, and patrol patterns

From plugin
godot-prompter
90361 skills9 agents1 hook

Claude Code

$ npx -y skills add jame581/GodotPrompter --skill ai-navigation --agent claude-code

SKILL.md

ai-navigation.SKILL.md
name: ai-navigation
description: Use when implementing AI movement — NavigationAgent2D/3D, steering behaviors, behavior trees, and patrol patterns

AI Navigation in Godot 4.3+

Cover NavigationAgent2D/3D, steering behaviors, behavior trees, and patrol patterns. All examples target Godot 4.3+ with no deprecated APIs.

> **Related skills:** **state-machine** for AI state management, **component-system** for modular AI behaviors, **player-controller** for movement physics patterns, **math-essentials** for pathfinding vectors and steering math, **limboai** for BT + HSM with a visual editor, **beehave** for lightweight GDScript behavior trees. For a structured behavior tree (rather than steering/navigation), see the comparison tables in **limboai** and **beehave**.

---

1. Navigation Setup

Scene Structure

World (Node2D or Node3D)
└── NavigationRegion2D (or NavigationRegion3D)
    ├── TileMapLayer / StaticBody2D (geometry)
    └── Enemy (CharacterBody2D with NavigationAgent2D child)

NavigationRegion2D / NavigationRegion3D

1. Add a **NavigationRegion2D** (or **NavigationRegion3D**) node to your scene. 2. Assign a **NavigationPolygon** (2D) or **NavigationMesh** (3D) resource to it. 3. Draw the walkable area in the NavigationPolygon editor, or configure the NavigationMesh bounds in 3D. 4. **Bake the mesh at edit time:** select the NavigationRegion node → click **Bake NavigationPolygon** (2D) or **Bake NavigationMesh** (3D) in the toolbar. 5. **Bake at runtime** when the world changes dynamically:

# 2D
$NavigationRegion2D.bake_navigation_polygon()

# 3D
$NavigationRegion3D.bake_navigation_mesh()
// 2D
GetNode<NavigationRegion2D>("NavigationRegion2D").BakeNavigationPolygon();

// 3D
GetNode<NavigationRegion3D>("NavigationRegion3D").BakeNavigationMesh();

Async Navigation Baking

Navigation baking can cause frame drops on large maps, so regions bake on a background thread by default: `bake_navigation_polygon()` (2D) and `bake_navigation_mesh()` (3D) take `on_thread = true` unless you pass `false`. Connect the region's `bake_finished` signal (use `CONNECT_ONE_SHOT`) to know when the mesh is ready. Threaded baking is unavailable on Web builds without thread support.

> See [references/async-baking.md](references/async-baking.md) for the full GDScript and C# background-thread bake examples (2D and 3D).

> **When to use async baking:** Procedurally generated levels, destructible terrain, or any scene where the navigation mesh must be rebuilt at runtime. The game continues running while the mesh bakes.

Navigation Layers

Navigation layers let you separate walkable areas for different agent types (ground troops, flying units, large enemies).

# Assign layer bits on the NavigationRegion (Inspector or code)
# Layer 1 = ground, Layer 2 = air, Layer 3 = large

# On the NavigationAgent, set matching layers:
$NavigationAgent2D.navigation_layers = 1   # ground only
$NavigationAgent2D.navigation_layers = 2   # air only
$NavigationAgent2D.navigation_layers = 1 | 2  # both (bitwise OR)
// Assign layer bits on the NavigationRegion (Inspector or code)
// Layer 1 = ground, Layer 2 = air, Layer 3 = large

var navAgent = GetNode<NavigationAgent2D>("NavigationAgent2D");
navAgent.NavigationLayers = 1;       // ground only
navAgent.NavigationLayers = 2;       // air only
navAgent.NavigationLayers = 1 | 2;   // both (bitwise OR)

> Set `navigation_layers` on both the **NavigationRegion** and the **NavigationAgent** so they match. Mismatched layers are one of the most common reasons an agent finds no path.

---

2. NavigationAgent2D Basic Usage

GDScript

extends CharacterBody2D

@export var speed: float = 120.0

@onready var nav_agent: NavigationAgent2D = $NavigationAgent2D


func _ready() -> void:
	# velocity_computed fires when avoidance calculates a safe velocity
	nav_agent.velocity_computed.connect(_on_velocity_computed)


func _physics_process(delta: float) -> void:
	if nav_agent.is_navigation_finished():
		return

	var next_pos: Vector2 = nav_agent.get_next_path_position()
	var direction: Vector2 = (next_pos - global_position).normalized()
	var desired_velocity: Vector2 = direction * speed

	if nav_agent.avoidance_enabled:
		# Hand desired velocity to the avoidance system; wait for the signal
		nav_agent.velocity = desired_velocity
	else:
		velocity = desired_velocity
		move_and_slide()


func _on_velocity_computed(safe_velocity: Vector2) -> void:
	velocity = safe_velocity
	move_and_slide()


func set_target(target_pos: Vector2) -> void:
	nav_agent.target_position = target_pos

**Key NavigationAgent2D properties:**

| Property | Purpose | |---|---| | `target_position` | World-space destination | | `path_desired_distance` | How close to each waypoint counts as reached (default 20) | | `target_desired_distance` | How close to the final target counts as finished (default 10) | | `avoidance_enabled` | Enable RVO obstacle avoidance | | `radius` | Agent collision radius for avoidance | | `time_horizon_agents` | Seconds of avoidance look-ahead (tune to reduce jitter) |

C#

using Godot;

public partial class Enemy2D : CharacterBody2D
{
    [Export] public float Speed { get; set; } = 120f;

    private NavigationAgent2D _navAgent;

    public override void _Ready()
    {
        _navAgent = GetNode<NavigationAgent2D>("NavigationAgent2D");
        _navAgent.VelocityComputed += OnVelocityComputed;
    }

    public override void _PhysicsProcess(double delta)
    {
        if (_navAgent.IsNavigationFinished()) return;

        Vector2 nextPos = _navAgent.GetNextPathPosition();
        Vector2 direction = (nextPos - GlobalPosition).Normalized();
        Vector2 desiredVelocity = direction * Speed;

        if (_navAgent.AvoidanceEnabled)
            _navAgent.Velocity = desiredVelocity;
        else
        {
            Velocity = desiredVelocity;
            MoveAndSlide();
        }
Read more
@jame581
Ships withgodot-prompter

Agentic skills framework for Godot 4.x game development. Gives AI coding agents domain-specific expertise for GDScript and C# projects.

90361 skills9 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
903
Star history of jame581/GodotPrompter on GitHub, a chart by star-history.com

Other skills on godot-prompter.

2d-essentials

2d-essentials

Use when working with 2D-specific systems — TileMaps, parallax scrolling, 2D lights and shadows, canvas layers, particles 2D,…

3d-essentials

3d-essentials

Use when working with 3D-specific systems — materials, lighting, shadows, environment, global illumination, fog, LOD, occlusion…

ability-system

ability-system

Use when building character abilities — Resource-based abilities with cost/cooldown/cast, buffs/debuffs, stat modifiers, gameplay…

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills11d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc12d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react1d252k
@facebook@facebookInstall Skill

Questions about ai-navigation.

Which coding agents can use ai-navigation?
ai-navigation installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.