Script states

Logic-only states that decide where the flow goes.

Not every step of a flow is a screen. Has the player finished onboarding? Is there a daily reward? Did the save sync succeed? A script state answers a question like that and routes the flow, without a prefab of its own.

Writing a script state

A script state is an ordinary StateFlowComponent with triggers. Do the work in Enter and invoke the trigger for the answer:

FirstRunCheck.cs
using StateFlow.Runtime.Components.State;
using StateFlow.Runtime.Delegates;

public class FirstRunCheck : StateFlowComponent
{
    public event Trigger FirstRun;
    public event Trigger Returning;

    public override void Enter()
    {
        if (Onboarding.IsDone)
        {
            Returning?.Invoke();
        }
        else
        {
            FirstRun?.Invoke();
        }
    }
}

Add it with Create › Script State: give it a name and drag in the script. The script must derive from StateFlowComponent and must not be abstract.

StateFlow Editor — Script States
First Run Check, a purple script state and the entry state, routes to Welcome or Home. Home's Sync port leads to Sync Profile, another script state, whose Finished<String> port leads to a Sync Result popup.
Script states are purple. First Run Check is this graph's entry state, so it decides which screen appears first.

How they run

Waiting for something

The component lives on a GameObject, so it can run coroutines or await tasks. Here the Home screen stays visible, showing "Syncing…", while the script waits:

SyncProfile.cs
public class SyncProfile : StateFlowComponent
{
    public event Trigger<string> Finished;

    public override void Enter()
    {
        StartCoroutine(Sync());
    }

    private IEnumerator Sync()
    {
        yield return new WaitForSecondsRealtime(1.2f);   // stand-in for real network work

        Finished?.Invoke("Profile synced.");
    }
}
Play mode
A Sync complete popup showing the message passed on by the Sync Profile script state, open over the Home screen.
The result popup receives the message Sync Profile passed on.
Try it

Import Feature Samples from the Package Manager and open 06 Script States/06 Script States.unity. About the samples

Tip

If a script state may never fire a trigger, for example a request that can fail, give it a trigger for that outcome too. Otherwise the flow waits on it, and the screen underneath stays inactive.