Error after Dialogue SO creation

When I create a Dialogue SO this error pops up in the console: [Worker1] Broken text PPtr in file(Assets/SO/New Dialogue.asset). Local file identifier (3681784713337156196) doesn’t exist!
UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)

Code:

namespace Dialogue
{

	public class DialogueNode : ScriptableObject
	{
		public string text;
		public List<string> children = new List<string>();
		public Rect rect = new Rect(0,0, 200, 100);
	}
}
namespace Dialogue
{
	[CreateAssetMenu(fileName = "New Dialogue", menuName = "Dialogue", order = 0)]
	public class Dialogue : ScriptableObject, ISerializationCallbackReceiver
	{
		[SerializeField]
		List<DialogueNode> nodes = new List<DialogueNode>();

		Dictionary<string, DialogueNode> nodeLookup = new Dictionary<string, DialogueNode>();

#if UNITY_EDITOR
		private void Awake()
		{
		}
#endif
		private void OnValidate()
		{
			nodeLookup.Clear();
			foreach (DialogueNode node in GetAllNodes())
			{
				if(node != null)
				{
					nodeLookup[node.name] = node;
				}
				
			}
		}

		public IEnumerable<DialogueNode> GetAllNodes()
		{
			return nodes;
		}

		public DialogueNode GetRootNode()
		{
			return nodes[0];
		}

		public IEnumerable<DialogueNode> GetAllChildren(DialogueNode parentNode)
		{
			foreach (string childID in parentNode.children)
			{
				if (nodeLookup.ContainsKey(childID))
				{
					yield return nodeLookup[childID];
				}
			}
		}

		public void CreateNode(DialogueNode parent)
		{
			DialogueNode newNode = CreateInstance<DialogueNode>();
			newNode.name = Guid.NewGuid().ToString();
			Undo.RegisterCreatedObjectUndo(newNode, "Created Dialogue Node");
			if (parent != null)
			{
				parent.children.Add(newNode.name);
			}
			nodes.Add(newNode);
			OnValidate();
		}

		public void DeleteNode(DialogueNode nodeToDelete)
		{
			nodes.Remove(nodeToDelete);
			Undo.DestroyObjectImmediate(nodeToDelete);
			OnValidate();
			CleanDanglingChildren(nodeToDelete);
		}

		private void CleanDanglingChildren(DialogueNode nodeToDelete)
		{
			foreach (DialogueNode node in GetAllNodes())
			{
				node.children.Remove(nodeToDelete.name);
			}
		}

		public void OnBeforeSerialize()
		{
			if (nodes.Count == 0)
			{
				CreateNode(null);
			}

			if (AssetDatabase.GetAssetPath(this) != "")
			{
				foreach (DialogueNode node in GetAllNodes())
				{
					if (AssetDatabase.GetAssetPath(node) == "")
					{
						AssetDatabase.AddObjectToAsset(node, this);
					}
				}
			}
		}

		public void OnAfterDeserialize()
		{
		}
	}
}
namespace Dialogue.Editor
{
	public class DialogueEditor : EditorWindow
	{
		Dialogue selectedDialogue = null;
		[NonSerialized]
		GUIStyle nodeStyle;
		[NonSerialized]
		DialogueNode draggingNode = null;
		[NonSerialized]
		Vector2 draggingOffset;
		[NonSerialized]
		DialogueNode creatingNode = null;
		[NonSerialized]
		DialogueNode deletingNode = null;
		[NonSerialized]
		DialogueNode linkingParentNode = null;
		Vector2 scrollPosition;
		[NonSerialized]
		bool draggingCanvas = false;
		[NonSerialized]
		Vector2 draggingCanvasOffset;
		const float canvasSize =  4000;
		const float backgroundSize = 50;

		[MenuItem("Window/Dialogue Editor")]
		public static void ShowEditorWindow()
		{
			GetWindow(typeof(DialogueEditor), false, "Dialogue Editor");
		}

