Introduction
OmniWalk is a high-performance, **C++ middleware framework** engineered specifically for Unreal Engine 5.4+. It bridges the technical gap between native physics and high-fidelity "Magneboot" locomotion, allowing characters to traverse **arbitrary geometry**—from spherical planets to interior pipe networks—with zero world-axis constraints.
The Locomotion Paradox
In standard Unreal Engine setups, CharacterMovement is tied to the World Z-Axis. When rotation exceeds 90°, capsule rejection and camera gimbal-lock occur.
OmniWalk resolves this by recalculating the **Pawn's Basis** every tick, translating world-space physics into **Local Surface-Normal Space**.
Core Technical Pillars
Unlike Blueprint-heavy templates, OmniWalk is optimized at the register level to handle sub-millisecond traces and quaternion math, ensuring your Game Thread remains lean.
Native C++ Performance
Runs in TG_PrePhysics. Bypasses Blueprint VM overhead for frame-perfect adhesion and movement integration.
Gimbal-Free Solver
A custom PlayerController math stack that prevents viewing-angle inversions when traversing 180° ceiling paths.
Volume-Less Logic
Uses surface-aware line traces. Your character sticks to any StaticMesh or Landscape normal automatically.
SetGravityDirection function within the UCharacterMovementComponent, making it incompatible with legacy 5.0-5.3 "force-based" gravity hacks.
Quick Start
1. Add the Actor Component
Attach the UOmniWalkComponent to any ACharacter subclass. This component handles the surface tracing and gravity vector updates.
2. Setup the Player Controller
Parent your PlayerController to AOmniWalkPlayerController. This remaps standard Input (WASD) to be relative to the character's local "Up" vector rather than the World Z-up.
3. Configure Enhanced Input
// In your Character's IA_Move handler:
FVector LocalMove = OmniController->GetGravityRelativeDirection(FVector(Value.Y, Value.X, 0.f));
AddMovementInput(LocalMove, 1.0f);
OmniWalk Universal Linker
The **Universal Linker** is for level designers who want Magneboot functionality without touching a single line of C++ or Blueprint graph.
1. Tag
Add OmniWalk.Enabled to any Character Actor's Tags array.
2. Autodetect
The OmniWalk Subsystem scans the level at start and injects the logic.
3. Surface Lock
Your character is now "Sticky." Use standard controls to walk on any mesh.
Zero Intervention Policy
"By using the Universal Linker, you do not need to change your GameMode, your PlayerController, or your Character Blueprint. OmniWalk intercepts the View rotation via a dynamic Camera Modifier at runtime."
Getting Started
OmniWalk is designed to be as "plug-and-play" as possible while maintaining a high-performance C++ backend. Follow these steps to transition a standard Character from Z-Up restricted movement to full arbitrary surface adhesion.
1 Plugin Installation
Place the OmniWalk folder into your project's Plugins directory. If your project is Blueprint-only, you will need to generate Visual Studio project files and perform an initial compile to register the C++ classes.
# Project Directory
YourProject/
└── Plugins/
└── OmniWalk/
├── OmniWalk.uplugin
└── Source/
Note: Ensure "Enhanced Input" is enabled in your Project Settings, as OmniWalk utilizes it for local-space vector remapping.
2 Character Integration
You can integrate OmniWalk into your character via C++ (recommended for performance) or Blueprints.
Via C++ (Internal Class)
// YourCharacter.h
UPROPERTY(VisibleAnywhere, Category = "Movement")
class UOmniWalkComponent* OmniWalkComp;
// YourCharacter.cpp
#include "OmniWalkComponent.h"
AYourCharacter::AYourCharacter()
{
OmniWalkComp = CreateDefaultSubobject<UOmniWalkComponent>(TEXT("OmniWalkComp"));
}
Via Blueprints
Open your Character Blueprint, click +Add, and search for OmniWalk. Once added, the component will automatically begin tracing for geometry below the capsule.
3 The Player Controller Bridge
The hardest part of gravity walking is the camera. Traditional AddControllerYawInput assumes a world-up axis. To fix this, your Player Controller must be a child of AOmniWalkPlayerController.
- ✔ Logic resolves gimbal lock when walking on walls.
- ✔ Prevents inverted "inverted controls" when upside down.
- ✔ Automatically handles View Rotation in local surface space.
4 Remapping Input Movement
Standard movement logic usually feeds (1, 0, 0) for Forward. In OmniWalk, "Forward" must be projected onto the current surface normal. Use the built-in translation node:
// Blueprint / C++ Input Logic
- Receive Input Action (e.g., IA_Move).
- Get the Player Controller and cast to
OmniWalkPlayerController. - Call GetGravityRelativeDirection.
- Pass the output into Add Movement Input.
5 Tuning & Calibration
Once the components are linked, use the Details Panel on the OmniWalk component to tune the "feel":
| Property | Suggested Value | Effect |
|---|---|---|
| AlignmentSpeed | 8.0 - 15.0 | Higher = Snappier rotation to floor; Lower = Smoother transitions. |
| TraceDistance | 150.0 | The "Magnetic" reach. Keep small to avoid snapping to high ceilings. |
| AdhesionForce | 2000.0 | Prevents flying off the top of spheres or sharp curves. |
Using OmniWalk
OmniWalk is more than a simple gravity switcher; it is a **Surface Adhesion Engine**. To get the most out of the system, you must understand the interplay between the tracing logic, the orientation solver, and the camera gimbal.
The Adhesion Pipeline
The system operates on a "Pre-Physics" update loop. Unlike standard Unreal gravity which is constant, OmniWalk calculates its force vector based on the geometry directly beneath (or around) the character's feet.
The Telemetry Tab
Tuning complex locomotion feels like guesswork without data. OmniWalk includes a built-in **Slate Debugger** that visualizes the invisible math driving your character.
To access the debugger, navigate to Window > OmniWalk Debugger while in the Level Editor. This window provides live telemetry from the active PIE (Play In Editor) session:
Visualized as a progress bar. It measures the Dot Product between the Actor's UpVector and the Surface Normal. A value of 1.0 means you are perfectly flush with the mesh.
Displays the X, Y, and Z components of the current gravity vector in real-time. This is useful for identifying "jitter zones" in organic, high-poly geometry.
Advanced Mesh Interaction
Walking on a simple sphere is easy—walking through a complex internal sci-fi pipe or over a 90-degree corner requires fine-tuning.
Cresting Convex Slopes
When a character reaches the top of a sphere or the edge of a vertical ramp, the character's momentum may "launch" them into the air, breaking the adhesion state. We solve this with the AdhesionForce:
// Native C++ Tip: If the character 'pops' off at high speeds,
// increase AdhesionForce to keep the capsule 'grounded'.
CMC->AddImpulse(-HitNormal * AdhesionForce, true);
The Camera "Auto-Pitch"
By default, OmniWalk aligns the character's orientation to the mesh. Because the camera is a child of the character, the camera view will tilt as you walk up a wall. The AOmniWalkPlayerController includes a Camera Adaption logic that attempts to smooth this motion, preventing motion sickness during rapid orientation shifts.
Best Practices
-
1.
Collision Channels: Ensure your walking surfaces are on the
ECC_Visibilitychannel (or a custom channel defined in your OmniWalk settings) for accurate tracing. - 2. Smooth Geodesics: While OmniWalk works on raw triangles, "Baking" or "Smoothing" normals on low-poly meshes results in a much smoother orientation feel.
-
3.
Ledge Behavior: If you walk off a ledge where no mesh exists within the
TraceDistance, the character will automatically revert to Global Z-Up (0,0,-1) gravity.
OmniWalk is a high-fidelity **C++17 Character Locomotion** system designed to solve the "Magneboot" problem. While UE5.4 introduced native gravity directions, OmniWalk provides the missing logic for **arbitrary mesh adhesion**, **gimbal-free camera controls**, and **normal alignment**.
No volumes required. Walk on any static or procedural mesh normal.
Tight integration with CharacterMovementComponent physics integration.
UOmniWalkComponent
The core logic processor. It ticks in TG_PrePhysics to ensure gravity is updated before the CharacterMovementComponent calculates displacement.
- TraceDistance: How far below the capsule to look for a walkable surface.
- AlignmentSpeed: Interp speed for the character's rotation to flush against the normal.
- AdhesionForce: Downward impulse applied when grounded to prevent "launching" off convex curves.
Local Control Solver
The AOmniWalkPlayerController solves the "Gimbal Singularity." When a character is upside down, a standard controller's Pitch and Yaw would invert or lock. OmniWalk maintains a local rotation basis.
// Core Math:
FVector GravityUp = -CMC->GetGravityDirection();
FRotator LocalSpaceRot = FRotationMatrix::MakeFromZX(GravityUp, GetActorForwardVector()).Rotator();
Surface Adhesion
Unlike planetary gravity systems that pull toward a center point, OmniWalk uses **Predictive Tracing**. It anticipates the surface normal 1-frame ahead to ensure the character capsule never "jitters" when traversing between a floor and a wall.
Slate Debugger
The **OmniWalk Editor Module** adds a custom telemetry tab. Open it via Window > OmniWalk Debugger to monitor:
- Real-time Gravity Vector (normalized).
- Alignment Strength (Dot product of Actor Up vs Surface Normal).
- Trace Hit distance and Normal vector.