This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

GS_Unit

The character and entity control system — unit registration, player and AI controllers, input processing, and modular movement.

GS_Unit is the complete character control system for GS_Play. It handles how entities are registered as controllable units, which controller possesses each unit, how raw player input is captured and converted into intent, and how that intent is translated into physical movement through a modular stack of movers, grounders, and influence fields.

For architecture details, component properties, and extending the system in C++, see the GS_Unit API.


Quick Navigation

I want to…FeatureAPI
Register units, track active controllers, or spawn units at runtimeUnit ManagerAPI
Possess and release units with player or AI controllersControllersAPI
Capture raw input and convert it into structured movement intentInput DataAPI
Move characters with movers, grounders, and movement influence fieldsMovementAPI

Installation

GS_Unit requires GS_Core. Add both gems to your project before using any Unit components.

For a full guided walkthrough, follow the Simple Project Setup guide.

 

Quick Installation Summary

  1. Enable the GS_Unit gem in your project configuration.
  2. Create a Unit Manager prefab and add it to the Game Manager’s Managers list.
  3. Configure physics collision layers for character movement.
  4. Place a Player Controller and Unit entity in your level.

Unit Manager

The Unit Manager is the singleton coordinator for everything unit-related. It handles registration of new units as they spawn, maintains an indexed list of all active units queryable by name or ID, and provides the spawn interface for runtime unit creation. It also participates in the standby system for clean level transitions.

Unit Manager API


Controllers

Controllers are the possession layer — they determine which entity a given intelligence (player or AI) currently owns and drives. Player and AI controllers share the same possession interface, so swapping control mid-game or having both active simultaneously requires no special-casing.

Controllers API


Input Data

The Input Data feature set converts hardware signals into structured intent your movement code can consume. The PlayerControllerInputReader reads raw input events, InputData components store the current state, and Input Reactors compute movement vectors from keyboard or joystick input with deadzones and scaling.

Input Data API


Units

Unit overview description, leads to movement.

Units API


See Also

For the full API, component properties, and C++ extension guide:

For step-by-step project setup:


Get GS_Unit

GS_Unit — Explore this gem on the product page and add it to your project.

1 - Unit Manager

How to work with the GS_Unit manager — spawning units, registering player controllers, and coordinating standby across all controlled characters.

The Unit Manager is the global coordinator for all units in a GS_Play project. It maintains a registry of every active unit entity, provides the interface for spawning new units at runtime, tracks which player controllers are currently active, and participates in the GS_Core standby system so that all controlled characters pause cleanly during level transitions.

For architecture details, component properties, and extending the system in C++, see the Framework API reference.

Unit Manager component in the O3DE Inspector Unit Manager entity setup in the O3DE Editor

 

Contents


What the Unit Manager Does

The Unit Manager runs as a singleton that all other unit systems report to. When a unit entity activates, it registers itself so the manager can track it by name and ID. When gameplay code needs a new unit spawned, it asks the manager — not the spawning system directly — so the manager can assign a unique name and fire the appropriate notification.

ResponsibilityDescription
Unit registryEvery active unit registers and deregisters automatically.
SpawningIssues RequestSpawnNewUnit and fires ReturnNewUnit when the entity is ready.
Player controller trackingStores which controllers are registered as player-driven so multi-actor setups stay consistent.
Standby coordinationBroadcasts EnterStandby and ExitStandby to pause and resume all units during transitions.
Unit validationCheckIsUnit lets any system confirm whether an entity is a registered unit.

Spawning Units

How Spawning Works

Spawning a unit is a two-step async operation. Your script calls RequestSpawnNewUnit, the manager creates the entity using the prefab spawner, and when the unit is fully initialized the manager fires ReturnNewUnit on UnitManagerNotificationBus with the new entity ID and its assigned unique name.

You should always listen for ReturnNewUnit rather than attempting to use the entity immediately after the request, because spawning can take one or more frames.

StepWhat Happens
1 — RequestCall RequestSpawnNewUnit with the prefab reference and desired spawn transform.
2 — WaitThe manager spawns the entity and runs its initialization.
3 — ReceiveReturnNewUnit fires on UnitManagerNotificationBus with the entity ID and name.

ScriptCanvas — Spawning a Unit


Registering Player Controllers

Player controllers must register themselves with the Unit Manager on activation so the game always knows which controllers are active. This is handled automatically by GS_PlayerControllerComponent, but if you are building a custom controller, call RegisterPlayerController in your activation logic.

