Skip to content

AI Move To & the NavMesh

At a glance

Lives in: Blueprint API / AI - Target: an AI-controlled Pawn - Returns: immediate execution plus later On Success / On Fail pins and a movement result enum - Changes: asks the pawn's AIController and path-following/navigation systems to move toward a destination or target actor - Can fail by: no AIController, no usable NavMesh, start or goal off the navmesh, unreachable path, invalid target, blocked path, or using a player-possessed pawn - Official docs: AI MoveTo, Basic Navigation, and AAIController::MoveToActor

The one-minute version

  • AI Move To tells an AI-controlled pawn to pathfind to a location or actor. It does not work like player input, teleporting, or Set Actor Location.
  • The pawn needs an AIController. A player-possessed pawn has a PlayerController, so this node is usually the wrong tool for moving the player character.
  • The level needs navigation data, usually created by a NavMeshBoundsVolume. Press P in the editor viewport to visualize the green navmesh.
  • The pawn's current location and the goal must be on or projectable to the navmesh, and the path must be reachable.
  • Use Destination for a fixed world point. Use Target Actor when the AI should follow an actor whose location can change.
  • On Success means the move finished within the accepted distance. On Fail means the request failed, was blocked/aborted, or could not complete.
  • Acceptance Radius is "close enough," not speed. Movement speed comes from the pawn's movement component, such as Character Movement.

What it actually does

AI Move To creates a movement request for a pawn controlled by an AIController. At beginner altitude:

pseudocode of the engine behavior - not engine source

AI Move To(Pawn, Destination, TargetActor, AcceptanceRadius):
    AIController = Pawn.GetController as AIController
    if AIController is missing:
        trigger failure

    Goal = TargetActor if valid, otherwise Destination
    ask navigation/path following for a path to Goal

    if request cannot start:
        trigger failure

    over later frames:
        path following steers the pawn through its movement component
        if close enough: On Success
        if blocked/aborted/unreachable: On Fail

The node is asynchronous. The normal execution output continues after the request starts, but the move result arrives later on On Success or On Fail. Do not put "attack after arrival" on the immediate Out pin and expect it to wait for the pawn.

The setup checklist

For a first enemy:

BP_EnemyCharacter:
    parent class = Character or Pawn with movement support
    AI Controller Class = BP_EnemyAIController
    Auto Possess AI = Placed in World or Spawned

Level:
    NavMeshBoundsVolume covers the floor where AI may walk
    press P and confirm green navmesh under enemy and goal

Blueprint:
    BeginPlay or behavior event
    -> AI Move To
       Pawn = Self
       Target Actor = player pawn
       Acceptance Radius = 100

If the enemy is spawned at runtime, make sure it gets an AIController. Common paths are setting the pawn defaults correctly, using Spawn AI From Class, or calling Spawn Default Controller when your spawn path requires it.

The NavMesh

The Navigation System builds a simplified walkable mesh from level collision. AI pathfinding searches that mesh instead of guessing through raw geometry.

A NavMeshBoundsVolume marks where navigation should be generated. It is not a wall, trigger, or gameplay collision volume. It is for the path builder.

Beginner debug loop:

  1. Place NavMeshBoundsVolume in the level.
  2. Scale it to cover the walkable area.
  3. Press P in the editor viewport.
  4. Look for green navmesh where the AI starts and where it needs to go.
  5. Move floors, ramps, blockers, or volume bounds until the green area matches the route you expect.

If there is no green navmesh, AI Move To has no useful path data. If there is green navmesh under the enemy but not under the goal, the request can still fail.

The pins that matter

Pawn

This is the pawn to move. Inside the enemy pawn Blueprint, Self is often correct. From an AIController Blueprint, use Get Controlled Pawn.

The pawn must be controlled by an AIController. If Get Controller returns None or a PlayerController, this node is not set up for that pawn.

Destination

Destination is a fixed world location. Use it for patrol points, random reachable locations, or a one-time "go here" command.

If the target moves after the request starts, Destination does not follow it. You would need a new request, continuous tracking through a different task, or Target Actor.

Target Actor

Target Actor tells the AI to move toward an actor. Epic's docs call out that the node only performs strafe behavior when Target Actor is provided.

Use this for chasing the player:

Get Player Character
-> AI Move To
   Pawn = Self
   Target Actor = player character

Still check that the target is valid. Moving to None is not a meaningful chase request.

Acceptance Radius

Acceptance Radius is how close is close enough. A value such as 50 or 100 is often more practical than 0 for characters with capsules.

If the AI stops "too early," inspect Acceptance Radius and Stop on Overlap before assuming pathfinding is broken.

Stop on Overlap

Stop on Overlap lets the pawn count overlap/contact with the goal area as arrival. For capsule-based pawns, this can make an AI stop at a reasonable body distance rather than trying to put its origin exactly on the target point.

On Success / On Fail / Movement Result

