Skip to content

How to customize Motion movement behavior

Practical examples of frequently requested modifications to Motion's movement system.

Behavior-defining defaults live on component profile assets. For project tuning, duplicate the assigned Motion profile into your project content, edit the duplicate, and assign it back to the component's Profile property. See Component profiles for the complete profile workflow.

Adding Stamina Drain to Sprint

Motion's sprint component includes built-in stamina support. Here's how to enable and customize it.

Enable Stamina System

  1. Duplicate the assigned sprint profile.
  2. Set bUseStaminaSystem = true.
  3. Configure stamina thresholds:
PropertyDescriptionRecommended
MinStaminaToSprintStamina needed to START1.5
MinStaminaToStopSprintingStamina to CONTINUE (hysteresis)0.25
RegenDelayDurationSeconds before regen after exhaustion2.0

Configure Stamina Effects

Assign these GameplayEffects on the sprint profile:

SprintStaminaDrainEffect = GE_Motion_SprintStaminaDrain
StaminaRegenEffect = GE_Motion_SprintStaminaRegen
StaminaRegenDelayEffect = GE_Motion_SprintStaminaRegenDelay

Custom Drain Rate

Create a custom GameplayEffect Blueprint:

  1. Duplicate GE_Motion_SprintStaminaDrain
  2. Modify the periodic effect magnitude
  3. Assign your custom effect to the sprint profile

Blueprint: React to Exhaustion

text
Event OnSprintStaminaDepleted
├── Play Sound (Exhaustion_SFX)
├── Play Camera Shake (Exhaustion_Shake)
└── Show UI Warning

Modifying Jump Behavior

Add Multi-Jump

Duplicate the assigned jump profile, then:

  1. Set bEnableMultiJump = true.
  2. Set MaxAdditionalJumps = 1 for double jump, or more for triple jump.
  3. Optionally set AdditionalJumpVelocityMultiplier = 0.8, or lower for weaker subsequent jumps.

Adjust Jump Height

Method 1: Jump profile values

JumpVelocityMultiplier = 1.2  // Multiply base jump velocity by 1.2
// OR
JumpVelocityModifier = 200.0  // Add 200 units to jump velocity

Method 2: GAS Attribute (dynamic)

text
// Create a GameplayEffect that modifies JumpVelocity attribute
// Apply the effect for temporary jump boosts

Add Coyote Time

On the assigned jump profile:

  1. Set CoyoteTime = 0.15 seconds after leaving ground, or 0 to disable.

Add Jump Buffer

On the assigned jump profile:

  1. Set JumpBufferTime = 0.2 seconds before landing, or 0 to disable.

Adding Movement Speed Buffs/Debuffs

Create Speed Modifier Effect

  1. Create new GameplayEffect Blueprint
  2. Configure:
    • Duration: Duration or Infinite
    • Modifier: Attribute = WalkSpeed, Op = Additive or Multiplicative
    • Magnitude: Your speed change value

Apply from Blueprint

text
Get Ability System Component
├── Make Outgoing Spec (YourSpeedEffect, Level 1)
└── Apply Gameplay Effect Spec to Self
    └── Store Handle (for later removal)

Apply from C++

cpp
// Apply speed buff
void ApplySpeedBuff(float SpeedBonus, float Duration)
{
    if (UAbilitySystemComponent* ASC = UMotionAbilitySystemHelper::GetAbilitySystemComponentFromActor(Character))
    {
        FGameplayEffectContextHandle Context = ASC->MakeEffectContext();
        FGameplayEffectSpecHandle Spec = ASC->MakeOutgoingSpec(SpeedBuffEffect, 1.0f, Context);

        // Set magnitude via SetByCaller
        Spec.Data->SetSetByCallerMagnitude(SpeedMagnitudeTag, SpeedBonus);

        SpeedBuffHandle = ASC->ApplyGameplayEffectSpecToSelf(*Spec.Data.Get());
    }
}

Remove the stored SpeedBuffHandle later with RemoveActiveGameplayEffect after checking that the handle is valid.

Creating Custom Movement States

Add a New State Tag

  1. Define your tag in your project's GameplayTags:

    Motion.State.Sliding
    Motion.State.WallRunning
    Motion.State.Swimming
  2. Create a GameplayEffect to grant the tag:

    • Duration: Infinite
    • Granted Tags: Your new state tag

React to Custom State

In Animation Blueprint

Add to GameplayTagPropertyMap:

Tag: Motion.State.Sliding
Property: bIsSliding (Bool)