		[OnOpenAsset(1)]
		public static bool OnOpenAsset(int instanceID,int line)
		{
			Dialogue dialogue = EditorUtility.InstanceIDToObject(instanceID) as Dialogue; // cast to check if Dialogue
			if(dialogue !=null)
			{
				ShowEditorWindow();
				return true;
			}
			return false;
		}

		private void OnEnable()
		{
			Selection.selectionChanged += OnSelectionChanged; // event
		}

		private GUIStyle SetNodeGUIStyle()
		{
			nodeStyle = new GUIStyle();
			nodeStyle.normal.background = EditorGUIUtility.Load("node0") as Texture2D;
			nodeStyle.padding = new RectOffset(20, 20, 20, 20);
			nodeStyle.border = new RectOffset(12, 12, 12, 12);

			return nodeStyle;
		}

		private void OnSelectionChanged()
		{
			Dialogue newDialogue = Selection.activeObject as Dialogue;
			if(newDialogue !=null)
			{
				selectedDialogue = newDialogue;
				Repaint(); // updates UI
			}
		}

		private void OnGUI()
		{
			if (selectedDialogue.GetAllNodes().FirstOrDefault() == null)
			{
				selectedDialogue.CreateNode(null);
			}
			else
			{
				ProcessEvents();

				scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);

				Rect canvas = GUILayoutUtility.GetRect(canvasSize, canvasSize);
				Texture2D backgroundTexture = Resources.Load("background") as Texture2D;
				Rect textureCoordinates = new Rect(0, 0, canvasSize / backgroundSize, canvasSize / backgroundSize);
				GUI.DrawTextureWithTexCoords(canvas, backgroundTexture, textureCoordinates);


				foreach (DialogueNode node in selectedDialogue.GetAllNodes()) // loop through Getter's nodes text
				{
					DrawConnections(node);
				}
				foreach (DialogueNode node in selectedDialogue.GetAllNodes()) // loop through Getter's nodes text
				{
					DrawNode(node); 
				}

				EditorGUILayout.EndScrollView();

				if(creatingNode != null)
				{
					Undo.RecordObject(selectedDialogue, "Added Dialogue Node");
					selectedDialogue.CreateNode(creatingNode);
					creatingNode = null;
				}
				if(deletingNode !=null)
				{
					Undo.RecordObject(selectedDialogue, "Deleted Dialogue Node");
					selectedDialogue.DeleteNode(deletingNode);
					deletingNode = null;
				}
			}				
		}

		private void DrawConnections(DialogueNode node)
		{

			Vector3 startPosition = new Vector2(node.rect.xMax, node.rect.center.y);
			foreach (DialogueNode childNode in selectedDialogue.GetAllChildren(node))
			{				
				Vector3 endPosition = new Vector2(childNode.rect.xMin, childNode.rect.center.y);
				Vector3 controlPointOffset = endPosition - startPosition;
				controlPointOffset.y = 0;
				controlPointOffset.x *= 0.8f;
				Handles.DrawBezier(startPosition, endPosition,
					startPosition + controlPointOffset, endPosition - controlPointOffset,
					Color.blue, null, 5f);
			}
		}

		private void ProcessEvents()
		{
			if (Event.current.type == EventType.MouseDown && draggingNode == null) // start dragging even
			{
				draggingNode = GetNodeAtPoint(Event.current.mousePosition + scrollPosition);
				if (draggingNode != null)
				{
					draggingOffset = draggingNode.rect.position - Event.current.mousePosition;
					Selection.activeObject = draggingNode;
				}
				else
				{
					draggingCanvas = true;
					draggingCanvasOffset = Event.current.mousePosition + scrollPosition;
					Selection.activeObject = selectedDialogue;
				}
			}
			else if (Event.current.type == EventType.MouseDrag && draggingNode != null)// dragging ongoing
			{
				Undo.RecordObject(selectedDialogue, "Move Dialogue Node"); // set editor dirty
				draggingNode.rect.position = Event.current.mousePosition + draggingOffset;

				GUI.changed = true;
			}
			else if (Event.current.type == EventType.MouseDrag && draggingCanvas)
			{
				scrollPosition = draggingCanvasOffset - Event.current.mousePosition;

				GUI.changed = true;
			}
			else if (Event.current.type == EventType.MouseUp && draggingNode != null) // finish dragging
			{
				draggingNode = null;
			}
			else if (Event.current.type == EventType.MouseUp && draggingCanvas)
			{
				draggingCanvas = false;
			}

		}



