Skip to content

Instantly share code, notes, and snippets.

@spirifoxy
Forked from Starviling/README.txt
Created August 15, 2023 22:00
Show Gist options
  • Save spirifoxy/8b507bb1815f097b08f376827077279d to your computer and use it in GitHub Desktop.
Save spirifoxy/8b507bb1815f097b08f376827077279d to your computer and use it in GitHub Desktop.
YarnSpinner loading from line
To set this up in Unity, it needs to:
1. have a reference to the DialogueRunner in the scene
2. be added to the Dialogue Views in the DialogueRunner
3. MAKE SURE THAT Yarn.LineJumper.asmdef and YarnLineJumper.cs ARE IN THEIR OWN SUBFOLDER
(This is for 2.2.2+)
To save a point, save integer returned from CurrentProgramCounter() somewhere.
To load a point, use LoadProgramCounter() with the node string name and integer saved from CurrentProgramCounter().
{
"name": "Yarn.LineJumper",
"rootNamespace": "",
"references": [
"YarnSpinner.Unity"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": true,
"precompiledReferences": [
"Yarn.Google.Protobuf.dll",
"YarnSpinner.dll"
],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}
using System;
using Yarn;
using Yarn.Unity;
using static Yarn.Instruction.Types;
namespace SaveSystem {
public class YarnLineJumper : DialogueViewBase
{
public DialogueRunner diaRunner;
// Name of the label being inserted
string operandName = "load_jump";
// Keep these for modifications and access
Program program;
Node currentNode;
// When saving specific instruction, use this
int linesRun;
public void Awake()
{
diaRunner.SetProject(Instantiate(diaRunner.yarnProject));
program = diaRunner.yarnProject.Program;
diaRunner.onNodeStart.AddListener((string input) => {
this.linesRun = 0;
currentNode = program.Nodes[diaRunner.CurrentNodeName];
});
}
public void LoadProgramCounter(string node, int line)
{
// Jump Instruction being inserted
Instruction jumpInstruction = new Instruction();
jumpInstruction.Opcode = OpCode.JumpTo;
jumpInstruction.Operands.Add(new Operand(operandName));
// Acquire the shennanigans
currentNode = program.Nodes[node];
// Tell it where to jump
if (!currentNode.Labels.ContainsKey(operandName))
{
foreach (string key in currentNode.Labels.Keys)
{
currentNode.Labels[key] += 1;
}
currentNode.Labels.Add(operandName, line);
currentNode.Instructions.Insert(0, jumpInstruction);
}
else
{
currentNode.Labels[operandName] = line;
currentNode.Instructions[0] = jumpInstruction;
}
diaRunner.Stop();
diaRunner.Dialogue.SetProgram(program);
diaRunner.StartDialogue(node);
currentNode.Labels[operandName] = 1;
// Set the runLineCount here to allow accurate saving
linesRun = 0;
for (int i = 0; i < line; i++)
{
if (currentNode.Instructions[i].Opcode == OpCode.RunLine)
linesRun++;
}
}
public int CurrentProgramCounter()
{
int programCounter = 0;
int runLineCount = 0;
while (runLineCount != linesRun)
{
if (currentNode.Instructions[programCounter].Opcode == OpCode.RunLine)
runLineCount++;
programCounter++;
}
if (!(currentNode.Instructions[0].Opcode == OpCode.JumpTo
&& String.ReferenceEquals(currentNode.Instructions[0].Operands[0].StringValue, operandName)))
programCounter++;
return programCounter;
}
public override void RunLine(LocalizedLine dialogueLine, Action onDialogueLineFinished)
{
linesRun++;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment