LCM Nav3D Free demo Get it on Fab

Tutorial 10 - Cost areas, query filters and 3D NavLinks

TL;DR: Drop an ALcmNavAreaModifier volume, give it a stock NavArea class, and every LCM Nav3D planner routes by it: FlyTo (BT and StateTree), Fly To Location, Mass crowds, FindPath and the stock Move To. A stock NavigationQueryFilter on the agent decides what each area costs that agent, or forbids it. ULcmNavLinkComponent places 3D ladders, drops and teleporters; link costs are queryable, and the planner does not route through links yet.

What an area does

A cost area is a volume (box, sphere or capsule) with a NavArea class. The planner reads three things from the class:

NavArea field Effect on a route
Default Cost Travel inside the area costs this many times the distance. 5.0 = five times dearer, 0.5 = a preferred lane.
Fixed Area Entering Cost Paid once each time the route goes in. Use it for a toll or a doorway you want used sparingly.
Default Cost at NavArea_Null's level (1e30 or more) Impassable for everyone. No route crosses it.

A query filter on an agent overrides those per class, exactly as it does for Recast: a travel cost override, an entering cost override, or excluded. Two agents read the same volume differently. The prey avoids a predator's territory that the predator itself ignores.

Routes follow the cheapest total, not the shortest distance. An agent goes round a storm when going round is cheaper, and flies straight through when the detour costs more than the storm.

Step 1 - Place a cost area

  1. Place an LCM Nav3D Nav Area Modifier (Volumetric) actor.
  2. Set Shape and scale the box to cover the volume. A sphere reads its radius from the extent's X. A capsule runs along local Z.
  3. Set Area Class. The plugin ships ready-made classes, and any stock or project NavArea subclass works:
Class What it does
LCM Nav Area - Storm (x5) Five times dearer inside.
LCM Nav Area - Preferred Lane (x0.5) Half price: routes are drawn into it.
LCM Nav Area - Toll Gate (+2000 to enter) Normal price inside, 2000 cm extra per entry.
LCM Nav Area - Territory (priced by filters) Free for everyone, until a filter prices it.
LCM Nav Area - Restricted (excluded by filters) Free, until a filter excludes it.
LCM Nav Area - No-Fly (impassable) Nobody crosses it, under any filter.

Leave Area Class empty to use Cost Multiplier on its own. That is the 3.3 behaviour, with no per-agent overrides.

Overlaps. Where volumes overlap, an area the agent's filter excludes always wins. Otherwise the higher Priority decides the cost. Costs do not multiply. (They did before 3.4.)

Moving areas. Attach the volume to anything that moves and tick Movable. Agents replan as it moves, and plan against where it will be over Prediction Seconds. Patrol moves a volume back and forth on its own, for demos and tests. After changing a class, shape, priority or size at runtime, call Notify Area Changed. Moving the actor needs no call.

Step 2 - Give an agent a filter

A filter is a stock NavigationQueryFilter Blueprint or class. Add Areas entries to override or exclude classes. The plugin ships two examples: LCM Nav Filter - Prey (Territory x10) and LCM Nav Filter - Civilian (Restricted excluded).

Agent Where the filter goes
Pawn with an AI controller (BT, StateTree, Fly To Location) The controller's Default Navigation Filter Class. FlyTo reads it on every request. No task property is needed.
A direct planner call FLcmNavigationQueryOptions::FilterClass.
Mass crowd Navigation Filter on the LCM Nav3D Agent trait.
Stock Move To Its Filter Class pin, as with Recast.

With no filter, each area uses its own class defaults.

Step 3 - See what an agent sees

On the LCM Nav3D Manager, under 6. Debug > Cost Areas:

The console variable r.LcmNav.CostView 0|1|2 overrides the property while playing. The Gameplay Debugger's LCM category shows the selected agent's route cost: length, priced length, entering costs paid, and the areas it crosses.

What happens at the edges

Situation Result
The goal is inside an area the agent's filter excludes The request fails: Get Last Path Cost Failure returns Goal In Excluded Area.
Every way to the goal crosses an excluded area The request fails: No Route Under Filter.
The agent starts inside an excluded area It is allowed out by the shortest way, then routes normally.
An area moves across an agent's route FlyTo replans when the route's cost changes enough to matter.

A FlyTo task reports these as Failed, with a Warning in the log, never an Error.

Step 4 - Query costs yourself

The query library prices a route the same way the planner does:

// The travel multiplier at a point, and a route's cost, as a given filter sees them:
bool bExcluded = false;
const float Here = ULcmNavAreaQueryLibrary::GetCostMultiplierAtForFilter(this, Location, UMyPreyFilter::StaticClass(), bExcluded);
float LengthCm, PricedCm, EnteringCost; bool bCrossesExcluded;
ULcmNavAreaQueryLibrary::EvaluatePathCostForFilter(this, Waypoints, UMyPreyFilter::StaticClass(),
    LengthCm, PricedCm, EnteringCost, bCrossesExcluded);

The filter-less versions (GetCostMultiplierAt, GetCostMultiplierAlongPath) read each area's own defaults. All of them are Blueprint-callable.

UE's stock UNavLinkCustomComponent projects its ends onto a Recast navmesh. A flying pawn can use any two points in space, so LCM Nav3D ships ULcmNavLinkComponent for vertical ladders, drops and teleporters.

  1. Add the LCM Nav Link (3D Vertical) component to an actor.
  2. Set LinkStart and LinkEnd in world space, e.g. (0, 0, 0) and (0, 0, 800).
  3. bBidirectional: climb up and slide down, or one way only.
  4. TraversalCostCm: the extra cost of using the link, e.g. 400 to favour a nearby ramp.

The link registers with UE's navigation system (it implements INavLinkCustomInterface) and with LCM Nav3D's registry. The LCM Nav3D planner does not route through links yet. Find and price them yourself:

ULcmNavLinkComponent* Nearest = ULcmNavAreaQueryLibrary::FindNearestNavLink(AgentLocation, /*MaxDist*/ 500.0f);
const float LinkCost = ULcmNavAreaQueryLibrary::GetNavLinkTraversalCostAlongPath(Waypoints);

A common pattern: FlyTo to LinkStart, play the traversal, then continue from LinkEnd.

Try it

Open the Cost Areas tile in the demo menu (NavCost_Showcase maps, in BT, StateTree and Mass versions). Six labelled stations: a storm the route bends round, a preferred lane off the direct line, a no-fly goal beside a storm goal (impassable is not the same as expensive), one territory that only the prey pays for, a toll gate, and two craft of different sizes making the same decision.

Acceptance test (manual)

  1. Place a Storm (x5) box between two points, with open space around it.
  2. Fly an agent across. It goes round.
  3. Stretch the storm wall to wall so there is no way round. The agent flies through it and pays the storm.
  4. Give the agent the Civilian filter and put a Restricted box across the only corridor to its goal. The request fails with No Route Under Filter.
  5. GetRegisteredLinkCount counts your ULcmNavLinkComponents. GetNavLinkTraversalCostAlongPath([(0,0,0),(0,0,500)]) returns the link's TraversalCostCm.