Yarn Spinner is an easy-to-use tool that lets you quickly write game dialogue and choices.  This page shows how you can make use of Yarn files in your AC game.

  1. Import Yarn's Unity integration into your project, and set up your scene with Yarn's Dialogue Runner and Dialogue UI components.
  2. Create a new C# file named ACYarnVariables.cs, and copy in the code below.  Attach the new AC Yarn Variables component to your Dialogue Runner.  Assign this as the Dialogue Runner component Inspector's Variable Storage field.
  3. To connect a Yarn variable with AC, create either a Global or Local variable of type Bool, Int, Float, or String, and give it the same name as the Yarn variable, but without the '$' at the start.  For example, $sally_warning in Yarn becomes sally_warning in AC.
  4. Create a new C# file named ActionYarn.cs, and copy in the code below.  Place this in a new folder and install this folder as a custom Actions directory in AC's Actions Manager.  For more on installing custom Actions, see this tutorial.
  5. You can now use the new "Dialogue: Yarn" Action in your AC ActionLists to trigger Yarn nodes.  This can also optionally assign the Yan Program file that contains the node.

ACYarnVariables.cs:

using Yarn.Unity;

namespace AC
{ 

	public class ACYarnVariables : VariableStorageBehaviour
	{

		public override void SetValue (string variableName, Yarn.Value value)
		{
			GVar variable = GetVariable (variableName);
			if (variable != null)
			{
				switch (value.type)
				{
					case Yarn.Value.Type.Bool:
						variable.BooleanValue = value.AsBool;
						break;

					case Yarn.Value.Type.Number:
						variable.IntegerValue = (int) value.AsNumber;
						variable.FloatValue = value.AsNumber;
						break;

					case Yarn.Value.Type.String:
						variable.TextValue = value.AsString;
						break;

					default:
						break;
				}
			}
		}
	
		public override Yarn.Value GetValue (string variableName)
		{
			GVar variable = GetVariable (variableName);
			if (variable != null)
			{
				switch (variable.type)
				{
					case VariableType.Boolean:
						return new Yarn.Value (variable.BooleanValue);

					case VariableType.Integer:
						return new Yarn.Value ((float) variable.IntegerValue);

					case VariableType.Float:
						return new Yarn.Value (variable.FloatValue);

					case VariableType.String:
						return new Yarn.Value (variable.TextValue);

					default:
						break;
				}
			}
			return Yarn.Value.NULL;
		}

		public override void ResetToDefaults ()
		{}

		private GVar GetVariable (string variableName)
		{
			string varName = variableName;
			if (varName.StartsWith ("$"))
			{
				varName = varName.Substring (1);
			}

			if (!varName.StartsWith ("l_"))
			{
				GVar variable = GlobalVariables.GetVariable (varName);
				if (variable != null)
				{
					return variable;
				}
			}

			if (!varName.StartsWith ("g_"))
			{
				GVar variable = LocalVariables.GetVariable (varName);
				if (variable != null)
				{
					return variable;
				}
			}

			ACDebug.LogWarning ("Cannot find AC Variable of the name " + varName);
			return null;
		}

	}
	
}

ActionYarn.cs:

using UnityEngine;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif

using Yarn.Unity;

namespace AC
{

	[System.Serializable]
	public class ActionYarn : Action
	{

		public override ActionCategory Category { get { return ActionCategory.Dialogue; } }
		public override string Title { get { return "Yarn"; } }
		public override string Description { get { return "Runs a Yarn node."; } }

		[SerializeField] private string node;
		[SerializeField] private YarnProgram yarnProgram = null;
		private DialogueRunner dialogueRunner;

		public override float Run ()
		{
			if (dialogueRunner == null)
			{
				dialogueRunner = FindObjectOfType <DialogueRunner>();
			}

			if (dialogueRunner == null)
			{
				LogWarning ("Cannot find a DialogueRunner component in the scene.");
				return 0f;
			}

			if (!isRunning)
			{
				if (yarnProgram && !dialogueRunner.NodeExists (node))
				{
					dialogueRunner.Add (yarnProgram);
				}

				dialogueRunner.StartDialogue (node);
				isRunning = true;
				return defaultPauseTime;
			}
			
			if (dialogueRunner.IsDialogueRunning)
			{
				return defaultPauseTime;;
			}

			isRunning = false;
			return 0f;
		}

		#if UNITY_EDITOR

		public override void ShowGUI ()
		{
			node = EditorGUILayout.TextField ("Node:", node);
			yarnProgram = (YarnProgram) EditorGUILayout.ObjectField ("Yarn program (optional):", yarnProgram, typeof (YarnProgram), false);
		}

		#endif

	}

}
Community content is available under CC-BY-SA unless otherwise noted.