In Other Components

cpp
bool bIsSliding = UMotionAbilitySystemHelper::ActorHasGameplayTag(
    Character,
    FGameplayTag::RequestGameplayTag(TEXT("Motion.State.Sliding"))
);

Block Other States

Use tag blocking in your GameplayEffect:

Blocked Tags:
- Motion.State.Sprinting
- Motion.State.Jumping

This prevents sprinting or jumping while in your custom state.

Integrating with Ability Cooldowns

Sprint with Cooldown

Override CanStartSprinting() in a C++ child class (Blueprint override not supported):

cpp
// In your C++ child class
class UMySprintComponent : public UMotionSprintingComponent
{
protected:
    virtual bool CanStartSprinting() const override
    {
        if (UAbilitySystemComponent* ASC = GetASC())
        {
            if (ASC->HasMatchingGameplayTag(FGameplayTag::RequestGameplayTag("Ability.Cooldown.Sprint")))
            {
                return false;
            }
        }
        return Super::CanStartSprinting();
    }
};

Jump with Cooldown

Override CanPerformJump() in a C++ child class (Blueprint override not supported):

cpp
// In your C++ child class
class UMyJumpComponent : public UMotionJumpComponent
{
protected:
    virtual bool CanPerformJump() const override
    {
        if (UAbilitySystemComponent* ASC = GetASC())
        {
            if (ASC->HasMatchingGameplayTag(FGameplayTag::RequestGameplayTag("Ability.Cooldown.Jump")))
            {
                return false;
            }
        }
        return Super::CanPerformJump();
    }
};

Note: For Blueprint-accessible cooldown logic, use GAS tag blocking instead.

Apply Cooldown After Action

cpp
void ApplyCooldown(TSubclassOf<UGameplayEffect> CooldownEffect)
{
    if (UAbilitySystemComponent* ASC = GetASC())
    {
        FGameplayEffectContextHandle Context = ASC->MakeEffectContext();
        FGameplayEffectSpecHandle Spec = ASC->MakeOutgoingSpec(CooldownEffect, 1.0f, Context);
        ASC->ApplyGameplayEffectSpecToSelf(*Spec.Data.Get());
    }
}

Adjusting Crouch Speed

Change Speed Modifier

On the assigned crouch profile:

CrouchWalkSpeedModifier = -200.0 (negative to slow down)

Variable Crouch Speed

Create a custom GameplayEffect with SetByCaller magnitude:

cpp
// Apply variable crouch speed
FGameplayEffectSpecHandle Spec = ASC->MakeOutgoingSpec(CrouchSpeedEffect, 1.0f, Context);
Spec.Data->SetSetByCallerMagnitude(
    MotionGameplayTags::SetByCaller_Magnitude_CrouchSpeed,
    CalculatedSpeedModifier
);
ASC->ApplyGameplayEffectSpecToSelf(*Spec.Data.Get());

Adding Camera Effects to Movement

Sprint Camera Shake

On the assigned sprint profile:

  1. Set bApplyCameraShake = true.
  2. Configure the SprintCameraShake curve.

Landing Camera Impact

The MotionJumpComponent already broadcasts landing events. Subscribe in Blueprint:

text
Event OnLanded
├── Get Character Movement Component
├── Get Last Update Velocity → Calculate Impact from Z velocity
├── Create Landing Camera Curve
└── Broadcast to Event Bus (Add)

Extending Component Behavior

Blueprint Child Class

  1. Create Blueprint child of any Motion component
  2. Override virtual functions:
    • CanStartSprinting() - Add custom conditions (C++ only)
    • OnSprintStateChanged() - React to state changes (Blueprint event)
    • UpdateSprintingState() - Modify update logic (C++ only, protected)

C++ Child Class

cpp
UCLASS()
class UMySprintComponent : public UMotionSprintingComponent
{
    GENERATED_BODY()

protected:
    virtual bool CanStartSprinting() const override
    {
        // Add custom logic
        if (!Super::CanStartSprinting())
            return false;

        // Your conditions here
        return bCanSprintBasedOnEquipment;
    }

    virtual void OnSprintStateChanged_Implementation(bool bIsSprinting) override
    {
        Super::OnSprintStateChanged_Implementation(bIsSprinting);

        // Your custom handling
        if (bIsSprinting)
        {
            PlaySprintStartSound();
        }
    }
};

Next steps

Use the reference pages when a customization needs exact API or GAS details.

Motion - Advanced First Person Character Controller