Page 2 of 2
Re: Blinking cursor when the text is finished
Posted: Sat Aug 24, 2019 11:58 pm
by AoF
Here's a gif showing it happening (notice the left and side text):
https://cdn.discordapp.com/attachments/ ... 71/gif.gif
I'll email you my project. Thanks!
Re: Blinking cursor when the text is finished
Posted: Sun Aug 25, 2019 4:31 pm
by Tony Li
This is the core code to blink the cursor. After setting TMP's text, it needs to call ForceMeshUpdate() to rebuild the visible mesh of the text. In the loop, this version changes the number of characters to show instead of changing the text, since changing the text would require it to rebuild the mesh every time.
Code: Select all
private IEnumerator BlinkCursor()
{
text.text += " x";
text.ForceMeshUpdate();
var fullLength = text.textInfo.characterCount;
while (blink)
{
text.maxVisibleCharacters = fullLength;
yield return new WaitForSeconds(.5f);
text.maxVisibleCharacters = fullLength - 1;
yield return new WaitForSeconds(.5f);
}
}
Re: Blinking cursor when the text is finished
Posted: Sun Aug 25, 2019 6:49 pm
by AoF
I tried that and modified it for my needs. It worked well, but what I didn't like is it put the sprite at the very end as soon as the text completed, almost as if it was part of the dialogue. I thought it would look better if there was a delay before it showed up. I thought this would be extremely straight forward, but for some reason, it doesn't work at all when I attempt it. Here's my code:
Code: Select all
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using System;
public class BlinkingCursor : MonoBehaviour
{
private const string CURSOR_1 = " <sprite=\"cursors\" index=0>";
private const string CURSOR_2 = " <sprite=\"cursors\" index=1>";
public TextMeshProUGUI text;
private bool blink = false;
private Coroutine coroutine;
public void OnBegin()
{
Debug.LogError("OnBegin");
blink = false;
if (coroutine != null)
{
StopCoroutine(coroutine);
}
}
public void OnEnd()
{
Debug.LogError("OnEnd");
blink = true;
coroutine = StartCoroutine(BlinkCursor());
}
private IEnumerator BlinkCursor()
{
yield return new WaitForSeconds(1f); // works exactly as expected when this line is removed
Debug.LogError("gonna blink! " + blink);
text.text += " " + CURSOR_1;
text.ForceMeshUpdate();
var fullLength = text.textInfo.characterCount;
while (blink)
{
text.text = text.text.Replace(CURSOR_1, CURSOR_2);
text.ForceMeshUpdate();
yield return new WaitForSeconds(.5f);
text.text = text.text.Replace(CURSOR_2, CURSOR_1);
text.ForceMeshUpdate();
yield return new WaitForSeconds(.5f);
}
}
}
Any idea why waiting at the beginning of the Coroutine would prevent the cursor from showing completely? This is the log output:
Re: Blinking cursor when the text is finished
Posted: Sun Aug 25, 2019 8:59 pm
by Tony Li
After a little research, it turns out that ForceMeshLayout() doesn't update a TextMeshProUGUI's internal cache of sprite references. I restructured the script to deactivate and immediately reactivate its GameObject when starting to blink, which forces it to refresh its sprite references. The script now also turns off the typewriter effect's Play On Enable checkbox since this would be unintentionally triggered by deactivating and reactivating the GameObject.