Last active
May 6, 2024 00:22
-
-
Save nndwn/5a6193474da03f20a71c0c184689457c to your computer and use it in GitHub Desktop.
Jitter TextMeshPro
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using TMPro; | |
using UnityEngine; | |
using Object = UnityEngine.Object; | |
using Random = UnityEngine.Random; | |
public class VertexJitter : MonoBehaviour | |
{ | |
private const float AngleMultiplier = 0.5f; | |
private const float CurveScale = 0f; | |
public bool play; | |
private TMP_Text _textComponent; | |
private bool _hasTextChanged; | |
private bool _isAnimating; | |
public Coroutine playing; | |
private struct VertexAnim | |
{ | |
public float angleRange; | |
public float angle; | |
public float speed; | |
} | |
public void Play(bool animate) | |
{ | |
play = false; | |
_isAnimating = animate; | |
if (_isAnimating) | |
{ | |
playing = StartCoroutine(AnimateVertexColors()); | |
} | |
} | |
private void OnEnable() | |
{ | |
TMPro_EventManager.TEXT_CHANGED_EVENT.Add(ON_TEXT_CHANGED); | |
_textComponent = GetComponent<TMP_Text>(); | |
if (play) | |
{ | |
playing = StartCoroutine(AnimateVertexColors()); | |
} | |
} | |
private void OnDisable() | |
{ | |
TMPro_EventManager.TEXT_CHANGED_EVENT.Remove(ON_TEXT_CHANGED); | |
} | |
private void ON_TEXT_CHANGED(Object obj) | |
{ | |
if (obj == _textComponent) | |
_hasTextChanged = true; | |
} | |
private IEnumerator AnimateVertexColors() | |
{ | |
_textComponent.ForceMeshUpdate(); | |
var textInfo = _textComponent.textInfo; | |
var loopCount = 0; | |
_hasTextChanged = true; | |
var vertexAnims = new VertexAnim[1024]; | |
for (var i = 0; i < vertexAnims.Length; i++) | |
{ | |
vertexAnims[i].angleRange = Random.Range(10f, 25f); | |
vertexAnims[i].speed = Random.Range(1f, 3f); | |
} | |
var cacheMeshInfo = textInfo.CopyMeshInfoVertexData(); | |
while (true) | |
{ | |
if (_hasTextChanged) | |
{ | |
cacheMeshInfo = textInfo.CopyMeshInfoVertexData(); | |
_hasTextChanged = false; | |
} | |
var characterCount = textInfo.characterCount; | |
for (var i = 0; i < characterCount; i++) | |
{ | |
var charInfo = textInfo.characterInfo[i]; | |
if (!charInfo.isVisible) continue; | |
var vertAnim = vertexAnims[i]; | |
var vertexIndex = textInfo.characterInfo[i].vertexIndex; | |
var materialIndex = textInfo.characterInfo[i].materialReferenceIndex; | |
var sourceVertices = cacheMeshInfo[materialIndex].vertices; | |
Vector2 charMidBaseline = (sourceVertices[vertexIndex + 0] + sourceVertices[vertexIndex + 2] / 2); | |
Vector3 offset = charMidBaseline; | |
var destinationVertices = textInfo.meshInfo[materialIndex].vertices; | |
destinationVertices[vertexIndex + 0] = sourceVertices[vertexIndex + 0] - offset; | |
destinationVertices[vertexIndex + 1] = sourceVertices[vertexIndex + 1] - offset; | |
destinationVertices[vertexIndex + 2] = sourceVertices[vertexIndex + 2] - offset; | |
destinationVertices[vertexIndex + 3] = sourceVertices[vertexIndex + 3] - offset; | |
vertAnim.angle = Mathf.SmoothStep(-vertAnim.angleRange, vertAnim.angleRange,Mathf.PingPong(loopCount / 25f * vertAnim.speed, 1f)); | |
var jitterOffset = new Vector3(Random.Range(-.25f, .25f), Random.Range(-25f, .25f), 0); | |
var matrix4X4 = Matrix4x4.TRS(jitterOffset * CurveScale, | |
Quaternion.Euler(0, 0, Random.Range(-5f, 5f) * AngleMultiplier), Vector3.one); | |
destinationVertices[vertexIndex + 0] = | |
matrix4X4.MultiplyPoint3x4(destinationVertices[vertexIndex + 0]); | |
destinationVertices[vertexIndex + 1] = | |
matrix4X4.MultiplyPoint3x4(destinationVertices[vertexIndex + 1]); | |
destinationVertices[vertexIndex + 2] = | |
matrix4X4.MultiplyPoint3x4(destinationVertices[vertexIndex + 2]); | |
destinationVertices[vertexIndex + 3] = | |
matrix4X4.MultiplyPoint3x4(destinationVertices[vertexIndex + 3]); | |
destinationVertices[vertexIndex + 0] += offset; | |
destinationVertices[vertexIndex + 1] += offset; | |
destinationVertices[vertexIndex + 2] += offset; | |
destinationVertices[vertexIndex + 3] += offset; | |
vertexAnims[i] = vertAnim; | |
} | |
for (var i = 0; i < textInfo.meshInfo.Length; i++) | |
{ | |
textInfo.meshInfo[i].mesh.vertices = textInfo.meshInfo[i].vertices; | |
_textComponent.UpdateGeometry(textInfo.meshInfo[i].mesh, i); | |
} | |
loopCount += 1; | |
yield return new WaitForSeconds(0.1f); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment