I've implemented the dialogue system using a queue, and now I'm trying to display a box with dialogue options RIGHT AFTER the last line of the dialogue, or the last element in the queue of dialogue lines. So it should go like "line 1", continue, "line 2", continue, "line 3", continue, "dialogue choices", and the dialogue box should not disappear. However, my dialogue options are showing only after THE WHOLE dialogue has played and when I'm trying to play it for the second time. Here is the script for the Dialogue Manager:
public class DialogueManager : MonoBehaviour
{
public Text dialogueName;
public Text dialogueText;
public static DialogueManager instance;
public int activeLineIndex;
public Animator anim;
public float typingSpeed = 0.2f;
public bool canPressE = true;
List<string> choices = new List<string>();
public bool dialogueFinished = false;
[SerializeField] ChoiceBox choiceBox;
public void EnqueueDialogue(DialogueBase db)
{
canPressE = false;
dialogueInfo.Clear();
foreach(DialogueBase.Info info in db.dialogueInfo)
{
dialogueInfo.Enqueue(info);
}
anim.SetBool("isopen", true);
DequeueDialogue();
}
public void DequeueDialogue()
{
if (dialogueInfo.Count == 0)
{
dialogueFinished = true;
StartCoroutine(DisplayChoices(choices));
EndDialogue();
return;
}
StopAllCoroutines();
DialogueBase.Info info = dialogueInfo.Dequeue();
dialogueName.text = info.myName;
dialogueText.text = info.dialogueText;
StartCoroutine(TypeText(info));
}
public IEnumerator DisplayChoices(List<string> choices = null)
{
if ((choices != null) && choices.Count > 1)
{
yield return choiceBox.ShowChoices(choices);
}
if ((choices == null) && (choices.Count <= 1))
{
yield return null;
}
}
IEnumerator TypeText(DialogueBase.Info info)
{
dialogueText.text = "";
foreach (char letter in info.dialogueText.ToCharArray())
{
yield return new WaitForSeconds(typingSpeed);
dialogueText.text += letter;
yield return null;
}
}
void EndDialogue()
{
anim.SetBool("isopen", false);
canPressE = true;
}
public void GetNextLine()
{
if (!canPressE)
{
DequeueDialogue();
Debug.Log("dalshe");
}
}
public void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
GetNextLine();
}
}
public Queue<DialogueBase.Info> dialogueInfo;
public void Start()
{
dialogueInfo = new Queue<DialogueBase.Info>();
canPressE = true;
}
public void Awake()
{
if (instance != null)
{
Debug.Log("fix this" + gameObject.name);
}
else
{
instance = this;
}
}
}
I'm using scriptable objects for my dialogues and everything works properly excluding dialogue choices. Here is the script for the Choice Box which should show dialogue options:
public class ChoiceBox : MonoBehaviour
{
[SerializeField] ChoiceText choiceTextPrefab;
bool choiceSelected = false;
public IEnumerator ShowChoices(List<string> choices)
{
choiceSelected = false;
gameObject.SetActive(true);
foreach (Transform child in transform)
{
Destroy(child.gameObject);
}
foreach (var choice in choices)
{
var choiceTextObj = Instantiate(choiceTextPrefab, transform);
choiceTextObj.TextField.text = choice;
}
yield return new WaitUntil(() => choiceSelected == true);
}
I'm showing the dialogue when the player collides with the object and it has a special event for that. Right after that, I'm trying to show dialogue options. So here is that part of the script for that object:
if (Input.GetKeyDown(KeyCode.E) && dM.canPressE)
{
onTriggerEnter.Invoke(); //the event that's showing the dialogue
Debug.Log("запускаем диалог");
if (dM.dialogueFinished == true)
{
Debug.Log("show choices");
StartCoroutine(DialogueManager.instance.DisplayChoices(new List<string> { "Yes", "No" }));
}
Everything is fine in the inspector, nothing is missing, but the choice box with the choices is shown only when I'm playing the dialogue for the second time. My guess is that something is wrong with the order of actions in DequeueDialogue(), but I don't know what exactly. I'm new to coding, please help!