DialogueSystemTrigger Interrupt
DialogueSystemTrigger Interrupt
1. I use DialogueSystemTrigger to start the first conversation. This conversation warns the player he is under attack.
2. I use DialogueSystemTrigger to start the second conversation. This conversation tells the player he died.
If #2 attempts to start before #1 finishes, #2 does not start. I never get the OnConversationEnd callback from the second conversation. The game relies on this to continue and the player is unable to proceed.
How would I fix this?
2. I use DialogueSystemTrigger to start the second conversation. This conversation tells the player he died.
If #2 attempts to start before #1 finishes, #2 does not start. I never get the OnConversationEnd callback from the second conversation. The game relies on this to continue and the player is unable to proceed.
How would I fix this?
Re: DialogueSystemTrigger Interrupt
Hi,
What if you allow simultaneous conversations? (Dialogue Manager GameObject > Other Settings > Allow Simultaneous Conversations) This way #2 can start even if #1 is still active.
Alternatively, you can make a subclass of DialogueSystemTrigger that overrides DoConversationAction(). If another conversation is already active, it can wait until the previous conversation is finished. Example:
That's just an example to show the idea. You can implement it differently if you want of course.
Then use this subclass wherever you need conversations to wait for a previous one to finish.
What if you allow simultaneous conversations? (Dialogue Manager GameObject > Other Settings > Allow Simultaneous Conversations) This way #2 can start even if #1 is still active.
Alternatively, you can make a subclass of DialogueSystemTrigger that overrides DoConversationAction(). If another conversation is already active, it can wait until the previous conversation is finished. Example:
Code: Select all
protected override void DoConversationAction(Transform actor)
{
StartCoroutine(StartConversationCoroutine(actor));
}
IEnumerator StartConversationCoroutine(Transform actor)
{
while (DialogueManager.isConversationActive)
{
yield return null;
}
base.DoConversationAction(actor);
}
Then use this subclass wherever you need conversations to wait for a previous one to finish.
Re: DialogueSystemTrigger Interrupt
Thanks for the answer.
Is it possible to make it so any time one conversation attempts to start, any conversations in progress are ended immediately (and still notify the game they ended)?
Is it possible to make it so any time one conversation attempts to start, any conversations in progress are ended immediately (and still notify the game they ended)?
Re: DialogueSystemTrigger Interrupt
Hi,
I can add that as a core feature. In the meantime, you can subclass DialogueSystemTrigger and override DoConversationAction():
Or, if you don't want to override, you can allow simultaneous conversations. Then add a script that hooks into DialogueManager.instance.conversationStarted. Kill all active conversations except the last one started:
I can add that as a core feature. In the meantime, you can subclass DialogueSystemTrigger and override DoConversationAction():
Code: Select all
protected override void DoConversationAction(Transform actor)
{
DialogueManager.StopConversation();
base.DoConversationAction(actor);
}
Code: Select all
DialogueManager.instance.conversationStarted += CheckActiveConversations;
...
void CheckActiveConversations(Transform actor)
{
foreach (var activeConversation in DialogueManager.instance.activeConversations)
{
if (activeConversation.conversationModel.firstState.subtitle.dialogueEntry.conversationID != DialogueManager.lastConversationID)
{
activeConversation.conversationController.Close();
}
}
}
Re: DialogueSystemTrigger Interrupt
Thanks, I'll try overriding DialogueSystemTrigger.
When I used allow multiple conversations it crashed in AbstractDialogueUI.cs ShowResponses() on this line "else if (this.transform == null)"
MissingReferenceException: The object of type 'StandardDialogUI2' has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.
PixelCrushers.DialogueSystem.AbstractDialogueUI.ShowResponses (PixelCrushers.DialogueSystem.Subtitle subtitle, PixelCrushers.DialogueSystem.Response[] responses, System.Single timeout) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/UI/Abstract/Dialogue/AbstractDialogueUI.cs:292)
PixelCrushers.DialogueSystem.StandardDialogueUI.ShowResponses (PixelCrushers.DialogueSystem.Subtitle subtitle, PixelCrushers.DialogueSystem.Response[] responses, System.Single timeout) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/UI/Standard/Dialogue/StandardDialogueUI.cs:215)
StandardDialogUI2.ShowResponses (PixelCrushers.DialogueSystem.Subtitle subtitle, PixelCrushers.DialogueSystem.Response[] responses, System.Single timeout) (at Assets/Mod/Export/BaseMod/Scenes/UI/ConversationDialog/StandardDialogUI2.cs:103)
PixelCrushers.DialogueSystem.ConversationView.StartResponses (PixelCrushers.DialogueSystem.Subtitle subtitle, PixelCrushers.DialogueSystem.Response[] responses) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/MVC/View/View/ConversationView.cs:425)
PixelCrushers.DialogueSystem.ConversationController.OnFinishedSubtitle (System.Object sender, System.EventArgs e) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/MVC/Controller/ConversationController.cs:276)
PixelCrushers.DialogueSystem.ConversationView.FinishSubtitle () (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/MVC/View/View/ConversationView.cs:397)
PixelCrushers.DialogueSystem.ConversationView.OnFinishedSubtitle () (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/MVC/View/View/ConversationView.cs:404)
PixelCrushers.DialogueSystem.Sequencer.FinishSequence () (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/MVC/Sequencer/Sequencer.cs:508)
PixelCrushers.DialogueSystem.Sequencer.Update () (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/MVC/Sequencer/Sequencer.cs:500)
When I used allow multiple conversations it crashed in AbstractDialogueUI.cs ShowResponses() on this line "else if (this.transform == null)"
MissingReferenceException: The object of type 'StandardDialogUI2' has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.
PixelCrushers.DialogueSystem.AbstractDialogueUI.ShowResponses (PixelCrushers.DialogueSystem.Subtitle subtitle, PixelCrushers.DialogueSystem.Response[] responses, System.Single timeout) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/UI/Abstract/Dialogue/AbstractDialogueUI.cs:292)
PixelCrushers.DialogueSystem.StandardDialogueUI.ShowResponses (PixelCrushers.DialogueSystem.Subtitle subtitle, PixelCrushers.DialogueSystem.Response[] responses, System.Single timeout) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/UI/Standard/Dialogue/StandardDialogueUI.cs:215)
StandardDialogUI2.ShowResponses (PixelCrushers.DialogueSystem.Subtitle subtitle, PixelCrushers.DialogueSystem.Response[] responses, System.Single timeout) (at Assets/Mod/Export/BaseMod/Scenes/UI/ConversationDialog/StandardDialogUI2.cs:103)
PixelCrushers.DialogueSystem.ConversationView.StartResponses (PixelCrushers.DialogueSystem.Subtitle subtitle, PixelCrushers.DialogueSystem.Response[] responses) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/MVC/View/View/ConversationView.cs:425)
PixelCrushers.DialogueSystem.ConversationController.OnFinishedSubtitle (System.Object sender, System.EventArgs e) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/MVC/Controller/ConversationController.cs:276)
PixelCrushers.DialogueSystem.ConversationView.FinishSubtitle () (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/MVC/View/View/ConversationView.cs:397)
PixelCrushers.DialogueSystem.ConversationView.OnFinishedSubtitle () (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/MVC/View/View/ConversationView.cs:404)
PixelCrushers.DialogueSystem.Sequencer.FinishSequence () (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/MVC/Sequencer/Sequencer.cs:508)
PixelCrushers.DialogueSystem.Sequencer.Update () (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/MVC/Sequencer/Sequencer.cs:500)
Re: DialogueSystemTrigger Interrupt
I think the DialogueSystemTrigger override will do what you want.
This may no longer be important to you but, for the error, you have done something that destroyed the dialogue UI's GameObject out from under it. When you run simultaneous conversations, make sure each one uses its own dialogue UI.
This may no longer be important to you but, for the error, you have done something that destroyed the dialogue UI's GameObject out from under it. When you run simultaneous conversations, make sure each one uses its own dialogue UI.
Re: DialogueSystemTrigger Interrupt
The DialogueSystemTrigger override you suggested is incorrect; it calls OnConversationEnd(Transform actor) immediately on itself.
> Void ModV1.Source.Dialogue.DeleteGameObjectOnConversationEnd:OnConversationEnd (Transform)+0x1 at E:\Work\EmpireOfEmber\Client\DLL\ModV1\Source\Dialogue\DeleteGameObjectOnConversationEnd.cs:14 C#
Void PixelCrushers.DialogueSystem.ConversationModel:InformParticipants (String, Boolean)+0x5c at E:\Work\EmpireOfEmber\Client\Assets\Plugins\Pixel Crushers\Dialogue System\Scripts\MVC\Model\Logic\Model\ConversationModel.cs:[194:37-194:117] C#
Void PixelCrushers.DialogueSystem.ConversationController:Close ()+0xa1 at E:\Work\EmpireOfEmber\Client\Assets\Plugins\Pixel Crushers\Dialogue System\Scripts\MVC\Controller\ConversationController.cs:[171:17-171:92] C#
Void PixelCrushers.DialogueSystem.DialogueSystemController:StopConversation ()+0x15 at E:\Work\EmpireOfEmber\Client\Assets\Plugins\Pixel Crushers\Dialogue System\Scripts\Manager\DialogueSystemController.cs:[910:17-910:50] C#
Void PixelCrushers.DialogueSystem.DialogueManager:StopConversation ()+0x14 at E:\Work\EmpireOfEmber\Client\Assets\Plugins\Pixel Crushers\Dialogue System\Scripts\Manager\DialogueManager.cs:[484:13-484:41] C#
Void PixelCrushers.DialogueSystem.DialogueSystemTrigger:DoConversationAction (Transform)+0x1 at E:\Work\EmpireOfEmber\Client\Assets\Plugins\Pixel Crushers\Dialogue System\Scripts\Triggers\Triggers\DialogueSystemTrigger.cs:[846:13-846:48] C#
Void PixelCrushers.DialogueSystem.DialogueSystemTrigger:Fire (Transform)+0x59 at E:\Work\EmpireOfEmber\Client\Assets\Plugins\Pixel Crushers\Dialogue System\Scripts\Triggers\Triggers\DialogueSystemTrigger.cs:[635:13-635:41] C#
Void PixelCrushers.DialogueSystem.DialogueSystemTrigger:TryStart (Transform, Transform)+0x33 at E:\Work\EmpireOfEmber\Client\Assets\Plugins\Pixel Crushers\Dialogue System\Scripts\Triggers\Triggers\DialogueSystemTrigger.cs:[617:21-617:33] C#
Void PixelCrushers.DialogueSystem.DialogueSystemTrigger:TryStart (Transform)+0x4 at E:\Work\EmpireOfEmber\Client\Assets\Plugins\Pixel Crushers\Dialogue System\Scripts\Triggers\Triggers\DialogueSystemTrigger.cs:[603:13-603:36] C#
Void PixelCrushers.DialogueSystem.DialogueSystemTrigger:OnUse ()+0x1c at E:\Work\EmpireOfEmber\Client\Assets\Plugins\Pixel Crushers\Dialogue System\Scripts\Triggers\Triggers\DialogueSystemTrigger.cs:[494:75-494:90] C#
GameObject DialogueSystem:StartOneShotDialogue (GameObject, EventHandler`1, PrefabCampaignQuest2)+0x11b at E:\Work\EmpireOfEmber\Client\Assets\Scripts\DialogueSystem.cs:[103:13-103:29] C#
> Void ModV1.Source.Dialogue.DeleteGameObjectOnConversationEnd:OnConversationEnd (Transform)+0x1 at E:\Work\EmpireOfEmber\Client\DLL\ModV1\Source\Dialogue\DeleteGameObjectOnConversationEnd.cs:14 C#
Void PixelCrushers.DialogueSystem.ConversationModel:InformParticipants (String, Boolean)+0x5c at E:\Work\EmpireOfEmber\Client\Assets\Plugins\Pixel Crushers\Dialogue System\Scripts\MVC\Model\Logic\Model\ConversationModel.cs:[194:37-194:117] C#
Void PixelCrushers.DialogueSystem.ConversationController:Close ()+0xa1 at E:\Work\EmpireOfEmber\Client\Assets\Plugins\Pixel Crushers\Dialogue System\Scripts\MVC\Controller\ConversationController.cs:[171:17-171:92] C#
Void PixelCrushers.DialogueSystem.DialogueSystemController:StopConversation ()+0x15 at E:\Work\EmpireOfEmber\Client\Assets\Plugins\Pixel Crushers\Dialogue System\Scripts\Manager\DialogueSystemController.cs:[910:17-910:50] C#
Void PixelCrushers.DialogueSystem.DialogueManager:StopConversation ()+0x14 at E:\Work\EmpireOfEmber\Client\Assets\Plugins\Pixel Crushers\Dialogue System\Scripts\Manager\DialogueManager.cs:[484:13-484:41] C#
Void PixelCrushers.DialogueSystem.DialogueSystemTrigger:DoConversationAction (Transform)+0x1 at E:\Work\EmpireOfEmber\Client\Assets\Plugins\Pixel Crushers\Dialogue System\Scripts\Triggers\Triggers\DialogueSystemTrigger.cs:[846:13-846:48] C#
Void PixelCrushers.DialogueSystem.DialogueSystemTrigger:Fire (Transform)+0x59 at E:\Work\EmpireOfEmber\Client\Assets\Plugins\Pixel Crushers\Dialogue System\Scripts\Triggers\Triggers\DialogueSystemTrigger.cs:[635:13-635:41] C#
Void PixelCrushers.DialogueSystem.DialogueSystemTrigger:TryStart (Transform, Transform)+0x33 at E:\Work\EmpireOfEmber\Client\Assets\Plugins\Pixel Crushers\Dialogue System\Scripts\Triggers\Triggers\DialogueSystemTrigger.cs:[617:21-617:33] C#
Void PixelCrushers.DialogueSystem.DialogueSystemTrigger:TryStart (Transform)+0x4 at E:\Work\EmpireOfEmber\Client\Assets\Plugins\Pixel Crushers\Dialogue System\Scripts\Triggers\Triggers\DialogueSystemTrigger.cs:[603:13-603:36] C#
Void PixelCrushers.DialogueSystem.DialogueSystemTrigger:OnUse ()+0x1c at E:\Work\EmpireOfEmber\Client\Assets\Plugins\Pixel Crushers\Dialogue System\Scripts\Triggers\Triggers\DialogueSystemTrigger.cs:[494:75-494:90] C#
GameObject DialogueSystem:StartOneShotDialogue (GameObject, EventHandler`1, PrefabCampaignQuest2)+0x11b at E:\Work\EmpireOfEmber\Client\Assets\Scripts\DialogueSystem.cs:[103:13-103:29] C#
- Attachments
-
- DSFUDelete.PNG (91.38 KiB) Viewed 696 times
Re: DialogueSystemTrigger Interrupt
Hi,
Shouldn't it call OnConversationEnd() since it's ending the first conversation?
Here's the example scene that I tested with:
DS_DialogueSystemTriggerCanInterrupt_2020-11-21.unitypackage
And here's the script from it:
DialogueSystemTriggerCanInterrupt
I added a ConversationLogger script to the Dialogue Manager so it will log messages such as OnConversationStart and OnConversationEnd.
If you play the scene and click the Interrupt button instead of the conversation's Continue button, it will interrupt the conversation with a new conversation.
If you don't want the first conversation to send its OnConversationEnd message when you stop it, you can import the DS patch from the Dialogue System Extras page. It's in the "Updated for 2.2.13" foldout. It exposes a static property DialogueSystemController.isWarmingUp. If this property is true, the Dialogue System won't send OnConversationStart/End/Line messages. So you could change DoConversationAction to:
Shouldn't it call OnConversationEnd() since it's ending the first conversation?
Here's the example scene that I tested with:
DS_DialogueSystemTriggerCanInterrupt_2020-11-21.unitypackage
And here's the script from it:
DialogueSystemTriggerCanInterrupt
Code: Select all
using UnityEngine;
using PixelCrushers.DialogueSystem;
public class DialogueSystemTriggerCanInterrupt : DialogueSystemTrigger
{
protected override void DoConversationAction(Transform actor)
{
if (DialogueManager.isConversationActive)
{
Debug.Log("Stopping conversation: " + DialogueManager.lastConversationStarted);
DialogueManager.StopConversation();
}
Debug.Log("Starting conversation: " + conversation);
base.DoConversationAction(actor);
}
}
If you play the scene and click the Interrupt button instead of the conversation's Continue button, it will interrupt the conversation with a new conversation.
If you don't want the first conversation to send its OnConversationEnd message when you stop it, you can import the DS patch from the Dialogue System Extras page. It's in the "Updated for 2.2.13" foldout. It exposes a static property DialogueSystemController.isWarmingUp. If this property is true, the Dialogue System won't send OnConversationStart/End/Line messages. So you could change DoConversationAction to:
Code: Select all
protected override void DoConversationAction(Transform actor)
{
if (DialogueManager.isConversationActive)
{
Debug.Log("Stopping conversation: " + DialogueManager.lastConversationStarted);
DialogueSystemController.isWarmingUp = true; // Temporarily suppress OnConversationXXX messages.
DialogueManager.StopConversation();
DialogueSystemController.isWarmingUp = false;
}
Debug.Log("Starting conversation: " + conversation);
base.DoConversationAction(actor);
}
Re: DialogueSystemTrigger Interrupt
"Shouldn't it call OnConversationEnd() since it's ending the first conversation?"
There is only one conversation. I am starting a conversation, and immediately at the same time I start it I get OnConversationEnd() on the same conversation I am starting. OnConversationEnd() should be called when the conversation ends, not when it starts.
There is only one conversation. I am starting a conversation, and immediately at the same time I start it I get OnConversationEnd() on the same conversation I am starting. OnConversationEnd() should be called when the conversation ends, not when it starts.
Re: DialogueSystemTrigger Interrupt
In my prior topic I said "immediately on itself."
What I mean by this, with the code you pasted
protected override void DoConversationAction(Transform actor)
{
DialogueManager.StopConversation();
base.DoConversationAction(actor);
}
Current:
<New scene>
1. Start the one and only conversation
2. OnConversationEnd() IMMEDIATELY
3. Conversation plays out
Expected
<New scene>
1. Start the one and only conversation
2. Conversation plays out
3. OnConversationEnd()
*Edit* I noticed in your sample you have an extra line "if (DialogueManager.isConversationActive)"
I'll see if that fixes the problem.
What I mean by this, with the code you pasted
protected override void DoConversationAction(Transform actor)
{
DialogueManager.StopConversation();
base.DoConversationAction(actor);
}
Current:
<New scene>
1. Start the one and only conversation
2. OnConversationEnd() IMMEDIATELY
3. Conversation plays out
Expected
<New scene>
1. Start the one and only conversation
2. Conversation plays out
3. OnConversationEnd()
*Edit* I noticed in your sample you have an extra line "if (DialogueManager.isConversationActive)"
I'll see if that fixes the problem.