using System.Collections; using System.Collections.Generic; using TMPro; using UnityEngine; public class DialogueManager : MonoBehaviour { private Queue sentences; private Dialogue currentDialogue; private DialogueVoice currentDialogueVoice; private float maxDialogueWaitTime = 1.0f; // use array of audio sources so we don't cut off any of them private AudioSource[] voiceSourcePool; private int audioSourcePoolIndex = 0; public TextMeshProUGUI nameText; public TextMeshProUGUI dialogueText; public TextMeshProUGUI itemText; // displays name of nearby item public TextMeshProUGUI pickupHint; // tells the player to press 'E' to pickup public Animator animator; // Start is called once before the first execution of Update after the MonoBehaviour is created void Start() { sentences = new Queue(); voiceSourcePool = GetComponentsInChildren(); } public void ReloadReferences() { nameText = GameObject.FindWithTag("DialogNameText").GetComponent(); dialogueText = GameObject.FindWithTag("DialogMessageText").GetComponent(); itemText = GameObject.FindWithTag("DialogItemText").GetComponent(); pickupHint = GameObject.FindWithTag("ItemPickupText").GetComponent(); animator = GameObject.FindWithTag("DialogContainer").GetComponent(); } public void StartDialogue(Dialogue dialogue, DialogueVoice dialogueVoice) { animator.SetBool("IsOpen", true); sentences.Clear(); currentDialogue = dialogue; currentDialogueVoice = dialogueVoice; nameText.text = dialogue.charName; foreach (string sentence in dialogue.sentences) { sentences.Enqueue(sentence); } currentDialogue.isActive = true; DisplayNextSentence(); } public void DisplayNextSentence() { if (sentences.Count == 0) { EndDialogue(); return; } string sentence = sentences.Dequeue(); StopAllCoroutines(); StopVoices(); StartCoroutine(TypeSentence(sentence)); } public void EndDialogue() { animator.SetBool("IsOpen", false); StopAllCoroutines(); StopVoices(); if (currentDialogue != null) { currentDialogue.isActive = false; } } IEnumerator TypeSentence(string sentence) { dialogueText.text = ""; char[] sentenceCharArray = sentence.ToCharArray(); for (int i = 0; i < sentenceCharArray.Length; i++) { dialogueText.text += sentenceCharArray[i]; if (currentDialogueVoice != null && currentDialogueVoice.voice != Voices.None) { if (i % currentDialogueVoice.speechInterval == 0) { AudioClip voiceToPlay = currentDialogueVoice.GetClipFromChar(char.ToLower(sentenceCharArray[i])); if (voiceToPlay != null) { PlayNextClip(voiceToPlay); } } yield return new WaitForSeconds(maxDialogueWaitTime - currentDialogueVoice.talkSpeed * maxDialogueWaitTime); } else { // TODO: Add speed variable to non-voices (Talkable.cs) yield return new WaitForSeconds(0.03f); } } } public void ShowItemText(string itemName) { itemText.text = itemName; pickupHint.text = "Press \"E\" to pick up"; } public void HideItemText() { itemText.text = ""; pickupHint.text = ""; } private void PlayNextClip(AudioClip clip) { audioSourcePoolIndex = (audioSourcePoolIndex + 1) % voiceSourcePool.Length; voiceSourcePool[audioSourcePoolIndex].clip = clip; voiceSourcePool[audioSourcePoolIndex].Play(); } private void StopVoices() { foreach (AudioSource voice in voiceSourcePool) { voice.Stop(); } } }