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

Return to the regular view of this page.

Grounders

Grounder base class and concrete grounder components — detect ground contact, compute ground normals and slope data, and drive mode switching on the MoverContext.

Grounders run each physics tick to determine whether the unit is in contact with the ground, what the slope looks like, and whether the surface is walkable. They write their findings to the MoverContext and switch movement modes when the ground state changes.

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

Grounder component in the O3DE Inspector

 

Contents


Class Hierarchy

GS_GrounderComponent (base — mode-aware activation, tick management)
  └── GS_PhysicsRayGrounderComponent  (grounding mode: "Free")

GS_GrounderComponent (Base)

Tick: AzPhysics::SystemEvents::OnPostSimulateEvent (after the physics step).

Mode-Aware Activation

Listens to MoverContextNotificationBus::GroundingModeChanged. Compares the broadcast mode name against its own m_groundModeName. Calls ToggleGrounder(true/false) accordingly. The physics post-simulate handler is only registered when the grounder is active.

Per-Tick Processing

Each tick:

  1. CheckCanOperate() — validates required pointers and state
  2. HandleGrounding() — performs ground detection and updates MoverContext (no-op in base)

Key Fields

FieldDescription
m_groundModeNameGrounding mode string this grounder activates for
deltaCached frame delta time

Concrete Grounders

ComponentGrounding ModeDescription
GS_PhysicsRayGrounderComponent"Free"Raycast-based grounder with coyote time, slope detection, and manual gravity

API Reference

Virtual Methods

Override these when extending any grounder:

MethodParametersReturnsDescription
ToggleGrounderbool onvoidCalled when the grounding mode activates or deactivates.
HandleGroundingvoidCalled each tick when the grounder is active. Override to implement ground detection logic.
GroundingStateChangeAZ::u32 newStatevoidCalled when ground contact state changes. Override to react to grounding transitions.
CheckCanOperateboolReturns true if the grounder has everything it needs to run this tick.

Consumed Buses

BusEventDescription
MoverContextNotificationBusGroundingModeChanged(modeName)Activates or deactivates this grounder based on mode name match.

Produced Calls

BusMethodDescription
MoverContextRequestBusSetGroundNormal(normal)Updates the ground normal used by the MoverContext for input projection.
MoverContextRequestBusSetContextState("grounding", value)Sets grounding state: 0 = Falling, 1 = Grounded, 2 = Sliding.
MoverContextRequestBusChangeMovementMode(modeName)Switches to "Slide" when slope exceeds maxWalkAngle, or back to "Free" on recovery.

Extension Guide

Use the Grounder ClassWizard template to generate a new grounder with boilerplate already in place — see GS_Unit Templates. The template offers two base class options: Physics Ray Grounder (default, includes raycast, coyote time, and gravity) or Base Grounder for fully custom detection.

Extend GS_GrounderComponent to implement custom ground detection.

#pragma once
#include <Source/Unit/Grounder/GS_GrounderComponent.h>

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

    protected:
        void Activate() override;

        void HandleGrounding() override;
        void GroundingStateChange(AZ::u32 newState) override;

    private:
        // Set in Activate():
        // m_groundModeName = "Free";
    };
}

In HandleGrounding(), run your detection and write results to the MoverContext:

void MyGrounder::HandleGrounding()
{
    AZ::Vector3 groundNormal = AZ::Vector3::CreateAxisZ();
    bool isGrounded = false;

    // ... custom detection logic ...

    GS_Unit::MoverContextRequestBus::Event(
        GetEntityId(),
        &GS_Unit::MoverContextRequestBus::Events::SetGroundNormal,
        groundNormal
    );

    AZ::u32 state = isGrounded ? 1 : 0;
    GS_Unit::MoverContextRequestBus::Event(
        GetEntityId(),
        &GS_Unit::MoverContextRequestBus::Events::SetContextState,
        "grounding", state
    );
}

See Also


Get GS_Unit

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

1 - 3D Free Grounder

Raycast-based grounder for standard 3D locomotion — detects ground contact with coyote time, applies manual gravity when airborne, switches to Slide mode on steep slopes.

GS_PhysicsRayGrounderComponent is the standard grounder for walking characters. Each physics tick it casts a ray downward from the unit’s capsule base, evaluates the slope, applies gravity when airborne, and updates the MoverContext with ground normal and grounding state.

Grounding mode name: "Free"

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

Grounder component in the O3DE Inspector

 

Contents


How It Works

Each post-physics tick, the grounder runs two operations in order:

  1. GroundCheck() — determines contact, slope, and normal
  2. GroundingMove() — applies gravity or snap force based on contact result

Ground Check

GroundCheck() casts a sphere (matching the capsule base radius) downward from the unit’s feet:

  1. If the ray hits geometry within groundCheckDistance:
    • Computes slope angle from the hit normal vs. world up.
    • Updates MoverContextRequestBus::SetGroundNormal(hitNormal).
    • If slope angle ≤ maxWalkAngle (from the MoverContext): reports Grounded.
    • If slope angle > maxWalkAngle: reports Sliding.
    • Resets coyote timer.
  2. If no hit:
    • Increments coyoteTimer.
    • If coyoteTimer < coyoteTime: still reports Grounded (coyote grace period).
    • If coyoteTimer ≥ coyoteTime: reports Falling.

Grounding Move

GroundingMove() applies vertical forces based on the current state:

Grounded: Applies a downward TimedSpringDamper to keep the unit snapped to the surface without bouncing.

Falling: Applies manual gravity — adds gravityScale * AZ::Physics::DefaultGravity to the rigid body’s linear velocity each frame:

AZ::Vector3 velocity = rigidBody->GetLinearVelocity();
velocity.SetZ(velocity.GetZ() + gravity * delta);
rigidBody->SetLinearVelocity(velocity);

Sliding: Does not override vertical velocity — the Free Mover’s AccelerationSpringDamper handles the slide direction entirely.


Grounding State Changes

GroundingStateChange(newState) is called whenever the ground state changes:

StateValueTriggerAction
Falling0Lost ground contact beyond coyote timeSetContextState("grounding", 0)
Grounded1Ray hit within walkable angleSetContextState("grounding", 1)
Sliding2Ray hit but slope > maxWalkAngleSetContextState("grounding", 2), ChangeMovementMode("Slide")

When returning to Grounded from Sliding, the grounder calls ChangeMovementMode("Free") to restore locomotion.


Editor-Exposed Settings

FieldDefaultDescription
groundCheckDistance0.15Raycast distance below the capsule base to detect ground.
capsuleRadius0.3Radius of the sphere used for the downward cast (should match capsule).
coyoteTime0.12Seconds of grace period before reporting Falling after losing ground contact.
gravityScale1.0Multiplier on AZ::Physics::DefaultGravity applied when airborne.
snapHalflife0.05Spring halflife for the ground-snap TimedSpringDamper. Smaller = tighter snap.

Extension Guide

Extend GS_PhysicsRayGrounderComponent to add custom ground detection or state reactions.

#pragma once
#include <Source/Unit/Grounder/GS_PhysicsRayGrounderComponent.h>

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

    protected:
        void GroundingStateChange(AZ::u32 newState) override;
    };
}
void MyGrounder::GroundingStateChange(AZ::u32 newState)
{
    // Call base to handle mode switching
    GS_PhysicsRayGrounderComponent::GroundingStateChange(newState);

    if (newState == 0)
    {
        // Unit became airborne — trigger jump animation, etc.
    }
}

See Also

  • Grounders — Grounder base class and class hierarchy
  • Slide Mover — Activated when this grounder reports Sliding state
  • Mover Context — Receives ground normal and state from this grounder
  • Springs UtilityTimedSpringDamper used for ground snap

Get GS_Unit

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