The Scene Graph documentation provides a comprehensive overview of the fundamentals and core concepts of Scene Graph. The information and examples in this page help reinforce this and provides some insight to best practices that you should use when developing your projects.
Example Projects using Scene Graph
These projects provide practical examples using Scene Graph that you can download and reference. You can create projects using these examples when you create a new project and select them from the Feature Examples section of the Project Browser.
Alpha Tycoon
Using Scene Graph
Simulation Entity
The Simulation Entity acts as the root entity of the scene graph. It is essential for navigation, as well as for spawning new prefabs into the world.
# Get the Simulation Entity and Spawn a prefab
if:
SimulationEntity := Entity.GetSimulationEntity[]
then:
SpawnedPrefab:entity = LightPost.P_LightPost{}
SimulationEntity.AddEntities(array {SpawnedPrefab{})
# Set the transform for the Spawned Prefab
SpawnTransform:transform = transform:
Translation := vector3:
Left := -9084.0
Navigating the Hierarchy
Verse provides several standard methods for traversing the Scene Graph hierarchy. These methods allow you to locate entities both above and below the current point in the tree.
(InEntity:entity).FindDescendantEntities<native><public>(entity_type:castable_subtype(entity))<transacts>:generator(entity_type)
(InEntity:entity).FindAncestorEntities<native><public>(entity_type:castable_subtype(entity))<transacts>:generator(entity_type)
(InEntity:entity).FindDescendantEntitiesWithComponent<native><public>(component_type:castable_subtype(component))<transacts>:generator(entity)
(InEntity:entity).FindAncestorEntitiesWithComponent<native><public>(component_type:castable_subtype(component))<transacts>:generator(entity)You can also find Components up and down the tree using something like this:
(InEntity:entity).FindDescendantComponents<native><public>(component_type:castable_subtype(component))<transacts>:generator(component_type)
(InEntity:entity).FindAncestorComponents<native><public>(component_type:castable_subtype(component))<transacts>:generator(component_type)You should avoid repeated wide hierarchy scans during active gameplay. Instead, use hierarchy search APIs to discover relationships but do not rely on repeated full tree queries every time gameplay state changes. It's preferably to cache important references during initialization, subscribe to events, or narrow searches using prefab structure and tags.
This is what a good pattern can look like:
On begin simulation, find the needed child components once.
Store the references or subscribe to their events.
React to events instead of searching the graph again each time.
Prefab Composition
The Scene Graph sample project provides the P_LightPost prefab as an excellent illustration of prefab composition.
At the top level of the P_LightPost prefab, there is a Verse Component that encapsulates all the core logic. This component is responsible for orchestrating the light post's behavior.
The Verse Component subscribes to the InteractedWithEvent exposed by a child entity's interactable_component. When a player interacts with the light post, the event triggers the logic within the top-level Verse Component.
Upon interaction, the Verse Component "calls down" into child entities that house specific functional components (for example, particle systems, sounds, and lights) to execute the light post's logic, such as:
Toggling the light's visibility.
Playing a sound effect.
Activating or deactivating a particle system effect.
Setting a material parameter.
This pattern demonstrates a clean separation of concerns, where the parent Verse Component manages the high-level state and interaction, while child entities provide the specific visual and auditory effects.
This approach achieves a clear separation of responsibilities: the parent Verse Component handles the overall state and interaction logic, leaving the specific visual and auditory effects to the child entities.
Lantern Interaction Component
The following code showcases the top-level Verse Component's methodology of "calling down" into its child entities' functional components to control the light post's behavior.
using { /Verse.org }
using { /Verse.org/Native }
using { /Verse.org/SceneGraph }
using { /Verse.org/Simulation }
LightPost := module:
Materials<public> := module:
lantern_interaction_component<public> := class<final_super>(component):
Scene Events and Hierarchy Scope
Scene Events provide a powerful event system designed for transmitting events throughout entity hierarchies. However, just like querying the Scene Graph hierarchy, broadcasting events across large portions of the graph can become expensive, if used indiscriminately.
Events that propagate broadly through ancestor or descendant chains may trigger logic on many entities that do not need to respond to the event. In large hierarchies this can lead to unnecessary event handling and increased runtime cost.
To avoid this, prefer targeting events as narrowly as possible. Instead of broadcasting events from high levels of the hierarchy, send them from the most relevant entity or subsystem responsible for the interaction. When possible, structure prefabs so that events are handled within a localized portion of the Scene Graph rather than traversing the entire hierarchy.
In general, Scene Events should follow the same scalability guidelines as hierarchy queries:
Avoid sending events through large portions of the Scene Graph when a more localized approach will work.
Prefer direct references or localized subscriptions when the event scope is known.
Structure prefabs so that most interactions occur within the prefab’s local hierarchy.
Using Scene Events in a targeted way helps maintain predictable behavior and ensures Scene Graph systems remain efficient as projects grow in complexity.
For additional information and details on using Scene Events, see Scene Events.
Fort Round Manager
Scene Graph components execute code during Edit Mode, which is different from Creative Devices that only execute during Game Mode. If you want Scene Graph component code to execute when the Fortnite Round starts, you can subscribe to the RoundStarted event from fort_round_mananger.
OnBeginSimulation<override>():void =
(super:)OnBeginSimulation()
if:
FortRoundManager := Entity.GetFortRoundManager[]
then:
FortRoundManager.SubscribeRoundStarted(OnRoundStarted)
OnRoundStarted():void =
....
Entity Entered
Entities are capable of detecting overlaps with other entities in Scene Graph. This is handled through the EntityEntered event on mesh_component.
OnRoundStarted():void =
if:
Mesh := Entity.GetComponent[mesh_component]
then:
Mesh.EntityEnteredEvent.Subscribe(OnEntityEntered)
OnEntityEntered(OtherEntity:entity):void=
Print("Entity Entered")Sweeps and Raycasting
Verse supports spatial queries such as sweeps and ray casts for detecting collisions in the world. Sweeps allow you to move a shape through space and detect what it collides with along the way.
Raycast (Line Trace)
A common point of confusion is how to perform a line trace. In Verse, this is done using collision_point.
Displacement:vector3 = vector3{Left:= 0.0, Up:= 0.0,Forward:= 300.0}
CollisionPoint:= collision_point{}
# Line Trace Forward 300 units starting from the entity transform
for:
Hit : Entity.FindSweepHits(Displacement, Entity.GetGlobalTransform(), CollisionPoint)
do:
# Handle hit...Overlap Queries
Overlap queries allow you to detect all entities within a given shape at a specific location. Unlike raycasts or sweeps, overlaps do not trace through space. They check what is already intersecting a volume.
# Overlap using a custom collision volume at a specific transform
OverlapWithVolume():void =
CollisionCapsule := collision_capsule{Radius := 36.0, Length := 328.0}
QueryTransform := Entity.GetGlobalTransform()
for:
Hit : Entity.FindOverlapHits(QueryTransform, CollisionCapsule)
do:
# Cast the hit target to a specific component type
if (MyMesh := my_mesh_component[Hit.TargetComponent]):
Print("Hit mesh at: {Hit.SourceGlobalTransform.Translation}")Entity Movement
keyframed_movement_component is currently the most efficient way to move entities because it will do client side updates.
Drag and Drop Preference
There is an Editor Preference you can enable that changes the drag and drop functionality allowing it to prioritize the placements of Entities and Components over Actors, when feasible to do so.
To enable this, open the Editor Preferences from the Edit menu. Navigate to the Unreal Editor for Fortnite > Settings > Workflows > Drag and Drop, and uncheck the box for Prefer Actor Placement.
Tags
Entities within Scene Graph can have Verse Tags assigned to them. These tags allow you to locate and reference entities, regardless of whether they are higher or lower in the Scene Graph hierarchy.
You can add and remove Tags on Entities in the Details panel:
@experimental
# Finds all descendant entities including `InEntity` with `Tag` present in their `tag_component`.
# When querying from the simulation entity, the simulation entity itself is not included in the results.
# The order of the returned entities is unspecified and subject to change.
(InEntity:entity).FindDescendantEntitiesWithTag<native><public>(tag_type:castable_subtype(tag))<transacts>:generator(entity)
@experimental
# Finds all ancestor entities to `InEntity` with `Tag` present in their `tag_component`.
# The order of the returned entities is unspecified and subject to change.
(InEntity:entity).FindAncestorEntitiesWithTag<native><public>(tag_type:castable_subtype(tag))<transacts>:generator(entity)