feature: Messages are now animated
This commit is contained in:
parent
1c8fbc94e0
commit
923b7b6f62
6 changed files with 83 additions and 8 deletions
|
@ -1,19 +1,32 @@
|
||||||
using System;
|
using System;
|
||||||
using TMPro;
|
using TMPro;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using Utilities;
|
||||||
|
|
||||||
namespace Messaging {
|
namespace Messaging {
|
||||||
public class Message : MonoBehaviour{
|
public class Message : MonoBehaviour {
|
||||||
public RectTransform RectTransform { private set; get; }
|
public RectTransform RectTransform { private set; get; }
|
||||||
public string Text => messageText.text;
|
public string Text => messageText.text;
|
||||||
|
|
||||||
[SerializeField] private TMP_Text messageText;
|
[SerializeField] private TMP_Text messageText;
|
||||||
|
|
||||||
|
private TextTyper _textTyper;
|
||||||
|
private Coroutine _typingCoroutine;
|
||||||
|
|
||||||
private void Awake() {
|
private void Awake() {
|
||||||
RectTransform = GetComponent<RectTransform>();
|
RectTransform = GetComponent<RectTransform>();
|
||||||
|
_textTyper = new TextTyper(messageText);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetMessageText(string text) {
|
public void SetMessageText(string text, bool animate) {
|
||||||
|
if (_textTyper.IsMessageAnimating()) {
|
||||||
|
_textTyper.SkipToEndOfCurrentMessage();
|
||||||
|
}
|
||||||
|
this.EnsureCoroutineStopped(ref _typingCoroutine);
|
||||||
|
|
||||||
|
if (animate)
|
||||||
|
_typingCoroutine = StartCoroutine(_textTyper.AnimateTextIn(text, null));
|
||||||
|
else
|
||||||
messageText.text = text;
|
messageText.text = text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Messaging {
|
namespace Messaging {
|
||||||
|
@ -10,16 +12,34 @@ namespace Messaging {
|
||||||
_messages = messageStructureGenerator.GenerateMessages();
|
_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) {
|
public void CreateMessage(string message) {
|
||||||
ModifyMessageText(message, _messages.Length - 1);
|
ModifyMessageText(message, _messages.Length - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ModifyMessageText(string message, int index) {
|
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;
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -10,13 +10,16 @@ namespace Messaging {
|
||||||
|
|
||||||
private readonly TMP_Text _textBox;
|
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) {
|
public TextTyper(TMP_Text textBox) {
|
||||||
_textBox = textBox;
|
_textBox = textBox;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerator AnimateTextIn(string processedMessage, Action onFinish) {
|
public IEnumerator AnimateTextIn(string processedMessage, Action onFinish) {
|
||||||
_textAnimating = true;
|
_textAnimating = true;
|
||||||
float secondsPerCharacter = 1f / 150f;
|
_stopAnimating = false;
|
||||||
float timeOfLastCharacter = 0;
|
float timeOfLastCharacter = 0;
|
||||||
|
|
||||||
TMP_TextInfo textInfo = _textBox.textInfo;
|
TMP_TextInfo textInfo = _textBox.textInfo;
|
||||||
|
@ -50,10 +53,10 @@ namespace Messaging {
|
||||||
visibleCharacterIndex = charCount;
|
visibleCharacterIndex = charCount;
|
||||||
FinishAnimating(onFinish);
|
FinishAnimating(onFinish);
|
||||||
}
|
}
|
||||||
if (ShouldShowNextCharacter(secondsPerCharacter, timeOfLastCharacter)) {
|
if (ShouldShowNextCharacter(SecondsPerCharacter, timeOfLastCharacter)) {
|
||||||
if (visibleCharacterIndex <= charCount) {
|
if (visibleCharacterIndex <= charCount) {
|
||||||
if (visibleCharacterIndex < charCount &&
|
if (visibleCharacterIndex < charCount &&
|
||||||
ShouldShowNextCharacter(secondsPerCharacter, timeOfLastCharacter)) {
|
ShouldShowNextCharacter(SecondsPerCharacter, timeOfLastCharacter)) {
|
||||||
charAnimStartTimes[visibleCharacterIndex] = Time.unscaledTime;
|
charAnimStartTimes[visibleCharacterIndex] = Time.unscaledTime;
|
||||||
visibleCharacterIndex++;
|
visibleCharacterIndex++;
|
||||||
timeOfLastCharacter = Time.unscaledTime;
|
timeOfLastCharacter = Time.unscaledTime;
|
||||||
|
@ -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);
|
_textBox.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);
|
||||||
for (int i = 0; i < textInfo.meshInfo.Length; i++) {
|
for (int i = 0; i < textInfo.meshInfo.Length; i++) {
|
||||||
TMP_MeshInfo theInfo = textInfo.meshInfo[i];
|
TMP_MeshInfo theInfo = textInfo.meshInfo[i];
|
||||||
|
|
3
Assets/Scripts/Utilities.meta
Normal file
3
Assets/Scripts/Utilities.meta
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1edc85165243485db8a6f414074b8f6c
|
||||||
|
timeCreated: 1706301321
|
11
Assets/Scripts/Utilities/MonoBehaviourExtensions.cs
Normal file
11
Assets/Scripts/Utilities/MonoBehaviourExtensions.cs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Assets/Scripts/Utilities/MonoBehaviourExtensions.cs.meta
Normal file
11
Assets/Scripts/Utilities/MonoBehaviourExtensions.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6950117e9f384976acc9489f6f1ae482
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
Loading…
Add table
Add a link
Reference in a new issue