Queueing conversations.
Queueing conversations.
Is there any way to queue a conversation, so that it plays immediately after the current one? My game has ongoing conversations as the player moves around the scene, and different events trigger different conversations. The problem is if there is already an active conversation, the DialogueManager.StartConversation() call gets ignored. Is this something I need to write custom scripts to handle, or is there a setting somewhere that I am missing? I have found the "Allow Simultaneous" switch, but it's not quite what I need (stacking conversations, rather that playing both at once). My biggest problem with writing my own conversation queue, is that I use both programatic triggers (easy) and triggers from built in DialogueSystem components (hard). Any ideas on how to proceed?
Re: Queueing conversations.
You perfectly identified the easy & hard parts -- but fortunately the hard part really isn't too hard.
To set up your queue, add a script to the Dialogue Manager that has an OnConversationEnd method. Something like:
ConversationQueueManager.cs
To start or queue a conversation from script, call:
To do it from a Dialogue System Trigger, make a subclass of Dialogue System Trigger. Override DoConversationActor to something like:
The operative part is the last line, which calls ConversationQueueManager.instance.PlayConversation instead of DialogueManager.StartConversation. I cut out a lot of the extra stuff that the base DoConversationAction does. You can load up DialogueSystemTrigger.cs and add it back in if you want.
To set up your queue, add a script to the Dialogue Manager that has an OnConversationEnd method. Something like:
ConversationQueueManager.cs
Code: Select all
using System;
using System.Collections.Generic;
using UnityEngine;
using PixelCrushers.DialogueSystem;
public class ConversationQueueManager : MonoBehaviour
{
[Serializable]
public class QueuedConversation
{
public string queuedConversation;
public Transform queuedActor;
public Transform queuedConversant;
}
Queue<QueuedConversation> queue = new Queue<QueuedConversation>();
public ConversationQueueManager instance;
void Awake()
{
instance = this;
}
public void AddConversation(string conversation, Transform actor, Transform conversant)
{
if (DialogueManager.isConversationActive)
{
queue.Enqueue(new QueuedConversation()
{
queuedConversation = conversation,
queuedActor = actor,
queuedConversant = conversant
});
}
else
{
DialogueManager.StartConversation(conversation, actor, conversant);
}
}
void OnConversationEnd(Transform actor)
{
if (queue.Count > 0)
{
var next = queue.Dequeue();
DialogueManager.StartConversation(next.queuedConversation, next.queuedActor, next.queuedConversant);
}
}
}
Code: Select all
ConversationQueueManager.instance.AddConversation("conversation", actor, conversant);
Code: Select all
protected virtual void DoConversationAction(Transform actor)
{
// Get actor and conversant:
var actorTransform = Tools.Select(conversationActor, actor);
var conversantTransform = conversationConversant;
if (conversantTransform == null)
{
var conversationAsset = DialogueManager.MasterDatabase.GetConversation(conversation);
var conversationConversantActor = DialogueManager.MasterDatabase.GetActor(conversationAsset.ConversantID);
var registeredTransform = (conversationConversantActor != null) ? CharacterInfo.GetRegisteredActorTransform(conversationConversantActor.Name) : null;
conversantTransform = (registeredTransform != null) ? registeredTransform : this.transform;
}
ConversationQueueManager.instance.PlayConversation(conversation, actorTransform, conversantTransform, startConversationEntryID);
}
Re: Queueing conversations.
Wow, you're a legend, thank you so much. I'll try that when I get back to game coding!