Table of Contents

Stride UI - Capsule and Window

A capsule in a 3D scene with a "Hello, World" panel drawn over it using Stride's built-in UI. The interesting part is the assembly order, which the example splits into one small method per step: load a font, build a TextBlock, put it on a Canvas, wrap the canvas in a UIComponent, and attach that to an entity. A UI in Stride is an entity like any other, and it will not render without a font loaded first.

The Program.cs file shows how to:

  • Building a UI hierarchy from code with Canvas and TextBlock
  • Loading a SpriteFont before any text can be drawn
  • Hosting a UI on an entity through UIComponent
  • Keeping scene setup readable by splitting it per element
  • Using helpers: SceneSetup3D, UseSkybox, CreatePrimitive

Stride UI - Capsule and Window

View on GitHub.

using Stride.CommunityToolkit.Bepu;
using Stride.CommunityToolkit.Engine;
using Stride.CommunityToolkit.Rendering.ProceduralModels;
using Stride.CommunityToolkit.Skyboxes;
using Stride.Core.Mathematics;
using Stride.Engine;
using Stride.Graphics;
using Stride.Rendering;
using Stride.UI;
using Stride.UI.Controls;
using Stride.UI.Panels;

// One small method per step, on purpose: the assembly order is the lesson. Load a font, build a
// TextBlock, put it on a Canvas, wrap the canvas in a UIComponent, and attach that to an entity.

SpriteFont? font = null;

using var game = new Game();

game.Run(new SceneSetup3D().UseBepu().UseSkybox(), start: Start);

void Start(Scene scene)
{
    AddCapsule(scene);
    LoadFont();
    AddWindow(scene);
}

void AddCapsule(Scene scene)
{
    var entity = game.CreatePrimitive(Primitive3D.Capsule());
    entity.Transform.Position = new Vector3(0, 8, 0);
    entity.Scene = scene;
}

// Text draws nothing without a font; this one ships with the engine, so the example needs no assets
void LoadFont() => font = game.Content.Load<SpriteFont>("/Stride.Engine/StrideDefaultFont");

void AddWindow(Scene scene) => CreateUIEntity().Scene = scene;

Entity CreateUIEntity() => new()
{
    new UIComponent
    {
        Page = new UIPage { RootElement = CreateCanvas() },
        RenderGroup = RenderGroup.Group31
    }
};

Canvas CreateCanvas()
{
    var canvas = new Canvas { Width = 300, Height = 100, BackgroundColor = new Color(248, 177, 149, 100) };

    canvas.Children.Add(CreateTextBlock(font));

    return canvas;
}

TextBlock CreateTextBlock(SpriteFont? font)
{
    if (font is null) Console.WriteLine("Font is null");

    return new TextBlock
    {
        Text = "Hello, World",
        TextColor = Color.White,
        TextSize = 20,
        Margin = new Thickness(3, 3, 3, 0),
        Font = font
    };
}