Skip to main content
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

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.
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).
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.
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.
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.
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:
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 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.