[On Entity Activated (custom controller)]
    └─► [UnitManagerRequestBus → RegisterPlayerController(selfEntityId)]

This registration matters most for split-screen or multi-player setups where the manager needs to route input correctly across multiple simultaneous controllers.


Checking Unit Identity

Any system can confirm whether an arbitrary entity is a registered unit without holding a direct reference to the Unit Manager:

ScriptCanvas NodeReturnsNotes
CheckIsUnit(entityId)booltrue if the entity is an active registered unit.

ScriptCanvas

[UnitManagerRequestBus → CheckIsUnit(targetEntityId)]
    └─► bool
            ├─► true  — proceed with unit-specific logic
            └─► false — entity is not a unit, skip

Standby Mode

The Unit Manager participates in GS_Core’s global standby system. During level transitions or other blocking operations, the Game Manager signals standby and the Unit Manager relays that signal to all units. Units should pause movement, suspend input processing, and halt any tick-driven logic while in standby.

Listen on UnitManagerNotificationBus to coordinate your own logic with unit standby:

EventWhen It FiresWhat to Do
EnterStandbyBefore a level transition or blocking operation begins.Pause all movement, halt ticks, stop animations.
ExitStandbyAfter the blocking operation completes.Resume movement, re-enable ticks.

ScriptCanvas


Quick Reference

NeedBusMethod / Event
Spawn a new unitUnitManagerRequestBusRequestSpawnNewUnit(prefab, transform)
Know when a unit is readyUnitManagerNotificationBusReturnNewUnit(entityId, uniqueName)
Register a player controllerUnitManagerRequestBusRegisterPlayerController(entityId)
Check if entity is a unitUnitManagerRequestBusCheckIsUnit(entityId)
Know when standby beginsUnitManagerNotificationBusEnterStandby
Know when standby endsUnitManagerNotificationBusExitStandby

Glossary

TermMeaning
Unit ManagerThe singleton manager that tracks all active units, handles spawning, and coordinates standby
Unit RegistryThe internal list of every active unit entity, indexed by name and ID
StandbyA pause state broadcast to all units during level transitions or blocking operations

For full definitions, see the Glossary.


See Also

For the full API, component properties, and C++ extension guide:

For related systems:


Get GS_Unit

GS_Unit — Explore this gem on the product page and add it to your project.

2 - Controllers

How to work with GS_Unit controllers — the possession model, player and AI controller setup, and switching control at runtime.

Controllers are the possession layer of GS_Unit. A controller is the intelligence — human input or AI logic — that owns and drives a unit at any given moment. Because both player and AI controllers share the same possession interface, your unit entities do not need to know what is controlling them, and swapping control at runtime requires no special-casing.

For architecture details, component properties, and extending the system in C++, see the Framework API reference.

Player Controller and Input Reader components in the O3DE Inspector

 

Contents


The Possession Model

Unit Possession Pattern Graph

Breakdown

Every unit has exactly one controller at a time, or no controller at all. Possession is established by calling Possess on the unit and released by calling DePossess. The unit fires UnitPossessed on UnitNotificationBus whenever ownership changes so other systems can react.

ConceptDescription
PossessionA controller attaches to a unit. The unit accepts input and movement commands from that controller only.
DePossessionThe controller releases the unit. The unit halts input processing and enters a neutral state.
UnitPossessed eventFires on UnitNotificationBus (addressed by entity ID) whenever a unit’s controller changes.
GetControllerReturns the entity ID of the current controller, or an invalid ID if none.
GetUniqueNameReturns the string name assigned by the Unit Manager when this unit was spawned.

Controller Types

GS_Unit ships three controller components that cover the full range of typical game use:

ComponentPurpose
GS_UnitControllerComponentBase class establishing the possession contract. Extend this for custom controllers.
GS_PlayerControllerComponentHuman-driven controller. Connects into the Input Data pipeline and routes player intent to the possessed unit.
GS_AIControllerComponentNPC controller. Provides the entry point for AI logic to issue movement commands through the same unit interface as player input.

Both GS_PlayerControllerComponent and GS_AIControllerComponent extend the base controller, meaning any code that works with the base controller interface works transparently with either type.


Player Controller

