G—P / FMX 320 / Tutorials / Tutorial 03

Tutorial 03 · AI

Many soldiers, one commander 60 min

A Total War unit is one brain and many bodies. The commander owns the order and the formation math, and each soldier runs a tiny AI that walks to its assigned slot and fights whatever comes close. Every block of spearmen in a Total War siege works this way.

Start Tutorial 02 finished: a working BP_Enemy with perception and a State TreeTime 60 minutes · 40 to build, 20 to add a formation and a unit-level brainNeed Nothing new; DetourCrowd is built inServes Strategy and crowd scenes, and any final that needs more than one AI acting together

Download the demo projectUETutorials-demo.zip, 71 MB. Unzip it and open the .uproject in Unreal 5.8 to follow along.

Download the answer keyUETutorials-answer-key.zip, 72 MB. Open Squad/Lvl_Squad. Right-click to order the squad, keys 1, 2 and 3 switch formation.

By the end of this tutorial you can

Brief · 10 min One brain, many bodies

One commander computes the slots; every soldier only walks to its own Player order Right-click on the ground sets Destination and Facing BP_SquadCommander (one per unit) Soldiers array, Formation enum (line, column, wedge), Spacing Computes one slot per soldier: destination plus rotated offset Soldier 1 AI ControllerMove To my slotFight an enemy within 300 cmReturn to slot when clearSoldier 2 AI ControllerMove To my slotFight an enemy within 300 cmReturn to slot when clearSoldier N AI ControllerMove To my slotFight an enemy within 300 cmReturn to slot when clear Character Movement and NavMesh Each soldier walks its own path; RVO avoidance keeps them from colliding destination and facing one slot each
Nothing in a soldier knows about the other soldiers. Adding a soldier is one more entry in the commander's array; changing formation is one function.

Formation math

The commander hands soldier number i a slot. Compute the offset in the formation's own space, rotate it by the unit's Facing, then add the Destination.

FormationRow of soldier iColumn of soldier iOffset (X back, Y right)
Line, c soldiers per rowi ÷ c, rounded downi mod cX = −row × Spacing; Y = (column − (c − 1) / 2) × Spacing
Columni ÷ 2i mod 2Same formula with c = 2
Wedge(i + 1) ÷ 2, rounded downsoldier 0 is the tip, then odd i left, even i rightX = −row × Spacing; Y = ±row × Spacing / 2

Build · 40 min The commander and its soldiers

  1. Make a soldier

    Duplicate BP_Enemy as BP_Soldier. Add variables Commander (object reference to BP_SquadCommander), SlotIndex (integer) and TargetSlot (vector).

  2. Make the commander

    Create BP_SquadCommander as a plain Actor. Add variables Soldiers (array of BP_Soldier), Formation (an enum with Line, Column, Wedge), Spacing (float, 150), SoldiersPerRow (integer, 8), Destination (vector) and Facing (rotator).

    BP_SquadCommander's My Blueprint panel: the Soldiers array, Spacing, SoldiersPerRow, UnitSize, Destination, Facing and the Formation enum, with the enum's Details on the right.
  3. Compute a slot

    Add a pure function GetSlotLocation(Index) that implements the table above. Use Rotate Vector with Facing, then add Destination.

    GetSlotLocation for the Line formation: row and column from Index, Make Vector for the offset, Rotate Vector by Facing, then add Destination.
  4. Issue an order

    Add a function IssueMoveOrder(NewDestination, NewFacing). Store both, then For Each Loop over Soldiers: set TargetSlot to GetSlotLocation(Index), get the soldier's AI Controller and call Move To Location with acceptance radius 50.

  5. Spawn the unit

    On Begin Play, loop UnitSize times: Spawn Actor From Class BP_Soldier at GetSlotLocation(Index), set its Commander and SlotIndex, and add it to Soldiers.

  6. Right-click to move

    In the player controller, on right mouse button: Get Hit Result Under Cursor By Channel, build Facing with Find Look At Rotation from the unit's center to the hit point, and call IssueMoveOrder on the selected commander. Use the Top Down template camera, or raise the Third Person camera, so you can see the whole block move.

    Line. 24 soldiers, three rows of eight at 150 cm spacing.
    Wedge. The same unit: each pair one row back and half a spacing further out.
  7. Give soldiers a shorter tree

    BP_Soldier needs only three states: Follow Slot (Move To TargetSlot), Engage (an enemy is within 300 cm, so chase and attack it) and Return (no enemy, go back to TargetSlot). The perception setup from Tutorial 02 carries over unchanged.

  8. Stop the pile-up

    Reparent BP_EnemyController to DetourCrowdAIController, or tick Use RVO Avoidance on the Character Movement component, so sixty soldiers do not jam a doorway.

  9. Give the unit a brain

    Add a second State Tree on the commander actor: Hold, Advance toward the nearest enemy commander, Charge when within 800 cm, Retreat when fewer than 30 percent of Soldiers are alive. You now have unit-level and soldier-level AI from the same tool.

How far Blueprint scales

Full Character actors with skeletal meshes run comfortably at a few dozen per unit and a few hundred in a scene on a laptop. Past that, turn on the Animation Budget Allocator plugin and lower Animation Blueprint update rates by distance. Thousands of soldiers, as in a Total War battle, need the Mass Entity framework that drives the City Sample crowds, which is a C++ topic. Aim for 50 to 200 soldiers, which already reads as Total War from a tactical camera.

Before you close this

Read next