Engine/Plugins/Verse/UnrealEngineExperimental/Source/UnrealEngineExperimental/Verse/Diagnostics/DebugDraw.native.verse
debug_draw#
Built as an archetype — MyDraw := debug_draw{Channel := my_channel} — and then used for as many draws as you like. Every method is <transacts> and defers its real work to transaction commit, so a shape requested inside a transaction that rolls back is never drawn at all. Drawing is broadcast: each shape becomes a reliable client RPC to every player controller in the world, so server-side Verse code draws on everybody's screen.
The <internal> constants behind the parameter defaults are yellow (NamedColors.Yellow) for colour, FiniteDuration and 5.0 seconds for duration, 10.0 for DefaultDebugDrawSize, 0.0 for thickness and 1.0 for text font scale. Distances are Unreal centimetres throughout, as the source's own examples make clear: ?Radius := 200.0 is a two-metre sphere and ?Thickness := 1.0 is a one-centimetre-thick line.
Two gates are worth knowing about. Debug drawing is active only in editor builds unless the host game explicitly turns it on, so in a cooked build every one of these calls early-outs. And there is a global budget of 100 draw calls per frame shared by all debug_draw instances (the console variable VerseDebugDraw.DrawLimitPerFrame); once you exceed it the rest of the frame's shapes are silently dropped and an on-screen notice appears. DrawText is exempt from that budget.
C++
debug_draw<native><public> := class:Channel<native><public>:subtype(debug_draw_channel)ShowChannel<native><public>()<transacts>:voidHideChannel<native><public>()<transacts>:voidClearChannel<native><public>()<transacts>:voidClear<native><public>()<transacts>:voidDrawSphere<native><public>(Center:(/Verse.org/SpatialMath:)vector3, ?Radius:float, ?Color:color, ?NumSegments:int, ?Thickness:float, ?DrawDurationPolicy:debug_draw_duration_policy, ?Duration:float)<transacts>:voidDrawSphere<public>(Center:(/UnrealEngine.com/Temporary/SpatialMath:)vector3, ?Radius:float, ?Color:color, ?NumSegments:int, ?Thickness:float, ?DrawDurationPolicy:debug_draw_duration_policy, ?Duration:float)<transacts>:voidDrawBox<native><public>(Center:(/Verse.org/SpatialMath:)vector3, Rotation:(/Verse.org/SpatialMath:)rotation, ?Extent:(/Verse.org/SpatialMath:)vector3, ?Color:color, ?Thickness:float, ?DrawDurationPolicy:debug_draw_duration_policy, ?Duration:float)<transacts>:voidDrawBox<public>(Center:(/UnrealEngine.com/Temporary/SpatialMath:)vector3, Rotation:(/UnrealEngine.com/Temporary/SpatialMath:)rotation, ?Extent:(/UnrealEngine.com/Temporary/SpatialMath:)vector3, ?Color:color, ?Thickness:float, ?DrawDurationPolicy:debug_draw_duration_policy, ?Duration:float)<transacts>:voidDrawCapsule<native><public>(Center:(/Verse.org/SpatialMath:)vector3, Rotation:(/Verse.org/SpatialMath:)rotation, ?Height:float, ?Radius:float, ?Color:color, ?Thickness:float, ?DrawDurationPolicy:debug_draw_duration_policy, ?Duration:float)<transacts>:voidDrawCapsule<public>(Center:(/UnrealEngine.com/Temporary/SpatialMath:)vector3, Rotation:(/UnrealEngine.com/Temporary/SpatialMath:)rotation, ?Height:float, ?Radius:float, ?Color:color, ?Thickness:float, ?DrawDurationPolicy:debug_draw_duration_policy, ?Duration:float)<transacts>:voidDrawCone<native><public>(Origin:(/Verse.org/SpatialMath:)vector3, Direction:(/Verse.org/SpatialMath:)vector3, ?Height:float, ?NumSides:int, ?AngleWidthRadians:float, ?AngleHeightRadians:float, ?Color:color, ?Thickness:float, ?DrawDurationPolicy:debug_draw_duration_policy, ?Duration:float)<transacts>:voidDrawCone<public>(Origin:(/UnrealEngine.com/Temporary/SpatialMath:)vector3, Direction:(/UnrealEngine.com/Temporary/SpatialMath:)vector3, ?Height:float, ?NumSides:int, ?AngleWidthRadians:float, ?AngleHeightRadians:float, ?Color:color, ?Thickness:float, ?DrawDurationPolicy:debug_draw_duration_policy, ?Duration:float)<transacts>:voidDrawCylinder<native><public>(Start:(/Verse.org/SpatialMath:)vector3, End:(/Verse.org/SpatialMath:)vector3, ?NumSegments:int, ?Radius:float, ?Color:color, ?Thickness:float, ?DrawDurationPolicy:debug_draw_duration_policy, ?Duration:float)<transacts>:voidDrawCylinder<public>(Start:(/UnrealEngine.com/Temporary/SpatialMath:)vector3, End:(/UnrealEngine.com/Temporary/SpatialMath:)vector3, ?NumSegments:int, ?Radius:float, ?Color:color, ?Thickness:float, ?DrawDurationPolicy:debug_draw_duration_policy, ?Duration:float)<transacts>:voidDrawLine<native><public>(Start:(/Verse.org/SpatialMath:)vector3, End:(/Verse.org/SpatialMath:)vector3, ?Color:color, ?Thickness:float, ?DrawDurationPolicy:debug_draw_duration_policy, ?Duration:float)<transacts>:voidDrawLine<public>(Start:(/UnrealEngine.com/Temporary/SpatialMath:)vector3, End:(/UnrealEngine.com/Temporary/SpatialMath:)vector3, ?Color:color, ?Thickness:float, ?DrawDurationPolicy:debug_draw_duration_policy, ?Duration:float)<transacts>:voidDrawPoint<native><public>(Position:(/Verse.org/SpatialMath:)vector3, ?Color:color, ?Thickness:float, ?DrawDurationPolicy:debug_draw_duration_policy, ?Duration:float)<transacts>:voidDrawPoint<public>(Position:(/UnrealEngine.com/Temporary/SpatialMath:)vector3, ?Color:color, ?Thickness:float, ?DrawDurationPolicy:debug_draw_duration_policy, ?Duration:float)<transacts>:voidDrawArrow<native><public>(Start:(/Verse.org/SpatialMath:)vector3, End:(/Verse.org/SpatialMath:)vector3, ?ArrowSize:float, ?Color:color, ?Thickness:float, ?DrawDurationPolicy:debug_draw_duration_policy, ?Duration:float)<transacts>:voidDrawArrow<public>(Start:(/UnrealEngine.com/Temporary/SpatialMath:)vector3, End:(/UnrealEngine.com/Temporary/SpatialMath:)vector3, ?ArrowSize:float, ?Color:color, ?Thickness:float, ?DrawDurationPolicy:debug_draw_duration_policy, ?Duration:float)<transacts>:voidDrawText<native><public>(Text:string, Position:(/Verse.org/SpatialMath:)vector3, ?Color:color, ?DrawDurationPolicy:debug_draw_duration_policy, ?Duration:float, ?FontScale:float, ?DrawDropShadow:logic)<transacts>:voidDrawText<public>(Text:string, Position:(/UnrealEngine.com/Temporary/SpatialMath:)vector3, ?Color:color, ?DrawDurationPolicy:debug_draw_duration_policy, ?Duration:float, ?FontScale:float, ?DrawDropShadow:logic)<transacts>:void
Channel<native><public>:subtype(debug_draw_channel)Holds a class, not an instance, and defaults to debug_draw_channel itself — so every debug_draw that does not name a channel ends up sharing one. The channel's unique class ID is what ShowChannel, HideChannel and ClearChannel key on, and what selects the line batcher your timed and persistent shapes are stored in. Give each subsystem its own channel and you can toggle its visualisation independently of the others.
ShowChannel<native><public>()<transacts>:voidEnables the channel on every connected player, unhiding the line batcher that holds its timed and persistent shapes.
In practice this is not optional. Channels start out disabled, and a channel's line batcher is created hidden when the channel is not yet enabled, so a freshly written debug-draw pass usually shows nothing at all until ShowChannel has been called once. Reach for it before concluding your coordinates are wrong.
HideChannel<native><public>()<transacts>:voidDisables the channel for every player. Existing geometry is not discarded, just hidden, and their lifetimes keep counting down while out of sight, so a later ShowChannel reveals whatever has not yet expired. SingleFrame draws issued while the channel is hidden are dropped rather than merely hidden, since they never reach the channel's batcher.
ClearChannel<native><public>()<transacts>:voidFlushes the channel's line batcher and discards its debug text on every client, irrespective of which debug_draw instance produced them. Like the draw calls it is deferred to transaction commit. It cannot remove SingleFrame shapes, which live in the shared world batcher and have already expired.
Clear<native><public>()<transacts>:voidThe narrower sibling of ClearChannel: it removes only the shapes and text drawn by this particular debug_draw object, using the object's own identity as a batch tag, and leaves anything drawn by other instances on the same channel alone. Prefer it whenever several debug_draw values share a channel — which they do by default, since Channel defaults to the same base class for everyone.
DrawSphere<native><public>(
Center:(/Verse.org/SpatialMath:)vector3,
?Radius:float = DefaultDebugDrawSize,
?Color:color = DefaultDebugDrawColor,
?NumSegments:int = 12,
?Thickness:float = DefaultDebugDrawThickness,
?DrawDurationPolicy:debug_draw_duration_policy = DefaultDebugDrawDurationPolicy,
?Duration:float = DefaultDebugDrawDuration
)<transacts>:voidA wireframe sphere of latitude and longitude rings. ?NumSegments — default 12, clamped up to a minimum of 4 — controls both directions at once, so the line count is roughly 2 × NumSegments²: the default already costs 288 lines, and 32 segments costs over two thousand. Given the 100-draws-per-frame budget applies to whole shapes rather than lines, it is the renderer rather than the budget that will complain.
?Radius defaults to DefaultDebugDrawSize, 10.0 centimetres, which is small enough to be easy to miss; ?Thickness of 0.0 gives hairline lines.
DrawSphere<public>(
Center:(/UnrealEngine.com/Temporary/SpatialMath:)vector3,
?Radius:float = DefaultDebugDrawSize,
?Color:color = DefaultDebugDrawColor,
?NumSegments:int = 12,
?Thickness:float = DefaultDebugDrawThickness,
?DrawDurationPolicy:debug_draw_duration_policy = DefaultDebugDrawDurationPolicy,
?Duration:float = DefaultDebugDrawDuration
)<transacts>:voidAn overload for the deprecated /UnrealEngine.com/Temporary/SpatialMath vector3. It is a plain Verse-level wrapper that converts the centre with FromVector3 and calls the /Verse.org/SpatialMath version, so behaviour is identical. Prefer the other overload in new code; this one exists only so that older callers keep compiling.
DrawBox<native><public>(
Center:(/Verse.org/SpatialMath:)vector3,
Rotation:(/Verse.org/SpatialMath:)rotation,
?Extent:(/Verse.org/SpatialMath:)vector3 = (/Verse.org/SpatialMath:)vector3{Forward := DefaultDebugDrawSize, Left := DefaultDebugDrawSize, Up := DefaultDebugDrawSize},
?Color:color = DefaultDebugDrawColor,
?Thickness:float = DefaultDebugDrawThickness,
?DrawDurationPolicy:debug_draw_duration_policy = DefaultDebugDrawDurationPolicy,
?Duration:float = DefaultDebugDrawDuration
)<transacts>:voidA twelve-line box wireframe. The important detail is that ?Extent is a half-extent measured outward from Center along each axis, so the default of 10.0 per axis draws a 20-centimetre cube, and passing an extent straight from a bounding-box size will give you a box twice as large as you expected. Rotation is applied about the centre.
The extent's components are named Forward, Left and Up here, matching /Verse.org/SpatialMath.
DrawBox<public>(
Center:(/UnrealEngine.com/Temporary/SpatialMath:)vector3,
Rotation:(/UnrealEngine.com/Temporary/SpatialMath:)rotation,
?Extent:(/UnrealEngine.com/Temporary/SpatialMath:)vector3 = (/UnrealEngine.com/Temporary/SpatialMath:)vector3{X := DefaultDebugDrawSize, Y := DefaultDebugDrawSize, Z := DefaultDebugDrawSize},
?Color:color = DefaultDebugDrawColor,
?Thickness:float = DefaultDebugDrawThickness,
?DrawDurationPolicy:debug_draw_duration_policy = DefaultDebugDrawDurationPolicy,
?Duration:float = DefaultDebugDrawDuration
)<transacts>:voidThe deprecated-vector3 overload, converting centre, rotation and extent and forwarding to the /Verse.org/SpatialMath version. Note that here the extent's components are X, Y and Z rather than Forward, Left and Up — the same numbers in the same order, but a different vocabulary. Prefer the other overload.
DrawCapsule<native><public>(
Center:(/Verse.org/SpatialMath:)vector3,
Rotation:(/Verse.org/SpatialMath:)rotation,
?Height:float = DefaultDebugDrawSize,
?Radius:float = 25.0,
?Color:color = DefaultDebugDrawColor,
?Thickness:float = DefaultDebugDrawThickness,
?DrawDurationPolicy:debug_draw_duration_policy = DefaultDebugDrawDurationPolicy,
?Duration:float = DefaultDebugDrawDuration
)<transacts>:voidDraws a capsule around Center, its axis along the rotated up direction, with a fixed sixteen sides — there is no segment count to tune. ?Height is the full height and is halved internally into a half-height that includes the hemispherical caps, so the cylindrical section is Height/2 - Radius long either side of the centre.
That interacts badly with the defaults: ?Height defaults to DefaultDebugDrawSize (10.0) while ?Radius defaults to 25.0, so a defaulted capsule has no cylindrical section at all and renders as a sphere-like blob. Pass a ?Height comfortably greater than twice ?Radius if you want something recognisably capsule-shaped.
DrawCapsule<public>(
Center:(/UnrealEngine.com/Temporary/SpatialMath:)vector3,
Rotation:(/UnrealEngine.com/Temporary/SpatialMath:)rotation,
?Height:float = DefaultDebugDrawSize,
?Radius:float = 25.0,
?Color:color = DefaultDebugDrawColor,
?Thickness:float = DefaultDebugDrawThickness,
?DrawDurationPolicy:debug_draw_duration_policy = DefaultDebugDrawDurationPolicy,
?Duration:float = DefaultDebugDrawDuration
)<transacts>:voidThe deprecated-vector3 overload: it converts Center and Rotation and forwards to the /Verse.org/SpatialMath version, defaults and quirks included. Prefer the other overload.
DrawCone<native><public>(
Origin:(/Verse.org/SpatialMath:)vector3,
Direction:(/Verse.org/SpatialMath:)vector3,
?Height:float = DefaultDebugDrawSize,
?NumSides:int = 12,
?AngleWidthRadians:float = PiFloat / 4.0,
?AngleHeightRadians:float = PiFloat / 4.0,
?Color:color = DefaultDebugDrawColor,
?Thickness:float = DefaultDebugDrawThickness,
?DrawDurationPolicy:debug_draw_duration_policy = DefaultDebugDrawDurationPolicy,
?Duration:float = DefaultDebugDrawDuration
)<transacts>:voidOrigin is the apex and Direction the axis the cone opens along; ?Height is its length along that axis. The two angles are full apex angles in radians, not half-angles, and are independent, so the cross-section is an ellipse unless you keep them equal — which makes this a natural fit for drawing view cones and perception frusta. Both default to PiFloat / 4.0, that is 45 degrees, and are clamped internally into the open interval between 0 and π.
?NumSides (default 12, clamped up to at least 4) is the number of rays around the rim.
DrawCone<public>(
Origin:(/UnrealEngine.com/Temporary/SpatialMath:)vector3,
Direction:(/UnrealEngine.com/Temporary/SpatialMath:)vector3,
?Height:float = DefaultDebugDrawSize,
?NumSides:int = 12,
?AngleWidthRadians:float = PiFloat / 4.0,
?AngleHeightRadians:float = PiFloat / 4.0,
?Color:color = DefaultDebugDrawColor,
?Thickness:float = DefaultDebugDrawThickness,
?DrawDurationPolicy:debug_draw_duration_policy = DefaultDebugDrawDurationPolicy,
?Duration:float = DefaultDebugDrawDuration
)<transacts>:voidThe deprecated-vector3 overload, converting both vectors and forwarding to the /Verse.org/SpatialMath version. Prefer the other overload.
DrawCylinder<native><public>(
Start:(/Verse.org/SpatialMath:)vector3,
End:(/Verse.org/SpatialMath:)vector3,
?NumSegments:int = 12,
?Radius:float = DefaultDebugDrawSize,
?Color:color = DefaultDebugDrawColor,
?Thickness:float = DefaultDebugDrawThickness,
?DrawDurationPolicy:debug_draw_duration_policy = DefaultDebugDrawDurationPolicy,
?Duration:float = DefaultDebugDrawDuration
)<transacts>:voidUnusually for this family, the cylinder is specified by its two end centres rather than a centre and a rotation, which makes it convenient for visualising a swept path or a spring between two points. ?Radius defaults to DefaultDebugDrawSize (10.0) and ?NumSegments to 12, clamped up to at least 4; each segment costs three lines. If Start and End coincide the axis falls back to world up rather than failing.
DrawCylinder<public>(
Start:(/UnrealEngine.com/Temporary/SpatialMath:)vector3,
End:(/UnrealEngine.com/Temporary/SpatialMath:)vector3,
?NumSegments:int = 12,
?Radius:float = DefaultDebugDrawSize,
?Color:color = DefaultDebugDrawColor,
?Thickness:float = DefaultDebugDrawThickness,
?DrawDurationPolicy:debug_draw_duration_policy = DefaultDebugDrawDurationPolicy,
?Duration:float = DefaultDebugDrawDuration
)<transacts>:voidThe deprecated-vector3 overload, converting both endpoints and forwarding to the /Verse.org/SpatialMath version. Prefer the other overload.
DrawLine<native><public>(
Start:(/Verse.org/SpatialMath:)vector3,
End:(/Verse.org/SpatialMath:)vector3,
?Color:color = DefaultDebugDrawColor,
?Thickness:float = DefaultDebugDrawThickness,
?DrawDurationPolicy:debug_draw_duration_policy = DefaultDebugDrawDurationPolicy,
?Duration:float = DefaultDebugDrawDuration
)<transacts>:voidThe cheapest primitive here — one line, and the unit every other shape is built out of. ?Thickness is in centimetres and defaults to 0.0, which draws a hairline of constant screen width; give it a positive value when a line needs to read at distance. Remember that the per-frame draw budget counts calls, so a polyline stitched together from DrawLine calls consumes it one segment at a time.
DrawLine<public>(
Start:(/UnrealEngine.com/Temporary/SpatialMath:)vector3,
End:(/UnrealEngine.com/Temporary/SpatialMath:)vector3,
?Color:color = DefaultDebugDrawColor,
?Thickness:float = DefaultDebugDrawThickness,
?DrawDurationPolicy:debug_draw_duration_policy = DefaultDebugDrawDurationPolicy,
?Duration:float = DefaultDebugDrawDuration
)<transacts>:voidThe deprecated-vector3 overload, converting both endpoints and forwarding to the /Verse.org/SpatialMath version. Prefer the other overload.
DrawPoint<native><public>(
Position:(/Verse.org/SpatialMath:)vector3,
?Color:color = DefaultDebugDrawColor,
?Thickness:float = DefaultDebugDrawThickness,
?DrawDurationPolicy:debug_draw_duration_policy = DefaultDebugDrawDurationPolicy,
?Duration:float = DefaultDebugDrawDuration
)<transacts>:voidA single screen-facing dot. The parameter to watch is ?Thickness, which is not a line width here — it is passed straight through as the point's size — and it defaults to DefaultDebugDrawThickness, which is 0.0. Always pass an explicit ?Thickness (a value of ten or twenty reads well) or you will be hunting for something with no size.
One further oddity: unlike the line-based shapes, a point's colour is reinterpreted rather than converted from sRGB, so the same color renders noticeably brighter as a point than as a line.
DrawPoint<public>(
Position:(/UnrealEngine.com/Temporary/SpatialMath:)vector3,
?Color:color = DefaultDebugDrawColor,
?Thickness:float = DefaultDebugDrawThickness,
?DrawDurationPolicy:debug_draw_duration_policy = DefaultDebugDrawDurationPolicy,
?Duration:float = DefaultDebugDrawDuration
)<transacts>:voidThe deprecated-vector3 overload, converting the position and forwarding to the /Verse.org/SpatialMath version — including the zero default size. Prefer the other overload.
DrawArrow<native><public>(
Start:(/Verse.org/SpatialMath:)vector3,
End:(/Verse.org/SpatialMath:)vector3,
?ArrowSize:float = 25.0,
?Color:color = DefaultDebugDrawColor,
?Thickness:float = DefaultDebugDrawThickness,
?DrawDurationPolicy:debug_draw_duration_policy = DefaultDebugDrawDurationPolicy,
?Duration:float = DefaultDebugDrawDuration
)<transacts>:voidA DrawLine from Start to End plus a two-line arrowhead at the End, which makes it the natural choice for velocities, normals and aim directions — three lines rather than the line's one.
?ArrowSize behaves surprisingly: it is square-rooted before use, so the head's barbs are sqrt(ArrowSize) centimetres long — about five centimetres at the default of 25.0. The head therefore grows very slowly, and you need ?ArrowSize := 400.0 for a twenty-centimetre head.
DrawArrow<public>(
Start:(/UnrealEngine.com/Temporary/SpatialMath:)vector3,
End:(/UnrealEngine.com/Temporary/SpatialMath:)vector3,
?ArrowSize:float = 25.0,
?Color:color = DefaultDebugDrawColor,
?Thickness:float = DefaultDebugDrawThickness,
?DrawDurationPolicy:debug_draw_duration_policy = DefaultDebugDrawDurationPolicy,
?Duration:float = DefaultDebugDrawDuration
)<transacts>:voidThe deprecated-vector3 overload, converting both endpoints and forwarding to the /Verse.org/SpatialMath version. Prefer the other overload.
DrawText<native><public>(
Text:string,
Position:(/Verse.org/SpatialMath:)vector3,
?Color:color = DefaultDebugDrawColor,
?DrawDurationPolicy:debug_draw_duration_policy = DefaultDebugDrawDurationPolicy,
?Duration:float = DefaultDebugDrawDuration,
?FontScale:float = DefaultDebugTextFontScale,
?DrawDropShadow:logic = false
)<transacts>:voidThe odd one out: text is not a line-batcher primitive but an entry in the player's HUD debug-text list, re-submitted every tick and drawn as flat screen text at the projected world position. It consequently needs the player to have a HUD, has no thickness, and is the one drawing call exempt from the hundred-draws-per-frame budget.
?FontScale defaults to 1.0 and ?DrawDropShadow to false; a shadow is worth turning on for text over bright geometry. Under SingleFrame each new piece of text supersedes the single-frame text submitted on earlier frames, so a label re-drawn every tick updates in place rather than accumulating.
DrawText<public>(
Text:string,
Position:(/UnrealEngine.com/Temporary/SpatialMath:)vector3,
?Color:color = DefaultDebugDrawColor,
?DrawDurationPolicy:debug_draw_duration_policy = DefaultDebugDrawDurationPolicy,
?Duration:float = DefaultDebugDrawDuration,
?FontScale:float = DefaultDebugTextFontScale,
?DrawDropShadow:logic = false
)<transacts>:voidThe deprecated-vector3 overload, converting the position and forwarding to the /Verse.org/SpatialMath version. Prefer the other overload.