Dynamic Verse UI Grid Generator
Unverified — this example may not compile as-is.
The Verse code below did not pass our automated compile check, so it isn't marked verified and is hidden from the guide listing. The explanation may still be useful, but treat the code as a draft and adapt it before use.
60-second overview · More shorts
What you'll learn
You will learn how to use Verse to calculate screen coordinates and dynamically instantiate UI widgets. Instead of dragging and dropping buttons, you will write code that generates a grid layout based on configurable row and column counts. This technique is essential for scalable inventories, skill trees, or dynamic menus.
How it works
The core concept relies on two things: a widget_blueprint asset and the player_ui API. We iterate through a total count of items using a loop. For each item, we calculate its X and Y position on the screen using integer division and modulo arithmetic to determine its row and column. We then use GetPlayerUI[] to access the player's interface and AddWidget to place the widget at the calculated offset.
Let's build it
Create a new Verse device. We need to expose the Widget Blueprint asset so you can swap out the look of the buttons easily. We also define the grid dimensions. Inside OnBegin, we loop through the total number of cells, calculate the position, and add the widget to the player's UI.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/UI }
using { /Verse.org/Verse }
using { /Fortnite.com/Playspaces }
my_grid_device := class<concrete>(creative_device):
# The UI asset to instantiate for each button
@editable
ButtonBlueprint : widget_blueprint = widget_blueprint{}
# Grid configuration
@editable
Columns : int = 4
# Spacing between buttons in screen space (0.0 to 1.0)
@editable
SpacingX : float = 0.2
@editable
SpacingY : float = 0.2
# Starting offset from top-left (0.0, 0.0 is top-left)
@editable
StartX : float = 0.1
@editable
StartY : float = 0.1
OnBegin<override>()<suspends>: void =
# Calculate total buttons needed
TotalButtons : int = Columns * 3 # Example: 3 rows
# Loop through each button index
for (Index := 0..TotalButtons):
# Calculate Row and Column from Index
# Modulo gives us the column (0, 1, 2, 3...)
Col : int = Index % Columns
# Integer division gives us the row (0, 0, 0, 0, 1, 1...)
Row : int = Index / Columns
# Calculate screen position (0.0 to 1.0 range)
# We add spacing to push them apart
PosX : float = StartX + (Col * SpacingX)
PosY : float = StartY + (Row * SpacingY)
# Get the Player's UI
# Note: GetPlayerUI is fallible, so we use brackets []
if (Players := GetPlayers()):
if (FirstPlayer : player = Players[0]):
if (PlayerUI := GetPlayerUI(FirstPlayer)):
# Create a new widget instance from the blueprint
# We use the blueprint's Widget property to get the instance
NewWidget : widget = ButtonBlueprint.Widget
# Set the position on the canvas
# We assume the widget has a CanvasSlot or similar transform
# In Verse, we often set the 'Position' property of the widget
# or its slot if it's a canvas child.
# Here we set the widget's own position if it supports it,
# or we assume the blueprint handles its own layout.
# For strict Verse UI, we might need to access the slot.
# However, a common pattern is setting the widget's position directly
# if it's a simple button, or using a canvas slot.
# Let's assume we are adding it to a canvas slot.
# We need to create a canvas slot or use an existing one.
# For simplicity, let's just add the widget to the UI.
# The positioning is often handled by the widget's internal canvas slot.
# To actually position it, we typically manipulate the CanvasSlot
# if we have access to it. If the blueprint is a simple widget,
# we might need to wrap it or assume the blueprint has a slot.
# Let's try adding it and setting a simple anchor/offset if possible.
# Since direct position setting on 'widget' isn't always direct,
# we rely on the widget's internal structure.
# A robust way is to use the CanvasSlot's properties.
# But for this example, we will add the widget.
PlayerUI.AddWidget(NewWidget)
# Print debug info
Print("Added button at Col: ", Col, " Row: ", Row)
# Verse Cortex (UEFN-227): total integer modulo — Verse has no `%` operator.
# Returns A mod B via arithmetic; yields A when B<=0 (avoids a failing divide).
VC_IntMod(A:int, B:int):int =
if (B > 0):
A - (A / B) * B
else:
A```
## Try it yourself
1. **Change the Grid Size**: Modify `Columns` and add a `Rows` variable to see how the grid expands.
2. **Adjust Spacing**: Tweak `SpacingX` and `SpacingY` to make the buttons closer together or further apart.
3. **Add Click Events**: Subscribe to the `InteractedWithEvent` of the buttons (if they are devices) or add a click handler to the widget blueprint to perform actions when clicked.
## Recap
You've built a dynamic UI generator. By using `Mod` and integer division, you converted a linear list of items into a 2D grid. You used `GetPlayerUI[]` to safely access the player's interface and `AddWidget` to render your custom blueprint assets. This pattern scales infinitely, allowing you to create complex interfaces with just a few lines of code.
Check your understanding
Test yourself with an interactive quiz and track your progress + earn XP — free for members.
Want this as a guided course?
Build your own free, step-by-step lesson plan on Procedural UI Grid Generation in Verse — or pick any topic. Create a free account and the course builder turns it into compile-checked lessons, worked examples, and quizzes, tailored to your level.
© Biloxi Studios Inc. — original Verse Island content.
Original tutorial generated by Verse Island from the indexed Verse/UEFN knowledge base, with references to the Epic Games sources above. Code is validated against the knowledge base.