Common questions and solutions for using Yarn Spinner in Unity.
Yarn Spinner doesn't do text rendering, you have to use existing Unity systems like TextMeshPro. Fortunately, TMP supports HTML-like rich text tags. See the TextMeshPro: Rich Text docs.
However, this bespoke approach is impractical for longer scripts or bigger projects. We recommend using TextMeshPro's Style Sheets, which make it much easier to write consistently styled text. See the TextMeshPro: Style Sheets docs.
Yarn Spinner doesn't handle text rendering. You'll need a separate wavy text system, like Text Animator.
Markup lets you mark a range of text (words, phrases) in a generic way, for whatever use. You could use it to style text, add sentence markers, make clickable words, etc.
Note that YS only processes the text data. You must still code the actual markup effect yourself. See Markup.
Wrap the variable (or any expression) in curly braces ({
, }
) to evaluate and output it. For more info, see Variables.
To read Yarn variables from C#, use VariableStorageBehaviour.TryGetValue<T>()
. To write Yarn variables from C#, use VariableStorageBehaviour.SetValue()
.
Don't forget the $
when writing the variable's name!
To read and write C# variables from Yarn, you must first code Yarn Functions and Commands in C#.
Then call the functions and commands in Yarn:
See the previous answers on working with variables. But we recommend avoiding any "sync" pattern, because then you'll have to track and maintain the same data in two different places. Programmers usually prefer a "single source of truth". Data should live in only one place. Variables should either live in Yarn or live in C#, and not in both.
To save the current node, save the value of DialogueRunner.CurrentNodeName
somewhere, e.g. to Unity's PlayerPrefs. Then to restore it, call DialogueRunner.StartDialogue()
and pass in the saved node name.
To save variables, see DialogueRunner.SaveStateToPlayerPrefs()
. Then to load variables, call DialogueRunner.LoadStateFromPlayerPrefs()
. These methods use Unity's built-in JSON utility to serialize a dictionary of variables to Unity's PlayerPrefs.
For custom save systems, create your own variable storage by subclassing VariableStorageBehaviour and implementing its methods. Study InMemoryVariableStorage.cs as an example. For more info, see Guide: Yarn Variables and Variable Storage.
It is not currently possible to save or restore the specific line that the dialogue is running.
To jump to a node from Yarn, use <<jump (nodeName)>>
. See Nodes, Lines, and Options.
To jump to a node with C#, just call DialogueRunner.StartDialogue()
, even if there's already dialogue running.
Jumping to a specific line in a node is currently not supported. Instead, jump to the start of a node.
In most cases, use the Dialogue Advance Input.
For more control, call UserRequestedViewAdvancement()
on a Dialogue View, or OnContinuedClicked()
on a Line View. See Creating Custom Dialogue Views.
Yarn Spinner automatically adds a #lastline
tag to a line when the next step is a set of options. Create a Custom Dialogue View that uses YarnProject.lineMetadata.GetMetadata()
to check for #lastline
and perform the behavior you want.
To display anything in Yarn Spinner, use a Dialogue View component. Line View for dialogue, Options List View for choices.
Most projects will need custom views. We recommend a modular architecture where each UI element has its own LineView component. For example, a nameplate bubble has a Dialogue Character Name View that displays LocalizedLine.CharacterName
, while the dialogue text window is another Line View that displays LocalizedLine.TextWithoutCharacterName
. See Creating Custom Dialogue Views.
For a working example, see the "Visual Novel" sample. (In Unity, go to Window > Package Manager
, and select Yarn Spinner package. Expand the "Samples" dropdown and select "Visual Novel" and import it.) Specifically, see VNManager.cs which inherits from DialogueViewBase, and changes the character name window background color (among other effects) based on the character name.
Write input code to detect clicking / tapping, then call DialogueRunner.StartDialogue()
.
The example tutorial NPC Dialogue Game can walk you through this step-by-step.
This implementation will vary for every game, so we purposely do not attempt to design a one-size-fits-all generic NPC system. Here's some example pseudo-code to make your own:
For a working example, see the "Space" sample. (In Unity, go to Window > Package Manager
, and select Yarn Spinner package. Expand the "Samples" dropdown and select "Space" and import it.) Specifically, see PlayerCharacter.cs for how to search for nearby NPCs from a list.
The math / code is a little complicated. Calculate the NPC's on-screen position, then convert this screen position to UI canvas space, and reposition the dialogue bubble.
For a working example, see the "3D" sample. (In Unity, go to Window > Package Manager
, and select Yarn Spinner package. Expand the "Samples" dropdown and select "3D" and import it.) Specfically, see YarnCharacterView.cs which has a method WorldToAnchoredPosition()
that does a lot of this UI positioning math.
This is more about Unity UI rather than Yarn Spinner. For a working example, see the "Phone Chat" sample. (In Unity, go to Window > Package Manager
, and select Yarn Spinner package. Expand the "Samples" dropdown and select "Phone Chat" and import it.)
To make a resizing dialogue bubble that automatically fits text, you will need a complex UI setup. Study the UI game objects and components in the sample scene. For more context about how it works, see this Unity UI Layout Groups explainer by Hallgrim Games.
The intended workflow is to generate and compile Yarn Projects at editor time, not runtime. See Yarn Projects.
As of v2.x, Yarn Spinner Unity no longer supports runtime loading. Instead, Yarn Projects compile at editor time into bytecode. The source text and parser no longer ship with the game build. If you have specific runtime needs, you might be better off using Yarn Spinner Unity v1.x instead, or use a different Yarn implementation on a different platform -- see Community Projects.
There is no real technical limit on the number of Yarn scripts or the size of Yarn Projects. You decide how to organize your data, and every project has different needs. Some factors to consider:
Simplicity. Putting everything into one big script file or one big project file is simpler sometimes.
Ease of writing. Writers may prefer to think in terms of one file per scene, one file per chapter.
Localization. 1 Yarn Project = 1 CSV spreadsheet per language. When translating, it is usually easier to work with fewer files, rather than fragmenting the translation across many files. As a workaround for games that need multiple Yarn Projects, you may prefer to create a single editor-only Yarn Project that's just for generating string files and translations. See Localizations and Assets.