---
title: AFS_UX_Locomotion
product: Advanced Framework Pro
version: 1.0
engine: Unreal Engine 5.8
updated: 2026-10-05
canonical: https://docs.human-codeable.com/plugins/afs-ux-locomotion.html
---

System

# AFS_UX_Locomotion

Smooth movement and snap or smooth turning as controller abilities, with camera- or controller-relative direction.

#### What it gives you

- Thumbstick movement with configurable reference frame
- Snap turn or smooth turn from one component
- Per-hand input binding

#### Requires

None

#### Required by

None

9 assets18 API members

## Description

Locomotion is two independent controller abilities, so you can put movement on one hand and turning on the other — the standard VR arrangement — without either knowing about the other.

`BPC_ControllerAbility_Movement` converts thumbstick input into world movement. **Movement Direction** decides the reference frame: relative to the camera means the player moves where they look, relative to the controller means they can steer with the hand independently of gaze, which some users find more comfortable.

`BPC_ControllerAbility_Turn` handles rotation. Setting **Rotate Step Duration** to zero gives a snap turn; a small non-zero value gives a quick smooth turn. Snap turning is the safer default for comfort.

## Setup

1. Enable `AFS_UX_Locomotion`.
2. Add `BPC_ControllerAbility_Movement` to one motion controller and `BPC_ControllerAbility_Turn` to the other.
3. Assign **Mapping Contexts Default** for the left and right hand.

## Usage

### Comfort settings

Expose **Rotate Step Degree** and **Rotate Step Duration** as game settings — see [Add a setting](../workflows/add-setting.html). Comfort preferences vary enormously between users.

### Blocking movement contextually

Call `setAbilityRestriction` on the pawn with the locomotion tag while a menu is open or an object is held.

[![The pawn mid-turn, snap-turn indicator on screen](../images/AFS_UX_Locomotion_result-1600.webp?v=87e07f36)](../images/AFS_UX_Locomotion_result-1600.webp?v=87e07f36)

The pawn mid-turn, snap-turn indicator on screen

## Key properties

| Property | When to change |
|---|---|
| `Movement Direction` | Camera-relative or controller-relative steering |
| `Movement Speed` | Overall movement multiplier |
| `Rotate Step Degree` | Snap turn increment; 30–45° is typical |
| `Rotate Step Duration` | Zero for snap, small non-zero for quick smooth turn |

## Extending

Derive from either ability to add acceleration curves, dash movement or vignetting.

## Performance notes

Performance

Movement calls `Interface_RecenterCapsule` each frame it moves, which keeps the capsule under the player. This is intentional and inexpensive.

## Example map

`Map_Examples_Locomotion` demonstrates both abilities with configurable settings.

## Troubleshooting

**The player drifts away from the capsule.** `Interface_RecenterCapsule` is not being called — it is invoked by movement, so custom movement code must call it too.

## API reference

Every blueprint asset in this plugin. Expand an asset to see its members.

### Components

**BPC_ControllerAbility_Movement**5 members

extends `BPC_ControllerAbility`

Hand ability turning a thumbstick into smooth locomotion. Movement Direction chooses whether the stick is read against the camera or against the controller, Movement Speed scales the input, and the pawn is recentred under the head before each move. Add it to a motion controller; the pawn has to implement the pawn info contract for the camera to be found.

| Kind | Name | Signature | Description |
|---|---|---|---|
| var | `Movement Direction`Settings | `E_Locomotion_Direction` | Whether the thumbstick moves the player relative to where they are looking or relative to where the controller points. Controller-relative allows steering with the hand independently of gaze. |
| var | `Movement Speed`Settings | `float` | Multiplier applied to movement input. |
| var | `Mapping Contexts Default`Input | `ST_MappingContext_Side` | Input mapping contexts applied for the left and right hand, so movement can be bound to a specific controller. |
| fn | `getControlDirection` | `(Vector2D: Vector2D, out MovementVector: Vector)` | Converts a two-axis input into a world movement direction using the configured movement direction mode. |
| event | `InitiateControllerAbility` | `(Pawn: Pawn, MotionController: Actor, Side: E_Side)` | Sets up the movement ability once the owning motion controller is ready. |

**BPC_ControllerAbility_Turn**6 members

extends `BPC_ControllerAbility`

Hand ability giving one motion controller snap turning. Each flick rotates the pawn by Rotate Step Degree over Rotate Step Duration, behind a cooldown so a held stick cannot turn twice, and it goes through the pawn's teleport ability so the fade matches an ordinary teleport. Add it to a motion controller; without the teleport ability on the pawn nothing turns.

