/// <summary> /// A method call to set and display the dialogue node content into the tempDialogueTree. /// </summary> /// <param name="dialogueTree">The dialogue tree that you are passing in from a NonMonobehavior object.</param> /// <param name="changeCharacterName">Used to overwrite the existing characterName string on a DialogueTree scriptable object.</param> public static void SetAndDisplayDialogueNodeContent(DialogueTree dialogueTree, bool changeCharacterName = false) { Debug.LogWarning("dialogueTree: " + dialogueTree); Debug.LogWarning("tempDialogueTree: " + tempDialogueTree); tempDialogueTree = (DialogueTree)ScriptableObject.CreateInstance(typeof(DialogueTree)); // Set this to the DialogueTree scriptable object that will only have a single reusable updatable node. // Add new dialogue node if dialogueNodeElements list count is 0 if (tempDialogueTree.dialogueNodeElements.Count == 0) { tempDialogueTree.dialogueNodeElements.Add(new DialogueTree.DialogueNode()); } // Create new dialogue node for tempDialogueTree to contain. DialogueTree.DialogueNode dialogueNode = new DialogueTree.DialogueNode(); // Get reference to the characterName from the DialogueTree scriptable object that will be modified. if (characterName == "") { characterName = tempDialogueTree.dialogueNodeElements[0].nodeCharacterName; } // First clear existing data that was previous used in the tempDialogueTree if any tempDialogueTree.dialogueNodeElements.Clear(); for (int i = 0; i < dialogueTree.dialogueNodeElements.Count; i++) { // Set the new dialogueNode's dialogue string and audio clip to dialogueTree contents that is being passed in. dialogueNode.nodeDialogueString = dialogueTree.dialogueNodeElements[i].nodeDialogueString; dialogueNode.nodeDialogueAudioClip = dialogueTree.dialogueNodeElements[i].nodeDialogueAudioClip; // Check to see if the characterName needs to be changed. (By default, it should be false.) if (!changeCharacterName) { dialogueNode.nodeCharacterName = characterName; } else { dialogueNode.nodeCharacterName = dialogueTree.dialogueNodeElements[i].nodeCharacterName; } // Then add the dialogueNode so that there is always one node in the dialogueNodeElements list. tempDialogueTree.dialogueNodeElements.Add(dialogueNode); } Debug.LogWarning("tempDialogueTree: " + tempDialogueTree); // Call the DialogueManager to start the tempDialogueTree DialogueManager.instance.StartDialogue(tempDialogueTree); }
/// <summary> /// A coroutine method that will type each nodeDialogueString one character at a time at the set speed and play the audioclip if it is available. /// </summary> /// <param nodeCharacterName="nodeDialogueString">The current nodeDialogueString that is out of the queue.</param> /// <param nodeCharacterName="nodeDialogueAudioClip">The current audioclip that is out of the queue.</param> /// <returns></returns> private IEnumerator TypeNodeDialogueString(DialogueTree.DialogueNode dialogueNode) { isTypeSentenceCoroutineRunning = true; if (debugComponent) { Debug.Log("isTypeSentenceCoroutineRunning: " + isTypeSentenceCoroutineRunning); } string nodeCharacterName = dialogueNode.nodeCharacterName; string nodeDialogueString = dialogueNode.nodeDialogueString; AudioClip nodeDialogueAudioClip = dialogueNode.nodeDialogueAudioClip; // Set nodeCharacterName text fields with the nodeCharacterName of the person talking in the dialogueTree nameText.text = nodeCharacterName; nameVRText.text = nodeCharacterName; if (requireContinueButton) { inputContinueDialogueImage.gameObject.SetActive(false); inputContinueDialogueVRImage.gameObject.SetActive(false); } currentSentence = nodeDialogueString; audioSource.Stop(); if (playWithAudio) { if (nodeDialogueAudioClip) { audioSource.PlayOneShot(nodeDialogueAudioClip, volume); } else { Debug.LogError("No audioclip for string displayed! Please place audioclip in AudioClip List for respective string element."); } } // Print full nodeDialogueString or type each character individually. if (instantPrintBegin) { int punctutationCount = 0; foreach (char letter in nodeDialogueString.ToCharArray()) { // If character is any form of punctutation, then delay next nodeDialogueString. Otherwise, print normally. if (letter == ',' || letter == ';' || letter == '.' || letter == '?' || letter == '!') { punctutationCount++; // Keep track of punctuation in each node } } dialogueText.text = nodeDialogueString; // Display full nodeDialogueString instantly dialogueVRText.text = nodeDialogueString; // Display full nodeDialogueString instantly float fullSentenceDelay = (currentPrintLetterDelay * nodeDialogueString.Length) + (punctutationCount * currentSentenceDelay) + currentSentenceDelay; // (CharacterCount from current dialogueTreeElement * print delay time) + (number of punctuation characters * nodeDialogueString delay time) + end of dialogueTreeElement delay time. if (debugComponent) { Debug.Log("fullSentenceDelay: " + fullSentenceDelay + ", nodeDialogueAudioClip.length: " + nodeDialogueAudioClip.length); } // Play next nodeDialogueString without button input if (!requireContinueButton) { if (nodeDialogueAudioClip) { yield return(new WaitForSeconds(nodeDialogueAudioClip.length)); } else { yield return(new WaitForSeconds(fullSentenceDelay)); } isTypeSentenceCoroutineRunning = false; // This ensures that you can check if the coroutine is done. DisplayNextSentence(); } else { DisplayNextSentence(); isTypeSentenceCoroutineRunning = false; // This ensures that you can check if the coroutine is done. } } else { // Clear text fields before printing dialogueText.text = ""; dialogueVRText.text = ""; foreach (char letter in nodeDialogueString.ToCharArray()) { dialogueText.text += letter; dialogueVRText.text += letter; // If character is any form of punctutation, then delay next nodeDialogueString. Otherwise, print normally. if (letter == ',' || letter == ';' || letter == '.' || letter == '?' || letter == '!') { yield return(new WaitForSeconds(currentSentenceDelay)); // Delay next nodeDialogueString } else { yield return(new WaitForSeconds(currentPrintLetterDelay)); // Delay character print } } // If moving on with the next dialogue to type requires input, then if (!requireContinueButton) { // If last character is not any form of punctutation, then delay next nodeDialogueString if (!(nodeDialogueString.EndsWith(",") || nodeDialogueString.EndsWith(";") || nodeDialogueString.EndsWith(".") || nodeDialogueString.EndsWith("?") || nodeDialogueString.EndsWith("!"))) { yield return(new WaitForSeconds(currentSentenceDelay)); } yield return(new WaitUntil(() => !audioSource.isPlaying)); // Wait until audioclip for the dialogue nodeDialogueString has stopped playing if it hasn't. isTypeSentenceCoroutineRunning = false; // This ensures that you can check if the coroutine is done. DisplayNextSentence(); } else { DisplayNextSentence(); isTypeSentenceCoroutineRunning = false; // This ensures that you can check if the coroutine is done. } } if (requireContinueButton) { inputContinueDialogueImage.gameObject.SetActive(true); inputContinueDialogueVRImage.gameObject.SetActive(true); // Update speed of animation with current settings inputContinueDialogueImage.GetComponent <Animator>().speed = inputContinueDialogueImageAnimationSpeed; inputContinueDialogueVRImage.GetComponent <Animator>().speed = inputContinueDialogueImageAnimationSpeed; } if (debugComponent) { Debug.Log("isTypeSentenceCoroutineRunning: " + isTypeSentenceCoroutineRunning); } }
/// <summary> /// A method to play the next string and audioclip in the queues. /// </summary> public void DisplayNextSentence() { // Check to see if current nodeDialogueString is typing first if (isTypeSentenceCoroutineRunning) { // Only used if input is required if (requireContinueButton) { // Instant print the rest of the current nodeDialogueString if (instantPrintFinish) { StopAllCoroutines(); // Stop coroutine that is currently printing. dialogueText.text = currentSentence; dialogueVRText.text = currentSentence; isTypeSentenceCoroutineRunning = false; // Make sure this is false after nodeDialogueString is done typing. } else { // Change speed of the text without changing the value for the setting. Create private copy of the value. if (speedPrintFinish) { // The fastest is actually one frame. currentPrintLetterDelay = 0.0f; currentSentenceDelay = 0.0f; } } inputContinueDialogueImage.gameObject.SetActive(true); inputContinueDialogueVRImage.gameObject.SetActive(true); // Update speed of animation with current settings inputContinueDialogueImage.GetComponent <Animator>().speed = inputContinueDialogueImageAnimationSpeed; inputContinueDialogueVRImage.GetComponent <Animator>().speed = inputContinueDialogueImageAnimationSpeed; } return; } // Reset delay times currentPrintLetterDelay = printLetterDelay; currentSentenceDelay = sentenceDelay; // End dialogue if queues are empty if (dialogueNodes.Count == 0) { // If DialogueTree has multipleChoiceNode with at least two answers, then if (currentDialogueTree.multipleChoiceNode.answers.Count >= 2) { // Display MutltipleChoiceCanvas dialogueText.text = ""; dialogueVRText.text = ""; inputContinueDialogueImage.gameObject.SetActive(false); inputContinueDialogueVRImage.gameObject.SetActive(false); autoContinueDialogueRawImage.gameObject.SetActive(false); autoContinueDialogueVRRawImage.gameObject.SetActive(false); if (multipleChoiceTemplate.transform.parent.parent.gameObject.activeSelf) { multipleChoiceTemplate.GetComponent <MultipleChoiceTemplate>().SetTemplate(currentDialogueTree.multipleChoiceNode); } if (multipleChoiceVRTemplate.transform.parent.parent.gameObject.activeSelf) { multipleChoiceVRTemplate.GetComponent <MultipleChoiceTemplate>().SetTemplate(currentDialogueTree.multipleChoiceNode); } return; } // If DialogueTree has another DialogueTree attached, then play that DialogueTree in EndDialogue() EndDialogue(); return; } // Adjust textDisplayWidth to fit more center with the camera screen. dialogueText.GetComponent <RectTransform>().sizeDelta = new Vector2(textDisplayWidth, dialogueText.GetComponent <RectTransform>().sizeDelta.y); dialogueVRText.GetComponent <RectTransform>().sizeDelta = new Vector2(textDisplayWidth, dialogueVRText.GetComponent <RectTransform>().sizeDelta.y); // Save nodeDialogueString and audioclip that is being dequeued DialogueTree.DialogueNode dialogueNode = dialogueNodes.Peek(); // Dequeue the current node so your not stuck on it for next call. dialogueNodes.Dequeue(); if (debugComponent) { Debug.Log(dialogueNode.nodeCharacterName + ": " + dialogueNode.nodeDialogueString); } StopAllCoroutines(); // Stop coroutine before starting new one. StartCoroutine(TypeNodeDialogueString(dialogueNode)); // Display or type one character at a time. }