Skip to main content
A Scene is the root container for everything that exists in your game at runtime. Every mesh, light, player, trigger, and piece of logic lives inside a Scene as a GameObject. GameObjects in turn hold Components that give them behavior — but before getting to components, it helps to understand how the hierarchy itself works.

The Scene

Scene inherits from GameObject, making it both the root node of the hierarchy and a special container that owns the physics world, the render world, the directory of all objects, and the frame tick.
// The currently active scene — available from anywhere
Scene active = Game.ActiveScene;

// Create a new blank scene
var scene = new Scene();

// Destroy a scene when you're done with it
scene.Destroy();
Only one scene is “active” at a time, exposed via Game.ActiveScene. Code you write in components always runs inside the active scene’s tick, so Game.ActiveScene is the scene you’re operating in.

Key Scene properties

PropertyTypeDescription
Game.ActiveSceneSceneThe scene currently being ticked
Scene.IsEditorboolTrue when this scene is an editor preview scene
Scene.PhysicsWorldPhysicsWorldThe physics simulation for this scene
Scene.SceneWorldSceneWorldThe render world that holds all scene objects
Scene.DirectoryGameObjectDirectoryFast lookup index for all GameObjects and components
Scene.TimeScalefloatMultiplier applied to Time.Delta each tick (0–1 for slow-motion)
Scene.WantsSystemSceneboolWhether to additive-load the project’s system scene on startup

Creating objects in a scene

Use Scene.CreateObject() to make a new root-level GameObject without worrying about scene push scopes:
// Creates a new enabled GameObject at the scene root
var go = Game.ActiveScene.CreateObject();
go.Name = "My Object";

Finding objects by tag

Scene exposes two helpers for tag-based search that iterate the full Directory:
// All GameObjects that have the "enemy" tag
foreach ( var enemy in Scene.FindAllWithTag( "enemy" ) )
{
    Log.Info( enemy.Name );
}

// All GameObjects that have every tag in the list
var tagged = Scene.FindAllWithTags( new[] { "pickup", "active" } );

GameObjects

A GameObject is a node in the scene hierarchy. On its own it has a name, a transform (position / rotation / scale), an enabled flag, and a tag set. All actual behavior comes from the components attached to it.
// Construct directly — automatically parents to Game.ActiveScene
var go = new GameObject( "Player" );

// Construct with a specific enabled state
var go2 = new GameObject( false, "Disabled Prop" );

// Construct with an explicit parent
var child = new GameObject( parentGo, true, "Child" );

Hierarchy

Every GameObject has one parent and can have any number of children. Setting Parent to null automatically re-parents to the scene root.
// Re-parent, preserving world position
child.SetParent( newParent, keepWorldPosition: true );

// Direct parent property (also keeps world position by default via SetParent)
child.Parent = anotherParent;

// Iterate children
foreach ( var c in go.Children )
{
    Log.Info( c.Name );
}

// Walk the whole subtree
foreach ( var obj in go.GetAllObjects( enabled: true ) )
{
    Log.Info( obj.Name );
}
IsRoot is true when a GameObject’s parent is the Scene itself. Use go.Root to climb to the top-most non-scene ancestor from anywhere in the hierarchy.

Enabled vs. Active

Enabled is what you set. Active is whether the object is actually running — it requires the object itself and all its ancestors to be enabled.
go.Enabled = false;  // Disable this object (and all its descendants)
bool alive = go.Active;  // False if any ancestor is also disabled
When Enabled changes, UpdateEnabledStatus propagates down through all components and children automatically.

Tags

Tags are free-form strings attached to a GameObject. Use them to categorize objects and find them with scene-wide queries.
go.Tags.Add( "enemy" );
go.Tags.Add( "boss" );

bool isEnemy = go.Tags.Has( "enemy" );
bool isBoss  = go.Tags.HasAll( new[] { "enemy", "boss" } );

GameObjectFlags

The Flags property on a GameObject controls editor and engine behaviour:
// Keep this object alive across scene loads
go.Flags = GameObjectFlags.DontDestroyOnLoad;

// Hide from the editor hierarchy and inspector
go.Flags |= GameObjectFlags.Hidden;

// Exclude from networking
go.Flags |= GameObjectFlags.NotNetworked;

// Only exist in the editor; don't spawn in-game
go.Flags |= GameObjectFlags.EditorOnly;

// Ignore the parent's transform (like `position: absolute`)
go.Flags |= GameObjectFlags.Absolute;
Setting DontDestroyOnLoad prevents the object from being cleaned up when a new scene loads. Make sure you manage its lifetime manually or it will persist for the entire session.

Destroying GameObjects

// Queue this object for destruction at end of frame
go.Destroy();

// Check the object is still alive before using it
if ( go.IsValid() )
{
    go.Destroy();
}

Putting it together

Here is a typical pattern: create a GameObject, configure it, add components, and parent it.
using var scope = Game.ActiveScene.Push();  // make this scene active for the scope

var container = new GameObject( "Enemies" );
container.Tags.Add( "group" );

for ( int i = 0; i < 5; i++ )
{
    var enemy = new GameObject( container, true, $"Enemy {i}" );
    enemy.Transform.LocalPosition = Vector3.Forward * i * 100f;
    enemy.Tags.Add( "enemy" );
    enemy.AddComponent<EnemyComponent>();
}

Components

Add behavior to GameObjects with components

Component lifecycle

Understand when OnAwake, OnUpdate, and friends are called

Build docs developers (and LLMs) love