| Kind | Name | Signature | Description |
|---|---|---|---|
| var | `Rotate Step Degree`Settings | `float` | Degrees turned per snap turn input. Set to a small value for near-continuous turning. |
| var | `Rotate Step Duration`Settings | `float` | How long a turn takes, in seconds. Zero gives an instant snap turn, which is more comfortable for many players. |
| var | `Mapping Contexts Default`Input | `ST_MappingContext_Side` | Input mapping contexts applied for the left and right hand. |
| var | `Sound Turn`Sound | `SoundBase` | Sound played on each turn. |
| event | `InitiateControllerAbility` | `(Pawn: Pawn, MotionController: Actor, Side: E_Side)` | Sets up the turn ability once the owning motion controller is ready. |
| event | `Turn` | `(Side: E_Side)` | Turns the player one step in the given direction. |

### Helper

**BP_Helper_ControllerAbility_Movement**1 members

extends `BP_Helper_ControllerAbility`

Input carrier for the movement ability, spawned alongside it. It holds the thumbstick bindings and forwards them to its ability once the hand side matches, since input actions have to live on an actor rather than on a component. Spawned for you, and of interest only when remapping the movement input.

| Kind | Name | Signature | Description |
|---|---|---|---|
| var | `Controller Ability` | `BPC_ControllerAbility_Movement` | The movement ability this helper visualises. |

**BP_Helper_ControllerAbility_Turn**1 members

extends `BP_Helper_ControllerAbility`

Input carrier for the snap turn ability, spawned alongside it. It holds the turn bindings and calls Turn Left or Turn Right on its ability for the matching hand. Spawned for you; touch it only to remap which action turns which way.

| Kind | Name | Signature | Description |
|---|---|---|---|
| var | `Controller Ability` | `BPC_ControllerAbility_Turn` | The turn ability this helper visualises. |

### Settings

**BP_Value_Settings_Boolean_Locomotion_Smooth**1 members

extends `BP_Value_Settings_Bool`

Ready-made toggle for smooth locomotion, activating or blocking the movement ability on both hands. The first comfort setting worth offering, because a player who cannot use it needs teleport instead.

| Kind | Name | Signature | Description |
|---|---|---|---|
| event | `Value_setBoolean`Value_Boolean | `(SourceInfo: ST_SourceInfo, Value: bool)` | Implemented by a boolean value to take a new setting from the pawn described by the source info. Buttons call it when their selection changes. |

**BP_Value_Settings_Boolean_Locomotion_Turn**1 members

extends `BP_Value_Settings_Bool`

Ready-made toggle choosing between snap and smooth turning on the turn ability. Snap is the comfortable default; offer the choice rather than deciding for the player.

| Kind | Name | Signature | Description |
|---|---|---|---|
| event | `Value_setBoolean`Value_Boolean | `(SourceInfo: ST_SourceInfo, Value: bool)` | Implemented by a boolean value to take a new setting from the pawn described by the source info. Buttons call it when their selection changes. |

**BP_Value_Settings_Float_Locomotion_TurnSpeed**1 members

extends `BP_Value_Settings_Float`

Ready-made slider for how long a turn takes. Zero is an instant snap, which most players find most comfortable; raising it animates the turn instead.

| Kind | Name | Signature | Description |
|---|---|---|---|
| event | `Value_setFloat`Value_Float | `(SourceInfo: ST_SourceInfo, Value: float)` | Implemented by a float value to take a new value from the pawn described by the source info. Sliders call it as their handle moves; the drag state reads the value as 0 to 1 across its own range. |

**BP_Value_Settings_Integer_Locomotion_Direction**1 members

extends `BP_Value_Settings_Integer`

Ready-made selector for whether the thumbstick moves the player relative to where they are looking or where the controller points. Head-relative is the more intuitive default; experienced players often prefer hand-relative.

| Kind | Name | Signature | Description |
|---|---|---|---|
| event | `Value_setInteger`Value_Integer | `(SourceInfo: ST_SourceInfo, Value: int)` | Implemented by an integer value to take a new value from the pawn described by the source info. Drop-downs call it when one of their options is chosen. |

**BP_Value_Settings_Integer_Locomotion_SnapAngle**1 members

extends `BP_Value_Settings_Integer`

Ready-made selector for how far a snap turn rotates. Pair it with the turn-style toggle and disable it while smooth turning is chosen, since it has no meaning there.

| Kind | Name | Signature | Description |
|---|---|---|---|
| event | `Value_setInteger`Value_Integer | `(SourceInfo: ST_SourceInfo, Value: int)` | Implemented by an integer value to take a new value from the pawn described by the source info. Drop-downs call it when one of their options is chosen. |
