UIShiny.cs 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.Serialization;
  5. using UnityEngine.UI;
  6. using System.Collections;
  7. namespace Coffee.UIEffects
  8. {
  9. /// <summary>
  10. /// UIEffect.
  11. /// </summary>
  12. [AddComponentMenu("UI/UIEffects/UIShiny", 2)]
  13. public class UIShiny : BaseMaterialEffect
  14. {
  15. private const uint k_ShaderId = 1 << 3;
  16. private static readonly ParameterTexture s_ParamTex = new ParameterTexture(8, 128, "_ParamTex");
  17. float _lastRotation;
  18. EffectArea _lastEffectArea;
  19. [Tooltip("Location for shiny effect.")] [FormerlySerializedAs("m_Location")] [SerializeField] [Range(0, 1)]
  20. float m_EffectFactor = 0.5f;
  21. [Tooltip("Width for shiny effect.")] [SerializeField] [Range(0, 1)]
  22. float m_Width = 0.25f;
  23. [Tooltip("Rotation for shiny effect.")] [SerializeField] [Range(-180, 180)]
  24. float m_Rotation = 135;
  25. [Tooltip("Softness for shiny effect.")] [SerializeField] [Range(0.01f, 1)]
  26. float m_Softness = 1f;
  27. [Tooltip("Brightness for shiny effect.")] [FormerlySerializedAs("m_Alpha")] [SerializeField] [Range(0, 1)]
  28. float m_Brightness = 1f;
  29. [Tooltip("Gloss factor for shiny effect.")] [FormerlySerializedAs("m_Highlight")] [SerializeField] [Range(0, 1)]
  30. float m_Gloss = 1;
  31. [Header("Advanced Option")] [Tooltip("The area for effect.")] [SerializeField]
  32. protected EffectArea m_EffectArea;
  33. [SerializeField] EffectPlayer m_Player;
  34. /// <summary>
  35. /// Effect factor between 0(start) and 1(end).
  36. /// </summary>
  37. public float effectFactor
  38. {
  39. get { return m_EffectFactor; }
  40. set
  41. {
  42. value = Mathf.Clamp(value, 0, 1);
  43. if (Mathf.Approximately(m_EffectFactor, value)) return;
  44. m_EffectFactor = value;
  45. SetEffectParamsDirty();
  46. }
  47. }
  48. /// <summary>
  49. /// Width for shiny effect.
  50. /// </summary>
  51. public float width
  52. {
  53. get { return m_Width; }
  54. set
  55. {
  56. value = Mathf.Clamp(value, 0, 1);
  57. if (Mathf.Approximately(m_Width, value)) return;
  58. m_Width = value;
  59. SetEffectParamsDirty();
  60. }
  61. }
  62. /// <summary>
  63. /// Softness for shiny effect.
  64. /// </summary>
  65. public float softness
  66. {
  67. get { return m_Softness; }
  68. set
  69. {
  70. value = Mathf.Clamp(value, 0.01f, 1);
  71. if (Mathf.Approximately(m_Softness, value)) return;
  72. m_Softness = value;
  73. SetEffectParamsDirty();
  74. }
  75. }
  76. /// <summary>
  77. /// Brightness for shiny effect.
  78. /// </summary>
  79. public float brightness
  80. {
  81. get { return m_Brightness; }
  82. set
  83. {
  84. value = Mathf.Clamp(value, 0, 1);
  85. if (Mathf.Approximately(m_Brightness, value)) return;
  86. m_Brightness = value;
  87. SetEffectParamsDirty();
  88. }
  89. }
  90. /// <summary>
  91. /// Gloss factor for shiny effect.
  92. /// </summary>
  93. public float gloss
  94. {
  95. get { return m_Gloss; }
  96. set
  97. {
  98. value = Mathf.Clamp(value, 0, 1);
  99. if (Mathf.Approximately(m_Gloss, value)) return;
  100. m_Gloss = value;
  101. SetEffectParamsDirty();
  102. }
  103. }
  104. /// <summary>
  105. /// Rotation for shiny effect.
  106. /// </summary>
  107. public float rotation
  108. {
  109. get { return m_Rotation; }
  110. set
  111. {
  112. if (Mathf.Approximately(m_Rotation, value)) return;
  113. m_Rotation = value;
  114. SetVerticesDirty();
  115. }
  116. }
  117. /// <summary>
  118. /// The area for effect.
  119. /// </summary>
  120. public EffectArea effectArea
  121. {
  122. get { return m_EffectArea; }
  123. set
  124. {
  125. if (m_EffectArea == value) return;
  126. m_EffectArea = value;
  127. SetVerticesDirty();
  128. }
  129. }
  130. /// <summary>
  131. /// Gets the parameter texture.
  132. /// </summary>
  133. public override ParameterTexture paramTex
  134. {
  135. get { return s_ParamTex; }
  136. }
  137. public EffectPlayer effectPlayer
  138. {
  139. get { return m_Player ?? (m_Player = new EffectPlayer()); }
  140. }
  141. /// <summary>
  142. /// This function is called when the object becomes enabled and active.
  143. /// </summary>
  144. protected override void OnEnable()
  145. {
  146. base.OnEnable();
  147. effectPlayer.OnEnable(f => effectFactor = f);
  148. }
  149. /// <summary>
  150. /// This function is called when the behaviour becomes disabled () or inactive.
  151. /// </summary>
  152. protected override void OnDisable()
  153. {
  154. base.OnDisable();
  155. effectPlayer.OnDisable();
  156. }
  157. public override Hash128 GetMaterialHash(Material material)
  158. {
  159. if (!isActiveAndEnabled || !material || !material.shader)
  160. return k_InvalidHash;
  161. return new Hash128(
  162. (uint) material.GetInstanceID(),
  163. k_ShaderId,
  164. 0,
  165. 0
  166. );
  167. }
  168. public override void ModifyMaterial(Material newMaterial, Graphic graphic)
  169. {
  170. var connector = GraphicConnector.FindConnector(graphic);
  171. newMaterial.shader = Shader.Find(string.Format("Hidden/{0} (UIShiny)", newMaterial.shader.name));
  172. paramTex.RegisterMaterial(newMaterial);
  173. }
  174. /// <summary>
  175. /// Modifies the mesh.
  176. /// </summary>
  177. public override void ModifyMesh(VertexHelper vh, Graphic graphic)
  178. {
  179. if (!isActiveAndEnabled)
  180. return;
  181. var normalizedIndex = paramTex.GetNormalizedIndex(this);
  182. var rect = m_EffectArea.GetEffectArea(vh, rectTransform.rect);
  183. // rotation.
  184. var rad = m_Rotation * Mathf.Deg2Rad;
  185. var dir = new Vector2(Mathf.Cos(rad), Mathf.Sin(rad));
  186. dir.x *= rect.height / rect.width;
  187. dir = dir.normalized;
  188. // Calculate vertex position.
  189. var vertex = default(UIVertex);
  190. var localMatrix = new Matrix2x3(rect, dir.x, dir.y); // Get local matrix.
  191. for (int i = 0; i < vh.currentVertCount; i++)
  192. {
  193. vh.PopulateUIVertex(ref vertex, i);
  194. Vector2 normalizedPos;
  195. connector.GetNormalizedFactor(m_EffectArea, i, localMatrix, vertex.position, out normalizedPos);
  196. vertex.uv0 = new Vector2(
  197. Packer.ToFloat(vertex.uv0.x, vertex.uv0.y),
  198. Packer.ToFloat(normalizedPos.y, normalizedIndex)
  199. );
  200. vh.SetUIVertex(vertex, i);
  201. }
  202. }
  203. /// <summary>
  204. /// Play effect.
  205. /// </summary>
  206. public void Play(bool reset = true)
  207. {
  208. effectPlayer.Play(reset);
  209. }
  210. /// <summary>
  211. /// Stop effect.
  212. /// </summary>
  213. public void Stop(bool reset = true)
  214. {
  215. effectPlayer.Stop(reset);
  216. }
  217. protected override void SetEffectParamsDirty()
  218. {
  219. paramTex.SetData(this, 0, m_EffectFactor); // param1.x : location
  220. paramTex.SetData(this, 1, m_Width); // param1.y : width
  221. paramTex.SetData(this, 2, m_Softness); // param1.z : softness
  222. paramTex.SetData(this, 3, m_Brightness); // param1.w : blightness
  223. paramTex.SetData(this, 4, m_Gloss); // param2.x : gloss
  224. }
  225. protected override void SetVerticesDirty()
  226. {
  227. base.SetVerticesDirty();
  228. _lastRotation = m_Rotation;
  229. _lastEffectArea = m_EffectArea;
  230. }
  231. protected override void OnDidApplyAnimationProperties()
  232. {
  233. base.OnDidApplyAnimationProperties();
  234. if (!Mathf.Approximately(_lastRotation, m_Rotation)
  235. || _lastEffectArea != m_EffectArea)
  236. SetVerticesDirty();
  237. }
  238. }
  239. }