Hello, I wanted to create an effect like in this video.
I’m talking about text smooth disappearing after it was erased. So I want to create the same effect for TMPro or some other text that when I erase one letter it will remain on the background and smoothly disappear.
Is this possible?
Hey @AlexTuh,
Yes, this is possible. My idea is to have two text fields on top of each other – one is the one you are currently writing to, the other is the one that is fading/invisible, and you swap them out on each new line of dialogue. Below is a simple, but complete example demonstrating the concept – press spacebar a few times to test it. First a couple screenshots showing the setup:
And the settings for TMP Text 2 (TMP Text 1 is the same, but without any initial text):
Finally, the code:
Assets/DialogueManager.cs
using TMPro;
using UnityEngine;
public class DialogueManager : MonoBehaviour
{
public TMP_Text txt;
public TMP_Text txt2;
TMP_Text activeTxt;
TMP_Text fadingTxt;
public float secondsPerChar = 0.03f;
public float secondsToFade = 1.0f;
int messageIdx; // Which message is displayed
int charIdx; // Which character of the message is being typed
float timeSinceLastChar;
float fadingTxtAlpha; // 0 = invisible, 1 = visible
bool waiting = true; // Are we waiting for the user to advance the dialogue?
void Start()
{
activeTxt = txt;
fadingTxt = txt2;
}
void Update()
{
if (waiting) { WaitForUserInput(); }
else { DisplayMessage(); }
FadeBackgroundMessage();
}
void WaitForUserInput()
{
if (messageIdx == messages.Length - 1) { return; } // No more messages
if (Input.GetKeyDown(KeyCode.Space))
{
AdvanceDialogue();
waiting = false;
}
}
void AdvanceDialogue()
{
// Reset the message/char indices for the new message
messageIdx++;
charIdx = 0;
// Clear out the last faded text and reset its alpha
fadingTxtAlpha = 1f;
fadingTxt.text = string.Empty;
fadingTxt.alpha = fadingTxtAlpha;
// Swap out the active and fading text boxes
var tmpTxt = activeTxt;
activeTxt = fadingTxt;
fadingTxt = tmpTxt;
}
void DisplayMessage()
{
var message = messages[messageIdx];
// Allow user to skip typing animation
if (Input.GetKeyDown(KeyCode.Space))
{
activeTxt.text = message;
charIdx = message.Length;
}
// Are we done typing this message?
if (charIdx >= message.Length)
{
waiting = true;
timeSinceLastChar = 0f;
return;
}
// Type the next character if we've waited long enough
while (timeSinceLastChar >= secondsPerChar)
{
activeTxt.text = message.Substring(0, charIdx + 1);
charIdx++;
timeSinceLastChar -= secondsPerChar;
}
timeSinceLastChar += Time.deltaTime;
}
void FadeBackgroundMessage()
{
if (fadingTxtAlpha > 0f)
{
fadingTxtAlpha -= Mathf.Clamp01((1 / secondsToFade) * Time.deltaTime);
fadingTxt.alpha = fadingTxtAlpha;
}
}
string[] messages = new[] // Some test messages to display
{
"Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
"Suspendisse venenatis quam id ante viverra, et suscipit purus posuere.",
"Nam non iaculis purus, a varius arcu.",
"Integer fermentum molestie turpis, sit amet pulvinar est viverra in.",
"Morbi pretium enim eu pellentesque aliquet.",
};
}