fix: Question and answers working correctly

This commit is contained in:
Gerard Gascón 2024-01-27 13:53:18 +01:00
parent 11243f1474
commit a3415767cd
4 changed files with 497 additions and 100 deletions

View file

@ -2,32 +2,66 @@ using System;
using Messaging.Typer;
using TMPro;
using UnityEngine;
using UnityEngine.Serialization;
using Utilities;
namespace Messaging {
public class Message : MonoBehaviour {
public RectTransform RectTransform { private set; get; }
public string Text => messageText.text;
public string RealText => realMessageText.text;
public string Text { private set; get; }
public string RealText { private set; get; }
public bool IsAnswer { private set; get; }
public bool IsReal { private set; get; }
[SerializeField] private TMP_Text messageText;
[SerializeField] private TMP_Text realMessageText;
private TextTyper _textTyper;
private TextTyper _realTextTyper;
private Coroutine _typingCoroutine;
private Coroutine _realTypingCoroutine;
[SerializeField] private MessageContainer questionContainer;
[SerializeField] private MessageContainer answerContainer;
private void Awake() {
RectTransform = GetComponent<RectTransform>();
_textTyper = new TextTyper(messageText);
_realTextTyper = new TextTyper(realMessageText);
questionContainer.InitializeTypers();
answerContainer.InitializeTypers();
}
public void SetMessageText(string text, bool animate) =>
SetText(ref _typingCoroutine, messageText, _textTyper, text, animate);
public void SetMessageRealText(string text, bool animate) =>
SetText(ref _realTypingCoroutine, realMessageText, _realTextTyper, text, animate);
public void SetMessageText(string text, bool animate, bool isAnswer) {
Text = text;
IsAnswer = isAnswer;
IsReal = false;
if (isAnswer) {
SetText(ref answerContainer.TypingCoroutine, answerContainer.messageText, answerContainer.TextTyper,
text, animate);
answerContainer.container.SetActive(true);
questionContainer.container.SetActive(false);
} else {
SetText(ref questionContainer.TypingCoroutine, questionContainer.messageText,
questionContainer.TextTyper, text, animate);
questionContainer.container.SetActive(true);
answerContainer.container.SetActive(false);
}
}
public void SetMessageRealText(string text, bool animate, bool isAnswer) {
RealText = text;
IsAnswer = isAnswer;
IsReal = true;
if (isAnswer) {
SetText(ref answerContainer.RealTypingCoroutine, answerContainer.realMessageText,
answerContainer.RealTextTyper, text, animate);
answerContainer.container.SetActive(true);
questionContainer.container.SetActive(false);
} else {
SetText(ref questionContainer.RealTypingCoroutine, questionContainer.realMessageText,
questionContainer.RealTextTyper, text, animate);
questionContainer.container.SetActive(true);
answerContainer.container.SetActive(false);
}
}
private void SetText(ref Coroutine routine, TMP_Text tmpText, TextTyper typer, string text, bool animate) {
this.EnsureCoroutineStopped(ref routine);
@ -37,5 +71,25 @@ namespace Messaging {
else
tmpText.text = text;
}
[Serializable]
private class MessageContainer {
public GameObject container;
public TMP_Text messageText;
public TMP_Text realMessageText;
public Coroutine TypingCoroutine;
public Coroutine RealTypingCoroutine;
public TextTyper TextTyper;
public TextTyper RealTextTyper;
public void InitializeTypers() {
TextTyper = new TextTyper(messageText);
RealTextTyper = new TextTyper(realMessageText);
container.SetActive(false);
}
}
}
}

View file

@ -19,43 +19,49 @@ namespace Messaging {
string[] fLines = textAsset.text.Split(':');
int i = 0;
while (Application.isPlaying) {
Debug.Log(textAsset.text);
CreateMessage(MessageParser.SplitMessage(fLines[i % 2]).Key);
++i;
bool isAnswer = i % 2 != 0;
CreateMessage(MessageParser.SplitMessage(fLines[i % 2]).Key, isAnswer);
await Task.Delay(2000);
CreateRealMessage(MessageParser.SplitMessage(fLines[i % 2]).Value, isAnswer);
await Task.Delay(2000);
++i;
}
}
public void CreateMessage(string message) {
ModifyMessageText(message, _messages.Length - 1);
}
public void CreateRealMessage(string message) {
ModifyRealMessageText(message, _messages.Length - 1);
public void CreateMessage(string message, bool isAnswer) {
ModifyMessageText(message, _messages.Length - 1, isAnswer);
}
private void ModifyMessageText(string message, int index) {
ModifyPreviousMessageText(_messages[index].Text, index - 1);
_messages[index].SetMessageText(message, true);
}
private void ModifyRealMessageText(string message, int index) {
ModifyPreviousRealMessageText(_messages[index].Text, index - 1);
_messages[index].SetMessageRealText(message, true);
public void CreateRealMessage(string message, bool isAnswer) {
ModifyRealMessageText(message, _messages.Length - 1, isAnswer);
}
private void ModifyPreviousMessageText(string message, int index) {
private void ModifyMessageText(string message, int index, bool isAnswer) {
ModifyPreviousMessage(index);
_messages[index].SetMessageText(message, true, isAnswer);
}
private void ModifyRealMessageText(string message, int index, bool isAnswer) {
_messages[index].SetMessageRealText(message, true, isAnswer);
}
private void ModifyPreviousMessage(int index) {
ModifyPreviousMessage(_messages[index].Text, _messages[index].RealText, index - 1,
_messages[index].IsAnswer, _messages[index].IsReal);
_messages[index].SetMessageText("", false, _messages[index].IsAnswer);
_messages[index].SetMessageRealText("", false, _messages[index].IsAnswer);
}
private void ModifyPreviousMessage(string message, string realMessage, int index, bool isAnswer, bool isReal) {
if (index < 0) return;
ModifyPreviousMessageText(_messages[index].Text, index - 1);
ModifyPreviousMessage(_messages[index].Text, _messages[index].RealText, index - 1,
_messages[index].IsAnswer, _messages[index].IsReal);
_messages[index].SetMessageText(message, false);
}
private void ModifyPreviousRealMessageText(string message, int index) {
if (index < 0) return;
ModifyPreviousRealMessageText(_messages[index].RealText, index - 1);
_messages[index].SetMessageRealText(message, false);
_messages[index].SetMessageText(message, false, isAnswer);
_messages[index].SetMessageRealText(realMessage, false, isAnswer);
}
}
}

View file

@ -7,8 +7,7 @@ namespace Messaging.Typer {
public class TextTyper {
private readonly TMP_Text _textBox;
private static readonly Color32 Clear = new(0, 0, 0, 0);
private const float SecondsPerCharacter = 1f / 60f;
private const float SecondsPerCharacter = 0.07f;
public TextTyper(TMP_Text textBox) {
_textBox = textBox;
@ -18,63 +17,26 @@ namespace Messaging.Typer {
float timeOfLastCharacter = 0;
TMP_TextInfo textInfo = _textBox.textInfo;
foreach (TMP_MeshInfo meshInfer in textInfo.meshInfo) {
if (meshInfer.vertices == null) continue;
for (int j = 0; j < meshInfer.vertices.Length; j++) {
meshInfer.vertices[j] = Vector3.zero;
}
}
_textBox.maxVisibleCharacters = 0;
_textBox.text = processedMessage;
_textBox.ForceMeshUpdate();
Color32[][] originalColors = new Color32[textInfo.meshInfo.Length][];
for (int i = 0; i < originalColors.Length; i++) {
Color32[] theColors = textInfo.meshInfo[i].colors32;
originalColors[i] = new Color32[theColors.Length];
Array.Copy(theColors, originalColors[i], theColors.Length);
}
int charCount = textInfo.characterCount;
int visibleCharacterIndex = 0;
while (true) {
if (ShouldShowNextCharacter(SecondsPerCharacter, timeOfLastCharacter)) {
if (visibleCharacterIndex <= charCount) {
if (visibleCharacterIndex < charCount &&
ShouldShowNextCharacter(SecondsPerCharacter, timeOfLastCharacter)) {
visibleCharacterIndex++;
timeOfLastCharacter = Time.unscaledTime;
if (visibleCharacterIndex == charCount) {
onFinish?.Invoke();
}
visibleCharacterIndex++;
_textBox.maxVisibleCharacters = visibleCharacterIndex;
timeOfLastCharacter = Time.unscaledTime;
if (visibleCharacterIndex == charCount) {
onFinish?.Invoke();
break;
}
}
}
for (int j = 0; j < charCount; j++) {
TMP_CharacterInfo charInfo = textInfo.characterInfo[j];
if (!charInfo.isVisible) continue;
int vertexIndex = charInfo.vertexIndex;
int materialIndex = charInfo.materialReferenceIndex;
Color32[] destinationColors = textInfo.meshInfo[materialIndex].colors32;
Color32 theColor = j < visibleCharacterIndex ? originalColors[materialIndex][vertexIndex] : Clear;
destinationColors[vertexIndex + 0] = theColor;
destinationColors[vertexIndex + 1] = theColor;
destinationColors[vertexIndex + 2] = theColor;
destinationColors[vertexIndex + 3] = theColor;
}
_textBox.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);
for (int i = 0; i < textInfo.meshInfo.Length; i++) {
TMP_MeshInfo theInfo = textInfo.meshInfo[i];
theInfo.mesh.vertices = theInfo.vertices;
_textBox.UpdateGeometry(theInfo.mesh, i);
}
if (visibleCharacterIndex == charCount) {
break;
}
yield return null;
}
}