Table of Contents

Entity Text

EntityTextComponent draws a line of text on the screen for the entity it is attached to, without using Stride's UI system. It is meant for labels, debug readouts, floating numbers and small HUDs in code-only projects.

This is screen-space text: always the same pixel size, always on top of the scene. For text that lives inside the scene - scaled by perspective and hidden by geometry in front of it - see World Text.

Two pieces are involved:

  • EntityTextComponent records what to draw and where.
  • EntityTextRenderer is a scene renderer that draws it. EntityTextProcessor adds it to the compositor when no AddEntityTextRenderer() call has.

The component, the renderer, TextAnchor and TextPositionMode are in the Stride.CommunityToolkit.Rendering.Text namespace; the AddEntityTextRenderer() extension is in Stride.CommunityToolkit.Engine.

game.AddEntityTextRenderer();

var entity = game.CreatePrimitive(Primitive3D.Cube());

entity.Add(new EntityTextComponent
{
    Text = "Hello",
    Anchor = TextAnchor.BottomCenter,
    Offset = new Vector2(0, -12),
    EnableShadow = true
});

entity.Scene = rootScene;

Where the text goes

PositionMode picks between three ways of deciding the position.

Mode Position comes from Culled when off screen Use it for
World (default) The entity's world position, projected to the screen Yes Labels on objects in the scene
Screen ScreenPosition, in pixels from the top-left No Fixed placement you want full control over
Anchored A point of the window, given by ScreenAnchor: a corner, the middle of an edge or the centre No A HUD that must survive the window being resized

Offset is applied in all three modes. In Anchored it acts as a margin and always points inwards, so new Vector2(16, 16) is sixteen pixels in from the chosen corner whichever corner that is. From an edge or the centre only the axis with an edge flips; the other is applied as given.

Anchored also takes its Anchor from the screen anchor rather than from the property, so text pinned to the top-right grows to the left and stays on screen. Use Screen when you want to choose the position and the anchor independently.

In World mode, FadeStartDistance and MaxDistance fade labels out with distance; MaxDistance alone is a cutoff.

Anchor is not Alignment

  • Anchor decides which point of the text sits on the position. A label floating above a point wants Anchor = TextAnchor.BottomCenter.
  • Alignment is Stride's TextAlignment. It only decides how the lines of a multi-line string sit relative to one another. On single-line text it does nothing: the alignment is computed against the width of the whole string, which for one line is the line itself.

Readability

Text drawn over a 3D scene has no control over what ends up behind it. Three options:

  • EnableShadow draws the string a second time in ShadowColor, offset by ShadowOffset. Cheap, and usually enough.
  • EnableOutline draws a ring of OutlineWidth pixels in OutlineColor (white by default) round every glyph. Readable over anything, including a background in the text's own colour.
  • EnableBackground fills a rectangle behind the text, sized from the text and expanded by Padding. BackgroundColor defaults to a dark, half-transparent panel.

The background is axis-aligned and does not turn with Rotation.

Animating

Scale, Opacity, Rotation and LayerDepth exist to be changed per frame:

  • Scale rather than FontSize. Changing the font size re-rasterises glyphs and re-measures the string; scaling does neither, and it scales about Anchor so centred text grows evenly.
  • Opacity multiplies into the text, shadow and background alpha, leaving the configured colours untouched.
  • LayerDepth orders the texts against each other. Higher is drawn on top.

IsVisible hides the text without removing the component, which keeps the cached measurement alive.

High-DPI displays

Every pixel figure on the component - FontSize, Offset, ScreenPosition, Padding, ShadowOffset, OutlineWidth - is a figure for a 100% display. On a scaled display the renderer multiplies them by the toolkit's shared DisplayScale, so a label designed at 18 px reads the same size to the eye on a 150% laptop as on a 100% monitor; the glyphs are rasterised at the larger size rather than stretched, so they stay sharp. A projected world position is not scaled. AutoScale = false on the component turns this off. The same applies to EntityDebugSceneRendererOptions, and it only works when the process is DPI aware; see the debug overlay page.

Fonts

Font is optional; leave it null and Stride's default font is used. Setting it per component lets different text use different faces in the same scene.

How it is collected

Components are gathered by EntityTextProcessor, registered through the component's DefaultEntityComponentProcessor attribute, so text on child entities is drawn and cached measurements are released when a component is removed.

The debug renderer

EntityDebugSceneRenderer is the other side of the same coin. Where EntityTextComponent draws text an entity opts into, the debug renderer labels every entity automatically with its name and/or position, in one shared style:

game.AddEntityDebugSceneRenderer(new()
{
    ShowEntityPosition = true,
    IncludeChildEntities = true,
    PositionColor = Color.DarkBlue,
    EnableBackground = true,
});

Both share their drawing - projection, anchoring, background, shadow - so those behave identically.

Options worth knowing:

  • IncludeChildEntities is off by default; labelling every child of a composed scene is usually unreadable.
  • EntityFilter narrows the labels to the entities that match, by name or component type.
  • PositionColor gives the coordinates their own colour, and moves them onto a line beneath the name.
  • MaxDistance drops labels past a given range.
Important

A default background only makes sense paired with a default text colour. The debug renderer's text defaults to black on a light panel; EntityTextComponent defaults to white on a dark one. If you change one default, change the other.

Limitations

  • One SpriteFont per component, no rich text or per-character colour.
  • No word wrapping. \n in the string works and Alignment then applies.
  • The background does not rotate with the text.
  • The renderer uses the first camera in the graphics compositor.