PortalFX_UVAnimation.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. using System;
  2. using System.Collections;
  3. using UnityEngine;
  4. public class PortalFX_UVAnimation : MonoBehaviour
  5. {
  6. public int TilesX = 4;
  7. public int TilesY = 4;
  8. public float FPS = 30;
  9. public int StartFrameOffset;
  10. public bool IsLoop = true;
  11. public float StartDelay = 0;
  12. public bool IsReverse;
  13. public bool IsBump;
  14. public AnimationCurve FrameOverTime = AnimationCurve.Linear(0, 1, 1, 1);
  15. private bool isInizialised;
  16. private int index;
  17. private int count, allCount;
  18. private float animationLifeTime;
  19. private bool isVisible;
  20. private bool isCorutineStarted;
  21. private Renderer currentRenderer;
  22. private Material instanceMaterial;
  23. private float animationStartTime;
  24. private bool animationStoped;
  25. #region Non-public methods
  26. private void Start()
  27. {
  28. currentRenderer = GetComponent<Renderer>();
  29. InitDefaultVariables();
  30. isInizialised = true;
  31. isVisible = true;
  32. Play();
  33. }
  34. private void InitDefaultVariables()
  35. {
  36. currentRenderer = GetComponent<Renderer>();
  37. if (currentRenderer==null)
  38. throw new Exception("UvTextureAnimator can't get renderer");
  39. if (!currentRenderer.enabled)
  40. currentRenderer.enabled = true;
  41. allCount = 0;
  42. animationStoped = false;
  43. animationLifeTime = TilesX * TilesY / FPS;
  44. count = TilesY * TilesX;
  45. index = TilesX - 1;
  46. var offset = Vector3.zero;
  47. StartFrameOffset = StartFrameOffset - (StartFrameOffset / count) * count;
  48. var size = new Vector2(1f / TilesX, 1f / TilesY);
  49. if (currentRenderer!=null) {
  50. instanceMaterial = currentRenderer.material;
  51. instanceMaterial.SetTextureScale("_MainTex", size);
  52. instanceMaterial.SetTextureOffset("_MainTex", offset);
  53. if (IsBump) {
  54. instanceMaterial.SetTextureScale("_BumpMap", size);
  55. instanceMaterial.SetTextureOffset("_BumpMap", offset);
  56. }
  57. }
  58. }
  59. private void Play()
  60. {
  61. if (isCorutineStarted)
  62. return;
  63. if (StartDelay > 0.0001f)
  64. Invoke("PlayDelay", StartDelay);
  65. else
  66. StartCoroutine(UpdateCorutine());
  67. isCorutineStarted = true;
  68. }
  69. private void PlayDelay()
  70. {
  71. StartCoroutine(UpdateCorutine());
  72. }
  73. #region CorutineCode
  74. private void OnEnable()
  75. {
  76. if (!isInizialised)
  77. return;
  78. InitDefaultVariables();
  79. isVisible = true;
  80. Play();
  81. }
  82. private void OnDisable()
  83. {
  84. isCorutineStarted = false;
  85. isVisible = false;
  86. StopAllCoroutines();
  87. CancelInvoke("PlayDelay");
  88. }
  89. private IEnumerator UpdateCorutine()
  90. {
  91. animationStartTime = Time.time;
  92. while (isVisible && (IsLoop || !animationStoped)) {
  93. if (!IsReverse)
  94. UpdateFrame();
  95. else
  96. UpdateFrameReversed();
  97. if (!IsLoop && animationStoped)
  98. break;
  99. var frameTime = (Time.time - animationStartTime) / animationLifeTime;
  100. var currentSpeedFps = FrameOverTime.Evaluate(Mathf.Clamp01(frameTime));
  101. yield return new WaitForSeconds(1f / (FPS * currentSpeedFps));
  102. }
  103. isCorutineStarted = false;
  104. //currentRenderer.enabled = false;
  105. }
  106. #endregion CorutineCode
  107. private void UpdateFrame()
  108. {
  109. ++allCount;
  110. ++index;
  111. if (index >= count)
  112. index = 0;
  113. if (count==allCount) {
  114. animationStartTime = Time.time;
  115. allCount = 0;
  116. animationStoped = true;
  117. }
  118. var offset = new Vector2((float)index / TilesX - (int)(index / TilesX), 1 - (int)(index / TilesX) / (float)TilesY);
  119. if (currentRenderer!=null) {
  120. instanceMaterial.SetTextureOffset("_MainTex", offset);
  121. if (IsBump)
  122. instanceMaterial.SetTextureOffset("_BumpMap", offset);
  123. }
  124. }
  125. private void UpdateFrameReversed()
  126. {
  127. --allCount;
  128. --index;
  129. if (index <= 0)
  130. index = count;
  131. if (count == allCount)
  132. {
  133. animationStartTime = Time.time;
  134. allCount = 0;
  135. animationStoped = true;
  136. }
  137. var offset = new Vector2((float)index / TilesX - (int)(index / TilesX), 1 - (int)(index / TilesX) / (float)TilesY);
  138. if (currentRenderer!=null) {
  139. instanceMaterial.SetTextureOffset("_MainTex", offset);
  140. if (IsBump)
  141. instanceMaterial.SetTextureOffset("_BumpMap", offset);
  142. }
  143. }
  144. private void OnDestroy()
  145. {
  146. if (instanceMaterial!=null) {
  147. Destroy(instanceMaterial);
  148. instanceMaterial = null;
  149. }
  150. }
  151. #endregion
  152. }