Ingen beskrivning
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TMP_SpriteAnimator.cs 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. using UnityEngine;
  2. using UnityEngine.TextCore;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. namespace TMPro
  6. {
  7. [DisallowMultipleComponent]
  8. public class TMP_SpriteAnimator : MonoBehaviour
  9. {
  10. private Dictionary<int, bool> m_animations = new Dictionary<int, bool>(16);
  11. //private bool isPlaying = false;
  12. private TMP_Text m_TextComponent;
  13. void Awake()
  14. {
  15. m_TextComponent = GetComponent<TMP_Text>();
  16. }
  17. void OnEnable()
  18. {
  19. //m_playAnimations = true;
  20. }
  21. void OnDisable()
  22. {
  23. //m_playAnimations = false;
  24. }
  25. public void StopAllAnimations()
  26. {
  27. StopAllCoroutines();
  28. m_animations.Clear();
  29. }
  30. public void DoSpriteAnimation(int currentCharacter, TMP_SpriteAsset spriteAsset, int start, int end, int framerate)
  31. {
  32. bool isPlaying;
  33. // Need to add tracking of coroutines that have been lunched for this text object.
  34. if (!m_animations.TryGetValue(currentCharacter, out isPlaying))
  35. {
  36. StartCoroutine(DoSpriteAnimationInternal(currentCharacter, spriteAsset, start, end, framerate));
  37. m_animations.Add(currentCharacter, true);
  38. }
  39. }
  40. IEnumerator DoSpriteAnimationInternal(int currentCharacter, TMP_SpriteAsset spriteAsset, int start, int end, int framerate)
  41. {
  42. if (m_TextComponent == null) yield break;
  43. // We yield otherwise this gets called before the sprite has rendered.
  44. yield return null;
  45. int currentFrame = start;
  46. // Make sure end frame does not exceed the number of sprites in the sprite asset.
  47. if (end > spriteAsset.spriteCharacterTable.Count)
  48. end = spriteAsset.spriteCharacterTable.Count - 1;
  49. // Get a reference to the current character's info
  50. TMP_CharacterInfo charInfo = m_TextComponent.textInfo.characterInfo[currentCharacter];
  51. int materialIndex = charInfo.materialReferenceIndex;
  52. int vertexIndex = charInfo.vertexIndex;
  53. TMP_MeshInfo meshInfo = m_TextComponent.textInfo.meshInfo[materialIndex];
  54. float baseSpriteScale = spriteAsset.spriteCharacterTable[start].scale * spriteAsset.spriteCharacterTable[start].glyph.scale;
  55. float elapsedTime = 0;
  56. float targetTime = 1f / Mathf.Abs(framerate);
  57. while (true)
  58. {
  59. if (elapsedTime > targetTime)
  60. {
  61. elapsedTime = 0;
  62. // Return if sprite was truncated or replaced by the Ellipsis character.
  63. char character = m_TextComponent.textInfo.characterInfo[currentCharacter].character;
  64. if (character == 0x03 || character == 0x2026)
  65. {
  66. m_animations.Remove(currentCharacter);
  67. yield break;
  68. }
  69. // Get a reference to the current sprite
  70. TMP_SpriteCharacter spriteCharacter = spriteAsset.spriteCharacterTable[currentFrame];
  71. // Update the vertices for the new sprite
  72. Vector3[] vertices = meshInfo.vertices;
  73. Vector2 origin = new Vector2(charInfo.origin, charInfo.baseLine);
  74. float spriteScale = charInfo.scale / baseSpriteScale * spriteCharacter.scale * spriteCharacter.glyph.scale;
  75. Vector3 bl = new Vector3(origin.x + spriteCharacter.glyph.metrics.horizontalBearingX * spriteScale, origin.y + (spriteCharacter.glyph.metrics.horizontalBearingY - spriteCharacter.glyph.metrics.height) * spriteScale);
  76. Vector3 tl = new Vector3(bl.x, origin.y + spriteCharacter.glyph.metrics.horizontalBearingY * spriteScale);
  77. Vector3 tr = new Vector3(origin.x + (spriteCharacter.glyph.metrics.horizontalBearingX + spriteCharacter.glyph.metrics.width) * spriteScale, tl.y);
  78. Vector3 br = new Vector3(tr.x, bl.y);
  79. vertices[vertexIndex + 0] = bl;
  80. vertices[vertexIndex + 1] = tl;
  81. vertices[vertexIndex + 2] = tr;
  82. vertices[vertexIndex + 3] = br;
  83. // Update the UV to point to the new sprite
  84. Vector2[] uvs0 = meshInfo.uvs0;
  85. Vector2 uv0 = new Vector2((float)spriteCharacter.glyph.glyphRect.x / spriteAsset.spriteSheet.width, (float)spriteCharacter.glyph.glyphRect.y / spriteAsset.spriteSheet.height);
  86. Vector2 uv1 = new Vector2(uv0.x, (float)(spriteCharacter.glyph.glyphRect.y + spriteCharacter.glyph.glyphRect.height) / spriteAsset.spriteSheet.height);
  87. Vector2 uv2 = new Vector2((float)(spriteCharacter.glyph.glyphRect.x + spriteCharacter.glyph.glyphRect.width) / spriteAsset.spriteSheet.width, uv1.y);
  88. Vector2 uv3 = new Vector2(uv2.x, uv0.y);
  89. uvs0[vertexIndex + 0] = uv0;
  90. uvs0[vertexIndex + 1] = uv1;
  91. uvs0[vertexIndex + 2] = uv2;
  92. uvs0[vertexIndex + 3] = uv3;
  93. // Update the modified vertex attributes
  94. meshInfo.mesh.vertices = vertices;
  95. meshInfo.mesh.uv = uvs0;
  96. m_TextComponent.UpdateGeometry(meshInfo.mesh, materialIndex);
  97. if (framerate > 0)
  98. {
  99. if (currentFrame < end)
  100. currentFrame += 1;
  101. else
  102. currentFrame = start;
  103. }
  104. else
  105. {
  106. if (currentFrame > start)
  107. currentFrame -= 1;
  108. else
  109. currentFrame = end;
  110. }
  111. }
  112. elapsedTime += Time.deltaTime;
  113. yield return null;
  114. }
  115. }
  116. }
  117. }