SCImage3D.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. using UnityEngine;
  2. [RequireComponent(typeof(RectTransform))]
  3. [RequireComponent(typeof(BoxCollider))]
  4. [RequireComponent(typeof(MeshRenderer))]
  5. [RequireComponent(typeof(MeshFilter))]
  6. public class SCImage3D : SCUI3D
  7. {
  8. private RectTransform m_RectTransform;
  9. private RectTransform RectTransform
  10. {
  11. get
  12. {
  13. if (m_RectTransform == null)
  14. {
  15. m_RectTransform = this.GetComponent<RectTransform>();
  16. }
  17. return m_RectTransform;
  18. }
  19. }
  20. /// <summary>
  21. /// 纹理
  22. /// </summary>
  23. [SerializeField]
  24. private Texture2D m_Texture = null;
  25. public Texture2D Texture
  26. {
  27. get => m_Texture;
  28. set
  29. {
  30. m_Texture = value;
  31. MarkUIDirty();
  32. }
  33. }
  34. /// <summary>
  35. /// 颜色
  36. /// </summary>
  37. [SerializeField]
  38. private Color m_Color = Color.white;
  39. public Color Color
  40. {
  41. get => m_Color;
  42. set
  43. {
  44. m_Color = value;
  45. MarkUIDirty();
  46. }
  47. }
  48. /// <summary>
  49. /// 材质
  50. /// </summary>
  51. [SerializeField]
  52. private Material m_Material;
  53. public Material Material
  54. {
  55. get => m_Material;
  56. set
  57. {
  58. m_Material = value;
  59. MarkUIDirty();
  60. }
  61. }
  62. /// <summary>
  63. /// 是否可以被交互
  64. /// </summary>
  65. [SerializeField]
  66. private bool m_RaycastTarget = true;
  67. public bool RaycastTarget
  68. {
  69. get => m_RaycastTarget;
  70. set
  71. {
  72. m_RaycastTarget = value;
  73. MarkUIDirty();
  74. }
  75. }
  76. /// <summary>
  77. /// 是否使用自定义ColliderSize
  78. /// </summary>
  79. [SerializeField]
  80. private bool m_CustomColliderSize = false;
  81. public bool CustomColliderSize
  82. {
  83. get => m_CustomColliderSize;
  84. set
  85. {
  86. m_CustomColliderSize = value;
  87. MarkUIDirty();
  88. }
  89. }
  90. public override void RebuildUI()
  91. {
  92. UpdateSize();
  93. UpdateMaterial();
  94. UpdateRaycaster();
  95. }
  96. public void UpdateSize()
  97. {
  98. MeshFilter meshFilter = this.GetComponent<MeshFilter>();
  99. Vector2 pivot = RectTransform.pivot;
  100. Vector2 pivotOffset = new Vector2((0.5f - pivot.x) * RectTransform.rect.width, (0.5f - pivot.y) * RectTransform.rect.height);
  101. meshFilter.sharedMesh = GenerateMesh(RectTransform.rect.size);
  102. if (!m_CustomColliderSize)
  103. {
  104. BoxCollider collider = this.GetComponent<BoxCollider>();
  105. float colliderSizeZ = collider.size.z;
  106. float colliderCenterZ = collider.center.z;
  107. collider.center = new Vector3(pivotOffset.x, pivotOffset.y, colliderCenterZ);
  108. collider.size = new Vector3(RectTransform.rect.width, RectTransform.rect.height, colliderSizeZ);
  109. }
  110. }
  111. public void UpdateMaterial()
  112. {
  113. MeshRenderer renderer = this.GetComponent<MeshRenderer>();
  114. if (m_Material == null)
  115. {
  116. renderer.sharedMaterial = Resources.Load<Material>(SCUI3DGlobalConstant.SC_3DUI_MATERIAL_PATH);
  117. }
  118. if (m_Material != null)
  119. {
  120. renderer.sharedMaterial = m_Material;
  121. }
  122. MaterialPropertyBlock materialPropertyBlock = new MaterialPropertyBlock();
  123. if (m_Texture != null)
  124. {
  125. materialPropertyBlock.SetTexture(SCUI3DGlobalConstant.SC_TEXTURE_PROPERTY_NAME, m_Texture);
  126. }
  127. materialPropertyBlock.SetColor(SCUI3DGlobalConstant.SC_COLOR_PROPERTY_NAME, m_Color);
  128. renderer.SetPropertyBlock(materialPropertyBlock);
  129. }
  130. public void UpdateRaycaster()
  131. {
  132. BoxCollider collider = this.GetComponent<BoxCollider>();
  133. collider.enabled = m_RaycastTarget;
  134. }
  135. private Mesh GenerateMesh(Vector2 size)
  136. {
  137. Vector2 pivot = RectTransform.pivot;
  138. Vector2 pivotOffset = new Vector2((0.5f - pivot.x) * size.x, (0.5f - pivot.y) * size.y);
  139. Mesh mesh = new Mesh();
  140. mesh.vertices = new Vector3[4]
  141. {
  142. new Vector3(-size.x / 2f + pivotOffset.x, -size.y / 2f + pivotOffset.y, 0f),
  143. new Vector3(-size.x / 2f + pivotOffset.x, size.y / 2f + pivotOffset.y, 0f),
  144. new Vector3(size.x / 2f + pivotOffset.x, size.y /2f + pivotOffset.y, 0f),
  145. new Vector3(size.x / 2f + pivotOffset.x, -size.y / 2f + pivotOffset.y, 0f)
  146. };
  147. mesh.uv = new Vector2[4]
  148. {
  149. new Vector2(0f, 0f),
  150. new Vector2(0f, 1f),
  151. new Vector2(1f, 1f),
  152. new Vector2(1f, 0f)
  153. };
  154. mesh.triangles = new int[6]
  155. {
  156. 0, 1, 2,
  157. 0, 2, 3
  158. };
  159. return mesh;
  160. }
  161. protected void OnRectTransformDimensionsChange()
  162. {
  163. MarkUIDirty();
  164. }
  165. protected void OnValidate()
  166. {
  167. MarkUIDirty();
  168. }
  169. }