V.3.0.0

  • Getting started
  • Demo Tutorials
  • Feature Tutorials
  • Assets

Lyra Sprint

Advanced Movement System is a plugin that you can easily integrate into your Unreal Engine projects.

Introduction

The goal here is simple: the CharacterMovementComponent is responsible only for the actual execution of sprinting (i.e., modifying movement speed), while GAS (Gameplay Ability System) fully handles the gameplay logic surrounding sprinting—such as activation, deactivation, cancellation, blocking, and various conditions.

This separation brings several advantages:

  • 🔄 Centralized sprint logic inside Abilities: easier to manage, test, and extend.

  • đź”’ Ability to block or force sprinting using gameplay tags (e.g., fatigue, buffs, control effects).

  • 🎮 Natural integration with Lyra’s input system and gameplay events.

alt text

Gameplay Ability

To handle sprinting in our system, we have a dedicated Gameplay Ability named ULyraGameplayAbility_Sprint, which is very simple and inherits from the ULyraGameplayAbility class provided by the Lyra framework.

This ability contains two methods:

  • StartSprinting

  • StopSprinting

These methods are called when the ability is activated or ended, and they simply delegate the action to the ACharacter, which already contains the StartSprinting and StopSprinting functions as part of its own movement logic.

alt text

In the constructor of this ability, we simply call the parent class constructor. This constructor sets up the ability to allow immediate client-side activation. At the same time, a request is sent to the server, which then validates or cancels the activation based on the game’s rules.

alt text

Our CharacterMovementComponent includes a method called CanSprint, which is initially used by the ULyraGameplayAbility_Sprint ability—specifically in the CanActivateAbility function—to determine whether the character is allowed to sprint.

However, it's important to note that CanSprint is also called continuously while the character is sprinting, directly from the CharacterMovementComponent, to ensure that sprint conditions remain valid.

If any condition is no longer met (for example, the character falls off a cliff), this method calls InterruptSprint to automatically stop the sprint. This is a useful and intuitive behavior in a traditional movement system.

However, in a project using the GAS (Gameplay Ability System), it is not recommended to let a component like the CharacterMovementComponent directly handle the deactivation of a gameplay state such as sprinting. This responsibility belongs to the Ability System, which is designed to manage such transitions in order to centralize gameplay rules and maintain consistent state logic (buffs, restrictions, interruptions, etc.).

âś… How to properly handle this with GAS

The solution is simple: 👉 We just need to completely override the InterruptSprint method in our ULyraCharacterMovementComponent so that it no longer directly interrupts the sprint, but instead triggers a Gameplay Event (GameplayEvent.InterruptSprint).

Then, inside our ULyraGameplayAbility_Sprint, we listen for this event and call EndAbility or CancelAbility to properly stop the sprint through the GAS system, respecting its synchronization and prediction rules.

alt text

That's all for the C++ setup. Now let's move on to the Blueprint part.

In our case, we are using an ability Blueprint named GA_Hero_Sprint, which inherits from the ULyraGameplayAbility_Sprint class defined in C++. This ability calls the StartSprinting method when activated, and StopSprinting when the ability ends, through a call to EndAbility.

It is also in this ability Blueprint that we listen for our Gameplay Event (GameplayEvent.InterruptSprint) emitted by the CharacterMovementComponent. When this event is received, the ability simply calls EndAbility, which properly stops the sprint via the GAS, while respecting network logic, prediction, and any gameplay effects.

alt text
alt text

Triggering Ability via Player Input

To bind an Ability to player inputs in Lyra, you need to follow two main steps:

Define the input in the Input Data Asset

In the InputData_Hero Data Asset, I added a new entry to the AbilityInputActions list.

This entry includes:

  • An InputAction, which corresponds to the specific input action.

  • An InputTag, which serves as a semantic identifier to link this input to the corresponding Ability in the system.

alt text

Associate the Ability in the Ability Set Data Asset

Then, in the AbilitySet_ShooterHero Data Asset, I added a new entry to the GrantedGameplayAbilities list.

This entry contains:

  • The Ability we want to grant.

  • The level of this Ability.

  • The corresponding Input Tag, which links the input to the activation of the Ability.

alt text

Thanks to this setup, when the player presses the key associated with sprinting, the event is automatically detected and triggers the activation of the linked Ability.

Blocking Sprint While Aiming

By default, after adding sprinting, it was possible to aim while the character was running. However, in most shooter games, aiming with a weapon automatically cancels sprinting for consistency and gameplay reasons.

Aiming is handled by the GA_ADS ability. So, one might be tempted to block the sprint ability by adding its tag to the BlockAbilitiesWithTag or CancelAbilitiesWithTag properties of the aiming ability.

That would work, but Lyra offers a more modular and centralized approach: using a GameplayTagRelationshipMapping Data Asset, such as the TagRelationships_ShooterHero file.

