Skip to content

Navigation

Surface Flow Field is the optional route-authority system for levels with walls, islands, or uneven walkable surfaces.

When to use it

Massive Swarm System works without a flow field for flat arenas. Behavior steering, body blocking, and obstacle blocking keep agents moving toward the target and clear of walls in simple geometry.

Use the Surface Flow Field when:

  • Agents need to route around walls, pillars, or closed rooms.
  • The level has stairs, ramps, or uneven terrain that steering alone cannot handle.
  • Agents get persistently stuck at corners or thin corridors.

Do not use it when:

  • The level is an open flat arena with no routing obstacles.
  • You need the lowest possible runtime overhead for very large agent counts.

How it works

The Surface Flow Field bakes a grid over the scene. Each cell stores a direction toward the swarm target. At runtime, agents sample their cell and blend the field direction with their behavior steering.

Bake cost scales with grid cell count, not agent count. Once the map is baked, per-agent cost is a single cell lookup.

Footprint and overhead clearance

The bake can reason about the agent's size so cells map cleanly around walls, gaps, and overhead obstacles. Two settings on SwarmManager drive it. Both are bake-time only and add no runtime cost.

  • Clearance Radius (footprint width). The ground probe is a sphere of this radius. A gap between two walls narrower than twice the radius bakes as non-passable, while a doorway wider than the footprint stays walkable. Closely-spaced raised blocks separated by sub-footprint gaps bake as one continuous top surface the agent bridges, instead of an alternating top/floor row.
  • Agent Height (standing height). With a non-zero height and an Unwalkable Layer Mask set, each cell checks a capsule of Clearance Radius spanning Agent Height above the floor. A floor under an overhead obstacle — a door lintel, a low arch, an overhang — bakes walkable when the agent fits under it and blocked when the obstacle is too low. Door jambs and full-height walls still block.

This requires floors and obstacles on separate layers: floors in Walkable Layer Mask, walls/overhead in Unwalkable Layer Mask. The bake samples the union of those two masks; there is no separate surface include mask to maintain. If the two masks overlap or Walkable is empty, the inspector warns and overhead detection turns off. Setting Clearance Radius to 0 reproduces the legacy single-ray point-sample bake.

Clearance Radius vs Wall Clearance

Clearance Radius is the agent's assumed footprint size — it decides what counts as passable. It is not Wall Clearance, the bake setting below that bows the route off walls, nor the runtime Surface Flow Wall Margin. See the Glossary.

Targets never bake as ground

The bake skips any collider that belongs to a SwarmTarget (and its children) while sampling. You can leave your player or boss on a layer that's also in the Walkable Layer Mask — the swarm chases it, but the bake won't carve a walkable patch out from under it. The exception is a target collider parented above the SwarmTarget object; keep the collider on the target or below it.

Single surface per cell

The field is a height map: each XZ cell stores exactly one walkable height. Two consequences to plan around:

  • Walking under an overhead obstacle is supported (one floor, obstacle above it). Two stacked walkable floors in the same column are not — a catwalk crossing over open floor bakes as only one of the two (the higher one the agent fits on).
  • The bake takes the topmost walkable surface the agent fits on. If that surface fails the height check, the cell is blocked; it does not retry a lower walkable surface in the same column.

Keeping a berth from walls

By default the route follows the shortest path, which can send agents right up to a wall before turning them along it — only the cells touching the wall redirect them. The Wall Clearance settings add a soft cost near obstacles so the route bows away earlier and rounds corners with a margin, instead of grazing the wall and peeling off at the last cell.

  • Wall Clearance Strength sets how hard the route is pushed off walls. 0 turns the berth off, so routes graze walls and corners as before.
  • Wall Clearance Distance sets how far the margin reaches, in world units.

The cost is soft: a corridor or doorway barely wider than an agent still routes through, because the berth only makes near-wall cells costlier to cross — it never closes a passage or strands a reachable cell. It is computed once at bake time and adds nothing to per-frame cost.

Wall Clearance vs Wall Margin

These Wall Clearance settings shape the baked route. They are separate from Surface Flow Wall Margin on SwarmSettings, which holds a moving agent's body off wall cells at runtime, and from Clearance Radius, the agent's footprint size. See the Glossary.

Setup

Disabled by default

