I have written a system of dialogues with game characters. It works simply: a player approaches another player, looks at him and presses the E key. A ray is thrown, it receives a RaycastHit and runs a dialog script from it. At this stage, the DialogueBox user interface is enabled, which contains all the main components for displaying the dialog on the screen. For some reason, there is a delay when pressing the E key and the dialog box appears. There are no delays at the further beginning of the dialogue with this character.
I looked at Profiler and found that the roots of the problem come from the Canvas render. How can I fix this problem, is there a way to get rid of lags if, say, I render the Canvas element in advance?
I also realized that the introduction of dialog texts into the queue is implemented through foreach, which can slow down the program
Script:
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
public class DialogueSystem : MonoBehaviour
{
public bool isActive;
[SerializeField] private GameObject dialogueBox;
[SerializeField] private PlayerMovement playerMovement;
[SerializeField] private PlayerCamera playerCamera;
[SerializeField] private TextMeshProUGUI speakerNameText;
[SerializeField] private TextMeshProUGUI dialogueText;
private Queue<string> _sentences;
private void Start()
{
_sentences = new Queue<string>();
dialogueBox.SetActive(false);
}
public void StartDialogue(Dialogue dialogue)
{
dialogueBox.SetActive(true);
speakerNameText.text = dialogue.speakerName;
SetCursorState(CursorLockMode.None, true);
playerMovement.enabled = false;
playerCamera.enabled = false;
_sentences.Clear();
foreach (string sentence in dialogue.sentences)
{
_sentences.Enqueue(sentence);
}
isActive = true;
DisplayNextSentence();
}
public void DisplayNextSentence()
{
if (_sentences.Count == 0)
{
EndDialogue();
return;
}
string sentence = _sentences.Dequeue();
StopAllCoroutines();
StartCoroutine(TypeSentence(sentence));
}
IEnumerator TypeSentence(string sentence)
{
dialogueText.text = "";
foreach (char letter in sentence)
{
dialogueText.text += letter;
yield return null;
}
}
void EndDialogue()
{
SetCursorState(CursorLockMode.Locked, false);
playerMovement.enabled = true;
playerCamera.enabled = true;
dialogueBox.SetActive(false);
isActive = false;
}
void SetCursorState(CursorLockMode mode, bool visible)
{
Cursor.lockState = mode;
Cursor.visible = visible;
}
}