Page 1 of 1
Is it possible to wait for multiple messages?
Posted: Thu Apr 02, 2020 9:49 pm
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.
Re: Is it possible to wait for multiple messages?
Posted: Thu Apr 02, 2020 10:15 pm
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])
Re: Is it possible to wait for multiple messages?
Posted: Fri Apr 03, 2020 2:19 pm
by VoodooDetective
Oh ok, thanks for the example. I'll give it a whirl!
Re: Is it possible to wait for multiple messages?
Posted: Fri Apr 03, 2020 2:27 pm
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;
}
}
}
Re: Is it possible to wait for multiple messages?
Posted: Fri Apr 03, 2020 2:51 pm
by VoodooDetective
Ah but that doesn't work because OnConversationLine seems to be called after the line finishes.
Re: Is it possible to wait for multiple messages?
Posted: Fri Apr 03, 2020 2:58 pm
by VoodooDetective
OK maybe I can just do this:
Code: Select all
WaitForMessage(Typed)@Message(VoiceComplete)->Message(Finished);
Would that work?
Re: Is it possible to wait for multiple messages?
Posted: Fri Apr 03, 2020 3:05 pm
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.
Re: Is it possible to wait for multiple messages?
Posted: Fri Apr 03, 2020 3:35 pm
by VoodooDetective
Ahhh that seems to work pretty well. Thanks so much for the suggestion!
Re: Is it possible to wait for multiple messages?
Posted: Fri Apr 03, 2020 3:55 pm
by Tony Li
Happy to help!