Page 1 of 1

GotoState() question

Posted: Sun Apr 03, 2022 6:23 am
by joeylu
Hi Tony, I have some scripts in

Code: Select all

    private void OnConversationLineEnd(Subtitle subtitle) {        
        DialogueEntry nextEntry = DialogueManager.MasterDatabase.GetDialogueEntry(subtitle.dialogueEntry.outgoingLinks[0]);
        ConversationState nextResponseState = DialogueManager.conversationModel.GetState(nextEntry);
        DialogueManager.conversationController.GotoState(nextResponseState);
    }
let's say I have a dislogue entry named " "Hello"
now if I put "someTrigger" into a "Hello" entry field, and create a NPC dialogue entry under this entry, that NPC dialogue won't play. However, if I create another Player dialogue entry under that NPC dialogue, the NPC line will be played

or, if I move above code to OnConversationLine(), it will play NPC dialogue entry, but it will cause both "Hello" entry and NPC dialogue entry be played at same time

anyway I can resolve this

FYI, I'm trying to specific a dialogue entry to go to a specific ongoingLink from script (if it has more than one onging link), currently I use GoToState() because I don't know any other way, maybe you can provide me some other solution to achive this

tks

Re: GotoState() question

Posted: Sun Apr 03, 2022 9:22 am
by Tony Li
Hi,

Can you call GotoState() outside of OnConversationLineEnd()? The Dialogue System calls OnConversationLineEnd() right before it calls DialogueManager.conversationView.FinishedSubtitleHandler, which is a delegate that calls DialogueManager.conversationController.OnFinishedSubtitle to advance the conversation. This means that, at the point where OnConversationLineEnd() is called, the Dialogue System is just about to go to the next state.

You probably want to make your manual call to GotoState() before the Dialogue System gets to the point where it calls OnConversationLineEnd().

Alternatively -- and this may be easier -- in your OnConversationLineEnd() method, you could remove the GotoState() call. Instead, adjust the response lists in DialogueManager.currentConversationState. If its npcResponses[] array has any elements, OnFinishedSubtitle will go to npcResponses[0].

Re: GotoState() question

Posted: Mon Apr 04, 2022 3:00 am
by joeylu
tks for the explaining,
My understanding is that OnFinishedSubtitle() only works on npcResponses?
let's say I want to pick the next response randomly disregard it's from NPC or PC, and if it's from PC, assume there are no other conditions are set
here is my script:

Code: Select all

  private void OnConversationLine(Subtitle subtitle) {
        if (DialogueManager.currentConversationState.pcResponses.Length > 1) { //the next responses are from player, and has more than 1 responses
        //disable the response menu selection
        //go to play a random response directly
        } else if (DialogueManager.currentConversationState.npcResponses.Length > 1) { //the next responses are from NPC, and has more than 1 responses
          System.Random rnd = new System.Random();
          DialogueManager.currentConversationState.npcResponses = DialogueManager.currentConversationState.npcResponses.OrderBy(x => rnd.Next()).ToArray();
        }
   }
obviously, I can't use npc logic on pc's condition, because when there are more than 1 pc responses available, a response menu will be appeared, my guess is to add something like [auto] tag to a random pc response? then when it is played, remove that [auto] tag?

Re: GotoState() question

Posted: Mon Apr 04, 2022 9:36 am
by Tony Li
Hi,

If I understand your question correctly, OnFinishedSubtitle() is called after any dialogue entry that's used in a conversation. That entry's current state is in DialogueManager.currentConversationState. It has a list of NPC & PC responses, which are the outgoing entries whose conditions are currently true. You can manipulate the npcResponses and pcResponses lists.

For example:

Code: Select all

void OnConversationLine(Subtitle subtitle)
{
    // Create a temp list of all responses (NPC & PC):
    var allResponses = new List<Response>();
    allResponses.AddRange(DialogueManager.currentConversationState.npcResponses);
    allResponses.AddRange(DialogueManager.currentConversationState.pcResponses);
    
    // Choose a random response:
    var index = Random.Range(0, allResponses.Count);
    var isNPCResponse = index < DialogueManager.currentConversationState.npcResponses.Length;
    
    // Set up the response lists:
    if (isNPCResponse)
    {
        DialogueManager.currentConversationState.npcResponses = new Response[1];
        DialogueManager.currentConversationState.npcResponses[0] = allResponses[index];
        DialogueManager.currentConversationState.pcResponses  = new Response[0];
    }
    else
    {
        DialogueManager.currentConversationState.npcResponses  = new Response[0];
        DialogueManager.currentConversationState.pcResponses = new Response[1];
        DialogueManager.currentConversationState.pcResponses[0] = allResponses[index];
        DialogueManager.currentConversationState.pcResponses[0].formattedText.forceAuto = true;
    }
}
(Note: I haven't tested the exact example I posted above. There may be typos.)

Re: GotoState() question

Posted: Mon Apr 04, 2022 11:41 am
by joeylu
DialogueManager.currentConversationState.pcResponses[0].formattedText.forceAuto = true;

this seems the one that can force a pc response to play regardless if there are any other pc responses, I will give it a try, tks Tony, great support ever!

Re: GotoState() question

Posted: Mon Apr 04, 2022 2:49 pm
by Tony Li
Happy to help!