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.

148 lines
5.1 KiB

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