Page 1 of 1
Queueing conversations.
Posted: Sun Nov 24, 2019 2:18 am
by ferakiii
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.
Posted: Sun Nov 24, 2019 8:05 am
by Tony Li
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
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);
}
}
}
To start or queue a conversation from script, call:
Code: Select all
ConversationQueueManager.instance.AddConversation("conversation", actor, conversant);
To do it from a
Dialogue System Trigger, make a subclass of Dialogue System Trigger. Override DoConversationActor to something like:
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);
}
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.
Re: Queueing conversations.
Posted: Sun Nov 24, 2019 11:13 pm
by ferakiii
Wow, you're a legend, thank you so much. I'll try that when I get back to game coding!