This system allows you to define, in a single place, the hierarchical relationships between gameplay tags, and therefore:

  • Tags that block other abilities,

  • Tags that cancel certain active abilities,

  • And even tags that can replace or precede other actions.

By using this Data Asset, you maintain a clean, easily manageable configuration that is decoupled from the ability code. This greatly simplifies the evolution of the project (adding new abilities, changing interactions, etc.), while allowing dynamic adaptation of blocking or canceling rules depending on the game context, such as a specific experience or an activated Game Feature.

alt text

And there you have it! Our sprint is automatically blocked as soon as the player aims.

Stamina Management

To manage sprint stamina, I added a ULyraStaminaSet component that inherits from the ULyraAttributeSet component, as well as a dedicated ULyraStaminaComponent to handle the stamina-related logic.

LyraStaminaSet

An AttributeSet is a class used in the Gameplay Ability System (GAS) to define and store a character's attributes (such as health, stamina, damage, etc.).

It allows you to:

  • Centralize gameplay-modifiable values.

  • React to changes through functions like PreAttributeChange or PostGameplayEffectExecute.

  • Automatically handle network replication.

  • Connect these data to Abilities and GameplayEffects.

Our ULyraStaminaSet component has 3 attributes:

alt text

Stamina:

  • The character’s current stamina value.

  • Decreases when the character expends energy.

  • Increases with buffs.

  • If it reaches 0, it triggers the OnOutOfStamina event.

MaxStamina:

  • The maximum stamina value the character can have.

  • Serves as an upper limit for Stamina.

  • Can be modified by effects (buffs, passives, equipment, etc.).

  • Often used to display a full stamina bar (Stamina / MaxStamina).

StaminaRegen:

  • A transient attribute used to regenerate the character’s stamina.

  • It does not represent a permanent state like Stamina but rather a temporary value.

  • When an effect is applied, StaminaRegen is set and then converted into Stamina gain in PostGameplayEffectExecute.

LyraStaminaComponent

This component allows connection to the AbilitySystemComponent to access the AttributeSet containing the stamina attributes.

The connection is made via the InitializeWithAbilitySystem method, which is responsible for:

  • Retrieving the AttributeSet,

  • Subscribing to the necessary events,

  • And preparing the stamina management logic.

This method should be called in OnAbilitySystemInitialized, usually from the LyraCharacter, to ensure that the ability system is fully ready.

alt text

The LyraStaminaComponent also has an UninitializeFromAbilitySystem method, which allows it to cleanly disconnect from the AbilitySystemComponent.

Its role is to:

  • 🔌 Unsubscribe the component from attribute-related events (such as stamina changes),

  • đź§ą Clean up internal references (e.g., pointers to the AttributeSet, timers, delegates),

  • 🛑 Stop any ongoing logic (like automatic regeneration or active callbacks).

alt text

The component also has an important method: HandleOutOfStamina.

HandleOutOfStamina acts as a callback, automatically triggered when stamina reaches zero. It is connected to the OnOutOfStamina event of the AttributeSet and is used to notify the ability system via a Gameplay Event. This allows our GA_Hero_Sprint ability to be informed of the character’s exhaustion and react accordingly.

alt text
alt text

Gameplay Effects

To reduce the player’s stamina while sprinting, we use a Gameplay Effect named GE_Sprint_Stamina. This GE directly modifies the Stamina attribute with a negative value, allowing the GAS system to automatically check if the player has enough stamina before activating the Ability. It is assigned to the CostGameplayEffectClass field in the sprint Ability and is applied automatically when CommitAbility is called. If the available stamina is insufficient, the Ability automatically fails without being activated.

alt text
alt text

To allow stamina regeneration outside of sprinting, we use a Gameplay Effect called GE_Sprint_RegenStamina. It modifies the StaminaRegen attribute, which is then processed in the AttributeSet to increase the current stamina value. This Gameplay Effect is added to the DefaultGameplayEffects array in the Character_Default blueprint, enabling it to be automatically applied to the character upon initialization, without needing manual activation through an Ability. This system ensures passive stamina regeneration as long as certain conditions are met: the character is not sprinting, is not dead, and no cooldown period is active.

alt text
alt text

To temporarily prevent stamina regeneration after stopping the sprint, we use a Gameplay Effect called GE_Sprint_StaminaCooldown. When applied, it adds the tag Status.Sprinting_Cooldown to the character. This tag is then used as a condition in GE_Sprint_RegenStamina, via the Must Not Have Tags field, to block regeneration while the cooldown is active. GE_Sprint_StaminaCooldown is applied in the GA_Hero_Sprint Ability through a call to ApplyGameplayEffectToOwner triggered in the OnEndAbility function. This introduces a short delay between the end of sprinting and the resumption of stamina regeneration.

alt text
alt text