GS_PlayerControllerComponent registers itself with the Unit Manager on activation, making it visible to the game’s controller tracking system. It connects to the Input Data pipeline on the possessed unit so that raw input events are routed correctly as soon as possession is established.

Setup

  1. Add GS_PlayerControllerComponent to a controller entity (not the unit entity itself).
  2. Ensure GS_InputDataComponent and GS_PlayerControllerInputReaderComponent are on the unit entity.
  3. Call Possess to attach the controller to the target unit.

ScriptCanvas — Possessing a Unit


AI Controller

GS_AIControllerComponent gives AI logic the same possession interface as the player controller. An AI behavior system possesses a unit, then issues movement commands through UnitRequestBus or directly drives the unit’s Input Data component to simulate input. The unit processes those commands through the same mover stack it would use for player input.

ScriptCanvas — Handing a Unit to AI

// Called from your behavior tree or AI activation event when the NPC starts acting
[AI behavior activates]
    └─► [UnitRequestBus(unitEntityId) → Possess(aiControllerEntityId)]

[UnitNotificationBus(unitEntityId) → UnitPossessed(aiControllerEntityId)]
    └─► [AI logic begins issuing movement / action commands]

Switching Controllers at Runtime

Because possession is a simple attach/detach operation on the unit, switching from player to AI control (or back) is two calls:

[Trigger: cutscene starts, character incapacitated, etc.]
    └─► [UnitRequestBus(unitEntityId) → DePossess]
            └─► [UnitRequestBus(unitEntityId) → Possess(aiControllerEntityId)]

[Trigger: cutscene ends, character recovers, etc.]
    └─► [UnitRequestBus(unitEntityId) → DePossess]
            └─► [UnitRequestBus(unitEntityId) → Possess(playerControllerEntityId)]

The DePossess call ensures the previous controller’s input pipeline is disconnected before the new controller attaches, preventing stale input state from leaking between ownership changes.


Querying Controller State

ScriptCanvas NodeReturnsNotes
GetController (on unit)EntityIdCurrent controller entity. Invalid ID means no controller.
GetUniqueName (on unit)stringThe name assigned to this unit at spawn time.

ScriptCanvas


Standby and Controllers

When the Unit Manager broadcasts EnterStandby, both player and AI controllers should stop issuing commands. Player controllers automatically halt input reading. AI controllers must be suspended by whatever behavior system drives them. On ExitStandby, normal command flow resumes.

EventController Action
UnitEnteringStandbyHalt input reads, suspend AI commands.
UnitExitingStandbyResume input reads, restart AI commands.

Both events fire on UnitNotificationBus addressed by unit entity ID.


Quick Reference

NeedBusMethod / Event
Attach a controller to a unitUnitRequestBus (by ID)Possess(controllerEntityId)
Release a controller from a unitUnitRequestBus (by ID)DePossess
Know when possession changesUnitNotificationBus (by ID)UnitPossessed(controllerEntityId)
Get the current controllerUnitRequestBus (by ID)GetController
Get a unit’s nameUnitRequestBus (by ID)GetUniqueName
Know when unit enters standbyUnitNotificationBus (by ID)UnitEnteringStandby
Know when unit exits standbyUnitNotificationBus (by ID)UnitExitingStandby

Glossary

TermMeaning
PossessionThe act of a controller attaching to a unit and becoming its active intelligence
DePossessionReleasing a controller from a unit, halting its input processing
Player ControllerA human-driven controller that routes input from the Input Data pipeline to a unit
AI ControllerAn NPC controller that issues movement commands through the same unit interface as player input

For full definitions, see the Glossary.


See Also

For the full API, component properties, and C++ extension guide:

For related systems:


Get GS_Unit

GS_Unit — Explore this gem on the product page and add it to your project.

3 - Input Data

How to work with the GS_Unit input pipeline — reading player input, converting keyboard and joystick signals into movement vectors, and chaining input reactors.

The Input Data system is the pipeline that converts raw hardware signals into structured intent your movement code can consume. It sits between the active input profile and the mover stack, so controllers, movement components, and action systems all read from a single consistent source rather than polling hardware directly. Swapping input profiles at runtime — for remapping, controller switching, or accessibility options — requires no change to any downstream component.

For architecture details, component properties, and extending the system in C++, see the Framework API reference.

Input Reactor component in the O3DE Inspector

 

Contents


Pipeline Overview

Unit Input Handling Pattern Graph

Breakdown

The input pipeline has three stages. Each stage is a separate component on the unit entity, and they run in order every frame:

StageComponentWhat It Does
1 — ReadGS_PlayerControllerInputReaderComponentReads raw input events from the active input profile and writes them into GS_InputDataComponent.
2 — StoreGS_InputDataComponentHolds the current frame’s input state — button presses, axis values — as structured data.
3 — ReactReactor componentsRead from GS_InputDataComponent and produce intent: movement vectors, action triggers, etc.

All reactor components downstream of the store stage read from the same GS_InputDataComponent, so there is no duplicated hardware polling and no risk of two reactors seeing different input states for the same frame.


Input Data Component

GS_InputDataComponent is the shared state store. It does not read hardware — it only holds the values written by the Reader and consumed by Reactors.

Add it to any unit entity that needs to process input. A unit should have exactly one GS_InputDataComponent. All input reactors on the same entity read from it automatically.


Input Reader

GS_PlayerControllerInputReaderComponent connects the unit to the game’s active input profile. It receives input events from the profile and writes the resulting state into the unit’s GS_InputDataComponent each frame.

When the player controller possesses the unit, the reader activates. When the unit is depossessed or control is handed to an AI controller, the reader goes silent and the Input Data component retains its last-written state until overwritten.

Setup

Add GS_PlayerControllerInputReaderComponent to the unit entity alongside GS_InputDataComponent. No additional configuration is required — it picks up the active input profile automatically.

Script Canvas - Enabling and Disabling Input Groups

Input Groups handling nodes in the O3DE Script Canvas


Input Reactors

Reactors are the components that transform stored input state into useful intent values. Each reactor handles one concern:

ComponentInput SourceOutput
GS_InputReactorComponentBase class — reads from GS_InputDataComponent.Override to produce custom intent.
GS_InputAxisReactorComponentAxis values from GS_InputDataComponent.Processed axis output (scaled, deadzoned).
KeyboardMovement_InputReactorComponentKeyboard directional buttons (WASD / arrow keys).Normalized 3D movement vector.
JoyAxisMovement_AxisReactorComponentJoystick axis pair from GS_InputDataComponent.Scaled, deadzoned 3D movement vector.

Add as many reactors as your unit needs. A typical ground character has both KeyboardMovement_InputReactorComponent and JoyAxisMovement_AxisReactorComponent active so it responds to either keyboard or gamepad input without requiring separate prefabs.


Keyboard Movement Reactor

KeyboardMovement_InputReactorComponent reads the four directional button states from GS_InputDataComponent and produces a normalized movement vector. The vector direction is relative to the unit’s forward axis, so rotating the unit automatically adjusts the movement direction without any additional calculation.

The reactor writes the resulting vector into a movement data field that the active mover reads each frame.

ScriptCanvas — Reading the Movement Vector

You generally do not need to read the movement vector directly — the mover components consume it automatically. However, if you need to inspect or override it:

// Use only if you need to inspect or override the movement vector — movers consume it automatically
[On Tick]
    └─► [GS_InputDataComponent → GetMovementVector]
            └─► Vector3 — current frame's movement intent

Joystick Axis Reactor

JoyAxisMovement_AxisReactorComponent reads a pair of axis values (horizontal and vertical) from GS_InputDataComponent and applies deadzone filtering and magnitude scaling before writing the resulting vector. This prevents stick drift at rest and allows variable-speed movement when the stick is partially deflected.

SettingEffect
DeadzoneAxis values below this threshold are treated as zero.
ScaleMultiplier applied after deadzone removal.
Axis mappingWhich input profile axis pair to read (left stick, right stick, etc.).

Adding Custom Reactors

To handle input not covered by the built-in reactors — jumping, sprinting, interaction, ability activation — extend GS_InputReactorComponent or GS_InputAxisReactorComponent in C++. Your reactor reads from GS_InputDataComponent the same way the built-in ones do, so it automatically benefits from any input profile that writes to those fields.

For the C++ extension guide, see the Framework API reference.


Quick Reference

NeedComponentNotes
Store input state on a unitGS_InputDataComponentRequired on every unit that processes input.
Read from active input profileGS_PlayerControllerInputReaderComponentActivates automatically when player controller possesses.
Keyboard → movement vectorKeyboardMovement_InputReactorComponentReads WASD / arrow keys from input data.
Joystick → movement vectorJoyAxisMovement_AxisReactorComponentReads axis pair, applies deadzone and scale.
Custom button or axis handlerExtend GS_InputReactorComponent (C++)Reads from GS_InputDataComponent same as built-ins.
Inspect movement vectorGS_InputDataComponent → GetMovementVectorVector3, current frame’s movement intent.

