Skip to content

About

Official Arcweave plugin for Unity. Bring branching dialogue and story logic into your game.

Topics

Resources

Stars

6 stars

Watchers

2 watching

Forks

Latest commit

 

History

113 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Arcweave Plugin for Unity

This plugin imports Arcweave projects into Unity. It supports data exported from Arcweave Project > Export > Engine > Export for Unity (available to all users) or fetched via Arcweave's web API (available to Team workspaces only).


Table of Contents


Installation

Choose one of the following methods:

Prerequisite: Unity UI

The bundled demo uses the Unity UI package. If your project does not already include it, install Unity UI (com.unity.ugui, version 2.0.0 or a compatible production release) from Window > Package Manager before importing the plugin. New Unity 6000.5 projects do not include this package by default, and the demo scripts cannot compile without it.

Method 1: Unity Package from GitHub - Recommended

  1. Download ArcweaveForUnity.unitypackage from the latest GitHub release
  2. In Unity, go to Assets > Import Package > Custom Package and select the downloaded file
  3. Click Import. You can untick the Demo folder if you don't need the demo scene

Alternatively, download ArcweaveForUnity.zip, extract it, and copy the Arcweave folder into your Unity project's Assets folder.

Method 2: Unity Asset Store

  1. Get the asset from the Unity Asset Store
  2. Open Unity and go to Window > Package Manager
  3. Select My Assets from the dropdown
  4. Find Arcweave for Unity and click Download, then Import

Note: This repository is not structured as a UPM (Unity Package Manager) package and cannot be installed via Git URL.


Getting Data from Arcweave

Option 1: Export for Unity

In Arcweave:

  1. Open your project
  2. Click the Export icon in the top bar
  3. Go to the Engine tab
  4. Click Export for Unity
  5. Check Include Assets if your project uses images or audio

You will get a .zip file containing:

  • project.json: all data of your Arcweave project
  • (Optional) assets/Images/: project image assets (if "Include Assets" was checked)
  • (Optional) assets/Audio/: project audio assets (if "Include Assets" was checked)
  • (Optional) cover/cover.jpg: the project cover image

File placement:

  • Place project.json anywhere in your Unity project's Assets folder.
  • For this demo project, images must go in a Resources folder (create one if it doesn't exist) or they won't load at runtime.

Option 2: Use Arcweave's Web API

Available to Team workspaces.

You will need:

  • Your Team workspace API key (found in your Workspace's API section).
  • Your project hash (found in Project Properties).

Importing from web can also download the images and audio your project uses (see Media Downloaded from Web), so you don't need to copy them into a Resources folder.

See the Arcweave API Documentation for details.


Creating an ArcweaveProjectAsset

To import your data into Unity:

  1. Right-click in the Unity Project Window.
  2. Navigate to Create > Arcweave > Project Asset.
  3. Name the new .asset file as you prefer.
  4. Select it to open the Inspector.

Import Settings

Choose your import source:

  • From Json: Drag your project.json file into the "Project Json File" field.
  • From Web: Enter your API Key and Project Hash. Optionally enable Download Media to download the project's images and audio.

Click the Import Project button to begin the import.

Media Downloaded from Web

Download Media is disabled by default, so your project only relies on media downloaded from Arcweave if you choose to. When it is enabled, importing from web in the Unity Editor downloads every image used as an element or component cover and every audio file attached to an element through Arcweave's web API. The first import saves the files in a <Project Asset Name> Media folder next to the project asset, named after their Arcweave asset ids, and links them to the imported project, so they are included in builds without a Resources folder.

  • Each import refreshes the media: changed files are updated in place and files the project no longer uses are deleted. The importer only overwrites or deletes files it downloaded for that project asset, so you can move or rename the folder and its files. A duplicated project asset downloads its own copy of the media.
  • If a file fails to download, the import continues, keeps any previously downloaded copy of that file, and logs a warning.
  • Unity cannot import some formats Arcweave accepts (.webp images and .webm audio). These are skipped with a warning.
  • Media downloads count towards your workspace's API rate limit. When the limit is reached, the importer waits up to a minute and tries each media download again, up to five attempts in total, so importing projects with lots of media can take a while. Click Cancel on the progress bar to stop downloading; media that was not downloaded keeps its previous copy.
  • Media is only downloaded in the Unity Editor, including when ArcweavePlayer imports the project on Play. Reimporting in a built player keeps the media downloaded in the editor for the assets the project still uses.

Leave Download Media disabled to provide images and audio yourself in a Resources folder, as described below. Disabling it later doesn't delete downloaded files, but the next import no longer uses them.

After successful import, the Inspector displays:

  • The project name
  • All global variables and their values
  • An "Open Project Viewer" button for viewing the project flowchart

If you press Play before importing, ArcweavePlayer imports the project automatically. You can also import from code with await aw.ImportProjectAsync(), or await aw.EnsureImportedAsync() to import only when the asset has no playable project yet.

Warning: The API key is saved in the asset and ships with your build. Treat From Web as a development workflow and import the project in the editor before building, so your game doesn't need the API key or a network connection to start.


Using the Demo Scene

The plugin includes a Demo folder with a complete example scene.

Running the Demo

  1. Open ArcweaveDemoScene from the Demo folder.
  2. Select the ArcweavePlayer GameObject in the hierarchy.
  3. Assign your imported project asset to the AW field.
  4. Press Play.

Unity 6+ Input System Fix

If you're using Unity 6 or newer, you need to update the Input System module:

  1. In the Hierarchy, select the EventSystem GameObject
  2. In the Inspector, find the Standalone Input Module component
  3. Click the Replace with InputSystemUIInputModule button
  4. This upgrades the legacy Input Manager to the new Input System

Without this step, UI interactions (buttons, clicks) will not work in Unity 6+.

Adding Image Assets

Images are downloaded when importing from web with Download Media enabled. Otherwise:

  1. Create a Resources folder in your Unity project (if it doesn't exist).
  2. Copy your image files into the Resources folder.
  3. Ensure image filenames match those in Arcweave (without extension).
  4. Set each image's Texture Type to Default in Import Settings.

The plugin loads images dynamically using Resources.Load().

Adding Audio Assets

Audio is downloaded when importing from web with Download Media enabled. Otherwise:

  1. Create a Resources folder in your Unity project (if it doesn't exist).
  2. Copy your audio files into the Resources folder.
  3. Ensure audio filenames match those in Arcweave (including extension, e.g. sfx.mp3).

The plugin resolves audio clips dynamically using AudioAsset.TryGetAudioClip(), which calls Resources.Load<AudioClip>() with the filename (without extension).


How the Demo Works

The demo consists of two main components that work together:

Architecture Overview

┌─────────────────────────────────────────────────────────────────┐
│                      ArcweavePlayer                              │
│  (Handles narrative logic, traversal, and state management)      │
├─────────────────────────────────────────────────────────────────┤
│  Events:                                                         │
│  ├── onProjectStart    → Fired when narrative begins             │
│  ├── onElementEnter    → Fired when entering any element         │
│  ├── onElementOptions  → Fired when multiple choices available   │
│  ├── onWaitInputNext   → Fired when single path (continue)       │
│  └── onProjectFinish   → Fired when narrative ends               │
└─────────────────────────────────────────────────────────────────┘
                              │
                              │ subscribes to events
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                     ArcweavePlayerUI                             │
│  (Handles all visual display and user interaction)               │
├─────────────────────────────────────────────────────────────────┤
│  Responsibilities:                                               │
│  ├── Display dialogue text (RuntimeContent)                      │
│  ├── Display cover images and character portraits                │
│  ├── Create choice buttons dynamically                           │
│  ├── Handle button clicks → invoke callbacks                     │
│  └── Manage Save/Load UI                                         │
└─────────────────────────────────────────────────────────────────┘

Event Flow Diagram

         PlayProject()
              │
              ▼
    ┌─────────────────┐
    │   Initialize    │ ← Resets all variables and visits
    │     Project     │
    └────────┬────────┘
              │
              ▼
    ┌─────────────────┐
    │ onProjectStart  │ ← UI can show "Game Started" message
    └────────┬────────┘
              │
              ▼
    ┌─────────────────┐
    │  Enter Element  │ ← element.Visits++ (incremented)
    │                 │
    └────────┬────────┘
              │
              ▼
    ┌─────────────────┐
    │ onElementEnter  │ ← UI displays content and images
    └────────┬────────┘
              │
              ▼
    ┌─────────────────┐
    │  GetOptions()   │ ← Evaluates all branch conditions
    └────────┬────────┘
              │
      ┌───────┴───────┐
      │               │
      ▼               ▼
┌───────────┐   ┌───────────┐   ┌───────────┐
│ Multiple  │   │  Single   │   │ No Paths  │
│  Paths    │   │   Path    │   │  (End)    │
└─────┬─────┘   └─────┬─────┘   └─────┬─────┘
      │               │               │
      ▼               ▼               ▼
┌───────────┐   ┌───────────┐   ┌───────────┐
│onElement- │   │onWaitInput│   │onProject- │
│  Options  │   │   Next    │   │  Finish   │
└─────┬─────┘   └─────┬─────┘   └───────────┘
      │               │
      │  callback(i)  │  callback()
      │               │
      └───────┬───────┘
              │
              ▼
    ┌─────────────────┐
    │ Execute Path    │ ← Runs Arcscript in connection labels
    │ Connection      │
    │ Labels          │
    └────────┬────────┘
              │
              ▼
         Enter Next
          Element
           (loop)

Key Methods Used in Demo

Method Class Purpose
Project.Initialize() Project Reset variables and visits before starting
element.Visits++ Element Track how many times element was visited
element.GetOptions() Element Get available paths from current element
element.RuntimeContent Element Get evaluated dialogue text
element.RunContentScript() Element Execute Arcscript and update RuntimeContent
element.GetCoverOrFirstComponentImage() Element Get element's cover or first component image
element.GetAudioAssets() Element Get audio assets attached to the element
path.ExecuteAppendedConnectionLabels() Path Run Arcscript in connection labels
path.text Path Get label text or target element title
options.Paths Options List of valid paths to choose from
options.hasPaths Options Check if any paths exist
options.hasOptions Options Check if multiple choices available

Plugin Documentation

Project

The root container for an imported Arcweave project. Access via ArcweaveProjectAsset.Project.

Properties

Property Type Description
name string Project name
boards List<Board> All boards in the project
components / Components List<Component> All components (characters/entities)
GlobalVariables List<Variable> All global/project-scoped variables
Variables List<Variable> Deprecated alias for GlobalVariables
StartingElement Element Entry point for the narrative

Methods

Method Description
void Initialize() Must call before use. Resets all variables and visit counts.
Board BoardWithID(string id) Get board by ID
Board BoardWithName(string name) Get board by name
Element ElementWithId(string id) Get element by ID
T GetNodeWithID<T>(string id) Get any node by ID and type
Variable GetVariable(string name, string scope = null) Get a variable by name. Pass a board or component CustomId for scoped variables
IEnumerable<Variable> GetAllVariables() Enumerate global, board-scoped, and component-scoped variables
bool SetVariable(string name, object value) Set a global/project-scoped variable by name
bool SetVariable(string name, string scope, object value) Set a scoped variable by name and owner CustomId
void ResetVariablesToDefaultValues() Reset all variables to defaults
string SaveVariables() Serialize current global and scoped variable state to JSON
void LoadVariables(string json) Restore current global and scoped variable state from JSON
int Visits(string elementId) Get visit count for an element
void ResetVisits() Reset all visit counts to 0

Scoped Variables

Boards and components can define scoped variables in addition to project/global variables. In current exports, scoped variables are backed by boolean, integer, float, or plain-string attributes with a custom ID.

  • Project.GlobalVariables contains only project/global variables.
  • Board.Variables and Component.Variables contain their scoped variables.
  • Project.GetAllVariables() enumerates variables from all three scopes.
  • Scoped variables use the attribute's CustomId as their name and the owning container's CustomId as their scope.
  • The attribute ID remains the variable ID used by runtime changes and save data.
  • In Arcscript, scoped variables use containerCustomId.variableName.
Variable globalHealth = project.GetVariable("health");
Variable boardHealth = project.GetVariable("health", "intro_board");
Variable componentHealth = project.GetVariable("health", "hero");

project.SetVariable("health", 10);
project.SetVariable("health", 2, "intro_board");
project.SetVariable("health", 5, "hero");

Both the source attribute and its board/component must have a CustomId for the attribute to become a scoped variable. Plain-string attributes with null data import as an empty string.

Upgrading from Project.Variables

Use Project.GlobalVariables when accessing the global-variable list. Existing Project.Variables code continues to work through a deprecated alias to the same list. IProject.Variables remains available so existing interpreter callers and custom implementations remain compatible.

Previously imported Unity assets retain their global variables automatically; no reimport is required. The Arcweave JSON export format and variable save-state format are unchanged.


Board

Container for narrative nodes.

Properties

Property Type Description
Id string Unique identifier
CustomId string Optional Arcweave custom id used as the board-variable scope
Name string Board name
Nodes List<INode> All nodes (Elements, Branches, Jumpers)
Notes List<Note> Annotation notes
Attributes List<Attribute> Board attributes
Variables List<Variable> Variables scoped to this board

Methods

Method Description
T NodeWithID<T>(string id) Get node by ID and type
Element ElementWithID(string id) Get element by ID

Element

A narrative node containing dialogue content.

Properties

Property Type Description
Id string Unique identifier
Title string Element title (may contain Arcscript)
RawContent string Original content with Arcscript markup
RuntimeContent string Evaluated content (call RunContentScript() first!)
Visits int Visit counter (get/set)
Components List<Component> Attached characters/entities
Attributes List<Attribute> Custom metadata
Outputs List<Connection> Outgoing connections
cover Cover Cover image reference
AudioAssets AudioAsset[] Audio assets attached to this element

Methods

Method Description
void RunContentScript() Evaluate Arcscript in content → updates RuntimeContent
Options GetOptions() Get available paths (evaluates branch conditions)
bool HasContent() Check if element has content
bool HasComponent(string name) Check if element has component by name
bool TryGetComponent(string name, out Component c) Try to get component by name
Texture2D GetCoverImage() Get the downloaded cover image or load it from Resources
Texture2D GetFirstComponentCoverImage() Get first component's cover image
Texture2D GetCoverOrFirstComponentImage() Get cover or fallback to component image
AudioAsset[] GetAudioAssets() Get all audio assets attached to this element

Code Example

// WRONG - RuntimeContent will be empty/outdated
string text = element.RuntimeContent;  // ❌ Don't do this!

// CORRECT - Always call RunContentScript() first
element.RunContentScript();            // ✅ Evaluates Arcscript
string text = element.RuntimeContent;  // ✅ Now it's updated

// Get available choices
Options options = element.GetOptions();
if (options.hasPaths) {
    foreach (Path path in options.Paths) {
        Debug.Log("Choice: " + path.text);
    }
}

Connection

Link between nodes with optional label.

Properties

Property Type Description
Id string Unique identifier
RawLabel string Original label with Arcscript
RuntimeLabel string Evaluated label (call RunLabelScript() first!)
Source INode Source node
Target INode Target node
isValid bool True if connection has valid ID

Methods

Method Description
void RunLabelScript() Evaluate Arcscript → updates RuntimeLabel

Branch

Conditional branching node with if/elseif/else logic.

Properties

Property Type Description
Id string Unique identifier
Conditions List<Condition> Ordered conditions (first true wins)
colorTheme string Visual theme color

Condition

Single condition in a branch.

Properties

Property Type Description
Id string Unique identifier
Script string Arcscript condition expression
Output Connection Output connection if true

Methods

Method Description
bool Evaluate() Evaluate condition (empty scripts return true)

Jumper

Navigation shortcut to another element.

Properties

Property Type Description
Id string Unique identifier
Target Element Target element to jump to

Component

Character or entity definition. Not a Unity MonoBehaviour.

Properties

Property Type Description
Id string Unique identifier
CustomId string Arcweave custom ID used as a variable scope
Name string Component name
Attributes List<Attribute> Custom attributes
Variables List<Variable> Variables scoped to this component
cover Cover Cover image reference

Methods

Method Description
Texture2D GetCoverImage() Get the downloaded cover image or load it from Resources

Attribute

Custom metadata on elements, components, or boards.

Properties

Property Type Description
Id string Arcweave attribute identifier
CustomId string Optional Arcscript variable name for eligible scoped attributes
Name string Attribute name
Type DataType Plain/rich string, component list, boolean, integer, or float
data object Attribute data (lazy-evaluated for RichText)
containerType ContainerType Element, Component, or Board
containerId string ID of the container

Variable

Project/global, board-scoped, or component-scoped state variable. Supports: int, double, bool, string.

Properties

Property Type Description
Id string Arcweave variable identifier used for runtime updates and save/load
Name string Variable name
Value object Current value
DefaultValue object Initial value
Parent IHasVariables Owning scope (null for globals, otherwise a Board or Component)
Type Type System.Type of the value

Methods

Method Description
void ResetToDefaultValue() Reset to default value

Cover

Image or video reference.

Properties

Property Type Description
type Cover.Type Image, Youtube, or Undefined
filePath string Asset filename
assetId string Arcweave asset id
downloadedImage Texture2D Image downloaded when importing from web

Methods

Method Description
Texture2D ResolveImage() Return the downloaded image, otherwise load it from a Resources folder

Options

Available paths from an element. Created by Element.GetOptions().

Properties

Property Type Description
Element Element Source element
Paths List<Path> Valid paths to next elements
hasPaths bool True if any paths exist
hasOptions bool True if multiple paths OR path has label

Path

Resolved path to a target element.

Properties

Property Type Description
label string Connection label (if any)
text string Label or target element's title
TargetElement Element Destination element

Methods

Method Description
void ExecuteAppendedConnectionLabels() Run Arcscript in all connection labels along path

ArcweavePlayer

Event-driven narrative player (demo helper class).

Inspector Fields

Field Type Description
aw ArcweaveProjectAsset The project to play
autoStart bool Auto-start on scene load

Events

Event Signature Description
onProjectStart (Project) Narrative started
onProjectFinish (Project) Narrative ended
onElementEnter (Element) Entered new element
onElementOptions (Options, Action<int>) Multiple choices available
onWaitInputNext (Action) Single path, waiting for continue

Methods

Method Description
void PlayProject() Start or restart the narrative
void Save() Save current state to PlayerPrefs
void Load() Load and restore saved state

Important Notes

  1. Unity 6+ requires Input System update: If using Unity 6 or newer, the EventSystem must use the new Input System module. Select EventSystem in Hierarchy, find Standalone Input Module in Inspector, and click "Replace with InputSystemUIInputModule". Without this, UI buttons won't respond to clicks. See Unity 6+ Input System Fix.

  2. RuntimeContent requires RunContentScript(): The RuntimeContent property is not automatically evaluated. You must call RunContentScript() before reading it.

  3. GetOptions() has side effects: This method internally saves and restores variable state while evaluating branch conditions.

  4. Initialize() resets everything: Calling Project.Initialize() resets all global and scoped variables to defaults and all visit counts to 0.

  5. Scoped variables require scope: Project.GetVariable("health") only searches project/global variables. Pass the owning board or component CustomId to access a scoped variable.

  6. Images and Audio clips come from web imports or a Resources folder: Importing from web with Download Media enabled downloads cover images and audio clips. Otherwise they are loaded via Resources.Load<T>(), so place them in any Resources folder and ensure filenames match (without extension).

  7. Components are not MonoBehaviours: Arcweave Components represent characters/entities in your narrative, not Unity components.

  8. Visit tracking is manual: The Visits property must be incremented manually (or use ArcweavePlayer which does it automatically).


Troubleshooting

Buttons not responding in Unity 6+?

Problem: UI buttons don't respond to clicks in Unity 6 or newer versions.

Solution:

  1. Select EventSystem in the Hierarchy
  2. In the Inspector, locate Standalone Input Module
  3. Click Replace with InputSystemUIInputModule
  4. This migrates from the legacy Input Manager to the new Input System

Unity 6 requires the new Input System for UI interactions.

Audio clips not loading?

Problem: TryGetAudioClip() returns null.

Solution:

  • If you import from web, check the Console for download warnings and confirm Download Media is enabled
  • Ensure audio files are in a folder named exactly Resources (case-sensitive)
  • Verify the filename in your Arcweave project matches the file on disk (the plugin strips the extension automatically)
  • Confirm the audio format is supported by Unity (e.g. .wav, .mp3, .ogg)

Images not loading?

Problem: GetCoverImage() returns null.

Solution:

  • If you import from web, check the Console for download warnings and confirm Download Media is enabled
  • Ensure images are in a folder named exactly Resources (case-sensitive)
  • Verify the filename matches (without extension)
  • Check the image's Texture Type is set to Default in Import Settings

RuntimeContent is empty or shows Arcscript markup?

Problem: Seeing {variable_name} or if/endif blocks in text.

Solution:

// Always call this before reading RuntimeContent
element.RunContentScript();

"NullReferenceException" when accessing variables?

Problem: Variables are null or throw errors.

Solution:

// Call Initialize() once before using the project
project.Initialize();

Choices/paths not appearing?

Problem: GetOptions() returns no paths or wrong paths.

Solution:

  • Check your branch conditions in Arcweave - they might all be evaluating to false
  • Verify variable values are correct: Debug.Log(project.GetVariable("varName").Value);
  • Use the Project Viewer in Unity to visually inspect connections

Save/Load not working?

Problem: Load() doesn't restore the correct state.

Solution:

  • Ensure you called Save() before Load()
  • PlayerPrefs persists between sessions - use PlayerPrefs.DeleteAll() to clear if testing
  • Check the save keys exist: PlayerPrefs.HasKey("arcweave_save_currentElement")

Import button is disabled?

Problem: Can't click "Import Project" button.

Solution:

  • From Json mode: Drag a TextAsset (.json file) into the "Project Json File" field
  • From Web mode: Fill in both API Key AND Project Hash fields
  • Ensure the JSON file is valid (open it in a text editor to verify it's not corrupted)

License

See the LICENSE file for details.

About

Official Arcweave plugin for Unity. Bring branching dialogue and story logic into your game.

Topics

Resources

Stars

6 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages