Hello. I have followed the instructions and when I try to test it in the game, the text in the Irate Guard dialogue is not updating. I tried deleting the Dialogue SO and creating a new one and hooking that instead, but it is still not updating.
I see that there is an error in the Console as shown below. I double checked the code and matched it with the lesson and it looks fine. I also watched the video a few times to makes sure I set up everything in Unity as we were told, but all seems ok.
Any help to solve this issues would be appreciated. Thank you!
The compiler is telling you where the error is occuring. So what happens on line 17 of PlayerConversant.cs?
On line 17 of PlayerConversant here is the return statement of the GetText method:
return currentDialogue.GetRootNode().GetText();
I am also including a screen shot of the DialogueUI.cs file since the error message mentions line 19 of that script too. I am wondering if there is some confusion with the reference to Get.Text() on this line and the one on line 17 of PlayerConversant.cs. Thanks in advance for your assistance.
And here is the full script for PlayerConversant just in case.
Line 17 of PlayerConversant is the culprit. There are two potential null references, but you’ve already eliminated the possibility of it being currentDialogue with the null check.
This means the issue is the GetRootNode().
Paste in your Dialogue.cs, and we’ll see why GetRootNode() is returning null.
Please paste the actual text, instead of a screenshot. You can format it by typing on a line three backwards apostrophes ``` and then pasting the text and finally a line with three more backwards apostrophes.
For example:
```
This is some sample code
```
becomes
this is some sample code
Please fine below the code for the Dialogue.cs script as requested. Thanks in advance for your help!
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace RPG.Dialogue
{
[CreateAssetMenu(fileName = "Dialogue", menuName = "New Dialogue", order = 0)]
public class Dialogue : ScriptableObject, ISerializationCallbackReceiver
{
[SerializeField]
List<DialogueNode> nodes = new List<DialogueNode>(); //list of all nodes
[NonSerialized]
Vector2 newNodeOffset = new Vector2(250, 0);
Dictionary<string, DialogueNode> nodeLookup = new Dictionary<string, DialogueNode>();
private void OnValidate()
{
nodeLookup.Clear();
foreach (DialogueNode node in GetAllNodes())
{
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.GetChildren())
{
if (nodeLookup.ContainsKey(childID))
{
yield return nodeLookup[childID];
}
}
}
#if UNITY_EDITOR
public void CreateNode(DialogueNode parent)
{
DialogueNode newNode = MakeNode(parent);
Undo.RegisterCreatedObjectUndo(newNode, "Created Dialogue Node");
Undo.RecordObject(this, "Added Dialogue Node");
AddNode(newNode);
}
public void DeleteNode(DialogueNode nodeToDelete)
{
Undo.RecordObject(this, "Deleted Dialogue Node");
nodes.Remove(nodeToDelete);
OnValidate();
CleanDanglingChildren(nodeToDelete);
Undo.DestroyObjectImmediate(nodeToDelete);
}
private void CleanDanglingChildren(DialogueNode nodeToDelete)
{
foreach (DialogueNode node in GetAllNodes())
{
node.RemoveChild(nodeToDelete.name);
}
}
private DialogueNode MakeNode(DialogueNode parent)
{
DialogueNode newNode = CreateInstance<DialogueNode>();
newNode.name = Guid.NewGuid().ToString();
if (parent != null)
{
parent.AddChild(newNode.name);
newNode.SetPlayerSpeaking(!parent.IsPlayerSpeaking());
newNode.SetPosition(parent.GetRect().position + newNodeOffset);
}
return newNode;
}
private void AddNode(DialogueNode newNode)
{
nodes.Add(newNode);
OnValidate();
}
#endif
public void OnBeforeSerialize()
{
#if UNITY_EDITOR
if (nodes.Count == 0)
{
DialogueNode newNode = MakeNode(null);
AddNode(newNode);
}
if (AssetDatabase.GetAssetPath(this) != "")
{
foreach (DialogueNode node in GetAllNodes())
{
if (AssetDatabase.GetAssetPath(node) == "")
{
AssetDatabase.AddObjectToAsset(node, this);
}
}
}
#endif
}
public void OnAfterDeserialize() // created by ISerializationCallbackReceiver
{ // used when loading file from hard drive but not used here
} // but need to be left in as part of the interface
}
}
Sorry for the delay getting back to you, I had to go on the road overnight. As it turns out, the Dialogue.cs wasn’t the culprit, it really is in your PlayerConversant. The second look over the code to remind myself what the issue was allowed me to notice the real problem:
The if(currentDialogue = null)
will return false because currentDialogue isn’t null, but then it will immedately assign null to currentDialogue. It is currentDialogue that is null.
The correct construction is to use two == symbles:
if(currentDialogue == null)
Hello. Thanks for your response. That was indeed the problem! It is updating fine now. Should have detected that mistake myself!
I do have another question though. When I create a New Dialogue scriptable object and click on it, it opens the Dialogue Editor ok but the later is empty. To get a node to appear in the Dialogue Editor, I have to click somewhere in the folder where the New Dialogue scriptable object is and then click on the New Dialogue scriptable object I have created again to make a node appear. Please could you help me figure out why this is happening? I believe I should have a node it the Dialogue Editor appear automatically when I create a New Dialogue scriptable object and click on it to open the Editor. Thanks in advance for your help!
See if this topic helps you out with this:
Great! Thanks. It helped me solve the problem.
This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.