Locomotion sample overview
Updated: May 7, 2026
This sample demonstrates how to build custom locomotion systems using the Interaction SDK’s locomotion event pipeline, including climbing, NavMesh-driven walking, and walking stick locomotion. You explore three distinct movement mechanics, each showing a different approach to extending ISDK’s ILocomotionEventBroadcaster and ILocomotionEventHandler interfaces.
- Implement custom locomotion systems using ISDK’s LocomotionEvent pipeline
- Use the Decorator pattern to attach custom metadata to locomotion events
- Convert tracking-space positions to world-space movement
- Integrate multiple locomotion modes with input-modality-agnostic interactors
- Use NavMesh pathfinding as an alternative to instant teleportation
- Device: Meta Quest headset with hand tracking or controllers
- Development environment: Unity with Meta XR SDK installed
See the repository README for version requirements and setup instructions.
Clone the Unity Interaction SDK Samples repository from GitHub and open the project in Unity. Navigate to Assets/ShowcaseSamples/Locomotion/Scenes/ and open LocomotionExamplesClimbing.unity. Build and deploy to your Quest device following the instructions in the repository README. The scene supports both controller and hand tracking input modes.
The sample organizes each locomotion system into a set of scripts that handle input broadcasting, event processing, and visual feedback. All three systems integrate with ISDK’s shared locomotion pipeline.
| File / Scene | Purpose | Key concepts |
|---|
LocomotionExamplesClimbing.unity | Single scene containing all three locomotion systems | Scene setup, prefab organization, input modality switching |
Climbable.cs | Interactable surface for grab-based climbing | Extending PointableElement, multi-hand support |
ClimbingLocomotionBroadcaster.cs | Converts grab events into climbing locomotion events | Decorator pattern, static lookup via Context.Global |
ClimbingLocomotor.cs | Processes climbing events into relative translation | ILocomotionEventHandler, multi-hand deltas, pull-up mechanics |
TelepathActionsBroadcaster.cs | Wraps ISDK’s TeleportInteractor | Hover/Unhover/Halt action broadcasting |
TelepathLocomotor.cs | NavMesh pathfinding for walk-to-target movement | NavMesh.CalculatePath(), velocity-based translation, teleport fallback
|
TelepathLocomotionVisual.cs | Renders dotted path preview | Graphics.DrawMeshInstanced
|
WalkingStick.cs | Virtual cane interactable | Tracking-space position registration, shoulder-based filtering |
WalkingStickLocomotor.cs | Processes stick positions into push/slide/jump movement | ITrackingToWorldTransformer, simultaneous dual-stick jump detection |
WalkingStickVisual.cs | Renders virtual cane | TubeRenderer, dynamic cane length (68% head height) |
When you run the scene, you see a park environment with climbing walls, ladders, poles, and platforms. Use hand tracking or controllers to interact with each locomotion system. Grab any climbable surface (highlighted when you point at it) to pull yourself upward or across. Aim at the ground to see a dotted path appear, then release to walk along the path instead of teleporting instantly. Summon two virtual canes by extending your hands downward below shoulder height, then push them simultaneously to jump or use them individually to slide forward. The scene switches between controller and hand tracking seamlessly.
The LocomotionEvent pipeline
The sample builds on ISDK’s locomotion event broadcasting and handling architecture. Each custom system implements ILocomotionEventBroadcaster to emit LocomotionEvent instances and ILocomotionEventHandler to process them. Events flow from interactables through broadcasters to locomotors, which emit final movement events consumed by ISDK’s FirstPersonLocomotor. This decoupling allows multiple locomotion modes to coexist without modifying core movement logic. See ClimbingLocomotor.cs for a complete handler implementation.
The Decorator pattern for custom events
Notice how ClimbingLocomotionBroadcaster attaches climbing-specific metadata to generic LocomotionEvent instances. It uses ValueToClassDecorator to store a ClimbingEvent reference in Context.Global, keyed by the interactor’s UniqueIdentifier. This pattern lets downstream handlers retrieve custom data without modifying the base LocomotionEvent struct. See the decorator implementation in ClimbingLocomotionBroadcaster.cs.
Tracking-space coordinate conversion
The walking stick locomotor performs all position calculations in tracking space (relative to the headset) before converting to world-space movement. This approach isolates stick mechanics from the play-space coordinate system. The locomotor uses ITrackingToWorldTransformer.ToTrackingPose() to convert stick positions, calculates push vectors in tracking space, then converts results back via ToWorldPose(). See WalkingStickLocomotor.cs for the conversion pattern.
The BeginStart/EndStart lifecycle
Every MonoBehaviour in the sample uses this.BeginStart(ref _started) at the start of its Start() method and this.EndStart(ref _started) at the end. This ISDK pattern ensures dependencies initialize in the correct order and prevents duplicate initialization when prefabs instantiate at runtime. The _started boolean tracks whether the component has completed initialization. See any script in the sample for usage.
- Add a new climbable object: Attach the Climbable component to any GameObject with a collider. The climbing system detects it automatically when you point at it. Experiment with moving platforms by attaching Climbable to a kinematic Rigidbody.
- Modify walking stick jump behavior: Open WalkingStickLocomotor in the inspector and adjust the AnimationCurve fields such as _jumpVelocityFactor and _jumpVerticalFactor. These curves control the relationship between stick push depth and jump velocity.
- Create a hybrid locomotion mode: Combine climbing with telepath by enabling both locomotors simultaneously. The event pipeline processes both systems’ outputs, allowing you to climb vertical surfaces and walk along the ground in the same session.