Skip to main content

Quick Start

Get from a finished StoryFlow Editor project to a working in-game dialogue in just a few minutes.

Prerequisites

Make sure you have the StoryFlow package installed in your Unity project before continuing. See the Installation guide if you haven't done this yet. You will also need a StoryFlow Editor project with at least one script file.

1. Export Your Project

Before you can use your story in Unity, you need to export it from the StoryFlow Editor as a JSON build.

  1. Open your project in StoryFlow Editor
  2. Go to File > Export > JSON Export
  3. Choose a destination folder and click Export

The exporter creates a build directory containing your project data, scripts, and media files.

Live Sync alternative

You can skip manual export entirely by using Live Sync. Open StoryFlow > Live Sync in Unity, connect to the editor, and click Request Sync. Your project is imported automatically. See Live Sync for details.

2. Import into Unity

Use the built-in import window to bring your exported project into Unity.

  1. In Unity, go to StoryFlow > Import Project in the menu bar.
  2. Set the Build Directory to the path of your exported build folder.
  3. Click Import Project.

The importer creates assets in Assets/StoryFlow — script assets, character assets, and media files, preserving the original folder structure from the editor.

3. Add the Component

Add a StoryFlowComponent to any GameObject that needs to run dialogue — typically an NPC, a dialogue trigger, or a game manager.

  1. Select a GameObject in your scene.
  2. Click Add Component and search for StoryFlowComponent.
  3. Optionally assign a Script asset in the Inspector (if left empty, the project's startup script is used automatically).

That's the entire setup. No manual manager creation needed — the plugin auto-creates a StoryFlowManager at runtime and auto-discovers your imported project.

4. Run It

Start the dialogue by calling StartDialogue on the component:

C#
// Start dialogue (e.g., when the player interacts with an NPC)
var storyFlow = GetComponent<StoryFlowComponent>();
storyFlow.StartDialogue();

A built-in dialogue UI appears automatically — dark panel at the bottom with character portrait, name, dialogue text, and option buttons. No UI setup needed for prototyping.

The component fires events as the script executes:

  1. OnDialogueStarted — Dialogue session began.
  2. OnDialogueUpdated — New dialogue node reached. The StoryFlowDialogueState parameter contains text, character, options, images, and audio.
  3. OnDialogueEnded — Script reached an End node.

You're up and running!

You now have a working dialogue system in Unity. Edit your scripts in the StoryFlow Editor, sync or re-import, and your in-game dialogue updates. Use Live Sync to see changes in real time without re-importing.

Customizing the UI

The built-in UI is great for prototyping, but for production you'll want your own look. There are three approaches:

Option A: Extend StoryFlowDialogueUI

Create a custom script that extends StoryFlowDialogueUI and override the virtual methods. Assign it to the component's Dialogue UI field to replace the built-in UI:

C#
using StoryFlow.Data;
using StoryFlow.UI;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

public class MyDialogueUI : StoryFlowDialogueUI
{
    [SerializeField] private TextMeshProUGUI speakerText;
    [SerializeField] private TextMeshProUGUI dialogueText;
    [SerializeField] private Transform optionsContainer;
    [SerializeField] private Button optionButtonPrefab;

    public override void HandleDialogueUpdated(StoryFlowDialogueState state)
    {
        speakerText.text = state.Character?.Name ?? "";
        dialogueText.text = state.Text;

        // Clear and rebuild option buttons
        foreach (Transform child in optionsContainer)
            Destroy(child.gameObject);

        foreach (var option in state.Options)
        {
            var button = Instantiate(optionButtonPrefab, optionsContainer);
            button.GetComponentInChildren<TextMeshProUGUI>().text = option.Text;
            var id = option.Id;
            button.onClick.AddListener(() => SelectOption(id));
        }

        // Show continue button when no options
        if (state.Options.Count == 0 && state.CanAdvance)
        {
            var button = Instantiate(optionButtonPrefab, optionsContainer);
            button.GetComponentInChildren<TextMeshProUGUI>().text = "Continue";
            button.onClick.AddListener(() => AdvanceDialogue());
        }
    }

    public override void OnDialogueStarted() => gameObject.SetActive(true);
    public override void OnDialogueEnded() => gameObject.SetActive(false);
}

Option B: Subscribe to Events Directly

For full control, skip the base class and subscribe to the component's C# events:

C#
var storyFlow = GetComponent<StoryFlowComponent>();
storyFlow.OnDialogueUpdated += state =>
{
    // Update your UI with state.Text, state.Options, state.Character, etc.
};
storyFlow.OnDialogueEnded += () =>
{
    // Hide dialogue UI
};

Which approach should I use?

Leave Dialogue UI empty for prototyping (built-in UI auto-creates). Use Option A for custom visuals with automatic lifecycle management. Use Option B for integrating into an existing UI system.

Need Help?

Join our Discord community to ask questions, share your projects, report bugs, and get support from the team and other users.

Join Discord