1

When I initiate my GameObject I loop through all if its dialogs. For each Dialog there is an action. Activate a quest or change NPC stage.

The method I pass to PopulateConversationList below gets called when I click the final button in a dialog-interaction, i.e "Okay". Below I pass an ActiveNpcQuest(questId) method, and pass the questId (get it from dialog data) like this:

//loop through all dialogs
for (int i = 0; i < dialogData.dialogs.Count; i++) 
    {
        startsQ = dialogData.dialogs[i].dialogStartsQuest;
        questId = dialogData.dialogs[i].dialogBelongToQuestId;

            //if we have a quest, activate it (if already active, nothing happens)
            if (startsQ) 
            {
                PopulateConversationList(dialogData.dialogs[i].dialogsInThisStage[j].pages, "Okay", npcObject.npcName, dialogData.dialogs[i].npcStage, () =>
                {
                    ActivateNPCQuest(questId); //This is the parameter I want to send
                });
            }
            //If this dialog ALWAYS changes the NPC stage, then change stage
            else if (autoChangeStage) 
            {
                PopulateConversationList(dialogData.dialogs[i].dialogsInThisStage[j].pages, "Okay", npcObject.npcName, dialogData.dialogs[i].npcStage, ChangeNPCStage);
            }
        }

I guess the value of questId doesnt actually get saved inside the ActivateNPCQuest-method. Which makes a lot of sense. But Is there any way I can do what I want here?

My PopulateConversationList declaration:

public void PopulateConversationList(List<string> fullConversation, string onLastPagePrompt, string npcName, int stage, UnityAction action)

My ActiveNpcQuest-method:

public void ActivateNPCQuest(int id)
{
    for (int i = 0; i < npcQuests.Count; i++)
    {
        if (npcQuests[i].questId == id && !npcQuests[i].active && !npcQuests[i].objective.isComplete)
        {
            npcQuests[i].active = true;
            npcObject.hasActiveQuest = true;
        }
    }
}

Had real problems knowing what to search for, not sure if Unity Actions are Lambda expressions or events.

Green_qaue
  • 3,561
  • 11
  • 47
  • 89
  • 2
    cache questId in a local variable and pass this variable instead – yes Jul 07 '17 at 19:03
  • But this is done in a loop. So if I only have 1 variable, its value will keep changing until eventually it just stays on the value it was given in the last iteration of the loop. Not sure if I made it clear, but the above is done when Initiating the object, and the method is then (supposed to be) stored and called when I interact with the NPC. – Green_qaue Jul 07 '17 at 19:05

1 Answers1

2

It is hard to understand you problem without having full code and knowing what you expect but it looks like you are having problems due to closures. Try to assign questId to a new variable each iteration of the loop and pass it to your ActivateNPCQuest method to see if you get the result you want:

//loop through all dialogs
for (int i = 0; i < dialogData.dialogs.Count; i++) 
    {
        startsQ = dialogData.dialogs[i].dialogStartsQuest;
        var questId = dialogData.dialogs[i].dialogBelongToQuestId; \\<----

            //if we have a quest, activate it (if already active, nothing happens)
            if (startsQ) 
            {
                PopulateConversationList(dialogData.dialogs[i].dialogsInThisStage[j].pages, "Okay", npcObject.npcName, dialogData.dialogs[i].npcStage, () =>
                {
                    ActivateNPCQuest(questId); //This is the parameter I want to send
                });
            }
            //If this dialog ALWAYS changes the NPC stage, then change stage
            else if (autoChangeStage) 
            {
                PopulateConversationList(dialogData.dialogs[i].dialogsInThisStage[j].pages, "Okay", npcObject.npcName, dialogData.dialogs[i].npcStage, ChangeNPCStage);
            }
        }
user1242967
  • 1,220
  • 3
  • 18
  • 30