class: ActorLocator
Specialized locators for querying and interacting with spatial 3D objects in the Unreal world. Extends the base SpecterLocator and features native Gameplay Ability System (GAS) integration.
actor.getLocation
Usage
const startPos = await enemy.getLocation();Returns
- Promise<Vector3>
actor.waitForGameplayTag
Usage
await player.waitForGameplayTag("Status.Stunned");Arguments
tagstringThe exact Gameplay Tag string to wait for.
Returns
- Promise<void>
actor.triggerAbilityByTag
Usage
await player.triggerAbilityByTag("Ability.Slot.Q");Arguments
tagstringThe tag identifying the ability (e.g. Ability.Slot.Q).
Returns
- Promise<void>
Transform & Spatial
Methods for interacting with the actor's 3D position and rotation in the world.
actor.getLocation
Usage
const pos = await player.getLocation();
console.log(pos.x, pos.y, pos.z);Returns
- Promise<Vector3>
actor.getForwardVector
Usage
const forward = await player.getForwardVector();Returns
- Promise<Vector3>
actor.setLocation
Usage
await player.setLocation({ x: 0, y: 0, z: 1000 });Arguments
locationVector3The target {x, y, z} coordinate.
Returns
- Promise<void>
actor.setRotation
Usage
await player.setRotation({ pitch: 0, yaw: 90, roll: 0 });Arguments
rotationRotatorThe target {pitch, yaw, roll} rotation.
Returns
- Promise<void>
actor.setTransform
Usage
await player.setTransform({ location: { x: 0, y: 0, z: 0 }, rotation: { pitch: 0, yaw: 0, roll: 0 }, scale: { x: 1, y: 1, z: 1 } });Arguments
transformTransformThe target transform object.
Returns
- Promise<void>
State & Testing
actor.highlight
Usage
await boss.highlight("Target Acquired!");Arguments
stateInfostring(optional)Text to float above the actor.
Returns
- Promise<void>
actor.checkVisibility
Usage
const isVisible = await boss.checkVisibility(true);Arguments
checkOnScreenboolean(optional)Whether to require it to be on-screen.
Returns
- Promise<boolean>
actor.isLocallyControlled
Usage
const localPlayer = world.actor('BP_Hero_Shooter').isLocallyControlled(true);Arguments
locallyControlledboolean(optional)Whether to filter for locally controlled (true) or non-locally controlled (false).
Returns
actor.getPlayerId
Usage
const id = await player.getPlayerId();Returns
- Promise<number>
actor.getByComponent
Usage
const skeleton = player.getByComponent("Skeleton");
await expect(skeleton).toHaveBoneRotation("head", { pitch: 0, yaw: 90, roll: 0 });Arguments
componentTypestringThe component type key (e.g. 'Skeleton', 'CharacterMovement').optionsobject(optional)Filters like name or exact UE class.
Returns
- ComponentLocator
Actor-Scoped Widgets (UI)
Methods for locating 3D/Screen-space UWidgetComponents and their hosted UMG widgets directly on this actor.
actor.widget
Usage
// Grabs the widget from Steel's UWidgetComponent:
const healthBar = steel.widget();
await expect(healthBar).toBeVisible();Arguments
widgetClassOrNamestring(optional)The specific UMG widget class to find.
Returns
- WidgetLocator<W>
actor.widgetComponent
Usage
const healthBar = steel.widgetComponent("HealthBarComponent");Arguments
componentNamestring(optional)The Unreal component name (e.g. 'HealthBarComponent').
Returns
actor.getByRole
Usage
const healthImage = steel.getByRole("image", { name: "HealthBarImage" });
await expect(healthImage).toBeVisible();Arguments
roleWidgetRoleThe semantic UI role.optionsWidgetRoleOptions(optional)Role options like { name: 'HealthBarImage', exact: false }.
Returns
actor.pin
Usage
// 1. Resolve and pin the current last minion in the level:
const targetMinion = await world.actor("BP_MinionRange").last().pin();
// 2. High-frequency polling now executes in O(1) ~0.001ms time:
await expect(targetMinion).toHaveLocation({ x: 100, y: 200, z: 92 });
// 3. Spawning new minions will not hijack targetMinion:
await world.spawnActor("BP_MinionRange");
await targetMinion.highlight("Still Original Minion");Returns
- Promise<ActorLocator>
actor.destroy
Usage
await fireHazard.destroy();
await expect(fireHazard).toBeDestroyed();Returns
- Promise<void>
actor.getControllerInfo
Usage
const info = await actor.getControllerInfo();
console.log(info.isPossessed); // true
console.log(info.isPlayerControlled); // false (AI bot)
console.log(info.controllerClass); // "BP_BossAIController"Returns
- Promise<ControllerInfo>
actor.isPossessed
Usage
const possessed = await minion.isPossessed();Returns
- Promise<boolean>
actor.isPlayerControlled
Usage
const isHuman = await player.isPlayerControlled();Returns
- Promise<boolean>
Gameplay Ability System (GAS)
actor.getAttributeValue
Usage
const health = await player.getAttributeValue("HealthSet", "Health");Arguments
attributeSetstringThe Attribute Set class name.attributeNamestringThe specific attribute name.
Returns
- Promise<number>
actor.hasGameplayTag
Usage
const isStunned = await player.hasGameplayTag("Status.Stunned");Arguments
tagstringThe tag to check.
Returns
- Promise<boolean>
actor.getGameplayTags
Usage
const tags = await enemy.getGameplayTags();
console.log(tags); // ['Status.Stunned', 'Status.Burning']Returns
- Promise<string[]>
actor.waitForGameplayTag
Usage
// Wait for the stun tag to be applied
await boss.waitForGameplayTag("Status.Stunned", true);Arguments
tagstringThe tag to wait for.expectedStatebooleanTrue to wait for addition, false to wait for removal.timeoutnumber(optional)Timeout in milliseconds (Default: 5000).
Returns
- Promise<boolean>
actor.waitForAttributeValue
Usage
const result = await player.waitForAttributeValue("HealthSet", "Health", 0);
console.log("Health dropped to 0! History:", result.history);Arguments
attributeSetstringThe Attribute Set class name.attributeNamestringThe specific attribute name.expectedValuenumberThe value to wait for.timeoutnumber(optional)Timeout in milliseconds (Default: 5000).
Returns
- Promise<{ finalValue: number, history: number[] }>
actor.triggerAbilityByTag
Usage
await player.triggerAbilityByTag("Ability.Attack.Melee");Arguments
inputTagstringThe ability input tag.
Returns
- Promise<void>
actor.triggerAbilityWithTarget
Usage
await player.triggerAbilityWithTarget("Ability.Spell.Fireball", boss);Arguments
abilityTagstringThe ability tag.targetSpecterLocator | Vector3The target locator or 3D coordinate.
Returns
- Promise<void>
actor.applyGameplayEffect
Usage
await player.applyGameplayEffect("/Game/Effects/GE_Damage_Poison.GE_Damage_Poison_C");Arguments
effectClassPathstringThe class path of the Gameplay Effect.levelnumber(optional)The effect level (Default: 1.0).
Returns
- Promise<void>
actor.hasActiveGameplayEffect
Usage
const isPoisoned = await player.hasActiveGameplayEffect("/Game/Effects/GE_Damage_Poison.GE_Damage_Poison_C");Arguments
effectClassPathstringThe class path of the Gameplay Effect.
Returns
- Promise<boolean>
Input Simulation
actor.playSequence
Usage
import { SpecterInputSequence } from '@specter-automation/test';
const accelerate = new SpecterInputSequence()
.addAxisSweep('Gamepad_RightTrigger', 0.0, 1.0, 0, 2000);
await playerCar.playSequence(accelerate);Arguments
sequenceSpecterInputSequenceThe input sequence to play.optionsObject(optional){ loops?: number } The number of times to loop the sequence.
Returns
- Promise<void>
actor.pressKey
Usage
// Quick press
await player.pressKey("SpaceBar");
// Hold the button for 500ms
await player.pressKey("Gamepad_FaceButton_Bottom", { holdMs: 500 });Arguments
keyUnrealKeyThe UE key name (e.g. 'SpaceBar', 'Gamepad_FaceButton_Bottom').optionsObject(optional){ holdMs?: number } How long to hold the key before releasing it.
Returns
- Promise<void>
actor.injectAxis
Usage
// Pull the right trigger 10% on a specific player's controller
await playerActor.injectAxis('Gamepad_RightTrigger', 0.1);Arguments
axisNamestringThe name of the axis binding (e.g. 'Gamepad_RightTrigger').valuenumberThe float value to inject (typically -1.0 to 1.0).
Returns
- Promise<void>
actor.type
Usage
await player.type("Hello Specter!");Arguments
textstringThe string of text to type.delayMsnumber(optional)Optional delay between keystrokes.
Returns
- Promise<void>
Enhanced Input
Methods for querying and triggering UE5 Enhanced Input Subsystem actions and mapping contexts.
actor.triggerInputAction
Usage
// Trigger a digital jump action
await player.triggerInputAction('IA_Jump', true);
// Trigger a 2D analog movement vector payload
await player.triggerInputAction('IA_Move', { x: 0.0, y: 1.0, z: 0.0 });Arguments
actionstringThe Input Action asset name or path (e.g. 'IA_Jump', 'IA_Move').valueboolean | number | Vector3The input action value payload.
Returns
- Promise<void>
actor.hasInputMappingContext
Usage
const hasIMC = await player.hasInputMappingContext("IMC_DefaultPlayer");Arguments
contextstringShort context asset name (e.g. 'IMC_DefaultPlayer') or full asset path.
Returns
- Promise<boolean>
actor.getInputActionValue
Usage
const info = await player.getInputActionValue("IA_Sprint");
console.log("Bool state:", info.boolValue);Arguments
actionstringShort action asset name (e.g. 'IA_Sprint') or asset path.
Returns
- Promise<{ value: number, boolValue: boolean, vector: Vector3 }>
Camera & FOV
Methods for querying and controlling camera properties, field of view, and camera shakes.
actor.getCameraFOV
Usage
const fov = await player.getCameraFOV(); // default: 90Returns
- Promise<number>
actor.setCameraFOV
Usage
await player.setCameraFOV(110);Arguments
fovnumberThe FOV angle in degrees.
Returns
- Promise<void>
actor.isCameraShaking
Usage
const shaking = await player.isCameraShaking();Returns
- Promise<boolean>
actor.getCameraViewTarget
Usage
const target = await player.getCameraViewTarget();Returns
- Promise<string>
AI & Navigation
Methods for querying AI pathfinding state and navigation goals.
Team System
Methods for querying the Generic Team Agent Interface (IGenericTeamAgentInterface).
actor.getTeamId
Usage
const teamId = await player.getTeamId(); // 255 = NoTeamReturns
- Promise<number>
actor.getTeamAttitudeTowards
Usage
const attitude = await player.getTeamAttitudeTowards(enemy);
// Returns: 'Friendly' | 'Hostile' | 'Neutral'Arguments
otherActorActorLocatorThe other actor to evaluate attitude towards.
Returns
- Promise<string>
Visual Debugging & Overlays
Real-time viewport overlays, motion trail ribbons, direction arrows, and auto-updating stats billboards.
actor.drawTrail
Usage
await player.drawTrail({
duration: 6, // How long trail recorder runs (seconds)
color: 'cyan', // 'cyan' | 'magenta' | 'yellow' | 'red' | 'green' | hex (#RRGGBB)
thickness: 4.0, // Line thickness in viewport
segmentDuration: 12.0 // Persistence of each drawn ribbon segment
});Arguments
optionsTrailOptions(optional)Configuration object: { duration?: number, color?: string, thickness?: number, segmentDuration?: number }.
Returns
- Promise<void>
actor.drawDirectionArrow
Usage
// Forward facing vector arrow
await player.drawDirectionArrow({ length: 200, color: 'cyan', duration: 5 });
// Velocity vector arrow
await player.drawDirectionArrow({ length: 200, color: 'yellow', duration: 5, useVelocity: true });Arguments
optionsDirectionArrowOptions(optional)Configuration object: { length?: number, color?: string, duration?: number, useVelocity?: boolean, arrowSize?: number, thickness?: number }.
Returns
- Promise<void>
actor.showStatsBillboard
Usage
// Live auto-updating stats billboard floating above actor
await marshmallow.showStatsBillboard({
attributes: ['Health', 'ToastLevel', 'MoveSpeed'],
properties: ['bCanBeDamaged'],
duration: 15,
color: 'yellow'
});Arguments
optionsStatsBillboardOptionsConfiguration object: { attributes?: string[], properties?: string[], duration?: number, color?: string, offset?: Vector3 }.
Returns
- Promise<void>
actor.updateStatsBillboard
Usage
// Reconfigure stats tracked on the fly
await marshmallow.updateStatsBillboard({
attributes: ['Health', 'ToastLevel'],
color: 'red'
});Arguments
optionsStatsBillboardOptionsUpdated billboard configuration.
Returns
- Promise<void>
actor.clearDebugVisuals
Usage
await player.clearDebugVisuals();Returns
- Promise<void>
Interfaces
ControllerInfo
interface ControllerInfo {
isPossessed: boolean;
isPlayerControlled: boolean;
isLocallyControlled: boolean;
controllerClass: string;
controllerName: string;
}StatsBillboardOptions
interface StatsBillboardOptions {
attributes?: string[];
properties?: string[];
duration?: number;
color?: string;
offset?: Vector3;
}TrailOptions
interface TrailOptions {
duration?: number;
color?: string;
thickness?: number;
segmentDuration?: number;
}Vector3
interface Vector3 {
x: number;
y: number;
z: number;
}Rotator
interface Rotator {
pitch: number;
yaw: number;
roll: number;
}Transform
interface Transform {
location: Vector3;
rotation?: Rotator;
scale?: Vector3;
}