Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/facepunch/sbox-public/llms.txt

Use this file to discover all available pages before exploring further.

Components are the building blocks of every s&box game object. A GameObject on its own is just a transform in the hierarchy; every piece of functionality — movement, rendering, physics, audio — is provided by one or more components attached to that object. This page covers how components work, their lifecycle callbacks, and how to add and query them from code.

What is a Component?

Component is an abstract C# class. You create behaviour by inheriting from it and overriding the lifecycle methods you need. Components live on a GameObject via its Components list and share the transform and scene of that object.
public class MyComponent : Component
{
    protected override void OnUpdate()
    {
        Log.Info( $"Running on {GameObject.Name} every frame" );
    }
}
Components that are enabled and whose parent GameObject is active will have their update methods called by the engine automatically — no registration required.

The component lifecycle

The engine calls the following virtual methods in a defined order. Override only the ones you need.
1

OnAwake

Called once, the first time the component becomes active. Use this for one-time initialisation that must run before OnEnabled.
protected override void OnAwake()
{
    // Runs once on first activation.
    // The GameObject and Scene are guaranteed to be valid here.
}
2

OnStart

Called once before the very first OnUpdate, after OnEnabled. Use this for anything that depends on other components having finished their OnAwake.
protected override void OnStart()
{
    // Runs once, just before the first frame update.
}
3

OnEnabled

Called every time the component transitions from inactive to active — either at first activation or after being re-enabled. Runs after OnAwake on first activation.
protected override void OnEnabled()
{
    // Subscribe to events, start timers, etc.
}
4

OnUpdate

Called every rendered frame while the component is active. Time.Delta contains the time in seconds since the last frame.
protected override void OnUpdate()
{
    Transform.LocalPosition += Vector3.Forward * Time.Delta * 100f;
}
OnUpdate does not run on a dedicated server. Use OnFixedUpdate for simulation logic that must run server-side.
5

OnFixedUpdate

Called on a fixed time step that matches the physics tick rate. Time.Delta is the fixed interval. Use this for physics forces, networked simulation, and anything that must be deterministic.
protected override void OnFixedUpdate()
{
    // Physics-safe, deterministic update.
}
6

OnDisabled

Called when the component becomes inactive — either because Enabled was set to false, or because an ancestor GameObject was disabled.
protected override void OnDisabled()
{
    // Unsubscribe from events, stop timers, etc.
}
7

OnDestroy

Called once when the component is permanently destroyed. After this returns, the component’s GameObject reference is set to null and IsValid returns false. Clean up any unmanaged resources here.
protected override void OnDestroy()
{
    // Final cleanup. Don't use the component after this.
}

Lifecycle order summary

CallbackWhen it runsFrequency
OnAwakeFirst activationOnce
OnStartBefore first OnUpdateOnce
OnEnabledEach time component becomes activePer activation
OnUpdateEvery render frame (not on dedicated server)Per frame
OnFixedUpdateEvery physics tickPer tick
OnDisabledEach time component becomes inactivePer deactivation
OnDestroyOn permanent removalOnce

The Enabled and Active properties

Enabled is what you set. Active is what the engine uses. A component is Active only when it is enabled and every ancestor GameObject in the hierarchy is also enabled.
myComponent.Enabled = false; // disable just this component

// Check true active state before doing work
if ( myComponent.Active )
{
    // safe to interact
}

Attaching components to a GameObject

Querying components

Use GetComponent<T> and related helpers to find components on a GameObject or in the surrounding hierarchy.

On the same object

// Get the first enabled component of type T on this object
var renderer = go.GetComponent<ModelRenderer>();

// Include disabled components
var renderer = go.GetComponent<ModelRenderer>( includeDisabled: true );

// Get all components of type T on this object
foreach ( var col in go.GetComponents<Collider>() )
{
    Log.Info( col );
}

Searching up and down the hierarchy

// Search this object and all ancestors
var health = go.GetComponentInParent<HealthComponent>();

// Search this object and all descendants
var gun   = go.GetComponentInChildren<GunComponent>();

// Get all matching components in descendants
var allLights = go.GetComponentsInChildren<Light>();

Using FindMode for fine-grained control

Components.GetAll<T>(FindMode) accepts a FindMode flags enum that lets you combine search scope and enabled state:
// Enabled components in self and all descendants
var results = go.Components.GetAll<Collider>( FindMode.EnabledInSelfAndDescendants );

// Everything (enabled + disabled) in self and ancestors
var results = go.Components.GetAll<AudioSource>( FindMode.EverythingInSelfAndAncestors );
GetComponent<T> and GetComponentInChildren<T> are the most readable options for common cases. Drop down to Components.GetAll<T>(FindMode) when you need precise control over scope or enabled state.

TryGet pattern

if ( go.Components.TryGet<Rigidbody>( out var rb ) )
{
    rb.Velocity = Vector3.Up * 400f;
}

Destroying a component

Destroy() removes just the component, leaving the GameObject and other components intact. To destroy the whole object, call DestroyGameObject().
myComponent.Destroy();       // remove this component only
myComponent.DestroyGameObject(); // remove the whole GameObject

Component flags

ComponentFlags control serialisation and networking behaviour:
FlagEffect
HiddenComponent is not shown in the editor inspector
NotSavedComponent is not saved to disk
NotNetworkedComponent is excluded from the network scene snapshot
NotClonedComponent is skipped when cloning the GameObject
// Hide this component from the inspector at runtime
Flags = ComponentFlags.Hidden;

Next steps

Scene and GameObject

Review how GameObjects are structured and found in the scene.

Prefabs

Package configured GameObjects into reusable prefab assets.

Build docs developers (and LLMs) love