DialogueUI and PlayerConversant error out

After working through and testing the Disjunctions and Conjunctions. Fixing an error I had and found the solution as another user had the same problem.

I now have an issue were my code is breaking with dialogue. I try to click the button of Sure how? for the foot cream quest but by clicking I cannot move to the next piece of dialogue so I cannot get the quest.

Following error: (Added details on each line of code in the scripts)
IndexOutOfRangeException: Index was outside the bounds of the array.
RPG.Dialogue.PlayerConversant.Next () (at Assets/Scripts/Dialogue/PlayerConversant.cs:99)
RPG.Dialogue.PlayerConversant.SelectChoice (RPG.Dialogue.DialogueNode chosenNode) (at Assets/Scripts/Dialogue/PlayerConversant.cs:82)
RPG.UI.DialogueUI+<>c__DisplayClass11_0.<BuildChoiceList>b__0 () (at Assets/Scripts/UI/DialogueUI.cs:75)
UnityEngine.Events.InvokableCall.Invoke () (at <6afd1274f120405096bc1ad9e2010ba6>:0)
UnityEngine.Events.UnityEvent.Invoke () (at <6afd1274f120405096bc1ad9e2010ba6>:0)
UnityEngine.UI.Button.Press () (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Button.cs:70)
UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Button.cs:114)
UnityEngine.EventSystems.ExecuteEvents.Execute (UnityEngine.EventSystems.IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/ExecuteEvents.cs:57)
UnityEngine.EventSystems.ExecuteEvents.Execute[T] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.ExecuteEvents+EventFunction`1[T1] functor) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/ExecuteEvents.cs:272)
UnityEngine.EventSystems.EventSystem:Update() (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:501)

PlayerConversant Code:

public void SelectChoice(DialogueNode chosenNode){
            currentNode = chosenNode;
            TriggerEnterAction();
            isChoosing = false;
            // onConversationUpdated(); // Only call onConversationUpdated() here if not calling Next().
            Next(); // This is line 82
        }

        public void Next()
        {
            int numPlayerResponses = FilterOnCondition(currentDialogue.GetPlayerChildren(currentNode)).Count();
            if (numPlayerResponses > 0)
            {
                isChoosing = true;
                TriggerExitAction();
                onConversationUpdated();
                return;
            }

            DialogueNode[] children = FilterOnCondition(currentDialogue.GetAIChildren(currentNode)).ToArray();
            int randomIndex = UnityEngine.Random.Range(0, children.Count());
            TriggerExitAction();
            currentNode = children[randomIndex]; // line 99
            TriggerEnterAction();
            onConversationUpdated();
        }
``

DialogueUI Code:
``
private void BuildChoiceList(){

            foreach (Transform item in choiceRoot)

            {

                Destroy(item.gameObject);

            }

            foreach (DialogueNode choice in playerConversant.GetChoices())

            {

                GameObject choiceInstance = Instantiate(choicePrefab, choiceRoot);

                var textComponent = choiceInstance.GetComponentInChildren<TextMeshProUGUI>();

                textComponent.text = choice.GetText();

                Button button = choiceInstance.GetComponentInChildren<Button>();

                button.onClick.AddListener(() =>

                {

                    playerConversant.SelectChoice(choice); // Error line 75

                });

            }

        }

This only came up after I fixed a null error with the commpletedQuest condition.
I found that answer here in case anyone else sees this post.
CompletedQuest1xwfe9j_gaODc1MjYwMDQ3LjE2NjcwOTI4ODY._ga_2C81L26GR9*MTY2Nzc3MjkzOC4yNi4xLjE2Njc3NzQyODkuMC4wLjA.

This error now is out of range so somehow after the null check the game now sees the button option as not within the range as at the end of the error it looks to be listing cashe problems.

I am guessing the condition and disjunction and conjunction setup is somehow effecting this since the error only came up after they were implemented unless I am missing an exit or enter action for the dialogue choice. But there should be an enter or exit action for the player dialogue as the quest giving is when the NPC responds to the player with the GiveQuest exit action.

I feel like I am on the right track with this start…but I also am not sure where to test.

The code looks correct.

I suspect the problem is that after accounting for all of the conditions there were no choices available.

There should always be a possible enemy dialogue after each player dialogue…

If there are conditions for the dialogue choices after a player dialogue, craft your conditions so that one will always be true… for example (warning: psuedocode ahead to represent the dialogues)

Condition: if CompletedObjective(BadGuards, KillSeargant) → “You really better take out that seargant”
Condition: if !CompletedObjective(BadGuards, KillSeargant) → “You’re on the right path, taking out that seargant”

These conditions ensure that either one or the other node will be available for the Next() method to act on.

I will give this a try and see what results I get.

I checked over the dialogue, I did have a branch from the bunion quest where the player could say something then there was no reply after for the AI. I added an angry kind of reply then added on Exit Action to Attack as this was the player rejecting the quest. I can add a different reaction of the NPC just not interacting with the player later, I just wanted to add something that I know should already work.

The game still seems to be angry saying things are out of bounds.
I checked and all dialogue is set with an NPC response and only responses that I have made in the course.
Error:
IndexOutOfRangeException: Index was outside the bounds of the array. RPG.Dialogue.PlayerConversant.Next () (at Assets/Scripts/Dialogue/PlayerConversant.cs:99) RPG.Dialogue.PlayerConversant.SelectChoice (RPG.Dialogue.DialogueNode chosenNode) (at Assets/Scripts/Dialogue/PlayerConversant.cs:82) RPG.UI.DialogueUI+<>c__DisplayClass11_0.<BuildChoiceList>b__0 () (at Assets/Scripts/UI/DialogueUI.cs:75) UnityEngine.Events.InvokableCall.Invoke () (at <6afd1274f120405096bc1ad9e2010ba6>:0) UnityEngine.Events.UnityEvent.Invoke () (at <6afd1274f120405096bc1ad9e2010ba6>:0) UnityEngine.UI.Button.Press () (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Button.cs:70) UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Button.cs:114) UnityEngine.EventSystems.ExecuteEvents.Execute (UnityEngine.EventSystems.IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/ExecuteEvents.cs:57) UnityEngine.EventSystems.ExecuteEvents.Execute[T] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.ExecuteEvents+EventFunction`1[T1] functor) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/ExecuteEvents.cs:272) UnityEngine.EventSystems.EventSystem:Update() (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:501)

