Movers

Mover base class and concrete mover components — translate MoverContext input into physics-based unit motion via named mode activation.

Movers translate the processed movement input from the MoverContext into physics forces on the unit’s rigid body. Each mover activates for a specific named mode — when the MoverContext broadcasts MovementModeChanged("Free"), only the mover whose m_moveModeName matches "Free" activates. All others deactivate. This makes the locomotion system fully mode-driven and composable.

For usage guides and setup examples, see The Basics: GS_Unit.

Mover component in the O3DE Inspector

 

Contents


Class Hierarchy

GS_MoverComponent (base — mode-aware activation, tick management)
  └── GS_PhysicsMoverComponent (adds RigidBody cache + validity check)
        ├── GS_3DFreeMoverComponent    (mode: "Free")
        └── GS_3DSlideMoverComponent   (mode: "Slide")

GS_MoverComponent (Base)

Tick: AzPhysics::SystemEvents::OnPostSimulateEvent (after the physics step). Optional debugForceTick uses AZ::TickBus for debugging without physics.

Mode-Aware Activation

Listens to MoverContextNotificationBus::MovementModeChanged and RotationModeChanged. Compares the broadcast mode name against its own m_moveModeName and m_rotateModeName. Calls ToggleMovement(true/false) and ToggleRotation(true/false) accordingly. The physics post-simulate handler is only registered when the mover is active, saving ticks when inactive.

Per-Tick Processing

Each tick:

  1. CheckCanOperate() — validates that the required pointers and state are valid
  2. HandleMovement() — calculates and applies movement (no-op in base)
  3. HandleRotation() — calculates and applies rotation (no-op in base)

Key Fields

FieldDescription
m_moveModeNameMode string this mover activates for (set in Activate())
m_rotateModeNameMode string this mover’s rotation activates for
movementActive / rotationActiveWhether movement/rotation processing is currently running
deltaCached frame delta time
activeProfilePointer to current GS_UnitMovementProfile (updated via MovementProfileChanged)
debugForceTickIf true, uses game tick instead of post-simulate (for debugging without physics)

GS_PhysicsMoverComponent

Extends GS_MoverComponent. On activate, fetches AzPhysics::RigidBody* from the entity. CheckCanOperate() verifies the rigid body pointer is valid before allowing tick processing.


Concrete Movers

ComponentMode NameDescription
GS_3DFreeMoverComponent"Free"Standard 3D locomotion — camera-relative, spring-damped velocity and rotation
GS_3DSlideMoverComponent"Slide"Slope-sliding locomotion — activated by the grounder when slope exceeds maxWalkAngle

API Reference

Movers consume two buses and produce one:

Consumed

BusEventDescription
MoverContextNotificationBusMovementModeChanged(modeName)Activates or deactivates movement processing based on mode name match.
MoverContextNotificationBusRotationModeChanged(modeName)Activates or deactivates rotation processing based on mode name match.
MoverContextNotificationBusContextStateChanged(stateName, value)Allows movers to react to state flags (e.g. "StopMovement").
MoverContextNotificationBusMovementProfileChanged(profile*)Updates the cached activeProfile pointer.

Virtual Methods

Override these when extending any mover:

MethodParametersReturnsDescription
ToggleMovementbool onvoidCalled when the movement mode activates or deactivates.
ToggleRotationbool onvoidCalled when the rotation mode activates or deactivates.
HandleMovementvoidCalled each tick when movement is active. Override to implement movement logic.
HandleRotationvoidCalled each tick when rotation is active. Override to implement rotation logic.
CheckCanOperateboolReturns true if the mover has everything it needs to run this tick.

Extension Guide

Use the Mover ClassWizard template to generate a new mover with boilerplate already in place — see GS_Unit Templates. The template offers two base class options: Physics Mover (default) for rigid-body locomotion, and Base Mover for transform-only movement.

Extend GS_PhysicsMoverComponent to create a custom physics-driven mover.

#pragma once
#include <Source/Unit/Mover/GS_PhysicsMoverComponent.h>

namespace MyProject
{
    class MyCustomMover : public GS_Unit::GS_PhysicsMoverComponent
    {
    public:
        AZ_COMPONENT_DECL(MyCustomMover);
        static void Reflect(AZ::ReflectContext* context);

    protected:
        void Activate() override;

        void HandleMovement() override;
        void HandleRotation() override;

    private:
        // Mode name must be set in Activate():
        // m_moveModeName = "MyMode";
        // m_rotateModeName = "MyMode";
    };
}

In HandleMovement(), read from the MoverContext and write to the rigid body:

void MyCustomMover::HandleMovement()
{
    AZ::Vector3* groundedInput = nullptr;
    GS_Unit::MoverContextRequestBus::EventResult(
        groundedInput, GetEntityId(),
        &GS_Unit::MoverContextRequestBus::Events::GetGroundMoveInputAxis
    );

    if (!groundedInput || groundedInput->IsZero()) return;

    AZ::Vector3 targetVelocity = *groundedInput * activeProfile->moveSpeed;
    m_rigidBody->SetLinearVelocity(targetVelocity);
}

See Also


Get GS_Unit

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