Back to the feed
Featured Tutorials 2026-06-21

Create Custom NPC Behavior in Unreal Editor for Fortnite

Custom NPC Behavior in UEFN: Scripting Navigation and Lifecycle with npc_behavior

The npc_behavior API gives you programmatic control over NPC character lifecycles and movement in UEFN, replacing the need to rely entirely on static AI Patrol Path nodes or built-in guard logic. This matters because it unlocks fully dynamic NPC roles — medics, bosses, shopkeepers, escorted VIPs — that respond to runtime game state rather than pre-placed level geometry.

What Changed

UEFN now exposes the npc_behavior abstract class in the /Fortnite.com/AI module, letting you attach a user-authored Verse script directly to an NPC Character Definition. Previously, NPC behavior was constrained to the fixed presets baked into Guard, Wildlife, or Custom character types. Now you subclass npc_behavior, override its spawn/despawn hooks, and bind your logic to any Character Definition via the Verse Behavior field in the asset editor.

Key API surface:

  • npc_behavior abstract class — your script inherits from this; the runtime calls your overrides when the NPC spawns or despawns.
  • GetFortCharacter[] — failable expression that retrieves the fort_character reference for an agent, which is the gateway to all other character interfaces.
  • GetNavigatable[] — failable expression on fort_character that returns the navigatable interface, available to Custom, Guard, and Wildlife NPC types.
  • MakeNavigationTarget(position : vector3) and MakeNavigationTarget(agent : agent) — construct a navigation_target from either a world-space position or another agent to follow.
  • NavigateTo(target : navigation_target) : navigation_result — suspends the calling coroutine until the NPC reaches the target or navigation fails; returns a navigation_result enum (Reached, Failed, etc.).
  • Navigatable.Wait(?Duration : float) — suspends the NPC at its current position for an optional duration, useful for idle beats between patrol waypoints.

Behavior scripts are created from the NPC Behavior template in Verse Explorer and compiled before being assigned to a Character Definition. Custom-type NPCs require a behavior script to act at all; Guard and Wildlife types fall back to their default AI if none is assigned.

What You Can Build

1. Dynamic Patrol with Runtime-Generated Waypoints

Guard-type NPCs are limited to AI Patrol Path nodes placed in the level. With npc_behavior you can generate waypoints at runtime — from spawn point offsets, other agents' positions, or game-state data — without touching the level layout.

using { /Fortnite.com/AI }
using { /Fortnite.com/Characters }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Verse.org/Random }

my_patrol_behavior := class(npc_behavior):
    PatrolRadius : float = 800.0
    WaitSeconds  : float = 3.0

    OnBegin<override>(Agent : agent) : void =
        if (Character := Agent.GetFortCharacter[],
            Nav        := Character.GetNavigatable[]):
            Spawn { RunPatrol(Agent, Character, Nav) }

    RunPatrol(Agent : agent, Character : fort_character, Nav : navigatable)<suspends> : void =
        SpawnPt := Character.GetTransform().Translation
        loop:
            Offset := vector3{
                X := GetRandomFloat(-PatrolRadius, PatrolRadius),
                Y := GetRandomFloat(-PatrolRadius, PatrolRadius),
                Z := 0.0}
            Target := MakeNavigationTarget(SpawnPt + Offset)
            Result := Nav.NavigateTo(Target)
            if (Result = navigation_result.Reached):
                Nav.Wait(?Duration := WaitSeconds)
            Home := MakeNavigationTarget(SpawnPt)
            Nav.NavigateTo(Home)

Because NavigateTo is a suspending call, the loop blocks cleanly until each leg of the patrol completes before advancing — no polling or timer gymnastics required.

2. Escort NPC That Follows a Player Agent

With MakeNavigationTarget(agent) you can create a target that tracks a living agent rather than a static position, enabling an escort or bodyguard that dynamically pursues a specific player.

my_escort_behavior := class(npc_behavior):
    # Set via Character Definition or injected at spawn time
    var EscortTarget : ?agent = false

    OnBegin<override>(Agent : agent) : void =
        if (Character := Agent.GetFortCharacter[],
            Nav        := Character.GetNavigatable[],
            Target     := EscortTarget?):
            Spawn { FollowAgent(Nav, Target) }

    FollowAgent(Nav : navigatable, Target : agent)<suspends> : void =
        loop:
            FollowTarget := MakeNavigationTarget(Target)
            Result := Nav.NavigateTo(FollowTarget)
            # If navigation fails (e.g., target unreachable), wait briefly and retry
            if (Result <> navigation_result.Reached):
                Nav.Wait(?Duration := 0.5)

This pattern composes well with OnEnd to clean up any state when the NPC despawns — e.g., removing the escorted player from a protected-player list.

3. Conditional Behavior Branching on Navigation Failure

The navigation_result enum lets you make NPCs react intelligently when pathfinding is blocked — switching to an alert state, calling for help, or teleporting to a fallback position — rather than silently stopping.

RunObjectiveRush(Nav : navigatable, Objective : vector3)<suspends> : void =
    MaxAttempts : int = 3
    var Attempts : int = 0
    loop:
        if (Attempts >= MaxAttempts):
            # Give up; trigger a fallback behavior
            break
        Result := Nav.NavigateTo(MakeNavigationTarget(Objective))
        if (Result = navigation_result.Reached):
            # Arrived — hand off to interaction logic
            break
        else:
            set Attempts += 1
            Nav.Wait(?Duration := 1.0)

Branching on navigation_result this way lets you build tiered NPC decision trees entirely in Verse, replacing what would otherwise require Blueprint state machines or complex AI behavior trees.

References

Related topics