Glossary

TermMeaning
Input Data ComponentThe shared state store that holds the current frame’s input values for a unit
Input ReaderThe component that reads raw input events from the active input profile and writes them into the Input Data Component
Input ReactorA component that reads from the Input Data Component and produces intent values (movement vectors, action triggers)
Movement VectorA normalized 3D direction produced by input reactors and consumed by movers

For full definitions, see the Glossary.


See Also

For the full API, component properties, and C++ extension guide:

For related systems:


Get GS_Unit

GS_Unit — Explore this gem on the product page and add it to your project.

4 - Units

What makes an entity a unit — the GS_UnitComponent, entity configuration, collision setup, possession, standby, and movement.

A “unit” in GS_Play is any entity that can be possessed by a controller and driven through gameplay. The GS_UnitComponent is the marker that transforms an ordinary entity into a unit — it provides the possession interface, unique naming, standby awareness, and automatic registration with the Unit Manager.

Units are the characters, vehicles, creatures, or any other controllable actors in your game. They do not contain decision-making logic themselves — that comes from the controller that possesses them. A unit provides the body: movement, collision, and visuals. The controller provides the brain: player input or AI logic.

For architecture details, component properties, and extending the system in C++, see the Framework API reference.

Unit component in the O3DE Inspector

 

Contents


How Units Work

Registration

When a GS_UnitComponent activates, it registers itself with the Unit Manager. The manager tracks all active units and responds to CheckIsUnit queries. When the component deactivates, it unregisters automatically.

Possession

Units are possessed by controllers through the UnitRequestBus:

  1. A controller calls Possess(controllerEntityId) on the unit.
  2. The unit stores the controller reference and broadcasts UnitPossessed on UnitNotificationBus.
  3. The controller can now drive the unit’s subsystems (movement, actions, etc.).
  4. Calling DePossess() clears the controller reference and releases the unit.

Standby

Units participate in the standby system for clean level transitions. When the Unit Manager signals standby, the unit broadcasts UnitEnteringStandby on its notification bus. Child components — movers, input reactors, and others — listen for this signal and pause their processing. UnitExitingStandby reverses the process.


Entity Configuration

A minimal unit entity requires:

  1. GS_UnitComponent — Registers the entity as a unit and provides the possession interface.
  2. Movement components — At least a mover and optionally a grounder for ground detection.
  3. PhysX collider — For physics interaction and ground detection raycasts.

A fully featured unit entity typically includes:

ComponentRole
GS_UnitComponentMarks the entity as a unit; handles possession and standby.
GS_MoverContextComponentCoordinates movers and grounders; holds the Movement Profile.
A mover (e.g. GS_3DSlideMoverComponent)Defines how the unit moves each frame.
A grounder (e.g. GS_PhysicsRayGrounderComponent)Detects surface contact and reports ground state.
PhysX Rigid Body + ColliderPhysics presence in the world.
Mesh or Actor componentVisual representation.

 

Entity Arrangement

Unit entity setup in the O3DE Editor

Entity arrangement


Collision Setup

Units require properly configured PhysX collision layers to interact with the environment and other units. If you have not set up collision layers yet, refer to the Simple Project Setup guide.

Typical collision layer assignments:

LayerPurpose
Unit layerThe unit’s own collider. Collides with environment geometry and other units.
Ground detection layerUsed by grounder raycasts. Collides with terrain and walkable surfaces only.

Movement

The Movement feature set is a composable stack where each component handles one concern of character locomotion. Movers define core behavior (free, strafe, grid, slide), the MoverContext manages movement state and selects the active mover, Grounders report ground state, and Influence components apply external forces like wind or currents.

Movement API


Quick Reference

NeedBusMethod
Assign a controller to this unitUnitRequestBus (ById)Possess(controllerEntityId)
Release the current controllerUnitRequestBus (ById)DePossess()
Get the possessing controllerUnitRequestBus (ById)GetController()
Get the unit’s unique nameUnitRequestBus (ById)GetUniqueName()

 

EventBusFired When
UnitPossessedUnitNotificationBusA controller takes possession of this unit.
UnitEnteringStandbyUnitNotificationBusThe unit is entering standby (level transition).
UnitExitingStandbyUnitNotificationBusThe unit is exiting standby and resuming.

Glossary

TermMeaning
UnitAny entity with a GS_UnitComponent — the controllable body in gameplay
ControllerThe intelligence (player or AI) that possesses and drives a unit
PossessionThe act of a controller claiming ownership of a unit via Possess()
StandbyA paused state units enter during level transitions, coordinated by the Unit Manager
Unique NameAn identifier generated at activation used to look up a unit by name

For full definitions, see the Glossary.


See Also

For the full API, component properties, and C++ extension guide:

For related systems:


Get GS_Unit

GS_Unit — Explore this gem on the product page and add it to your project.

4.1 - Mover Context

Movement state coordinator for GS_Unit — manages movement modes, context states, input axis transformation, and movement profile priority.

GS_MoverContextComponent is the coordinator that sits above the movers and owns the movement state for a unit. It does not move the character itself — it decides which mover runs, transforms input into the correct movement vector, and exposes state to every other system that needs to know what the character is doing.

Add exactly one GS_MoverContextComponent to any unit that uses movers.

For architecture details, component properties, and extending the system in C++, see the Framework API: Mover Context.

Mover Context component in the O3DE Inspector

 

Contents


Movement Modes

The Mover Context uses three independent mode tracks — movement, rotation, and grounding — each holding a named string. Only the mover or grounder whose assigned mode name matches the active mode on that track will run. All others stay dormant.

TrackControlsExample modes
MovementWhich mover applies velocity each frame"Free", "Slide"
RotationWhich component rotates the character"Free", "Locked"
GroundingWhich grounder runs surface detection"Free", "Disabled"

The three tracks are independent — changing the movement mode does not reset rotation or grounding.

Reverting Modes

Every mode change stores the previous value. Calling RevertToLastMovementMode, RevertToLastRotationMode, or RevertToLastGroundingMode restores it. This is how the Slide mover hands control back to Free movement after a slope is cleared — without needing to know what mode was active before.


Context States

Context states are named key/value pairs stored on the Mover Context. Any component can write or read them via MoverContextRequestBus. They provide a lightweight shared blackboard for movement systems to coordinate without direct dependencies.

Built-in StateValuesMeaning
"grounding"0 — FallingNo surface contact.
1 — GroundedStable surface contact.
2 — SlidingSurface too steep to stand. Slide mover will activate.
"StopMovement"1 — ActiveHalts all mover velocity processing for this frame.

The grounder writes "grounding" each frame. The Slide mover writes it back to 0 or 1 when the slope clears. Your own companion components can write custom states in the same way.


Input Axis Transformation

The Mover Context processes raw input through two transformations before handing it to the active mover.

StepMethodWhat It Does
Raw inputSetMoveInputAxisWritten by the input reactor. Screen-space direction.
1 — Camera-relativeModifyInputAxis()Rotates the axis to align with the active camera’s facing.
2 — Ground-projectedGroundInputAxis()Projects onto the contact surface to prevent skating above or below terrain.

Movers read the ground-projected axis. Both intermediate values are available via bus if a component needs an earlier stage.


Movement Profile Priority

The Mover Context resolves which GS_UnitMovementProfile governs the unit’s locomotion parameters at runtime using a priority stack:

  1. Influence fields — Any MovementInfluenceFieldComponent or GlobalMovementInfluenceComponent that has added a profile to the unit. Highest priority. Multiple influences are stacked additively.
  2. Global profile — The scene-level default from GlobalMovementRequestBus. Applied when no influence overrides are active.
  3. Default profile — The profile assigned directly to the GS_MoverContextComponent. Used as the final fallback.

To change a unit’s movement feel in a specific area, place a MovementInfluenceFieldComponent with a volume shape and assign an alternate profile to it. The unit’s own component property does not need to change.


Script Canvas Examples

Changing movement mode:

Script Canvas nodes for changing movement mode

Reverting to the previous movement mode:

Script Canvas nodes for reverting movement mode

Setting a context state flag:

Script Canvas nodes for setting context state


Quick Reference

