NStarPolygon.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. using System;
  2. using UnityEngine;
  3. namespace MPUIKIT {
  4. /// <summary>
  5. /// N-star polygon shape is equal sided uniform polygon shape with the ability to morph
  6. /// to a star corresponding to the original shape. ie: an equilateral pentagon will morph
  7. /// to a five sided star.
  8. /// </summary>
  9. [Serializable]
  10. public struct NStarPolygon: IMPUIComponent {
  11. [SerializeField] private float m_SideCount;
  12. [SerializeField] private float m_Inset;
  13. [SerializeField] private float m_CornerRadius;
  14. [SerializeField] private Vector2 m_Offset;
  15. /// <summary>
  16. /// How many sides should there be in the shape. These sides are equal is size.
  17. /// 3 sides create an equilateral triangle, 6 sides create a hexagon and so on
  18. /// <para>Value of SideCount should remain between 3 and 10.</para>
  19. /// </summary>
  20. public float SideCount {
  21. get => m_SideCount;
  22. set {
  23. m_SideCount = Mathf.Clamp(value, 3f, 10f);
  24. if (ShouldModifySharedMat) {
  25. SharedMat.SetFloat(SpNStarPolygonSideCount, m_SideCount);
  26. }
  27. OnComponentSettingsChanged?.Invoke(this, EventArgs.Empty);
  28. Inset = m_Inset;
  29. }
  30. }
  31. /// <summary>
  32. /// Inset is the value that determine how much should the sides go inside the shape
  33. /// and create a concave star shape. Each sides will break into half and their middle
  34. /// point will go towards the center of the shape
  35. /// <para>Value of inset should remain between 2 and (SideCount - 0.01). 2 is default
  36. /// and means no breaking of the sides. </para>
  37. /// </summary>
  38. public float Inset {
  39. get => m_Inset;
  40. set {
  41. m_Inset = Mathf.Clamp(value, 2f, SideCount - 0.01f);
  42. if (ShouldModifySharedMat) {
  43. SharedMat.SetFloat(SpNStarPolygonInset, m_Inset);
  44. }
  45. OnComponentSettingsChanged?.Invoke(this, EventArgs.Empty);
  46. }
  47. }
  48. /// <summary>
  49. /// Corner Radius of all the corners of the shape.
  50. /// </summary>
  51. public float CornerRadius {
  52. get => m_CornerRadius;
  53. set {
  54. m_CornerRadius = Mathf.Max(value, 0);
  55. if (ShouldModifySharedMat) {
  56. SharedMat.SetFloat(SpNStarPolygonCornerRadius, m_CornerRadius);
  57. }
  58. OnComponentSettingsChanged?.Invoke(this, EventArgs.Empty);
  59. }
  60. }
  61. /// <summary>
  62. /// Position offset of the shape from the origin.
  63. /// </summary>
  64. public Vector2 Offset {
  65. get => m_Offset;
  66. set {
  67. m_Offset = value;
  68. if (ShouldModifySharedMat) {
  69. SharedMat.SetVector(SpNStarPolygonOffset, m_Offset);
  70. }
  71. OnComponentSettingsChanged?.Invoke(this, EventArgs.Empty);
  72. }
  73. }
  74. private static readonly int SpNStarPolygonSideCount = Shader.PropertyToID("_NStarPolygonSideCount");
  75. private static readonly int SpNStarPolygonInset = Shader.PropertyToID("_NStarPolygonInset");
  76. private static readonly int SpNStarPolygonCornerRadius = Shader.PropertyToID("_NStarPolygonCornerRadius");
  77. private static readonly int SpNStarPolygonOffset = Shader.PropertyToID("_NStarPolygonOffset");
  78. public Material SharedMat { get; set; }
  79. public bool ShouldModifySharedMat { get; set; }
  80. public RectTransform RectTransform { get; set; }
  81. public void Init(Material sharedMat, Material renderMat, RectTransform rectTransform) {
  82. SharedMat = sharedMat;
  83. ShouldModifySharedMat = sharedMat == renderMat;
  84. RectTransform = rectTransform;
  85. OnValidate();
  86. }
  87. public event EventHandler OnComponentSettingsChanged;
  88. public void OnValidate() {
  89. SideCount = m_SideCount;
  90. Inset = m_Inset;
  91. CornerRadius = m_CornerRadius;
  92. Offset = m_Offset;
  93. }
  94. public void InitValuesFromMaterial(ref Material material) {
  95. m_SideCount = material.GetFloat(SpNStarPolygonSideCount);
  96. m_Inset = material.GetFloat(SpNStarPolygonInset);
  97. m_CornerRadius = material.GetFloat(SpNStarPolygonCornerRadius);
  98. m_Offset = material.GetVector(SpNStarPolygonOffset);
  99. }
  100. public void ModifyMaterial(ref Material material, params object[] otherProperties) {
  101. material.SetFloat(SpNStarPolygonSideCount, m_SideCount);
  102. material.SetFloat(SpNStarPolygonInset, m_Inset);
  103. material.SetFloat(SpNStarPolygonCornerRadius, m_CornerRadius);
  104. material.SetVector(SpNStarPolygonOffset, m_Offset);
  105. }
  106. }
  107. }