Use these pins for follow-up logic:

AI Move To
    On Success -> attack / choose next patrol point / wait
    On Fail    -> retry later / choose another point / print result

Movement Result is the report for how the move ended. Print it while debugging so "fail" is not just a mystery branch.

The pattern everyone actually uses

Simple patrol:

Custom Event MoveToNextPatrolPoint
-> AI Move To
   Pawn = Self
   Destination = PatrolPointLocation
   Acceptance Radius = 75

On Success
-> Delay 1.0
-> choose next point
-> MoveToNextPatrolPoint

On Fail
-> Print String Movement Result
-> Delay 0.25
-> choose another reachable point or retry

Random roaming:

BeginPlay
-> Get Random Reachable Point in Radius
   Origin = self location
   Radius = 1000
-> Branch Return Value
   true:
       AI Move To Destination = Random Location
   false:
       wait and retry after checking navmesh

Chase the player:

On See Player or perception event
-> Is Valid PlayerPawn
-> AI Move To
   Pawn = Self
   Target Actor = PlayerPawn
   Acceptance Radius = AttackRange

On Success
-> if player still valid and in range: attack

On Fail
-> lose target, pick patrol, or retry after a short delay

For repeated chasing, avoid blindly firing a new AI Move To every Tick. Start or update move requests from events, timers, perception changes, or AI logic that is deliberate about how often it replans.

When it fails (and what failure does)

Common causes:

  1. The pawn has no AIController. Check the pawn defaults, Auto Possess AI, spawned-pawn setup, and Get Controller.
  2. The pawn is player-possessed. A PlayerController is not the AI brain this node expects. Use player input, Simple Move, or a deliberate controller swap/design instead.
  3. There is no NavMesh under the pawn or goal. Press P and inspect the green area.
  4. The goal is unreachable. A wall, missing ramp link, gap, off-mesh point, or nav filter can prevent a complete path.
  5. The Acceptance Radius is too strict. A capsule may never put its origin exactly on a point blocked by the target's collision.
  6. The movement component cannot move. Movement disabled, wrong movement mode, blocked capsule, or a raw Pawn with no useful nav movement can stop visible motion.
  7. The target actor becomes invalid. The chase target was destroyed, unloaded, or never assigned.
  8. Another move aborts this one. New movement requests can replace or abort older path-following work.
  9. You are running authority-sensitive AI logic on the wrong machine. In multiplayer, AI movement is normally server-owned.

Failure does not automatically choose a better point, rebuild the navmesh, or spawn a controller. Your On Fail path is where you print, retry, pick a new goal, or return to idle.

AI Move To vs Simple Move

Node Use when Tradeoff
AI Move To An AI-controlled pawn should move and you need success/fail pins. Requires AIController-style setup.
Move To Location or Actor task You are using AI task/behavior-style flows with more request options. More advanced setup and more pins.
Simple Move to Location / Actor A controller should issue a very simple navigation move. No success/fail completion pins on the simple Blueprint node.
Add Movement Input A player or pawn should request movement in a direction. No pathfinding; movement system consumes input.
Set Actor Location You are placing an actor directly. Bypasses AI path following and can fight collision/movement systems.
Behavior Tree Move To You are building a Behavior Tree. Outside the first-enemy page, but this is where larger AI usually goes.

The quick path is to make a player Character briefly AI-possessed just to use AI Move To. The concrete cost is that camera, input, possession, UI, and network assumptions change under the player. For click-to-move or player auto movement, design that path explicitly instead of borrowing enemy AI setup.

Debug checklist

When the enemy stands still:

  1. Print Get Controller class from the pawn.
  2. Print whether the target actor is valid.
  3. Press P and inspect the navmesh under start and goal.
  4. Temporarily move the goal to a clearly green reachable area.
  5. Use a forgiving Acceptance Radius such as 100.
  6. Print Movement Result from On Fail.
  7. Confirm the pawn can move normally: movement component enabled, capsule not wedged, speed nonzero.
  8. Confirm you are not starting a new move every frame and aborting the old one.

Use Print String and the Output Log and breakpoints instead of guessing.

The C++ twin

For the curious, the direct C++ version often goes through AAIController (our own example code):

void ATrainingEnemy::Chase(AActor* TargetActor)
{
    AAIController* AIController = Cast<AAIController>(GetController());
    if (!IsValid(AIController) || !IsValid(TargetActor))
    {
        return;
    }

    const EPathFollowingRequestResult::Type RequestResult =
        AIController->MoveToActor(
            TargetActor,
            100.0f,
            true,
            true,
            false,
            nullptr,
            true);

    if (RequestResult == EPathFollowingRequestResult::Failed)
    {
        UE_LOG(LogTemp, Warning, TEXT("Enemy move request failed to start"));
    }
}

Completion is reported later through AI/path-following callbacks, just like Blueprint's success/fail pins are later than the initial request.

Going deeper