// Show choices only after the dialogue has finished typing private IEnumerator DisplayChoicesAfterDialogue(DialogueValues values) { do { yield return(new WaitForSeconds(0.5f)); }while (content.IsTyping); choices.gameObject.SetActive(true); // Set dialogue controller choiceOptions currentChoiceOptions = values.choiceOptions; for (int i = 0; i < values.choiceOptions.choice.Count; i++) { var choice = choices.transform.GetChild(i); var button = choice.GetComponent <Button>(); choice.gameObject.SetActive(true); // Set choice text choice.GetComponentInChildren <TextMeshProUGUI>().text = values.choiceOptions.choice[i].select; // Add choice selection function to the button's onClick var choiceCopy = values.choiceOptions.choice[i]; button.onClick.AddListener(delegate { SelectChoice(values.entity, choiceCopy); }); } }
/// <summary> /// Called when a dialogue choice is made. Write the resulting text attached to the choice in the dialogue box with proper DialogueValues. /// </summary> /// <param name="entity">The entity that is being talked to.</param> /// <param name="choice">The choice object in the DialogueObject.</param> public void SelectChoice(Entity entity, Dialogue.Conversation.Chain.DialogueOptions.ChoiceOptions.Choice choice) { choiceId = choice.id; DialogueValues dialogueValues = new DialogueValues(); foreach (Dialogue.Conversation.Chain.DialogueOptions.TextOptions option in choice.textOptions) { if (entity is NPC) { var npc = entity as NPC; if (npc.MatchPersona(option.persona)) { dialogueValues.entityName = Player.Instance.entityName; dialogueValues.portrait = Player.Instance.portraitList[GetPortraitNumber(option.portraitValue)]; dialogueValues.content = option.dialogueText[UnityEngine.Random.Range(0, option.dialogueText.Count)].text; break; } } } DisplayDialogue(dialogueValues); choosing = false; }
/// <summary> /// Activate and display the dialogue box UI, showing given DialogueValues. /// </summary> /// <param name="values">The dialogue content, speaker name and portrait, and choices.</param> public void DisplayDialogue(DialogueValues values) { // If it's the last dialogue option, close the dialogue instead of continuing if (last) { foreach (Transform choice in choices.transform) { choice.gameObject.SetActive(false); } choices.gameObject.SetActive(false); this.gameObject.SetActive(false); last = false; return; } this.gameObject.SetActive(true); entityName.text = values.entityName; content.TypeText(values.content); image.sprite = values.portrait; // Display choices if there are any if (values.choiceOptions != null) { // Wait until the content has finished typing before showing the choices StartCoroutine(DisplayChoicesAfterDialogue(values)); } else { // Hide choice menu if there aren't any choices foreach (Transform choice in choices.transform) { choice.gameObject.SetActive(false); } choices.gameObject.SetActive(false); } // If last has been flagged, set the state of dialogue to last line if (values.last) { last = true; } }
/// <summary> /// Retrieve next set of DialogueValues from an entity's current dialogue chain. /// </summary> /// <param name="entity">The entity to take a dialogue chain from.</param> /// <returns>The chain's DialogueValues.</returns> public DialogueValues GetDialogueValuesFromChain(Entity entity) { DialogueValues result = new DialogueValues(); var currChain = entity.currentChain; result.entity = entity; for (int i = 0; i < currChain.dialogueOptions.Count; i++) { if (entity is NPC) { var npc = entity as NPC; // If a choice has been made and its Id doesn't equal the dialogue option id, then skip this option if (!choiceId.Equals(currChain.dialogueOptions[i].id)) { continue; } // If this dialogue option has already been spoke, skip it if (currChain.dialogueOptions[i].type.Equals("used")) { continue; } foreach (Dialogue.Conversation.Chain.DialogueOptions.TextOptions textOption in currChain.dialogueOptions[i].textOptions) { // Check for persona restraints if (!npc.MatchPersona(textOption.persona)) { continue; } // Check which entity is doing the talking foreach (Entity speaker in Entity.entityList) { if (currChain.dialogueOptions[i].speaker.Equals(speaker.id)) { // Set the name of the speaker result.entityName = speaker.entityName; // Set the portrait of the speaker result.portrait = speaker.portraitList[GetPortraitNumber(textOption.portraitValue)]; break; } } // Select a random line of text from the text options and set it as the dialogue content result.content = textOption.dialogueText[UnityEngine.Random.Range(0, textOption.dialogueText.Count)].text; // If this dialogue option has a choice in it, send the choice as part of the value if (currChain.dialogueOptions[i].type.Equals("choice")) { result.choiceOptions = currChain.dialogueOptions[i].choiceOptions; choosing = true; } // Flag the current dialogue option as used (to advance the chain) // However, shift repeating dialogue options over eachother so they repeat forever (until the day progresses and new dialogue can be spoken) if (!currChain.dialogueOptions[i].type.Equals("repeater") && !currChain.dialogueOptions[i].type.Equals("last") && !currChain.dialogueOptions[i].type.Equals("uniquelast")) { currChain.dialogueOptions[i].type = "used"; // If the next dialogue in the chain is marked as uniquelast, mark the current one as last as dialogue value if (i < currChain.dialogueOptions.Count) { if (currChain.dialogueOptions[i + 1].type.Equals("uniquelast")) { result.last = true; } } } else { // If a dialogue option is marked as last or uniquelast, send it as a dialogue value if (currChain.dialogueOptions[i].type.Equals("last") || currChain.dialogueOptions[i].type.Equals("uniquelast")) { result.last = true; } if (!last) { // Move repeating dialogue to back of list currChain.dialogueOptions.Add(currChain.dialogueOptions[i]); currChain.dialogueOptions.RemoveAt(i); } } break; } break; } else { // Implement interaction with NON-NPC here Debug.Log("Non-NPC GetChainValues unimplemented"); break; } } return(result); }