Is it possible to wait for multiple messages?

Announcements, support questions, and discussion for the Dialogue System.
Post Reply
VoodooDetective
Posts: 222
Joined: Wed Jan 22, 2020 10:48 pm

Is it possible to wait for multiple messages?

Post by VoodooDetective »

I'm thinking something like this: "@Message(message1, message2)"

I'd like to wait until voiceover and typed have both completed. A sort of Mathf.Max(Voice length, Typed length) message.
User avatar
Tony Li
Posts: 22054
Joined: Thu Jul 18, 2013 1:27 pm

Re: Is it possible to wait for multiple messages?

Post by Tony Li »

There isn't a built-in @Message(message1, message2) syntax.

If you know that typing will always finish before voiceover, then you can just wait for voiceover.

However, if sometimes typing will be longer and sometimes voiceover will be longer, you could store Mathf.Max(Voice length, Typed length) in a variable:

Code: Select all

void OnConversationLine(Subtitle subtitle)
{
    string entrytag = DialogueManager.masterDatabase.GetEntrytag(subtitle.dialogueEntry.conversationID, subtitle.dialogueEntry.id, DialogueManager.displaySettings.cameraSettings.entrytagFormat);
    AudioClip audioClip = DialogueManager.LoadAsset(entrytag, typeof(AudioClip));
    float voiceLength = audioClip.length;
    float typedLength = ConversationView.GetDefaultSubtitleDurationInSeconds(subtitle.formattedText.text);
    float duration = Mathf.Max(voiceLength, typedLength);
    DialogueLua.SetVariable("duration", duration);
}
And then use the variable in your sequence:

Code: Select all

Audio(entrytag);
Delay([var=duration])
VoodooDetective
Posts: 222
Joined: Wed Jan 22, 2020 10:48 pm

Re: Is it possible to wait for multiple messages?

Post by VoodooDetective »

Oh ok, thanks for the example. I'll give it a whirl!
VoodooDetective
Posts: 222
Joined: Wed Jan 22, 2020 10:48 pm

Re: Is it possible to wait for multiple messages?

Post by VoodooDetective »

Oh actually, because I'm using TextAnimator, I'm not sure this would work as expected.

I'll try something like this:

Code: Select all

using System;
using System.Collections;
using Febucci.UI;
using PixelCrushers.DialogueSystem;
using UnityEngine;
using UnityEngine.UI;

namespace Dialogue
{
    /// <summary>
    /// A bridge between Dialogue System for Unity and Text Animator for Unity.
    /// </summary>
    [RequireComponent(typeof(TextAnimatorPlayer))]
    [RequireComponent(typeof(Button))]
    public class TextAnimatorDialogueSystemBridge : MonoBehaviour
    {
        // References
        public TextAnimatorPlayer textAnimatorPlayer;
        public Button continueButton;

        // Properties
        private DateTime startSpeak;
        private float voiceLength;

        void Reset()
        {
            textAnimatorPlayer = GetComponent<TextAnimatorPlayer>();
            continueButton = gameObject.transform.parent.GetComponentInChildren<Button>();
        }

        void OnEnable()
        {
            textAnimatorPlayer.onTextShowed.AddListener(OnTextShowed);
            continueButton.onClick.AddListener(OnContinuePressed);
        }

        void OnDisable()
        {
            textAnimatorPlayer.onTextShowed.RemoveListener(OnTextShowed);
            continueButton.onClick.RemoveListener(OnContinuePressed);
        }

        public void OnTextShowed()
        {
            TimeSpan typeTime = DateTime.Now - startSpeak;
            if (typeTime.Seconds < voiceLength) StartCoroutine(DelayedTypedEvent(voiceLength - typeTime.Seconds));
            else Sequencer.Message(SequencerMessages.Typed);
        }

        public void OnConversationLine(Subtitle subtitle)
        {
            // Get Start Time
            startSpeak = DateTime.Now;

            // Get Voice Length
            string entrytag = DialogueManager.masterDatabase.GetEntrytag(
                subtitle.dialogueEntry.conversationID,
                subtitle.dialogueEntry.id,
                DialogueManager.displaySettings.cameraSettings.entrytagFormat);
            AudioClip audioClip = (AudioClip)DialogueManager.LoadAsset(entrytag, typeof(AudioClip));
            if (audioClip != null) voiceLength = audioClip.length;
            else voiceLength = 0f;
        }

        public void OnContinuePressed()
        {
            textAnimatorPlayer.SkipTypewriter();
        }

        private IEnumerator DelayedTypedEvent(float delay)
        {
            yield return new WaitForSeconds(delay);
            Sequencer.Message(SequencerMessages.Typed);
            yield break;
        }
    }
}

VoodooDetective
Posts: 222
Joined: Wed Jan 22, 2020 10:48 pm

Re: Is it possible to wait for multiple messages?

Post by VoodooDetective »

Ah but that doesn't work because OnConversationLine seems to be called after the line finishes.
VoodooDetective
Posts: 222
Joined: Wed Jan 22, 2020 10:48 pm

Re: Is it possible to wait for multiple messages?

Post by VoodooDetective »

OK maybe I can just do this:

Code: Select all

WaitForMessage(Typed)@Message(VoiceComplete)->Message(Finished);
Would that work?
User avatar
Tony Li
Posts: 22054
Joined: Thu Jul 18, 2013 1:27 pm

Re: Is it possible to wait for multiple messages?

Post by Tony Li »

It won't start waiting for "Typed" until it gets the message "VoiceComplete", so it will miss the "Typed" message if it comes before "VoiceComplete". Are you using Text Animator's typewriter?

If so, you could add a script to the Dialogue Manager with these methods:

Code: Select all

private int numActionsLeft;

public void OnConversationLine(Subtitle subtitle)
{
    numActionsLeft = 2; // audio and typewriter
}

public void ActionFinished()
{
    numActionsLeft--;
    if (numActionsLeft <= 0) Sequencer.Message("All_Done");
}
Configure the Text Animator Player's OnTextShowed() event to call the script's ActionFinished() method.

Use this Sequence:

Code: Select all

AudioWait(entrytag)->Message(VoiceComplete);
SendMessage(ActionFinished,,Dialogue Manager)@Message(VoiceComplete);
WaitForMessage(All_Done)
When a subtitle starts, the script's OnConversationLine method will mark that it's waiting for 2 actions (audio and typewriter). Each action will decrement the number of actions it's waiting for. When it's zero, it sends the sequencer message "All_Done", which advances the conversation.
VoodooDetective
Posts: 222
Joined: Wed Jan 22, 2020 10:48 pm

Re: Is it possible to wait for multiple messages?

Post by VoodooDetective »

Ahhh that seems to work pretty well. Thanks so much for the suggestion!
User avatar
Tony Li
Posts: 22054
Joined: Thu Jul 18, 2013 1:27 pm

Re: Is it possible to wait for multiple messages?

Post by Tony Li »

Happy to help!
Post Reply