> ## Documentation Index
> Fetch the complete documentation index at: https://docs-unity.molca.id/llms.txt
> Use this file to discover all available pages before exploring further.

# Set up a basic sequence with custom steps

> Create a SequenceController with custom Step components for ordered execution.

**Applies to:** Molca Core

## Overview

This recipe shows you how to create a `SequenceController` with custom `Step` components to execute training or onboarding tasks in order. The controller manages step activation, listens for completion events, and advances through child steps automatically. This is the foundation for building training scenarios, tutorials, and any workflow that requires sequential execution.

## Prerequisites

* **SDK modules**: Molca Core installed
* **Unity setup**: RuntimeManager configured in your scene
* **Prior knowledge**: [RuntimeManager](/core/runtime-manager), [Dependency injection](/core/dependency-injection)

## Step-by-step

### Step 1: Create a GameObject with SequenceController

Add a `SequenceController` component to a GameObject in your scene. This will be the parent container for all your steps.

```csharp theme={null}
// In the Unity Editor:
// 1. Create an empty GameObject (right-click Hierarchy → Create Empty)
// 2. Rename it to "TrainingSequence"
// 3. Add Component → Molca → Sequence → SequenceController
```

**Why this works**: The `SequenceController` manages the execution state (`Idle`, `Running`, `Paused`, `Completed`) and calls `UpdateStep()` on the active step each frame.

### Step 2: Create child GameObjects for each step

Under the `SequenceController` GameObject, create child GameObjects for each step in your sequence. The controller executes steps in hierarchy order (top to bottom).

```csharp theme={null}
// In the Unity Editor:
// 1. Right-click "TrainingSequence" → Create Empty
// 2. Rename to "Step1_Introduction"
// 3. Repeat for "Step2_Practice", "Step3_Assessment"
```

**Why this works**: The `SequenceController` discovers child `Step` components automatically and executes them in the order they appear in the hierarchy.

### Step 3: Add Step components to child GameObjects

Add `Step` components (or custom `Step` subclasses) to each child GameObject. You can use built-in Core step types or create your own.

```csharp theme={null}
// In the Unity Editor:
// 1. Select "Step1_Introduction"
// 2. Add Component → Molca → Sequence → Step
// 3. Repeat for other step GameObjects
```

**Why this works**: Each `Step` component tracks its own status (`Inactive`, `Active`, `Completed`) and dispatches completion events via `EventDispatcher` when finished.

### Step 4: Create a custom Step subclass

For custom logic, create a `Step` subclass. This example creates a timed step that completes after a delay.

```csharp theme={null}
using Molca.Sequence;
using UnityEngine;

public class TimedIntroductionStep : Step
{
    [SerializeField] private float displaySeconds = 3f;
    private float _elapsed;

    protected override void OnStepActivated()
    {
        base.OnStepActivated();
        _elapsed = 0f;
        Debug.Log("Introduction step started");
    }

    public override void UpdateStep()
    {
        base.UpdateStep();
        _elapsed += Time.deltaTime;
        
        if (_elapsed >= displaySeconds)
        {
            Debug.Log("Introduction complete");
            Complete();
        }
    }
}
```

**Why this works**: Overriding `OnStepActivated()` lets you initialize state when the step becomes active. Calling `Complete()` dispatches `Step.Completed` and `Step.FullyCompleted` events, which the `SequenceController` listens for to advance to the next step.

### Step 5: Start the sequence from code

Create a script to start the sequence after `RuntimeManager` initialization. The controller requires injected dependencies (`EventDispatcher`, `ReferenceManager`) to function.

```csharp theme={null}
using Molca;
using Molca.Sequence;
using UnityEngine;

public class SequenceStarter : MonoBehaviour
{
    [SerializeField] private SequenceController sequence;

    private async void Start()
    {
        // Wait for RuntimeManager to inject dependencies
        await RuntimeManager.WaitForInitialization();
        
        // Start the sequence
        sequence.StartSequence();
    }
}
```

**Why this works**: `RuntimeManager.WaitForInitialization()` ensures that dependency injection is complete before starting the sequence. Without this, the `SequenceController` won't have access to `EventDispatcher` and will fail to listen for step completion events.

## Complete example

Here's a complete custom step that waits for user input before completing:

```csharp theme={null}
using Molca.Sequence;
using UnityEngine;

/// <summary>
/// A step that completes when the user presses the Space key.
/// </summary>
public class WaitForInputStep : Step
{
    [SerializeField] private KeyCode triggerKey = KeyCode.Space;
    [SerializeField] private string instructionText = "Press Space to continue";

    protected override void OnStepActivated()
    {
        base.OnStepActivated();
        Debug.Log(instructionText);
    }

    public override void UpdateStep()
    {
        base.UpdateStep();
        
        if (Input.GetKeyDown(triggerKey))
        {
            Debug.Log("Input received, advancing to next step");
            Complete();
        }
    }

    protected override void OnStepDeactivated()
    {
        base.OnStepDeactivated();
        Debug.Log("Step deactivated");
    }
}
```

Attach this script to a child GameObject under your `SequenceController`, and it will wait for the Space key before advancing.

## Troubleshooting

* **Sequence never starts**: Ensure you call `StartSequence()` only after `RuntimeManager.WaitForInitialization()`. The controller uses `[Inject]` for `EventDispatcher` and `ReferenceManager`.
* **Step never advances**: Verify that your custom step calls `Complete()` when finished. The `SequenceController` listens for `Step.Completed` and `Step.FullyCompleted` events via `EventDispatcher`.
* **Steps run out of order**: Child `Step` components execute in hierarchy order (top to bottom). Reorder GameObjects in the Hierarchy or use the [Sequence Visualizer](/core/sequence-visualizer) to adjust the order.
* **Pause doesn't freeze step logic**: `PauseSequence()` stops advancement but does not pause `Time.deltaTime`. If your step has timer logic, check `SequenceController.SequenceState` and skip updates when paused.

## Related

* [SequenceController](/core/sequence-controller) — manages ordered step execution and state
* [Step](/core/step) — base class for all step components
* [Core step types](/core/core-step-types) — built-in step types like `ParallelStep`, `AnimationStep`
* [Sequence Visualizer](/core/sequence-visualizer) — editor tool for browsing and editing step hierarchies
