Skip to main content

Sequence System

Build gameplay presentation flows as declarative step lists instead of deeply nested coroutines.

Structure

SequenceAsset (ScriptableObject)
[SerializeReference] List<SequenceStep>

SequenceRunner (MonoBehaviour)
- Runs steps in order as coroutines

SequenceStep (abstract, [Serializable])
- Base class for custom steps

Built-In Steps

StepDescription
WaitStepWaits for N seconds
MoveStepMoves a Transform to a destination with easing
FadeStepAnimates CanvasGroup alpha
ScaleStepAnimates Transform scale
SoundStepPlays an AudioClip
CallbackStepInvokes a UnityEvent

Quick Start

Option A: SequenceAsset

Create -> AchUtils/Sequence/Sequence Asset

Add steps in the inspector, then run the asset:

using AchUtils.Sequence;

[SerializeField] SequenceAsset introSequence;
[SerializeField] SequenceRunner runner;

void PlayIntro()
{
runner.Run(introSequence);
}

Option B: Build in Code

var steps = new List<SequenceStep>
{
new FadeStep { Target = overlay, TargetAlpha = 1f, Duration = 0.3f },
new WaitStep { Duration = 0.5f },
new MoveStep { Target = boss, Destination = centerPos, Duration = 1f },
new ScaleStep { Target = boss, TargetScale = Vector3.one * 1.5f, Duration = 0.3f },
new SoundStep { Clip = bossRoar },
new FadeStep { Target = overlay, TargetAlpha = 0f, Duration = 0.5f },
};

runner.Run(steps);

API

SequenceRunner

void Run(SequenceAsset asset)
void Run(IEnumerable<SequenceStep> steps)
void Stop()

bool IsRunning

event Action OnCompleted
event Action OnStopped

MoveStep

Transform Target
Vector3 Destination
float Duration
AnimationCurve Ease
bool UseLocalSpace

FadeStep

CanvasGroup Target
float TargetAlpha
float Duration
AnimationCurve Ease

ScaleStep

Transform Target
Vector3 TargetScale
float Duration
AnimationCurve Ease

SoundStep

AudioClip Clip
float Volume
bool WaitUntilFinished

SoundStep plays the clip at the SequenceRunner position and does not depend on Camera.main.

CallbackStep

UnityEvent OnExecute

Custom Steps

[Serializable]
public class ShowPanelStep : SequenceStep
{
public GameObject Panel;
public float HoldDuration = 2f;

public override IEnumerator Execute(SequenceRunner runner)
{
Panel.SetActive(true);
yield return new WaitForSeconds(HoldDuration);
Panel.SetActive(false);
}
}

Add [Serializable] so the type can be selected through [SerializeReference].

Completion Event

runner.OnCompleted += () =>
{
Debug.Log("Intro sequence completed");
StartGameplay();
};

runner.Run(introSequence);

Boss Intro Example

FadeStep Overlay fade in
WaitStep Wait 0.5s
MoveStep Boss enters
ScaleStep Boss scales up
SoundStep Boss roar
FadeStep Overlay fade out
CallbackStep Show UI