Custom Vector Motion: Bypassing Keyframes in Verse
What you'll learn
You will build a custom movement loop that replaces heavy editor keyframes with lightweight Verse math. You'll calculate sinusoidal trajectories, manage a simple object-pool index using total integer helpers, and push real-time position data to the player's HUD.
How it works
Instead of relying on the engine's animation system, we drive movement manually:
- Trigonometry:
SinandCosgenerate smooth circular X/Y paths. - Interpolation:
Lerpmaps vertical oscillation between two bounds safely. - Concurrency: A
loop:withSleepyields control back to the simulation each frame, preventing main-thread locks. - UI Feedback: We hook into
GetPlayerUI[], grab thecanvas, andAddWidgeta live tracker so you can see the math execute in real-time.
Let's build it
Drop this device into your level. Place a trigger_device nearby and assign it to the Trigger field. Press Play and step on the trigger to watch the custom motion loop activate.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
my_example_device := class<concrete>(creative_device):
@editable Trigger : trigger_device = trigger_device{}
Phase : float = 0.0
Speed : float = 2.0
Radius : float = 100.0
VC_IntMod(A:int, B:int):int =
if (R := Mod[A, B]): R else: 0
VC_IntDiv(A:int, B:int):int =
if (B > 0, R := Mod[A, B], Q := Floor[(A - R) * 1.0 / (B * 1.0)]): Q else: 0
OnBegin<override>()<suspends>: void =
// Wire up the trigger to launch our custom motion loop
_ := Trigger.TriggeredEvent.Subscribe((Agent) -> RunTrajectory())
RunTrajectory()
RunTrajectory()<suspends>: void =
// Access player UI to visualize the calculated trajectory
PUI := GetPlayerUI[]
Canvas := PUI.GetCanvas()
Label := text_block_widget{ Text: "Ready" }
Canvas.AddWidget(Label)
Index : int = 0
Loop:
// Advance phase based on speed and simulated delta time
set Phase = Phase + (Speed * 0.016)
set Index = Index + 1
// Calculate grid layout indices using total int helpers
Col := VC_IntMod(Index, 4)
Row := VC_IntDiv(Index, 4)
// Generate circular X/Y coordinates
X := Cos(Phase) * Radius
Y := Sin(Phase) * Radius
// Map vertical oscillation between -50 and 50
Z := Lerp(-50.0, 50.0, (Sin(Phase) + 1.0) * 0.5)
// Push real-time position data to the HUD widget
set Label.Text = "Grid:{Col},{Row} Pos:X:{X} Y:{Y} Z:{Z}"
// Yield control back to the simulation loop without blocking
Sleep(0.016)
Try it yourself
- Change
Speedto5.0and watch the orbit tighten and accelerate. - Swap
Radiusto200.0to double the flight path diameter. - Replace
Sleep(0.016)withSleep(0.05)to drop the update rate and observe how the UI lags behind the math.
Recap
Custom movement in Verse gives you deterministic control over trajectories without the bloat of keyframe systems. By combining Sin/Cos for paths, Lerp for bounds, and GetPlayerUI[] for feedback, you can scale complex animations across hundreds of entities while keeping performance buttery smooth.
Check your understanding
Test yourself with an interactive quiz and track your progress + earn XP — free for members.
Turn this into a guided course
Add Implementing Custom Entity Movement in Verse to your free study plan — we'll suggest related pages and stitch the lot into one compile-checked, self-guided lesson with worked examples and quizzes.
Original tutorial generated by Verse Island from the Verse/UEFN knowledge base, with references to the Epic Games sources above. Code is validated against the knowledge base.