Surface Flow Field Navigation is off by default. You turn it on per scene from the SwarmManager, so one scene can run the field while another that reuses the same SwarmSettings does not. Agents use behavior steering and obstacle blocking until you enable it.

  1. On SwarmManager, enable Surface Flow Field Navigation.
  2. On SwarmManager, set the Sampling Bounds for the bake volume:
  3. Edit Bounds Center and Bounds Size directly to place the volume, or click Snap Bounds To Scene to fit it automatically around scene colliders that match the Walkable and Unwalkable masks.
  4. Set Bounds Source to scope the snap to one object's geometry only (useful when a large floor elsewhere would inflate the fit).
  5. Set the bake layers on SwarmManager:
  6. Walkable Layer Mask — the floor/ground the bake stands agents on. Put your floors and ramps here.
  7. Unwalkable Layer Mask — walls, columns, overhead bars, and props that block. Keep this separate from Walkable.
  8. Enter Play mode. The manager bakes the map at startup.

Keep agents off the bake layers

Put your agent prefabs on a layer that is not in the Walkable, Unwalkable, or Obstacle masks. The field rebakes with agents present, so an agent that shares a bake layer reads as a wall and carves holes in its own route. The sample archetypes ship on the Enemy layer for this reason, and the archetype inspector warns when an assigned prefab's layer overlaps a mask.

Key settings

Surface Flow settings live in two places: the per-scene on/off toggle and bake-time grid configuration on SwarmManager, shared runtime routing parameters on SwarmSettings.

On SwarmManager

Field What it does
Enable Surface Flow Navigation Turns the field on for this scene. Lives on the manager, not the shared settings asset, so another scene reusing the same SwarmSettings is unaffected.
Cell Size Grid resolution in world units. Smaller cells route more precisely but cost more to bake and store.
Walkable Layer Mask The floor/ground layers the ground probe lands on. The down-cast targets these layers only, so it passes through an overhead obstacle (door lintel, low arch) and resolves the floor beneath it. Leave empty to fall back to the combined Walkable + Unwalkable mask (legacy point-sample behavior, no overhead handling).
Unwalkable Layer Mask Obstacle layers (walls, columns, overhead bars, props). The lateral wall test and the standing-clearance check query this mask. Must stay separate from Walkable Layer Mask.
Clearance Radius Agent footprint radius the bake reasons about, in world units. The bake sphere-casts at this radius, so a gap narrower than the footprint reads as solid ground the agent bridges, while a wider opening stays walkable. A slot between two walls narrower than twice this radius bakes non-passable. 0 = legacy single-ray point sample.
Agent Height Agent standing height the bake reasons about, in world units. With a non-zero height and an Unwalkable mask set, each cell checks a capsule spanning this height above the floor, so a floor under an overhead obstacle bakes walkable only when the agent fits under it. 0 = footprint-only (no overhead detection).
Quality Cardinal stores 8-way direction arrows. Smooth stores an integration field for wall-aware gradient sampling — more accurate around walls and corners, and it unlocks the per-agent Smooth Direction Blend on SwarmSettings. Eikonal solves that same field with Fast Marching so flow directions vary by continuous angle instead of the eight grid steps — the smoothest option, best where a wide front should fan out instead of collapsing onto one path, at a heavier bake.
Climb Cost Bias Soft penalty against routes that climb upward, as extra step cost per world unit of climb (in multiples of one flat step). 0 ignores climb; 1 makes a 1-unit climb cost as much as one extra flat step. A steep climb is still taken when no comparably short flatter route exists.
Wall Clearance Strength How hard routes bow away from walls, as extra step cost at the wall face (in multiples of one flat step). 0 keeps the shortest path that grazes walls and corners; higher values push the route farther off. Soft — it never seals a gap an agent could otherwise fit through.
Wall Clearance Distance How far the wall berth reaches, in world units. The penalty is strongest one cell off the wall and fades to zero at this distance. Below half a cell it rounds to off.

On SwarmSettings

Field What it does
Surface Flow Target Mode How targets map to goal fields. Per Swarm Target bakes a separate field per active target slot. Nearest Swarm Target bakes one multi-source field toward all active targets simultaneously.
Surface Flow Authority How strongly the flow field overrides behavior steering. 1 means the field fully controls direction; lower values blend with behavior steering.
Surface Flow Direct Approach Distance How close to its target, measured along the flow route, an agent must be before it steers straight at the target instead of following the route. Stops agents beelining a target that is near in a straight line but far by path — one on a ledge reached by a ramp. In world units along the path; a sloped or raised route counts as farther. 0 turns the hand-off off so seek always blends in. Needs Quality Smooth or Eikonal. Pairs with Goal Release Distance, the final hand-off to surround.
Surface Flow Goal Release Distance Agents inside this distance from their target ignore the flow field and use behavior steering directly.
Smooth Direction Blend Blends the flow direction from the four cells around each agent so headings turn smoothly across cell borders instead of stepping at each boundary. Smooth or Eikonal quality only; applied to Full and Reduced importance agents, while Cheap agents keep the snapped per-cell direction. Cosmetic — it does not change the route.
Enforce Cell Boundaries Prevents agents from crossing into cells the bake marked as blocked. Recommended on.

Fallback behavior

These modes apply when an in-field agent has no valid route — no baked field, the goal flood did not reach the cell, or the target is sealed:

Fallback mode What happens
Keep Behavior Steering (default) Agent uses behavior steering without flow field influence.
Stop Agent stops moving.
Use Last Flow Direction Agent reuses the last valid flow direction.

Grounding with the flow field

The field stores the ground height at each baked cell. When Surface Flow Grounding Mode is Prefer Field Height, agents on the field lerp their Y position to the cell's baked height. This replaces or supplements physics grounding for agents on the walkable surface.

  • Prefer Field Height — uses field height for agents on the field; falls back to physics grounding for off-field agents.
  • Replace Physics When Available — uses field height for agents on the field; off-field agents always use gravity regardless of the Enable Grounding setting.
  • Disabled — flow field does not control Y. Physics grounding runs independently.

Runtime rebake

Surface Flow Runtime Rebake is enabled by default in SwarmSettings so goal fields rebake automatically as targets move. The bake is throttled by Rebake Interval and only triggers when the target moves past Goal Move Rebake Distance.

Background thread baking (the default) keeps bakes off the simulation thread and falls back to Main Thread automatically on WebGL. V1 ships no Jobs/Burst scheduler.

Congestion bias

When dense crowds funnel through a single corridor, a flow field alone tends to single-file every agent through the lowest-cost cell. Enable Congestion Bias in SwarmSettings to spread that traffic across parallel routes.

How it works:

  • Each fixed step the manager counts how many agents currently sit in each surface-flow cell.
  • When an agent samples its next direction, candidate neighbor cells that are already occupied are scored as less attractive — but never blocked.
  • An agent will only divert if another route is also valid (lower-cost). In a one-cell-wide corridor it still walks straight through.

Settings:

Field What it does
Congestion Bias (toggle) Master toggle. The checkbox sits in the section header — checking it enables the whole Congestion Bias feature. Off by default.
Strength 0 disables the penalty. 1 strongly prefers equally valid lower-occupancy cells. Default 0.65 reads as a noticeable but not overpowering bias.
Free Cell Capacity How many agents can sit in a candidate cell before the soft penalty starts. Default 1 keeps single-occupancy cells neutral; raise it for crowds that should pack more tightly before re-routing.

Requirements:

  • Quality must be Smooth or Eikonal on the SwarmManager. Cardinal quality skips the integration field this feature samples; the bias has no effect there and a one-time warning is logged at runtime.
  • Settings take effect immediately — no rebake or restart is needed when toggling the feature or adjusting Strength / Free Cell Capacity in Play mode.

When to use it:

  • Dense crowds that pile up at chokepoints or single-file along corridors that have parallel alternatives.
  • Bullet-heaven / survivor scenes where agents should spread out around the player rather than stack into one column.

When to skip it:

  • Open arenas with no corridors — there is nothing to spread.
  • Very low agent counts where a single-file route is acceptable and you want to save the per-step occupancy pass.

Congestion reroute

Experimental

Congestion Reroute is experimental. Tuning defaults and trigger heuristics may change in future updates, and it is not covered by the support promise.

Where Congestion Bias nudges an agent's sampled direction at runtime, Congestion Reroute rebakes the surface flow itself. When a corridor stays crowded, the next bake charges those cells extra Dijkstra cost and the new field routes agents through alternative corridors.

How it works:

  • Each fixed step the manager counts occupancy per surface-flow cell (the same data Congestion Bias reads).
  • Agents moving slower than Stuck Speed count as more than one toward occupancy, so a single-file queue still trips the trigger even when no two agents share a cell.
  • When total congestion weight across the map is at or above Trigger Crowding, the manager schedules one extra goal-field rebake for that target — at most once per Interval seconds.
  • The rebake runs on the background bake scheduler. While it is in flight, agents keep following the previous field with no stall.

Settings (under SwarmSettingsCongestion Reroute):

Field Default What it does
Enable Congestion Reroute Off Master toggle.
Interval 2.0 s Minimum seconds between rebakes per target. Smaller values respond faster but burn more CPU on Dijkstra rebakes. Recommended 1.53.0.
Cost Scale 4.0 How heavily congested cells weigh the Dijkstra cost. 0 disables the penalty. 1 means one extra agent costs as much as one extra horizontal step. Tight bottlenecks where agents can only stack 1–2 per cell often need 48 to overcome the extra length of the alternate route; wide bottlenecks reroute fine at 12.
Trigger Crowding 2 Minimum total congestion weight before a rebake is scheduled. Lower values react faster to small pile-ups; raise it to avoid rebakes from transient crowding. With cell size ≈ the agent footprint (Clearance Radius × 2), keep this at 13.
Stuck Speed 1.0 units/sec Agents below this speed count as 2 toward occupancy; faster agents count as 1. 0 disables the bonus. Typical agent speed is 35 units/sec, so the default catches body-blocked queueing without flagging normal motion.

The Free Cell Capacity setting from Congestion Bias is shared — it controls how many agents a cell can hold before either feature treats it as congested.

Requirements:

  • Works at any Quality setting — Cardinal, Smooth, or Eikonal — because it only modifies edge costs, not the integration field.
  • Settings take effect immediately. Changes to Interval / Cost Scale / Trigger Crowding / Stuck Speed do not require a manual rebake.
  • Per-target rebake state is cleared automatically when targets disconnect or the swarm is reset.

When to use it:

  • Persistent bottlenecks where Congestion Bias alone cannot spread the crowd because no parallel route is visible to the local sampler.
  • Levels with two or more roughly equal paths to the same target — the rebake will discover the alternative and divert traffic.

When to skip it:

  • One-corridor levels with no alternative route. The rebake cost buys nothing because the field has no other path to find.
  • Scenes where bake cost is already tight — every triggered rebake is a full goal-field bake.

Use both together for the best spread: the bias smooths distribution in the moment, the reroute commits the change to the field over a few seconds.

Performance guidance

  • Bake cost scales with total grid cells. For a 50 × 50 unit scene at 1-unit cell size: 2500 cells.
  • Use Cardinal quality and a coarser cell size for maximum throughput. Use Smooth when routing near corners matters, or Eikonal for the smoothest flow at a heavier bake.
  • Keep Surface Flow Concurrent Bakes low (1–2) to avoid bake traffic spikes when multiple targets are moving simultaneously.
  • Reduced and Cheap tier agents resample the field less frequently (configured by Surface Flow Reduced LOD Sample Interval and Surface Flow Cheap LOD Sample Interval in SwarmSettings). Cached directions are reused between samples.

Troubleshooting

Target moves off the field and the swarm scatters or idles

When the target moves off the baked grid, inside a wall, or onto walkable ground that belongs to a different connected region from the crowd — ground outside a perimeter wall bakes as its own separate region — the system searches for a stand-in goal at the nearest reachable edge cell on the crowd's side that also has a clear straight line to the target. The crowd routes to that cell, and agents that reach it direct-seek the live target from there.

The crowd falls to fallback when no stand-in cell can be found. Two conditions produce that outcome: the target is in a disconnected region with no walkable path to the crowd's area, or the target is outside but every nearby edge cell is blocked from it by a wall (a closed room or sealed corner). In either case, agents apply the configured Fallback Mode in SwarmSettings. Keep Behavior Steering lets agents use plain steering; Stop freezes them in place.

  1. Confirm Fallback Mode in SwarmSettings matches the behavior you want (see Choosing a fallback mode below).
  2. Make sure Sampling Bounds on SwarmManager cover the full play area — if the target can leave the baked grid entirely, no stand-in cell can be found.
  3. If the crowd moves toward a gap or opening and then flows toward the target, the stand-in proxy is working as designed.

Some agents chase while others wander or stand still

Agents with a valid route follow the field normally. Agents that are off the grid or standing in an unwalkable cell get no flow direction and keep their plain behavior steering. In-field agents whose route is sealed off — the target sits in an isolated patch or on the wrong side of a sealed wall — get no direction and fall to the configured fallback instead. Either way the field is correctly reporting that those agents have no path.

Restore a reachable target position, or choose a fallback mode that fits the look you want.

Console: 'a successful bake reached only X of Y walkable cells'

The goal flood reached far less of its own walkable region than expected — the bake covered only part of the area the target sits in. Usual causes: Sampling Bounds that stop short of the full floor, so the flood ends at the bounds edge mid-area, or geometry that splits one apparent area into pieces the route cannot bridge.

Fixes: - Click Snap Bounds To Scene so the bounds cover the whole floor, then confirm no part of the play area sits outside them. - Check that a wall, gap, or steep drop isn't cutting one intended area into separate regions the route can't cross.

Ground that sits outside the play area, past a perimeter wall, is handled for you — the crowd routes to the nearest reachable edge — so a stray outer strip on its own does not trip this warning.

Agents on a walkable patch never follow the field

The bake groups walkable cells into connected regions. Two cells belong to the same region only when a passable path connects them. A sealed room, a raised island, or an area cut by a full-height wall bakes as its own region.

When the goal floods from a target in a different region, it cannot reach the isolated patch. Agents there have no direction and fall to fallback.

Fixes: - Add a walkable passage connecting the isolated area to the main region — a doorway, a ramp, or a lower wall. - Add a SwarmTarget inside the isolated area so agents there have a reachable goal.

Choosing a fallback mode

The Fallback behavior section above lists the three modes. In tight walled layouts the choice matters — here is when each fits.

Keep Behavior Steering (the default) leaves behavior steering untouched when agents lose the flow field. This works for mostly-open levels where off-field agents can still navigate roughly toward the target on their own. In tight walled layouts the field normally prevents agents from steering into walls; without it, obstacle blocking handles containment.

Stop zeros the steering accumulator for any agent that loses its route. The agent stays awake — obstacle and body blocking still run — and re-engages the moment the field bakes a valid route. Use this when you want agents to hold position rather than spread out.

Use Last Flow Direction reuses the cached heading from the last successful field sample, keeping agents moving in a consistent direction across a brief routing gap. The cache becomes invalid when the goal field rebakes — after a rebake, agents fall to behavior steering until they get a new successful sample. Use this for short coverage gaps (target moved one cell, new bake not yet landed), not for long-lived routing failures.


Simple Flow Field Follower

A sample component that moves any non-swarm GameObject along the baked surface flow field. Use it for player characters, companion bots, or any object you want to navigate the same field the swarm uses — without connecting it to the swarm simulation.

Add it via Component → Massive Swarm System → Samples → Simple Flow Field Follower.

The component requires the flow field to be baked before it does anything. It runs in Update and calls SurfaceFlowField.TrySample each frame to read the flow direction at its current world position, then moves along that direction at Move Speed.

Field What it controls
Flow Field The SurfaceFlowField to follow. When not assigned and Auto Find Field is on, the component finds the first active SurfaceFlowField in the scene at startup
Auto Find Field Automatically locates a SurfaceFlowField at Awake when Flow Field is empty
Move Speed Horizontal movement speed in world units per second
Height Offset World-unit offset above the sampled ground height
Height Follow Speed How quickly the object lerps toward the sampled ground height. 0 snaps immediately
Face Flow Direction Rotates the object to face the current flow direction each frame
Turn Speed Maximum turn rate in degrees per second when Face Flow Direction is on
Stop When No Flow Stops movement when the current cell has no direction, which typically means the object reached the goal or landed in an unreachable cell
Enforce Cell Boundaries Prevents the object from crossing into cells the bake marked as blocked. Mirrors the containment pass the swarm uses. Recommended on
Radius Body radius used to keep the object clear of blocked cell edges, in world units
Wall Margin Extra clearance beyond Radius. Increase if the body still clips into walls

Runtime API. The component calls SurfaceFlowField.TrySample for flow direction and height, TryWorldToCellIndex and IsCellWalkable for cell containment, and CanMove to test whether a given cell transition is permitted by the bake. You can call these methods directly from your own scripts to build a custom follower without the sample component.

Use this when you want a non-swarm object to share the same routing as the swarm. Do not use it when the object needs physics-driven movement or when the flow field is not active in the scene.