Skip to content

Gizmo Components

Retained-mode gizmos are ECS components that persist on entities and render every frame until the component is removed. Each component requires the canonical Transform component from @shell/transform to define its position.


import { GizmoCircle } from '@shell/gizmos';
import { Transform } from '@shell/transform';
commands.spawn(
Define.prefab()
.with(Transform, { x: 100, y: 100 })
.with(GizmoCircle, { radius: 50, color: 0xff0000 }),
);

export const GizmoCircle = Define.component('gizmoCircle')
.withSchema({
radius: { type: StoreType.Float32, default: 16 },
color: { type: StoreType.Int32, default: 0x00ff00 },
alpha: { type: StoreType.Float32, default: 1 },
width: { type: StoreType.Float32, default: 0 },
layer: { type: StoreType.String, default: 'default' },
})
.serializable()
.showInEditor();
FieldTypeDefaultDescription
radiusnumber16Circle radius
colornumber0x00ff00Stroke color (hex)
alphanumber1Opacity (0-1)
widthnumber0Stroke width (0 uses gizmos.defaultLineWidth)
layerstring'default'Layer name for rendering and visibility

export const GizmoRect = Define.component('gizmoRect')
.withSchema({
width: { type: StoreType.Float32, default: 32 },
height: { type: StoreType.Float32, default: 32 },
color: { type: StoreType.Int32, default: 0x00ff00 },
alpha: { type: StoreType.Float32, default: 1 },
strokeWidth: { type: StoreType.Float32, default: 0 },
layer: { type: StoreType.String, default: 'default' },
})
.serializable()
.showInEditor();
FieldTypeDefaultDescription
widthnumber32Rectangle width
heightnumber32Rectangle height
colornumber0x00ff00Stroke color (hex)
alphanumber1Opacity (0-1)
strokeWidthnumber0Stroke width (0 uses gizmos.defaultLineWidth)
layerstring'default'Layer name for rendering and visibility

The rectangle is centered on the entity’s Transform position.


export const GizmoLine = Define.component('gizmoLine')
.withSchema({
toX: { type: StoreType.Float32, default: 50 },
toY: { type: StoreType.Float32, default: 0 },
color: { type: StoreType.Int32, default: 0x00ff00 },
alpha: { type: StoreType.Float32, default: 1 },
width: { type: StoreType.Float32, default: 0 },
layer: { type: StoreType.String, default: 'default' },
})
.serializable()
.showInEditor();
FieldTypeDefaultDescription
toXnumber50End point offset from transform X
toYnumber0End point offset from transform Y
colornumber0x00ff00Stroke color (hex)
alphanumber1Opacity (0-1)
widthnumber0Stroke width (0 uses gizmos.defaultLineWidth)
layerstring'default'Layer name for rendering and visibility

The line starts at the entity’s Transform position and ends at Transform + (toX, toY).


export const GizmoArrow = Define.component('gizmoArrow')
.withSchema({
toX: { type: StoreType.Float32, default: 50 },
toY: { type: StoreType.Float32, default: 0 },
headLength: { type: StoreType.Float32, default: 10 },
color: { type: StoreType.Int32, default: 0x00ff00 },
alpha: { type: StoreType.Float32, default: 1 },
width: { type: StoreType.Float32, default: 0 },
layer: { type: StoreType.String, default: 'default' },
})
.serializable()
.showInEditor();
FieldTypeDefaultDescription
toXnumber50End point offset from transform X
toYnumber0End point offset from transform Y
headLengthnumber10Length of the arrowhead
colornumber0x00ff00Stroke color (hex)
alphanumber1Opacity (0-1)
widthnumber0Stroke width (0 uses gizmos.defaultLineWidth)
layerstring'default'Layer name for rendering and visibility

export const GizmoCross = Define.component('gizmoCross')
.withSchema({
size: { type: StoreType.Float32, default: 8 },
color: { type: StoreType.Int32, default: 0x00ff00 },
alpha: { type: StoreType.Float32, default: 1 },
width: { type: StoreType.Float32, default: 0 },
layer: { type: StoreType.String, default: 'default' },
})
.serializable()
.showInEditor();
FieldTypeDefaultDescription
sizenumber8Half-length of each cross arm
colornumber0x00ff00Stroke color (hex)
alphanumber1Opacity (0-1)
widthnumber0Stroke width (0 uses gizmos.defaultLineWidth)
layerstring'default'Layer name for rendering and visibility

  • All components are serializable and visible in the editor.
  • All components require a Transform component from @shell/transform to define their position.
  • Component defaults use green (0x00ff00). Immediate-mode defaults use white (0xffffff).
  • Component gizmos on a disabled layer are skipped during rendering.