[HOWTO] How To: Interrupt Conversation
Posted: Mon Mar 29, 2021 9:42 am
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:
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:
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.
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);
}
}
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);
}
}