I can add my code from the other scripts mentioned if that helps. I read over the sudo code example on testing to make sure one item is always true. Everything should be working correctly.

I am going to go back through the lesson and see if I can missing something. Maybe a script didn’t save and I am missing code and do not realize it.

This error is always equivalent to “There are no choices left after you filtered them”… Leaving the next thing to testing the conditions themselves…

Quick question on this angry reply → Exit…
Did you have any conditions on this node? (You shouldn’t need any if it’s just the one reply, and the conditions that led you to this have already been tested before the player replies).

Barring that, let’s get specific on the conditions that might be failing…

First, we’re going to create a testing Dialogue that we’ll change as we go through the process (leaving your current dialogues in tact)

We’re just going to run with a test branch and a no branch, testing one Condition at a time

First Dialogue: “Hello there, I’m your dialogue testing dummy. Would you like to run a test?”

  • Player Response 1 “Sure, why not?”
    → Condition(!HasQuest(SomeQuest)) “Great, I’ve signed you up for a quest” (exit action GiveQuest(SomeQuest)))
    → Condition(HasQuest(SomeQuest)) “You already have that quest”
  • Player Response 2 “No thanks”
    → No condition “Ok, fine, be that way.”

Run this dialogue twice. The first time should yield “Great, I’ve signed you up for a quest”, and then add the quest to the quest list.
The second time, the resonse should be You already have that quest".

The idea here is that we’ll be testing one condition at a time, noting which ones are working properly and which ones aren’t, or if the whole system is out of whack.

See if you’re still getting the null reference when using this dialogue.

Wait I think I found the problem. My Conditions never saved or they were reset to nothing somehow. That may be why it is falling out of range. It is because there is nothing there to check in the first place.

But how would that have happened?..well regardless I just need to go back through the conditions lesson and reconfigure my conditions. Then that should fix this.