NeedBusMethod
Change active movement modeMoverContextRequestBusChangeMovementMode(modeName)
Restore previous movement modeMoverContextRequestBusRevertToLastMovementMode()
Read the ground-projected inputMoverContextRequestBusGetGroundMoveInputAxis()
Write a context stateMoverContextRequestBusSetMoverState(name, value)
Read a context stateMoverContextRequestBusGetMoverState(name)
Push a movement profile overrideMoverContextRequestBusAddMovementProfile(influencer, profile)
Remove a profile overrideMoverContextRequestBusRemoveMovementProfile(influencer)
Listen for mode changesMoverContextNotificationBusMovementModeChanged, GroundingModeChanged
Listen for state changesMoverContextNotificationBusMoverStateChanged

Glossary

TermMeaning
Mover ContextThe coordinator component that owns movement state, selects the active mover, and transforms input each frame
Movement ModeA named string on a mode track that determines which mover or grounder is active
Context StateA named key/value pair on the Mover Context used as a shared blackboard between movement components
Input AxisThe movement direction written by input reactors, transformed through camera-relative and ground-projected stages
Movement ProfileA data asset storing locomotion parameters (speed, acceleration, jump force) for a unit

For full definitions, see the Glossary.


See Also

For the full API, component properties, and C++ extension guide:

For related systems:


Get GS_Unit

GS_Unit — Explore this gem on the product page and add it to your project.

4.2 - Movement

How to work with GS_Unit movement — mover types, mover context, grounders, movement profiles, and influence fields.

The Movement system is a composable stack of components that each handle one concern of character locomotion. Movers define the core behavior, grounders report surface contact, the Mover Context manages which mover is active and what movement state the character is in, influence fields apply external forces, and Movement Profiles store the parameters that govern all of it. You assemble what you need — most characters use two or three components — and replace individual pieces without touching anything else.

For architecture details, component properties, and extending the system in C++, see the Framework API reference.

 

Contents


How it Works

Movers & Grounders Pattern Graph

Breakdown

Movers and Grounders are multiple components on a Unit that are constantly changing activation based on the units state. When a mover is active, it freely processes the unit’s movement based on it’s functionality. At any moment, through internal or external forces, the Movement, Rotation, or Grounding state can change, which disables the old movers, and activates the new one to continue controlling the Unit.

Input
    ↓  InputDataNotificationBus::InputStateChanged
Input Reactor Components
    ↓  MoverContextRequestBus::SetMoveInputAxis
GS_MoverContextComponent
    ↓  ModifyInputAxis() → camera-relative
    ↓  GroundInputAxis() → ground-projected
    ↓  MoverContextNotificationBus::MovementModeChanged("Free")
GS_3DFreeMoverComponent  [active when mode == "Free"]
    ↓  AccelerationSpringDamper → rigidBody->SetLinearVelocity
GS_PhysicsRayGrounderComponent  [active when grounding mode == "Free"]
    ↓  MoverContextRequestBus::SetGroundNormal / SetContextState("grounding", ...)
    ↓  MoverContextRequestBus::ChangeMovementMode("Slide")  ← when slope too steep
GS_3DSlideMoverComponent  [active when mode == "Slide"]

The Slide mover activates when the Unit is walking on too steep an angle. It takes control over the unit, slides down the hill, then restores the previous movement behaviour.


Mover Types

Mover component in the O3DE Inspector

Each mover defines one locomotion behavior. A unit has one active mover at a time, selected by the Mover Context. All movers read from the unit’s movement vector (produced by the input pipeline) and translate it into entity movement each frame.

ComponentBest ForHow It Moves
GS_3DFreeMoverComponentFlying, swimming, zero-gravityUnconstrained motion in all three axes. No ground contact required.
GS_3DSlideMoverComponentGround-bound characters on uneven terrainSlides the character along the contact surface, maintaining ground contact smoothly.
GS_PhysicsMoverComponentCharacters needing full collision responseDrives an O3DE physics rigid body. Forces and impulses apply normally.

Choosing a Mover

  • Use GS_3DFreeMoverComponent for any character that needs to move through air or water without ground contact.
  • Use GS_3DSlideMoverComponent for most ground-bound characters. It handles slopes and steps without requiring physics simulation.
  • Use GS_PhysicsMoverComponent when the character must interact physically with the world — pushing objects, being knocked back by forces, or responding to physics joints.

Mover Context

GS_MoverContextComponent sits above the movers and coordinates everything: it selects which mover runs each frame, owns the movement mode tracks, transforms raw input into camera-relative and ground-projected vectors, and manages the movement profile priority stack.

Add exactly one to any unit that uses movers.

Mover Context →


Grounders

Grounder component in the O3DE Inspector

Grounders detect whether the character has contact with a surface and report that information to the Mover Context. Without a grounder, the Context cannot distinguish ground-bound from airborne states.

ComponentMethodNotes
GS_GrounderComponentBase class — extend for custom detection logic.Not used directly.
GS_PhysicsRayGrounderComponentFires a downward raycast each frame.Suitable for most characters. Configurable ray length and collision layer.

Add one grounder to a unit that uses GS_3DSlideMoverComponent or any mover that needs ground awareness. GS_3DFreeMoverComponent does not require a grounder because it never needs ground contact.


Movement Profiles

Movement Profile asset in the O3DE Asset Editor

GS_UnitMovementProfile is a data asset that stores all locomotion parameters for a unit configuration: walk speed, run speed, acceleration, deceleration, air control, jump force, and any mover-specific values. The Mover Context component holds a reference to a profile asset, so multiple prefabs can share the same profile or each have their own without duplicating inline values.

Creating a Profile

  1. In the O3DE Asset Browser, right-click and select Create Asset → GS_UnitMovementProfile.
  2. Configure the parameters in the asset editor.
  3. Assign the asset to the Movement Profile slot on GS_MoverContextComponent.

Changing a profile asset at runtime allows you to alter all locomotion parameters at once — for example, switching a character between normal and encumbered movement profiles without touching individual component properties.

Reading Movement Profile Data - ScriptCanvas


Influence Fields

Movement Influence component in the O3DE Inspector

Influence components dynamically apply priority that change a units dominant movement profile. Priority values are additive — a unit accumulates priority values from all active sources and evaluate the final priority to determine the acting movement profile.

ComponentScopeTypical Use
GlobalMovementInfluenceComponentAll units globallyStandard movement for the region.
MovementInfluenceFieldComponentUnits inside a spatial volumeOpen fields, narrow channels, indoors and outdoors transitions.

GlobalMovementInfluenceComponent is placed once in the level, usually on the Stage Data entity. MovementInfluenceFieldComponent uses a shape component to define its volume — place one wherever you need to change movement priority.


Assembly Guide

A typical ground-bound player character uses this component combination:

ComponentRole
GS_InputDataComponentHolds input state — movement vector written here each frame.
GS_PlayerControllerInputReaderComponentReads input profile and fills GS_InputDataComponent.
KeyboardMovement_InputReactorComponentConverts keyboard input to movement vector.
JoyAxisMovement_AxisReactorComponentConverts joystick input to movement vector.
GS_PhysicsRayGrounderComponentDetects ground contact below the character.
GS_MoverContextComponentCoordinates grounders and movers, holds the Movement Profile.
GS_3DSlideMoverComponentMoves the character along the contact surface.

A flying or swimming character replaces the grounder and slide mover with GS_3DFreeMoverComponent and removes the grounder entirely.


Quick Reference

NeedComponentNotes
Free 3D movement (fly / swim)GS_3DFreeMoverComponentNo ground contact required.
Surface-hugging ground movementGS_3DSlideMoverComponentSmooth contact on slopes and steps.
Physics-simulated movementGS_PhysicsMoverComponentFull rigid body collision response.
Coordinate movers and stateGS_MoverContextComponentRequired on any unit with movers.
Raycast ground detectionGS_PhysicsRayGrounderComponentUsed with slide and physics movers.
Shared locomotion parametersGS_UnitMovementProfile (asset)Referenced by GS_MoverContextComponent.
Global force on all unitsGlobalMovementInfluenceComponentStandard movement values.
Localized force in a volumeMovementInfluenceFieldComponentNarrow paths, roughage, indoors to outdoors.

Glossary

TermMeaning
MoverA component that defines one locomotion behavior (free flight, surface sliding, physics-driven)
Mover ContextThe coordinator that tracks movement state and selects the active mover each frame
GrounderA component that detects surface contact and reports ground state to the Mover Context
Movement ProfileA data asset storing all locomotion parameters (speed, acceleration, jump force) for a unit
Influence FieldA component that applies additive priority to a units active movement profile

For full definitions, see the Glossary.


See Also

For the full API, component properties, and C++ extension guide:

For related systems:


Get GS_Unit

GS_Unit — Explore this gem on the product page and add it to your project.