		private void DrawNode(DialogueNode node)
		{
			GUILayout.BeginArea(node.rect, SetNodeGUIStyle());
			EditorGUI.BeginChangeCheck(); // start check if any changes have been made to the dialogue data

			string newText = EditorGUILayout.TextField(node.text);

			if (EditorGUI.EndChangeCheck()) // end check if any changes have been made to the dialogue data
			{
				Undo.RecordObject(selectedDialogue, "Update Dialogue Text");
				node.text = newText;
			}
			GUILayout.BeginHorizontal();
			Color defaultGUIColor = GUI.backgroundColor;
			GUI.backgroundColor = Color.green;
			if (GUILayout.Button("Add"))
			{
				creatingNode = node;

			}

			DrawLinkButtons(node);

			GUI.backgroundColor = Color.red;
			if (GUILayout.Button("Remove"))
			{
				deletingNode = node;
			}
			GUI.backgroundColor = defaultGUIColor;
			GUILayout.EndHorizontal();
			GUILayout.EndArea();
		}

		private void DrawLinkButtons(DialogueNode node)
		{
			GUI.backgroundColor = Color.yellow;
			if (linkingParentNode == null)
			{
				if (GUILayout.Button("Link"))
				{
					linkingParentNode = node;
				}
			}
			else if(linkingParentNode == node)
			{
				if(GUILayout.Button("Cancel"))
				{
					linkingParentNode = null;
				}
			}
			else if(linkingParentNode.children.Contains(node.name))
			{
				if (GUILayout.Button("UnLink"))
				{
					Undo.RecordObject(selectedDialogue, "Remove Dialogue Link");
					linkingParentNode.children.Remove(node.name);
					linkingParentNode = null;
				}
			}
			else
			{
				if (GUILayout.Button("Link Child"))
				{
					Undo.RecordObject(selectedDialogue, "Add Dialogue Link");
					linkingParentNode.children.Add(node.name);
					linkingParentNode = null;
				}
			}
		}

		private DialogueNode GetNodeAtPoint(Vector2 point)
		{
			DialogueNode foundNode = null;
			foreach(DialogueNode node in selectedDialogue.GetAllNodes())
			{
				if(node.rect.Contains(point))
				{
					foundNode = node;

				}
			}
			return foundNode;
		}
	}
}

It looks like you’ve applied my patch in DialogueEditor.cs. While this will not clear the error (which is due to an error within the Editor itself) the defaul node should still be being created. Let me know if the default node does not exist after the file is named.

You should also include a check to ensure that the current dialogue exits or your window will be in an error state.
At the beginning of OnGUI, be sure to put the check to ensure that the selectedDialogue is not null

if (selectedDialogue == null)
            {
                EditorGUILayout.LabelField("No Dialogue Selected.");
                return;
            }

I did copy and past your script as I run into some errors and couldn’t fix them myself. Did I corrupt any files in the project? Let me know if I should start again my project as I do plan on building my project at some point in the future (this project is just a blank project with the dialogue code so it wont be so bad if i need to restart or something). The default node is being created and the behavior is normal.

I’m not seeing any other red flags in the code. I’m still working on finding a way to achieve our nodes without the error, but for now the error is just Unity’s jobs system complaining.

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms