using UnityEngine; using UnityEditor.AssetImporters; using Unity.GraphToolkit.Editor; using System; using System.Collections.Generic; using System.Linq; using Dialogue; namespace Editor.Dialogue { [ScriptedImporter(1, DialogueGraph.AssetExtension)] public class DialogueGraphImporter : ScriptedImporter { public override void OnImportAsset(AssetImportContext ctx) { DialogueGraph editorGraph = GraphDatabase.LoadGraphForImporter(ctx.assetPath); RuntimeDialogueGraph runtimeGraph = ScriptableObject.CreateInstance(); var nodeIDMap = new Dictionary(); foreach (var node in editorGraph.GetNodes()) { nodeIDMap[node] = Guid.NewGuid().ToString(); } // TODO: This could be done in the above loop, but for clarity, I'm keeping it separate for now. var startNode = editorGraph.GetNodes().OfType().FirstOrDefault(); if (startNode != null) { var entryPoint = startNode.GetOutputPorts().FirstOrDefault()?.firstConnectedPort; if (entryPoint != null) { runtimeGraph.entryNodeID = nodeIDMap[entryPoint.GetNode()]; } runtimeGraph.speakerName = GetPortValue(startNode.GetInputPortByName("SpeakerName")); } foreach (var iNode in editorGraph.GetNodes()) { if (iNode is StartNode || iNode is EndNode) continue; var runtimeNode = new RuntimeDialogueNode{ nodeID = nodeIDMap[iNode]}; if (iNode is DialogueNode dialogueNode) { ProcessDialogueNode(dialogueNode, runtimeNode, nodeIDMap); } runtimeGraph.allNodes.Add(runtimeNode); } ctx.AddObjectToAsset("RuntimeData", runtimeGraph); ctx.SetMainObject(runtimeGraph); } private void ProcessDialogueNode(DialogueNode node, RuntimeDialogueNode runtimeNode, Dictionary nodeIDMap) { runtimeNode.dialogueLine = GetPortValue(node.GetInputPortByName("DialogueLine")); var nextNodePort = node.GetOutputPortByName("out")?.firstConnectedPort; if (nextNodePort != null) { runtimeNode.nextNodeID = nodeIDMap[nextNodePort.GetNode()]; } } private T GetPortValue(IPort port) { if (port == null) return default(T); if (port.isConnected) { if (port.firstConnectedPort.GetNode() is IVariableNode variableNode) { variableNode.variable.TryGetDefaultValue(out T value); return value; } } port.TryGetValue(out T fallbackValue); return fallbackValue; } } }