Loading Assets/Scripts/Messaging/Message.cs +16 −3 Original line number Diff line number Diff line using System; using TMPro; using UnityEngine; using Utilities; namespace Messaging { public class Message : MonoBehaviour { Loading @@ -9,11 +10,23 @@ namespace Messaging { [SerializeField] private TMP_Text messageText; private TextTyper _textTyper; private Coroutine _typingCoroutine; private void Awake() { RectTransform = GetComponent<RectTransform>(); _textTyper = new TextTyper(messageText); } public void SetMessageText(string text, bool animate) { if (_textTyper.IsMessageAnimating()) { _textTyper.SkipToEndOfCurrentMessage(); } this.EnsureCoroutineStopped(ref _typingCoroutine); public void SetMessageText(string text) { if (animate) _typingCoroutine = StartCoroutine(_textTyper.AnimateTextIn(text, null)); else messageText.text = text; } } Loading Assets/Scripts/Messaging/MessageManager.cs +22 −2 Original line number Diff line number Diff line using System; using System.Threading.Tasks; using UnityEngine; namespace Messaging { Loading @@ -10,16 +12,34 @@ namespace Messaging { _messages = messageStructureGenerator.GenerateMessages(); } private async void Start() { await Task.Delay(2000); CreateMessage("asl;dkrhjufioe qvnfioeqlcnnmcuq"); await Task.Delay(2000); CreateMessage("asl;dkrhjufioe qvnfioeqlcnnmcuq"); await Task.Delay(2000); CreateMessage("asl;dkrhjufioe qvnfioeqlcnnmcuq"); await Task.Delay(2000); CreateMessage("asl;dkrhjufioe qvnfioeqlcnnmcuq"); await Task.Delay(2000); CreateMessage("asl;dkrhjufioe qvnfioeqlcnnmcuq"); } public void CreateMessage(string message) { ModifyMessageText(message, _messages.Length - 1); } private void ModifyMessageText(string message, int index) { ModifyPreviousMessageText(_messages[index].Text, index - 1); _messages[index].SetMessageText(message, true); } private void ModifyPreviousMessageText(string message, int index) { if(index < 0) return; ModifyMessageText(_messages[index].Text, index - 1); ModifyPreviousMessageText(_messages[index].Text, index - 1); _messages[index].SetMessageText(message); _messages[index].SetMessageText(message, false); } } } No newline at end of file Assets/Scripts/Messaging/TextTyper.cs +20 −3 Original line number Diff line number Diff line Loading @@ -10,13 +10,16 @@ namespace Messaging { private readonly TMP_Text _textBox; static readonly Color32 Clear = new(0, 0, 0, 0); private const float SecondsPerCharacter = 1f / 60f; public TextTyper(TMP_Text textBox) { _textBox = textBox; } public IEnumerator AnimateTextIn(string processedMessage, Action onFinish) { _textAnimating = true; float secondsPerCharacter = 1f / 150f; _stopAnimating = false; float timeOfLastCharacter = 0; TMP_TextInfo textInfo = _textBox.textInfo; Loading Loading @@ -50,10 +53,10 @@ namespace Messaging { visibleCharacterIndex = charCount; FinishAnimating(onFinish); } if (ShouldShowNextCharacter(secondsPerCharacter, timeOfLastCharacter)) { if (ShouldShowNextCharacter(SecondsPerCharacter, timeOfLastCharacter)) { if (visibleCharacterIndex <= charCount) { if (visibleCharacterIndex < charCount && ShouldShowNextCharacter(secondsPerCharacter, timeOfLastCharacter)) { ShouldShowNextCharacter(SecondsPerCharacter, timeOfLastCharacter)) { charAnimStartTimes[visibleCharacterIndex] = Time.unscaledTime; visibleCharacterIndex++; timeOfLastCharacter = Time.unscaledTime; Loading @@ -64,6 +67,20 @@ namespace Messaging { } } 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]; Loading Assets/Scripts/Utilities.meta 0 → 100644 +3 −0 Original line number Diff line number Diff line fileFormatVersion: 2 guid: 1edc85165243485db8a6f414074b8f6c timeCreated: 1706301321 No newline at end of file Assets/Scripts/Utilities/MonoBehaviourExtensions.cs 0 → 100644 +11 −0 Original line number Diff line number Diff line using UnityEngine; namespace Utilities { public static class MonoBehaviourExtensions { public static void EnsureCoroutineStopped(this MonoBehaviour value, ref Coroutine routine) { if (routine == null) return; value.StopCoroutine(routine); routine = null; } } } No newline at end of file Loading
Assets/Scripts/Messaging/Message.cs +16 −3 Original line number Diff line number Diff line using System; using TMPro; using UnityEngine; using Utilities; namespace Messaging { public class Message : MonoBehaviour { Loading @@ -9,11 +10,23 @@ namespace Messaging { [SerializeField] private TMP_Text messageText; private TextTyper _textTyper; private Coroutine _typingCoroutine; private void Awake() { RectTransform = GetComponent<RectTransform>(); _textTyper = new TextTyper(messageText); } public void SetMessageText(string text, bool animate) { if (_textTyper.IsMessageAnimating()) { _textTyper.SkipToEndOfCurrentMessage(); } this.EnsureCoroutineStopped(ref _typingCoroutine); public void SetMessageText(string text) { if (animate) _typingCoroutine = StartCoroutine(_textTyper.AnimateTextIn(text, null)); else messageText.text = text; } } Loading
Assets/Scripts/Messaging/MessageManager.cs +22 −2 Original line number Diff line number Diff line using System; using System.Threading.Tasks; using UnityEngine; namespace Messaging { Loading @@ -10,16 +12,34 @@ namespace Messaging { _messages = messageStructureGenerator.GenerateMessages(); } private async void Start() { await Task.Delay(2000); CreateMessage("asl;dkrhjufioe qvnfioeqlcnnmcuq"); await Task.Delay(2000); CreateMessage("asl;dkrhjufioe qvnfioeqlcnnmcuq"); await Task.Delay(2000); CreateMessage("asl;dkrhjufioe qvnfioeqlcnnmcuq"); await Task.Delay(2000); CreateMessage("asl;dkrhjufioe qvnfioeqlcnnmcuq"); await Task.Delay(2000); CreateMessage("asl;dkrhjufioe qvnfioeqlcnnmcuq"); } public void CreateMessage(string message) { ModifyMessageText(message, _messages.Length - 1); } private void ModifyMessageText(string message, int index) { ModifyPreviousMessageText(_messages[index].Text, index - 1); _messages[index].SetMessageText(message, true); } private void ModifyPreviousMessageText(string message, int index) { if(index < 0) return; ModifyMessageText(_messages[index].Text, index - 1); ModifyPreviousMessageText(_messages[index].Text, index - 1); _messages[index].SetMessageText(message); _messages[index].SetMessageText(message, false); } } } No newline at end of file
Assets/Scripts/Messaging/TextTyper.cs +20 −3 Original line number Diff line number Diff line Loading @@ -10,13 +10,16 @@ namespace Messaging { private readonly TMP_Text _textBox; static readonly Color32 Clear = new(0, 0, 0, 0); private const float SecondsPerCharacter = 1f / 60f; public TextTyper(TMP_Text textBox) { _textBox = textBox; } public IEnumerator AnimateTextIn(string processedMessage, Action onFinish) { _textAnimating = true; float secondsPerCharacter = 1f / 150f; _stopAnimating = false; float timeOfLastCharacter = 0; TMP_TextInfo textInfo = _textBox.textInfo; Loading Loading @@ -50,10 +53,10 @@ namespace Messaging { visibleCharacterIndex = charCount; FinishAnimating(onFinish); } if (ShouldShowNextCharacter(secondsPerCharacter, timeOfLastCharacter)) { if (ShouldShowNextCharacter(SecondsPerCharacter, timeOfLastCharacter)) { if (visibleCharacterIndex <= charCount) { if (visibleCharacterIndex < charCount && ShouldShowNextCharacter(secondsPerCharacter, timeOfLastCharacter)) { ShouldShowNextCharacter(SecondsPerCharacter, timeOfLastCharacter)) { charAnimStartTimes[visibleCharacterIndex] = Time.unscaledTime; visibleCharacterIndex++; timeOfLastCharacter = Time.unscaledTime; Loading @@ -64,6 +67,20 @@ namespace Messaging { } } 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]; Loading
Assets/Scripts/Utilities.meta 0 → 100644 +3 −0 Original line number Diff line number Diff line fileFormatVersion: 2 guid: 1edc85165243485db8a6f414074b8f6c timeCreated: 1706301321 No newline at end of file
Assets/Scripts/Utilities/MonoBehaviourExtensions.cs 0 → 100644 +11 −0 Original line number Diff line number Diff line using UnityEngine; namespace Utilities { public static class MonoBehaviourExtensions { public static void EnsureCoroutineStopped(this MonoBehaviour value, ref Coroutine routine) { if (routine == null) return; value.StopCoroutine(routine); routine = null; } } } No newline at end of file