Master Spatial Validation & Dynamic Spawning
What you'll learn
In this guide, you will master the art of Spatial Point Validation. You'll learn how to query the SceneGraph for existing items, calculate safe spawn points using vector math, and dynamically instantiate new props only when strict spatial rules are met. We'll also wire up a live Player UI to give creators immediate feedback on whether a spawn attempt succeeded or was blocked.
How it works
Dynamic spawning isn't just about calling SpawnProp; it's about ensuring the result fits your design intent. The workflow follows three critical steps:
- Query: Retrieve the current state of the world by iterating through
GetPlayspace().GetEntities()and extracting positional data viaGetGlobalTransform(). - Validate: Compare your candidate spawn coordinate against existing items. We use coordinate delta checks to ensure no object violates your
MinSpacingthreshold. - Execute & Feedback: If the point is clear, call
SpawnPropinside a<transacts>context. Simultaneously, update the Player UI (viaGetPlayerUI[]andAddWidget) so the player knows exactly what happened.
Let's build it
This device creates a "Loot Validator" button on the player's screen. Clicking it attempts to spawn a prop 100 units in front of the player. The script checks all existing entities; if any are too close, the spawn is denied and the console logs why. Otherwise, the prop appears and the counter increments.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/UI }
using { /Verse.org/SpatialMath }
using { /UnrealEngine.com/Temporary/SpatialMath }
spatial_loot_validator := class<concrete>(creative_device):
@editable LootAsset : creative_prop_asset = creative_prop_asset{}
@editable MinSpacing : float = 200.0
SpawnedCount : int = 0
OnBegin<override>()<suspends>: void =
# Initialize Player UI once when the device begins
if (FirstPlayer : GetPlayspace().GetPlayers()[0]):
if (PlayerUI : FirstPlayer.GetPlayerUI[]):
# Construct a real widget instance
SpawnButton := button_loud_device{}
# Add the widget to the player's canvas
PlayerUI.AddWidget(SpawnButton)
# Wire up the interaction to our validation logic
_ := SpawnButton.InteractedWithEvent.Subscribe(
_(:void)<suspends>: void =>
AttemptValidationAndSpawn[PlayerUI]
)
AttemptValidationAndSpawn<transacts>(TargetUI:player_ui)<suspends>: void =
# 1. Query: Get player position to calculate candidate spawn point
if (Character : GetPlayspace().GetPlayers()[0].GetFortCharacter[]):
PlayerPos := Character.GetGlobalTransform().Translation
# Define candidate point (100 units forward from player)
CandidatePos := vector3{
Left := PlayerPos.Left + 100.0,
Up := PlayerPos.Up,
Forward := PlayerPos.Forward
}
# 2. Validate: Check against all existing entities in the playspace
IsClear := true
for (Entity : GetPlayspace().GetEntities()):
# Only check entities that implement the positional interface
if (PosInterface : Entity.GetComponent[positional][]):
ExistingPos := PosInterface.GetGlobalTransform().Translation
# Perform coordinate delta validation
LowerBound := CandidatePos.Left - MinSpacing
UpperBound := CandidatePos.Left + MinSpacing
# Check if existing item overlaps our exclusion zone
if (ExistingPos.Left >= LowerBound && ExistingPos.Left <= UpperBound &&
ExistingPos.Up >= CandidatePos.Up - MinSpacing && ExistingPos.Up <= CandidatePos.Up + MinSpacing &&
ExistingPos.Forward >= CandidatePos.Forward - MinSpacing && ExistingPos.Forward <= CandidatePos.Forward + MinSpacing):
IsClear := false
break
# 3. Execute: Spawn only if validation passed
if (IsClear):
Result := SpawnProp[LootAsset, (/UnrealEngine.com/Temporary/SpatialMath:)FromVector3(CandidatePos)]
if (SpawnedProp : Result(0)):
SpawnedCount += 1
Print("Success! Spawned count: {SpawnedCount}")
else:
Print("SpawnProp returned failure.")
else:
Print("Blocked: Candidate point too close to existing geometry.")
Try it yourself
- Adjust Spacing: Change
MinSpacingto500.0and observe how the validator becomes much stricter. - Visualize Zones: Create a
trigger_volume_devicematching yourMinSpacingand visualize its bounds in-game to see the exclusion area. - Multiple Players: Modify the
OnBeginloop to attach the UI button to every player inGetPlayspace().GetPlayers()instead of just index[0].
Recap
You've successfully implemented a robust spatial validation system. By querying the SceneGraph, performing precise coordinate checks, and handling the SpawnProp result safely, you've automated balanced loot distribution. Remember: always validate your coordinates before mutating state to keep your island performant and bug-free.
Check your understanding
Test yourself with an interactive quiz and track your progress + earn XP — free for members.
Turn this into a guided course
Add Spatial Point Validation and Dynamic SceneGraph Spawning to your free study plan — we'll suggest related pages and stitch the lot into one compile-checked, self-guided lesson with worked examples and quizzes.
Original tutorial generated by Verse Island from the Verse/UEFN knowledge base, with references to the Epic Games sources above. Code is validated against the knowledge base.