[HOWTO] How To: Interrupt Conversation

Announcements, support questions, and discussion for the Dialogue System.
Post Reply
User avatar
Tony Li
Posts: 22107
Joined: Thu Jul 18, 2013 1:27 pm

[HOWTO] How To: Interrupt Conversation

Post by Tony Li »

This post describes how to interrupt one conversation with another. The example context is that the player is talking to an NPC. At any point, the player can select an inventory item and ask the NPC about it, which should start a new conversation about the inventory item

One approach is to stop the current conversation and start the new one. Add a method that runs when the player clicks on an inventory item. In that method, check if a conversation is active. If so, stop the conversation and start a new conversation. For example, something like:

Code: Select all

using PixelCrushers.DialogueSystem;
...
public void AskAboutItem(Item item)
{
    if (DialogueManager.isConversationActive)
    {
        DialogueManager.StopConversation();
        string conversationTitle =  "Ask About " + item.name;
        DialogueManager.StartConversation(conversationTitle, DialogueManager.currentActor, DialogueManager.currentConversant);
    }
}
If you need to resume the position in the previous conversation after talking about the item, then in the method above you can record the current conversation state before stopping the conversation. (It's in DialogueManager.currentConversationState.) When the item conversation is done, restart the previous conversation:

Code: Select all

using PixelCrushers.DialogueSystem;
...
private string previousConversationTitle = string.Empty;
private int previousEntryID;
private Transform previousActor, previousConversant;
...
public void AskAboutItem(Item item)
{
    if (DialogueManager.isConversationActive)
    {
        previousConversationTitle = DialogueManager.lastConversationStarted;
        previousEntryID = DialogueManager.currentConversationState.subtitle.dialogueEntry.id;
        previousActor = DialogueManager.currentActor;
        previousConversant = DialogueManager.currentConversant;
        DialogueManager.StopConversation();
        string conversationTitle =  "Ask About " + item.name;
        DialogueManager.StartConversation(conversationTitle, DialogueManager.currentActor, DialogueManager.currentConversant);
        DialogueManager.instance.conversationEnded += ResumePreviousConversation;
    }
}

public void ResumePreviousConversation(Transform actor)
{
    DialogueManager.instance.conversationEnded += ResumePreviousConversation;
    if (!string.IsNullOrEmpty(previousConversationTitle))
    {
        DialogueManager.StartConversation(previousConversationTitle, previousActor, previousConversant, previousEntryID);
        previousConversationTitle = string.Empty;
    }
}

Alternatively, you can keep the original conversation going. Instead of that code above, tell the current conversation to switch to the first entry in the item conversation. Before starting the item conversation, we'll push the current conversation position onto a Conversation Position Stack. The last node of the item conversation should call PopConversationPosition() in its Script to return to the previously-pushed position. This approach assumes you've added a ConversationPositionStack component to the Dialogue Manager.

Code: Select all

public void AskAboutItem(Item item)
{
    if (DialogueManager.isConversationActive)
    {
        ConversationPositionStack.PushConversationPosition();
        
        string conversationTitle =  "Ask About " + item.name;
        var conversation = DialogueManager.GetConversation(conversationTitle);
        var startEntry = conversation.GetFirstDialogueEntry();
        var firstRealEntry = DialogueManager.GetDialogueEntry(startEntry.outgoingLinks[0]);
        var newState = DialogueManager.conversationModel.GetState(firstRealEntry);
        DialogueManager.conversationController.GotoState(newState);
    }
}
User avatar
Tony Li
Posts: 22107
Joined: Thu Jul 18, 2013 1:27 pm

Re: [HOWTO] How To: Interrupt Conversation

Post by Tony Li »

Note: DialogueManager.lastConversationStarted contains the name of the last conversation started by a Dialogue System Trigger or C# call to DialogueManager.StartConversation() or equivalent visual scripting action. If your conversation links to other conversations, it doesn't contain the name of the linked conversation. To record the actual current conversation in this case, use DialogueManager.currentConversationState:

Code: Select all

int conversationID = DialogueManager.currentConversationState.subtitle.dialogueEntry.conversationID;
previousConversationTitle = DialogueManager.masterDatabase.GetConversation(conversationID).Title;
Post Reply