using UnityEngine; using System.Collections; using System.Collections.Generic; using System.Text; using TMPro; public class TextManager : MonoBehaviour { public static TextManager Instance { get; private set; } [Header("Text Settings")] public float defaultTypeSpeed = 0.01f; public Color defaultTextColor = Color.white; private Coroutine currentTextCoroutine; private StringBuilder currentTextBuilder; private Vector2 currentTextPosition; private bool isTyping = false; private ScriptCommand currentCommand; void Awake() { if (Instance == null) { Instance = this; } else { Destroy(gameObject); } } public void ShowText(List tokens, ScriptCommand cmd) { currentCommand = cmd; // Останавливаем предыдущую корутину, если она активна if (currentTextCoroutine != null) { StopCoroutine(currentTextCoroutine); } currentTextCoroutine = StartCoroutine(ProcessTokensCoroutine(tokens)); } private IEnumerator ProcessTokensCoroutine(List tokens) { isTyping = true; currentTextBuilder = new StringBuilder(); App.UI.ClearText(); for (int a = 0; a < tokens.Count - 1; a++) { TextToken token = tokens[a]; switch(token.Key) { case "text": yield return StartCoroutine(TypeText(token.Value)); break; case "cmd": yield return StartCoroutine(ProcessCommand(token.Value)); break; case "color": SetTextColor(token.Value); break; case "pause": yield return new WaitForSeconds(float.Parse(token.Value) / 60); break; case "user_selection": byte varCount = byte.Parse(token.Value); //preparing selection strings List selectionList = new List(); for (byte x = 1; x <= varCount * 2; x += 2) //string and \n { selectionList.Add(tokens[a+x].Value); } a += varCount * 2; //jump over selection strings (text + \n) App.UI.ShowSelection(selectionList); break; } } isTyping = false; } private IEnumerator TypeText(string text) { foreach (char c in text) { currentTextBuilder.Append(c); App.UI.SetText(currentTextBuilder.ToString()); // Обновляем тень, если она есть if (App.UI.shadowText != null) { App.UI.shadowText.text = currentTextBuilder.ToString(); } yield return new WaitForSeconds(defaultTypeSpeed); } } private IEnumerator ProcessCommand(string command) { switch (command) { case "newline": currentTextBuilder.Append("\n"); App.UI.AppendText("\n"); break; case "tab": currentTextBuilder.Append(" "); App.UI.AppendText(" "); break; case "wait_input": App.UI.ShowCursor(true); yield return WaitForInput(); App.UI.ShowCursor(false); break; case "wait_selection": yield return WaitForSelectionInput(); App.VM.SetSelectionVariable(App.UI.userSelectionVariant); //TODO: App.UI.WipeSelection(); break; case "wipe": currentTextBuilder.Clear(); App.UI.ClearText(); break; case "end": yield break; } } private IEnumerator WaitForInput() { bool inputReceived = false; while (!inputReceived) { if (Input.GetButtonDown("Submit")) { inputReceived = true; } yield return null; } if (currentCommand != null) { App.VM.MarkCommandCompleted(currentCommand); } } private IEnumerator WaitForSelectionInput() { bool acceptReceived = false; while (!acceptReceived) { if (Input.GetKeyDown(KeyCode.DownArrow) || Input.GetKeyDown(KeyCode.UpArrow)) { //recieve input for } if (Input.GetMouseButtonDown(0) || Input.GetKeyDown(KeyCode.Space) || Input.GetKeyDown(KeyCode.Return)) { acceptReceived = true; } yield return null; } if (currentCommand != null) { App.VM.MarkCommandCompleted(currentCommand); } } private void SetTextColor(string colorCode) { int colorIndex; if (int.TryParse(colorCode, out colorIndex)) { string colorTag = $""; currentTextBuilder.Append(colorTag); App.UI.AppendText(colorTag); } } private string GetColorByIndex(int index) { switch (index) { case 1: return "white"; case 3: return "gray"; case 5: return "#D327F5"; //pink! case 7: return "#27F5D3"; //blue case 9: return "#27F56C"; //green case 11: return "yellow"; case 13: return "#F56C27"; //orange default: return "white"; } } public void SkipTyping() { if (isTyping && currentTextCoroutine != null) { StopCoroutine(currentTextCoroutine); isTyping = false; } } public bool IsTyping() { return isTyping; } }