Wait no, my conditions are still there…

I do see something though…the conditions and setup I have them marked on the player dialogue not the npc dialogue responses. So I am wondering if the conditions are just in the wrong place.

Since in the test the conditions are being placed on the npc dialogue responses to the player dialogue.

Oh this is really broken…
Here are screenshots.
I finished the test dialogue as explained with the conditions. Here is what I get when I first speak to the guard.

Next this is what Happen when I first speak to the guard for the mother bunions quest.
I click the next button as that comes up for this dialogue. then I get to the choices.


Both options will give me the same error message.
See Here:
IndexOutOfRangeException: Index was outside the bounds of the array.
RPG.Dialogue.PlayerConversant.Next () (at Assets/Scripts/Dialogue/PlayerConversant.cs:99)
RPG.Dialogue.PlayerConversant.SelectChoice (RPG.Dialogue.DialogueNode chosenNode) (at Assets/Scripts/Dialogue/PlayerConversant.cs:82)
RPG.UI.DialogueUI+<>c__DisplayClass11_0.b__0 () (at Assets/Scripts/UI/DialogueUI.cs:75)
UnityEngine.Events.InvokableCall.Invoke () (at <6afd1274f120405096bc1ad9e2010ba6>:0)
UnityEngine.Events.UnityEvent.Invoke () (at <6afd1274f120405096bc1ad9e2010ba6>:0)
UnityEngine.UI.Button.Press () (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Button.cs:70)
UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Button.cs:114)
UnityEngine.EventSystems.ExecuteEvents.Execute (UnityEngine.EventSystems.IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/ExecuteEvents.cs:57)
UnityEngine.EventSystems.ExecuteEvents.Execute[T] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.ExecuteEvents+EventFunction`1[T1] functor) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/ExecuteEvents.cs:272)
UnityEngine.EventSystems.EventSystem:Update() (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:501)

Lastly if I choose to speak to the other guard used to test the completion of one of the objectives of the mother bunion quest.

I can show what my condition setup looks like here as well if that can give additional help.
I must have done something wrong, I do not understand how the dialogue ui is not breaking.

yes, show the condition setup as you have it (maybe a screen of the dialogue tree, and then an expanded look at each dialoguenode)

Here are screenshots for the test dialogue and the mother bunions dialogue as well as the setup for the new in town dialogue just in case.

I also have details on the dialogue nodes as well.









I hope this helps. Let me know if you need any further details.

Oh I know, here are the NPC characters that I would talk to for the dialogue.
Here are the three NPC characters to talk with:



I think I’m going to need to take a closer look at the project to see if I can figure out the issue.

Zip up your project and upload it to https://gdev.tv/projectupload (Be sure to remove the Library folder to conserve space).

I made a copy of the project removed the library folder and zipped it up and then uploaded the project as requested.

In the mean time I think I will continue my work on the fourth and final main course of the set. Once that is complete I plan to go through the new 3rd person combat and traversal course.

I think I am going to combine elements of all five courses into the project I am planning for making my own full game. Something with a small start but can easily be expanded on as time goes on.

I appreciate you taking the time to review the project though and helping me solve this issue.

Ok, this threw me off when I ran the test, because if the condition is blank, then it should always pass, but in my test dialogue, the Player responses conditions were blank, i.e. they should have both come back in the filter…

It occurred to me that I never actually asked you for your Condition.cs and the issue appears to be in the Condition class…
Your code here reads:

        public bool Check(IEnumerable<IPredicateEvaluator> evaluators)
        {
            foreach (Disjunction pred in and)
            {
                if (pred.Check(evaluators))
                {
                    return true;
                }
            }
            return false;
        }

In this case, the logic is inverted… Using this set up, a blank condition will always fail because it will never be seen by evaluators. Checking against the course code to be sure, this section should actually read:

        public bool Check(IEnumerable<IPredicateEvaluator> evaluators)
        {
            foreach (Disjunction pred in and)
            {
                if (!pred.Check(evaluators))
                {
                    return false;
                }
            }
            return true;
        }
1 Like

Making that change was the fix I needed. Dialogue is working as it should now.
Thank You!

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

Privacy & Terms