Configuring Squads, Formations, and Slots
This guide does more than describe which components and fields to configure. It completes two verifiable scenarios: spawning a fixed formation from a template and regrouping units that already exist in the level. When finished, you should be able to observe runtime convergence of members, roles, formation slots, navigation-adapted positions, and Movement Intent.
Related documentation: see Squad System, Formation System, Squad, Role, and Unit Parameters, and Formation, Slot, and Navigation Parameters.
Prerequisites
- The squad-host Actor class implements
IGAIS_SquadActorInterfaceand hasUGAIS_SquadComponent,UGAIS_FormationComponent, and the components required by commands and AI. - Every Actor that can join a squad has
UGAIS_UnitComponent. If it must also receive commands, it must be a Pawn/Character withUGAIS_CommandSystemComponenton the Pawn. - The project defines role and slot tags, such as
GAIS.Role.Frontline,GAIS.Role.Ranged,GAIS.Formation.Slot.Front, andGAIS.Formation.Slot.Backline. - The level has a usable NavMesh. To verify navigation adaptation, prepare a slope, stairs, or edge terrain.
Scenario 1: Spawn a Fixed Formation from a Template
Create a UGAIS_FormationDefinition subclass or Blueprint asset and configure a formation with clear spatial semantics. Every slot needs a stable SlotId; do not use the array index as identity. Give important positions a higher Weight and add SlotTags, such as GAIS.Formation.Slot.Front for front-line slots and GAIS.Formation.Slot.Backline for rear slots.
If the formation should follow the squad's overall facing, such as a shield wall or advancing line, keep bHasDirection enabled. For circular, scattered, or encirclement formations, per-slot rotation is more important and the overall direction semantic can be disabled.
Then create a UGAIS_SquadDefinition:
- Set
SquadActorClassto the squad-host class. - Add the formation to
AvailableFormations. - Configure role capacity, qualification tags, required status, and role StateTree in
AvailableRoles. - Configure unit types to spawn and their
DesiredRoleinDefaultUnits. - Configure
DefaultSquadStateTree,DefaultUnitStateTree, or roleStateTreeso the squad and units receive an explicit behavior layer after joining. - Tune
SlotAssignmentSettingsso role tags and SlotTags match correctly. - Tune
DefaultMovementIntentResponseSettingsandDefaultMovementIntentTagsto control start/stop distance, response speed, and the project semantics carried by final Intent.
At runtime, create the squad with UGAIS_SquadSubsystem::CreateSquad and allow default units to spawn. The squad initializes its Definition, FormationComponent selects an available formation, SquadComponent waits for Formation Ready, then assigns slots and generates Movement Intent.
Scenario 2: Regroup Existing Units into a Squad
If units already exist in the level, do not respawn them just to use the squad system. Use CreateSquadFromActors to create the squad host and add the existing Actors. Every Actor must have UGAIS_UnitComponent, must not already belong to another squad, and must satisfy Unit/StateTree runtime contracts. If any Actor cannot be accepted, the entire transaction returns null and does not leave a partial squad.
For independent units that are recruited only after a gameplay condition, ensure they are automatically registered with UGAIS_SquadSubsystem by UGAIS_UnitComponent, then use CreateSquadFromNearbyUnits to recruit a specified number of unassigned units near the squad's spawn location. This entry point requires authority, a search radius greater than 0, and a recruitment count greater than 0. If enough valid candidates cannot be found or all candidates cannot be added atomically, it also returns null. Use TryReorganizeSquad to recruit nearby auto-recruitable units and fill missing roles during combat. Use MergeSquads to combine two squads; the primary squad retains identity and high-level command semantics.
After regrouping, validate more than member count. Confirm role-container recalculation, required-role gaps, slot reassignment, and Movement Intent refresh. When a unit leaves, its Squad-layer StateTree should clear and fall back to its own behavior layer.
Adjusting a Squad from a Client in Multiplayer
- Confirm that members, roles, TeamId, formation, and commands are maintained by the server.
- Server AI, Subsystems, or authoritative scripts call
AddUnit,AssignRoleToUnit,SetCurrentFormation, and other authority entry points directly. - A client that owns the squad host uses
Server Add/Remove Unit,Server Assign/Revoke Role,Server Set Current Formation, orServer Issue Squad Command. - If the client does not own the squad host, send a project RPC through its PlayerController. The server validates permissions and invokes the GAIS authority entry point.
- Verify that server and client
UnitsContainer,RoleContainer,CurrentFormation, and Unit mirrors eventually agree.
Configure Navigation Adaptation
Inspect Navigation Adaptation on the squad host's UGAIS_FormationComponent:
Setting | Recommendation |
|---|---|
| Enable for most projects with real movement. When disabled, slots use geometric positions only. |
| Configure a project QueryFilter when different unit types or squads have different traversable areas. |
| Increase Z when slots may be on slopes, stairs, or terrain with height variation. |
| Increase for large, frequently moving squads to reduce repeated projection. |
| Enable near terrain edges, bridges, or obstacles so failed slots contract toward the formation root. |
Move the squad host onto a slope or near a NavMesh edge and verify that slot world positions land on navigable areas. If slot preview Actors are enabled, they should follow formation movement and show navigation offsets.
Validation
GetInitializationState()isActive, andIsSquadActive()is true. If still waiting, verify that Formation is Ready.- Each role in
RoleContainerhas the expected current count,MaxNum, andbRequiredstate. - FormationComponent has a current formation,
IsFormationReadyis true, and slot count matches the asset definition. QuerySlotsorFindSlotRuntimeViewshows stableSlotId, SlotTags, and world transforms. Do not infer availability from legacy state fields or array indices.- Every Unit participating in formation has a reasonable
AssignedSlotId. - Movement Intent exposes
RawDesiredLocation,DesiredLocation,DesiredOrientation,DesiredSpeed,bShouldMove, andMovementIntentTags. - GameplayDebugger Squad / Formation sections show members, roles, current formation, slots, and slot-score explanations.
Common Failures
Symptom | Check first |
|---|---|
Squad initialization stalls | Does FormationComponent exist, can |
Unit joins but has no role | Does |
Unit has no slot | Are there enough slots, is the SlotTags policy too strict, or do distance/stability weights overpower semantic matching? |
Slot position is not walkable | Is Navigation Adaptation enabled, do QueryFilter/ProjectionQueryExtent fit the NavMesh, and is fallback radius large enough? |
Movement Intent exists but the unit does not move | Is |
Client formation click has no effect | Was an authority-only API called? If using |
