using FMOD.Studio; using FMODUnity; using System.Collections; using System.Collections.Generic; using TMPro; using Unity.VisualScripting; using UnityEngine; namespace Moloch { public class SubtitleManager : MonoBehaviour { [Header("Text")] [SerializeField] private TMP_Text m_Text; [Header("Audio")] [SerializeField] private EventReference m_NarrationSFX; [SerializeField] private EventInstance m_NarrationSFXInst; private float m_TimeElapsed; private bool m_FirstRun; private void OnEnable() { NarrationManager.m_UpdateSubtitile += UpdateText; } private void OnDisable() { NarrationManager.m_UpdateSubtitile -= UpdateText; } private void Start() { m_Text = GetComponent(); m_TimeElapsed = 0; m_Text.text = ""; m_FirstRun = true; } private void UpdateText(string sentence, float waitTime) { FMOD.Studio.PLAYBACK_STATE state; m_NarrationSFXInst = AudioManager.instance.PlaySound(m_NarrationSFX); m_NarrationSFXInst.getPlaybackState(out state); if(m_FirstRun) { m_FirstRun = false; m_NarrationSFXInst.start(); } else { m_NarrationSFXInst.getPlaybackState(out state); if(state == PLAYBACK_STATE.STOPPED) { m_NarrationSFXInst.start(); } } StartCoroutine(TextScroll(sentence, waitTime)); } // Wait time, how long the text will stay on the screen for + if the audio stops late, apply an offset private IEnumerator ClearText(float waitTime, bool earlyStop) { var offset = (waitTime - m_TimeElapsed) * Random.Range(0.6f, 0.95f); float earlyOffset = 0; if (!earlyStop) { earlyOffset = offset / Random.Range(2, 4); offset -= earlyOffset; yield return new WaitForSecondsRealtime(earlyOffset); AudioManager.instance.StopSound(m_NarrationSFXInst); } yield return new WaitForSecondsRealtime(offset); m_Text.text = ""; m_TimeElapsed = 0; } private IEnumerator TextScroll(string sentence, float waitTime) { var characterLength = sentence.ToCharArray().Length; int randomStoppingValue = (int) Random.Range(characterLength * 0.6f, characterLength); var index = 0; bool earlyStop = false; if(Random.Range(0f, 10f) > 6) earlyStop = true; foreach (char c in sentence.ToCharArray()) { index++; m_Text.text += c; float randomInterval = Random.Range(0.02f, 0.04f); yield return new WaitForSecondsRealtime(randomInterval); m_TimeElapsed += randomInterval; // Stop audio early based on probability if( randomStoppingValue == index && earlyStop) { AudioManager.instance.StopSound(m_NarrationSFXInst); } } StartCoroutine(ClearText(waitTime, earlyStop)); } } }