using FMOD.Studio; using FMODUnity; using System.Collections; using System.Collections.Generic; using TMPro; using Unity.VisualScripting; using UnityEngine; public class SubtitleManager : MonoBehaviour { [Header("Text")] public TMP_Text m_Text; [Header("Audio")] [SerializeField] private EventReference m_NarrationSFX; [SerializeField] private EventInstance m_NarrationSFXInst; [SerializeField] private EventReference m_TextScrollSFX; [SerializeField] private EventInstance m_TextScrollSFXInst; 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_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); if (offset > 12.5) { offset = 10f; } if(offset < 5) { offset = Random.Range(5f, 7f); } 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; yield return new WaitForSecondsRealtime(0); //m_Text.text = sentence; m_TextScrollSFXInst = AudioManager.instance.PlaySound(m_TextScrollSFX); m_TextScrollSFXInst.start(); foreach (char c in sentence.ToCharArray()) { index++; m_Text.text += c; float randomInterval = Random.Range(0.02f, 0.06f); yield return new WaitForSecondsRealtime(randomInterval); m_TimeElapsed += randomInterval; // Stop audio early based on probability if (randomStoppingValue == index && earlyStop) { AudioManager.instance.StopSound(m_NarrationSFXInst); } } m_TextScrollSFXInst.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT); StartCoroutine(ClearText(waitTime, false)); } }