Function Library
UCrowdToolkitLibrary is the plugin's Blueprint function library. It provides one-node access
to the world's crowd actor, plus bulk math nodes that apply one operation over a whole
array of positions or transforms in a single C++ pass - replacing the Blueprint ForEach
loop (and its per-element node overhead) for the arrays the crowd getters return.
The canonical use is the render pipeline: GetAgentPositions → PositionsToTransforms →
AddInstances, with no loop in the graph.
The bulk nodes are impure (they have exec pins) on purpose. A pure node with an array output re-runs once per connected pin, silently multiplying an O(n) pass. Always drive them from the exec line. Inputs are never mutated - each node returns a new array.
World access
static ACrowdToolkitActor* GetCrowd(const UObject* WorldContextObject);
The calling world's crowd actor. Resolves the world from the hidden world-context pin, so
there's no need to fetch the subsystem first - callable from any Blueprint. Returns null
outside game worlds. BlueprintPure.
Position arrays
static TArray<FVector> OffsetPositions(const TArray<FVector>& Positions, const FVector& Offset);
Each position + Offset.
static TArray<FVector> TransformPositions(const TArray<FVector>& Positions, const FTransform& Transform);
Each position run through Transform (scale, rotate, then translate) - e.g. local-to-world
through an actor's transform.
static TArray<FTransform> PositionsToTransforms(
const TArray<FVector>& Positions,
const FVector& Offset,
FRotator Rotation = FRotator(0,0,0),
FVector Scale = FVector(1,1,1));
One transform per position: location = position + Offset, with the same Rotation and
Scale on every element. The one-call replacement for a "make a transform per point" loop
(instanced-mesh markers and the like).
static FVector GetPositionsCentroid(const TArray<FVector>& Positions);
Average of the positions (zero vector for an empty array) - e.g. a selection's centre point.
Transform arrays
static TArray<FVector> TransformsToPositions(const TArray<FTransform>& Transforms);
Each transform's location, dropping rotation and scale.
static TArray<FTransform> OffsetTransforms(const TArray<FTransform>& Transforms, const FVector& Offset);
Each transform translated by Offset (rotation and scale untouched).
static TArray<FTransform> SetTransformsRotation(const TArray<FTransform>& Transforms, const FRotator& Rotation);
Each transform with its rotation replaced by Rotation.
static TArray<FTransform> SetTransformsScale(const TArray<FTransform>& Transforms, FVector Scale = FVector(1,1,1));
Each transform with its scale replaced by Scale.
static TArray<FTransform> ComposeTransforms(const TArray<FTransform>& Transforms, const FTransform& Other);
Each transform composed with Other (element * Other) - every element re-expressed in
Other's space. Pass an actor's world transform to move a whole local-space batch into the
world at once.
Example: build instance transforms
The render pipeline with no Blueprint loop: read positions, turn them into transforms (lifted to the mesh half-height), and add them as instances.
// Lift every agent to its mesh half-height and render, no Blueprint loop.
TArray<FVector> Positions = Crowd->GetAgentPositions({});
TArray<FTransform> Transforms = UCrowdToolkitLibrary::PositionsToTransforms(
Positions, FVector(0, 0, 88));
ISM->AddInstances(Transforms, /*bReturnIndices*/ false, /*bWorldSpace*/ true);