Spin to Win: Rotating Entities with the Scene Graph
Tutorial intermediate compiles

Spin to Win: Rotating Entities with the Scene Graph

Updated intermediate Scene Graph Animation Code verified

Spin to Win: Rotating Entities with the Scene Graph

In Part 1 we moved an entity to a new spot. Now we keep it planted and turn it instead — the move that makes a trophy revolve on its pedestal, a coin glint as it spins, or a vault dial crank around. Same tool (the keyframed movement component), one new idea (rotation), and one genuinely surprising gotcha.

The vault's spinning money stack, mid-display

A rotation = an axis + an angle

<!-- section-art:a-rotation-an-axis-an-angle --> Spin to Win: Rotating Entities with the Scene Graph: A rotation = an axis + an angle

Axis and Angle

To turn something you need two things: a spin axis (the invisible pole it turns around) and an angle (how far around that pole). In Verse you build a rotation with MakeRotationDegrees:

# A rotation is built from an axis (which way the spin-pole points) and an
# angle (how far to turn around it). Up is the vertical axis, so spinning
# around Up turns a thing like a record on a turntable.
SpinAxis := vector3{ Left := 0.0, Up := 1.0, Forward := 0.0 }
HalfTurn := MakeRotationDegrees(SpinAxis, 180.0)

SpinAxis points straight Up, so rotating around it spins the entity like a record on a turntable — flat, level, around its own center. Point the axis Forward instead and it would roll like a wheel; point it Left and it would tumble end over end.

The gotcha: rotations take the shortest path

Here's the trap that catches everyone. You'd expect "rotate 360 degrees" to spin a full circle. It doesn't. A rotation describes an orientation, and the engine always turns the shortest way to reach it. A full 360° turn ends up exactly where it started — so the shortest path is don't move at all. Your spin would sit there, frozen.

Even 270° is risky: the shortest path to "270° clockwise" is "90° counter-clockwise" — it'd spin the wrong way!

The fix: never ask for a turn of 180° or more in a single keyframe. Break a full spin into smaller, unambiguous steps. We'll use three 120° hops, which the engine always reads the way we mean.

Spin forever: three hops on a loop

using { /Verse.org/SceneGraph }
using { /Verse.org/SceneGraph/KeyframedMovement }
using { /Verse.org/Simulation }
using { /Verse.org/SpatialMath }

# Bolt this onto an entity that also has a Keyframed Movement component to
# make it spin forever around its vertical axis — like a trophy on a
# rotating display, or a coin pickup catching the light.
spin_forever_component := class<final_super>(component):

    # Seconds for ONE full turn. Smaller = faster spin.
    @editable
    var SecondsPerTurn<public>:float = 4.0

    OnBeginSimulation<override>():void =
        (super:)OnBeginSimulation()

        if (Mover := Entity.GetComponent[keyframed_movement_component]):
            # The vertical axis. Spinning around Up turns us like a turntable.
            SpinAxis := vector3{ Left := 0.0, Up := 1.0, Forward := 0.0 }
            # One third of a full turn.
            ThirdTurn := MakeRotationDegrees(SpinAxis, 120.0)
            # Each step lasts a third of the total turn time.
            StepSeconds := SecondsPerTurn / 3.0

            # One 120-degree step. A constant (linear) speed keeps the spin
            # even, with no slow-down between hops.
            Step := keyframed_movement_delta:
                Duration := StepSeconds
                Easing := linear_easing_function{}
                Transform := transform:
                    Rotation := ThirdTurn

            # Three identical steps = one full circle.
            Steps := array{ Step, Step, Step }
            # Loop mode replays the three steps forever: endless smooth spin.
            Mover.SetKeyframes(Steps, loop_keyframed_movement_playback_mode{})
            Mover.Play()

The new pieces:

  • ThirdTurn := MakeRotationDegrees(SpinAxis, 120.0) — a safe, unambiguous 120° turn around the up-axis.
  • A delta with only Rotation set — no translation, so the entity turns in place. Anything you leave out of a transform just stays as it was.
  • linear_easing_function{} — we want constant speed here. An eased spin would stutter (slow-fast-slow) at every hop; linear makes three hops read as one smooth, continuous rotation.
  • array{ Step, Step, Step } — three identical hops chain into a full 360°.
  • loop_keyframed_movement_playback_mode{} — the star. Loop replays the whole list end-to-end, forever. Three hops → full circle → repeat → an eternal spin.

From lesson to playable island: a real prize wheel

The component above proves the idea. Here's the same idea wired into a playable vignette you can stand in front of and use: a casino-style prize wheel that a player spins by pressing a Button, which then awards a prize from an Item Granter.

The built Spin to Win wheel — Button in front, Item Granter behind, framed by Art Deco pillars

This version is a creative_device rather than a scene-graph component, because a device is what you wire to other devices (a Button, an Item Granter) and drop into a level. It keeps the lesson's two load-bearing ideas verbatim — spin around the Up axis, and never turn 180° or more in a single step — but drives a creative_prop with MoveTo instead of a keyframed-movement component:

The same gotcha discipline carries straight over: instead of one giant 1080° turn (which the shortest-path rule would collapse to nothing), we chain nine 120° hops, each composed onto the wheel's live orientation with ApplyWorldRotationZ (the Unreal-Temporal SpatialMath equivalent of spinning around Up). Because MoveTo suspends, each hop blends into the next — a smooth, continuous three-revolution spin, then a prize.

Overhead view: the green prize wheel centered between the pillars, Button in front

This device is compile-verified in UEFN 5.8 (the whole PipelineBuild project builds clean with it installed) — grab it from the download panel as 03-device.verse. Wire its three @editable slots in the Details panel: drag your Button into SpinButton, your wheel prop into Wheel, and an Item Granter into PrizeGranter.

Playback modes, your animation's personality

<!-- section-art:playback-modes-your-animation-s-personality --> Spin to Win: Rotating Entities with the Scene Graph: Playback modes, your animation's personality

Spin Modes

You've now met three of the four playback modes:

Mode What it does
oneshot... Play the list once, then stop (Part 1's glide)
loop... Play the list, snap back, play again — forever (this spin)
pingpong... Play forward, then reverse, forever (next lesson's patrol)

Pick the mode and the same keyframes behave completely differently. That's the lever you'll reach for constantly.

Recap

  • A rotation = a spin axis (vector3) + an angle (degrees), built with MakeRotationDegrees.
  • Spinning around the Up axis turns an entity like a turntable.
  • Gotcha: rotations take the shortest path, so a single 360° keyframe does nothing and 180°+ is ambiguous. Split big turns into small steps (we used 3 × 120°).
  • A delta with only Rotation set turns the entity in place.
  • loop playback repeats the keyframe list forever — perfect for an endless spin. Use linear easing so the hops blend into one smooth turn.

Next — Part 3: On Patrol — we chain several moves into a route and use ping-pong to make a guard pace back and forth.

Get the complete code — free

You've read the full walkthrough. The complete, copy-paste-ready Verse solution is free for members — sign in to unlock it.

Free with your BrainDead.TV / BrainDeadGuild Discord account. The walkthrough above is always free.

Verse source files

Check your understanding

Test yourself with an interactive quiz and track your progress + earn XP — free for members.

Up next · Scene Graph: Animation On Patrol: Sequences and Loops with Keyframes Continue →

Turn this into a guided course

Add Verse Scene Graph — rotations, MakeRotationDegrees, loop playback, shortest-path gotcha 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.

Comments

    Sign in to vote, comment, or suggest an edit. Sign in