GotoState() question

Announcements, support questions, and discussion for the Dialogue System.
Post Reply
joeylu
Posts: 111
Joined: Sun May 17, 2020 1:07 pm

GotoState() question

Post 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
User avatar
Tony Li
Posts: 21678
Joined: Thu Jul 18, 2013 1:27 pm

Re: GotoState() question

Post 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].
joeylu
Posts: 111
Joined: Sun May 17, 2020 1:07 pm

Re: GotoState() question

Post 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?
User avatar
Tony Li
Posts: 21678
Joined: Thu Jul 18, 2013 1:27 pm

Re: GotoState() question

Post 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.)
joeylu
Posts: 111
Joined: Sun May 17, 2020 1:07 pm

Re: GotoState() question

Post 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!
User avatar
Tony Li
Posts: 21678
Joined: Thu Jul 18, 2013 1:27 pm

Re: GotoState() question

Post by Tony Li »

Happy to help!
Post Reply