using UnityEngine; using System.Collections; using System.Linq; namespace Crosstales.RTVoice.Tool { /// Simple sequencer for dialogues. [HelpURL("https://www.crosstales.com/media/data/assets/rtvoice/api/class_crosstales_1_1_r_t_voice_1_1_tool_1_1_sequencer.html")] public class Sequencer : MonoBehaviour { #region Variables /// All available sequences. [Tooltip("All available sequences.")] public Model.Sequence[] Sequences; /// Delay in seconds before the Sequencer starts processing (default: 0). [Tooltip("Delay in seconds before the Sequencer starts processing (default: 0).")] public float Delay; /// Enable the Sequencer on start (default: false). [Header("Behaviour Settings")] [Tooltip("Enable the Sequencer on start (default: false).")] public bool PlayOnStart; private int currentIndex; private string uidCurrentSpeaker; private bool playAllSequences; private bool played; #endregion #region Properties /// Returns the current Sequence. /// The current Sequence. public Model.Sequence CurrentSequence => Sequences[currentIndex]; #endregion #region MonoBehaviour methods private void Start() { Speaker.Instance.OnVoicesReady += onVoicesReady; Speaker.Instance.OnSpeakComplete += speakCompleteMethod; play(); } private void OnDestroy() { if (Speaker.Instance != null) { Speaker.Instance.OnSpeakComplete -= speakCompleteMethod; Speaker.Instance.OnVoicesReady -= onVoicesReady; } } private void OnValidate() { if (Delay < 0f) Delay = 0f; foreach (Model.Sequence seq in Sequences.Where(seq => !seq.Initialized)) { seq.Rate = 1f; seq.Pitch = 1f; seq.Volume = 1f; seq.Initialized = true; } } #endregion #region Public methods /// Plays a Sequence with a given index. /// Index of the Sequence (default: 0, optional). public void PlaySequence(int index = 0) { if (Sequences != null) { if (index >= 0 && index < Sequences.Length) { StartCoroutine(playMe(Sequences[index])); currentIndex = index + 1; } else { Debug.LogWarning("The given index is outside the range of Sequences: " + index, this); } } else { Debug.LogWarning("Sequences is null!", this); } } /// Plays the next Sequence in the array. public void PlayNextSequence() { PlaySequence(currentIndex); } /// Plays all Sequences. public void PlayAllSequences() { StopAllSequences(); playAllSequences = true; PlaySequence(); } /// Stops and silences all active Sequences. public void StopAllSequences() { StopAllCoroutines(); Speaker.Instance.Silence(); playAllSequences = false; } #endregion #region Callback methods private void speakCompleteMethod(Model.Wrapper wrapper) { if (playAllSequences) { if (wrapper.Uid.Equals(uidCurrentSpeaker) && currentIndex < Sequences.Length) { PlayNextSequence(); } else { StopAllSequences(); } } } private void onVoicesReady() { play(); } #endregion #region Private methods private void play() { if (PlayOnStart && !played && Speaker.Instance.Voices.Count > 0) { played = true; PlayAllSequences(); } } private IEnumerator playMe(Model.Sequence seq) { yield return new WaitForSeconds(Delay); uidCurrentSpeaker = seq.Mode == Model.Enum.SpeakMode.Speak ? Speaker.Instance.Speak(seq.Text, seq.Source, seq.Voices.Voice, true, seq.Rate, seq.Pitch, seq.Volume) : Speaker.Instance.SpeakNative(seq.Text, seq.Voices.Voice, seq.Rate, seq.Pitch, seq.Volume); } #endregion } } // © 2016-2020 crosstales LLC (https://www.crosstales.com)