Skip to main content
Component is the abstract base class you extend to write gameplay code. Every component lives on a GameObject, and the engine calls its lifecycle methods automatically as the object is created, enabled, updated, and destroyed.
public sealed class Rotator : Component
{
    [Property] public float Speed { get; set; } = 90f;

    protected override void OnUpdate()
    {
        WorldRotation = WorldRotation.RotateAroundAxis( Vector3.Up, Speed * Time.Delta );
    }
}

Properties

GameObject
GameObject
The GameObject this component belongs to. Becomes null after the component is destroyed — at which point IsValid also returns false.
Scene
Scene
Shortcut for GameObject.Scene. The scene this component is in.
Transform
GameTransform
Shortcut for GameObject.Transform. See GameTransform for the full reference.
Enabled
bool
Whether this component wants to be active. Does not account for parent GameObject state — use Active to check whether the component is truly running.
GetComponent<Collider>().Enabled = false;
Active
bool
True when the component is enabled and its parent GameObject is active. Lifecycle callbacks such as OnUpdate only run when Active is true.
IsValid
bool
True when the component still has a GameObject and is in a scene. Use this to guard stale references.
if ( _target.IsValid() )
    _target.TakeDamage( 10 );
Tags
ITagSet
The tags of the parent GameObject. Shortcut for GameObject.Tags.
Components
ComponentList
The component list of the parent GameObject. Shortcut for GameObject.Components.
Task
TaskSource
Provides async helpers (Task.DelaySeconds, etc.) that are automatically cancelled when the GameObject is disabled or destroyed. Use this instead of raw Task.Delay to avoid dangling async operations.
protected override void OnEnabled()
{
    _ = SpawnAfterDelay();
}

async Task SpawnAfterDelay()
{
    await Task.DelaySeconds( 3f );
    // If the GameObject was destroyed, execution stops here automatically
    SpawnProjectile();
}

World-space transform shortcuts

These properties forward to the parent GameObject’s world transform.
WorldTransform
Transform
Full world-space transform (position + rotation + scale).
WorldPosition
Vector3
World-space position.
WorldPosition += Vector3.Forward * Speed * Time.Delta;
WorldRotation
Rotation
World-space rotation.
WorldRotation = Rotation.LookAt( target - WorldPosition );
WorldScale
Vector3
World-space scale.

Local-space transform shortcuts

LocalTransform
Transform
Full local-space transform relative to the parent GameObject.
LocalPosition
Vector3
Position relative to the parent.
LocalRotation
Rotation
Rotation relative to the parent.
LocalScale
Vector3
Scale relative to the parent.

Lifecycle methods

Override these virtual methods to respond to engine events. You do not need to call the base implementation unless the docs say otherwise.

OnAwake

protected virtual void OnAwake()
Called once when the component is first initialized, before OnEnabled. Called even if the component starts disabled. Use this to cache references to other components.
CharacterController _cc;

protected override void OnAwake()
{
    _cc = Components.Get<CharacterController>();
}

OnEnabled

protected virtual void OnEnabled()
Called whenever the component transitions from inactive to active — either after OnAwake completes, or whenever Enabled (or the parent GameObject) switches back on.

OnStart

protected virtual void OnStart()
Called once, just before the first OnUpdate, after the component has been fully initialized and enabled. A good place for one-time setup that depends on the scene being fully loaded.

OnUpdate

protected virtual void OnUpdate()
Called every frame while the component is active. Time.Delta is the time elapsed since the last frame, in seconds.
protected override void OnUpdate()
{
    var move = Input.AnalogMove;
    WorldPosition += WorldRotation * move * MoveSpeed * Time.Delta;
}
OnUpdate does not run on a dedicated server. Implement server-side logic in OnFixedUpdate.

OnFixedUpdate

protected virtual void OnFixedUpdate()
Called at a fixed time step that matches the physics simulation rate. Time.Delta is the fixed interval. Use this for physics-dependent logic such as applying forces or processing networked input.
protected override void OnFixedUpdate()
{
    if ( _cc.IsOnGround && Input.Pressed( "Jump" ) )
        _cc.Punch( Vector3.Up * JumpStrength );

    _cc.Move();
}

OnPreRender

protected virtual void OnPreRender()
Called every frame, just before rendering. Use this to update scene objects that need to be synchronized to the camera or final transform state, such as view models or effects. Does not run on a dedicated server.

OnDisabled

protected virtual void OnDisabled()
Called whenever the component transitions from active to inactive. The inverse of OnEnabled. Always paired: if OnEnabled ran, OnDisabled will run before the component is destroyed.

OnDestroy

protected virtual void OnDestroy()
Called once, just before the component is removed. Clean up subscriptions, native handles, and other resources here. After this returns, GameObject is set to null.
protected override void OnDestroy()
{
    Scene.GetSystem<EventSystem>()?.Unsubscribe( this );
}

OnValidate

protected virtual void OnValidate()
Called immediately after deserialization and whenever a property is changed in the editor. Use this to clamp values or react to inspector edits.
protected override void OnValidate()
{
    Speed = Speed.Clamp( 0f, 1000f );
}

OnRefresh

protected virtual void OnRefresh()
Called after the component’s state is refreshed from a network snapshot. Use this to react to networked property updates that require side effects beyond what [Sync] provides.

OnParentChanged

protected virtual void OnParentChanged( GameObject oldParent, GameObject newParent )
Called when the parent GameObject changes. Useful for updating cached references that depend on the hierarchy.

OnTagsChanged

protected virtual void OnTagsChanged()
Called when the tag set of the parent GameObject changes. Use this to react to tag-based state changes.

Component query methods

These methods are identical to the GameObject equivalents but operate on the component’s own GameObject.
// Get another component on the same GameObject
var rb = GetComponent<Rigidbody>();

// Get a component in a child
var muzzle = GetComponentInChildren<MuzzleFlash>();

// Add a component
var audio = AddComponent<SoundComponent>();
See GameObject component methods for the full list and signatures.

Other methods

Destroy

public void Destroy()
Removes this component from its GameObject. The component’s OnDisabled and OnDestroy callbacks run before it is removed. The GameObject itself is unaffected.
// Remove only this component
GetComponent<TempEffect>()?.Destroy();

DestroyGameObject

public void DestroyGameObject()
Destroys the parent GameObject and all its components and children. This is a convenience wrapper around GameObject.Destroy().

Invoke

public async void Invoke( float secondsDelay, Action action, CancellationToken ct = default )
Calls action after secondsDelay seconds. Silently does nothing if the component is no longer active when the delay expires.
// Respawn the player 3 seconds after death
Invoke( 3f, Respawn );

Complete minimal example

public sealed class HealthComponent : Component
{
    [Property, Sync] public float MaxHealth { get; set; } = 100f;
    [Property, Sync] public float Health { get; private set; }

    protected override void OnAwake()
    {
        Health = MaxHealth;
    }

    public void TakeDamage( float amount )
    {
        if ( !Active ) return;

        Health -= amount;

        if ( Health <= 0f )
            Die();
    }

    void Die()
    {
        Log.Info( $"{GameObject.Name} died." );
        Invoke( 2f, DestroyGameObject );
    }

    protected override void OnValidate()
    {
        MaxHealth = MaxHealth.Clamp( 1f, 10000f );
    }
}

Build docs developers (and LLMs) love