Created
October 2, 2023 15:17
-
-
Save randalfien/54d73ebc41dcf68e31e331cdf30bae04 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using UnityEditor; | |
using Yarn.Unity; | |
using System.Collections.Generic; | |
using System.IO; | |
class YarnAssetPostProcessor : AssetPostprocessor | |
{ | |
private const string ScriptFolder = "Assets/Yarn/"; | |
private static readonly string _filePath = ScriptFolder + "YarnNodesRef.cs"; | |
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths, bool didDomainReload) | |
{ | |
foreach (string str in importedAssets) | |
{ | |
if (str.ToLowerInvariant().EndsWith(".yarnproject")) | |
{ | |
OnYarnProjectChanged(); | |
} | |
} | |
} | |
private static YarnProject GetYarnProject() | |
{ | |
var assetGUIDs = AssetDatabase.FindAssets("t: YarnProject"); | |
if (assetGUIDs.Length <= 0) | |
{ | |
Debug.LogError("Yarn Project not found"); | |
return null; | |
} | |
var assetPath = AssetDatabase.GUIDToAssetPath(assetGUIDs[0]); | |
return AssetDatabase.LoadAssetAtPath<YarnProject>(assetPath); | |
} | |
private static void OnYarnProjectChanged() | |
{ | |
var project = GetYarnProject(); | |
if( NodesChanged( project.NodeNames ) ) | |
{ | |
GenerateNodeReferenceClass(); | |
} | |
} | |
private static bool NodesChanged(string[] projectNodeNames) | |
{ | |
var infile = YarnNodesRef.All; | |
if (infile.Length != projectNodeNames.Length) return true; | |
foreach (var projectNodeName in projectNodeNames) | |
{ | |
var nodeFound = false; | |
foreach (var classNodeName in infile) | |
{ | |
if (classNodeName == projectNodeName) | |
{ | |
nodeFound = true; | |
break; | |
} | |
} | |
if (!nodeFound) return true; | |
} | |
return false; | |
} | |
public static void GenerateNodeReferenceClass() | |
{ | |
var nodeNames = GetYarnProject().NodeNames; | |
var sceneList = new List<string>(); | |
var nodesMap = new Dictionary<string, List<string>>(); | |
foreach (var nodeName in nodeNames) | |
{ | |
var underscoreIndex = nodeName.IndexOf('_'); | |
if (underscoreIndex == -1) | |
{ | |
Debug.LogWarning("node name has no prefix! "+nodeName); | |
continue; | |
} | |
var prefix = nodeName[..underscoreIndex]; | |
if (prefix.Length > 4) | |
{ | |
Debug.LogWarning("node name prefix too long! "+nodeName); | |
} | |
if (!sceneList.Contains(prefix)) | |
{ | |
sceneList.Add(prefix); | |
nodesMap.Add(prefix, new List<string>()); | |
} | |
nodesMap[prefix].Add(nodeName); | |
} | |
using StreamWriter outfile = new StreamWriter(_filePath, false); | |
var listofall = new List<string>(); //keep track of all added constants | |
// Class contents generation | |
outfile.WriteLine("/// <summary>"); | |
outfile.WriteLine("/// Auto-generated class"); | |
outfile.WriteLine("/// </summary>"); | |
outfile.WriteLine(""); | |
outfile.WriteLine("public static class YarnNodesRef"); | |
outfile.WriteLine("{"); | |
foreach (var prefix in sceneList) | |
{ | |
var nodes = nodesMap[prefix]; | |
outfile.WriteLine("public static class "+prefix); //nested class for each prefix | |
outfile.WriteLine("{"); | |
if (nodes != null) | |
{ | |
for (var i = 0; i < nodes.Count; i++) | |
{ | |
var node = nodes[i]; | |
if (node == null) | |
{ | |
Debug.LogWarning("node name is NULL"); | |
continue; | |
} | |
var nameWithoutPrefix = node.Replace(prefix+"_", ""); | |
outfile.WriteLine("\tpublic static string " + nameWithoutPrefix + " = \"" + node + "\";"); | |
listofall.Add(prefix+"."+nameWithoutPrefix); | |
} | |
} | |
outfile.WriteLine("}"); | |
} | |
outfile.WriteLine("public static string[] All = {"); | |
foreach (var item in listofall) | |
{ | |
outfile.WriteLine(item+","); | |
} | |
outfile.WriteLine("};"); | |
outfile.WriteLine("}"); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Auto-generated class | |
/// </summary> | |
public static class YarnNodesRef | |
{ | |
public static string[] All = { | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This utility for YarnSpinner in Unity generates a static class for easy references to nodes. You can start dialogs by writing stuff like StartDialog(YarnNodesRef.Scene1.Introduction). It assumes you use prefixes with your node names like node name is Scene1_Introduction.