暫無描述
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.

EditorSpriteGUIUtility.cs 9.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. using UnityEditor;
  2. using UnityEngine;
  3. using UnityEditor.Sprites;
  4. using System.Collections;
  5. using System.Collections.Generic;
  6. namespace UnityEditor.U2D
  7. {
  8. internal static class EditorSpriteGUIUtility
  9. {
  10. public enum FitMode
  11. {
  12. BestFit,
  13. FitHorizontal,
  14. FitVertical,
  15. Fill,
  16. Tiled
  17. }
  18. private static Material s_SpriteMaterial;
  19. public static Material spriteMaterial
  20. {
  21. get
  22. {
  23. if (s_SpriteMaterial == null)
  24. {
  25. s_SpriteMaterial = new Material(Shader.Find("Hidden/InternalSpritesInspector"));
  26. s_SpriteMaterial.hideFlags = HideFlags.DontSave;
  27. }
  28. s_SpriteMaterial.SetFloat("_AdjustLinearForGamma", PlayerSettings.colorSpace == ColorSpace.Linear ? 1.0f : 0.0f);
  29. return s_SpriteMaterial;
  30. }
  31. }
  32. public static Texture GetOriginalSpriteTexture(Sprite sprite)
  33. {
  34. return UnityEditor.Sprites.SpriteUtility.GetSpriteTexture(sprite, false);
  35. }
  36. public static Vector2[] GetOriginalSpriteUvs(Sprite sprite)
  37. {
  38. return UnityEditor.Sprites.SpriteUtility.GetSpriteUVs(sprite, false);
  39. }
  40. public static void DrawSpriteInRectPrepare(Rect rect, Sprite sprite, FitMode fitMode, bool excludeBorders, bool forceQuad, Mesh mesh)
  41. {
  42. var vertices = new List<Vector3>();
  43. var uvs = new List<Vector2>();
  44. var indices = new List<int>();
  45. mesh.Clear();
  46. if (!sprite)
  47. {
  48. mesh.UploadMeshData(false);
  49. return;
  50. }
  51. Vector2 scale = Vector2.one;
  52. Rect spriteRect = sprite.textureRect;
  53. Vector2 bottomLeftBorderOffset = sprite.rect.position + new Vector2(sprite.border.x, sprite.border.y) - spriteRect.position;
  54. Vector2 topRightBorderOffset = new Vector2(sprite.border.z, sprite.border.w) + (spriteRect.position + spriteRect.size) - (sprite.rect.position + sprite.rect.size);
  55. if (excludeBorders)
  56. {
  57. forceQuad = true;
  58. spriteRect.position = spriteRect.position + bottomLeftBorderOffset;
  59. spriteRect.size = spriteRect.size - bottomLeftBorderOffset - topRightBorderOffset;
  60. }
  61. bool tiled = false;
  62. if (fitMode == FitMode.Tiled)
  63. {
  64. tiled = true;
  65. forceQuad = true;
  66. fitMode = FitMode.BestFit;
  67. }
  68. if (fitMode == FitMode.BestFit)
  69. {
  70. float spriteRatio = spriteRect.width / spriteRect.height;
  71. float frameRatio = rect.width / rect.height;
  72. if (spriteRatio < frameRatio)
  73. fitMode = FitMode.FitVertical;
  74. else
  75. fitMode = FitMode.FitHorizontal;
  76. }
  77. if (fitMode == FitMode.FitHorizontal)
  78. scale = Vector2.one * (rect.width / spriteRect.width);
  79. if (fitMode == FitMode.FitVertical)
  80. scale = Vector2.one * (rect.height / spriteRect.height);
  81. if (fitMode == FitMode.Fill)
  82. {
  83. scale.x = rect.width / spriteRect.width;
  84. scale.y = rect.height / spriteRect.height;
  85. }
  86. Texture spriteTexture = GetOriginalSpriteTexture(sprite);
  87. if (spriteTexture == null)
  88. return;
  89. if (forceQuad)
  90. {
  91. Vector2 uvScale = new Vector2(1f / spriteTexture.width, 1f / spriteTexture.height);
  92. Vector2 uvPos = Vector2.Scale(spriteRect.position, uvScale);
  93. Vector2 uvSize = Vector2.Scale(spriteRect.size, uvScale);
  94. Vector2 uv0 = uvPos;
  95. Vector2 uv1 = uvPos + Vector2.up * uvSize.y;
  96. Vector2 uv2 = uvPos + Vector2.right * uvSize.x;
  97. Vector2 uv3 = uvPos + uvSize;
  98. Vector3 v0 = new Vector3(uv0.x * spriteTexture.width - spriteRect.position.x - spriteRect.width * 0.5f, uv0.y * spriteTexture.height - spriteRect.position.y - spriteRect.height * 0.5f, 0f);
  99. Vector3 v1 = new Vector3(uv1.x * spriteTexture.width - spriteRect.position.x - spriteRect.width * 0.5f, uv1.y * spriteTexture.height - spriteRect.position.y - spriteRect.height * 0.5f, 0f);
  100. Vector3 v2 = new Vector3(uv2.x * spriteTexture.width - spriteRect.position.x - spriteRect.width * 0.5f, uv2.y * spriteTexture.height - spriteRect.position.y - spriteRect.height * 0.5f, 0f);
  101. Vector3 v3 = new Vector3(uv3.x * spriteTexture.width - spriteRect.position.x - spriteRect.width * 0.5f, uv3.y * spriteTexture.height - spriteRect.position.y - spriteRect.height * 0.5f, 0f);
  102. v0 = Vector3.Scale(v0, scale);
  103. v1 = Vector3.Scale(v1, scale);
  104. v2 = Vector3.Scale(v2, scale);
  105. v3 = Vector3.Scale(v3, scale);
  106. //TODO: Support vertical tiling when horizontal fitted
  107. if (tiled && fitMode == FitMode.FitVertical)
  108. {
  109. Vector2 scaledRectSize = Vector2.Scale(rect.size, new Vector2(1f / scale.x, 1f / scale.y));
  110. float halfDistanceToFill = (scaledRectSize.x - spriteRect.width) * 0.5f;
  111. int halfFillSegmentCount = (int)Mathf.Ceil(halfDistanceToFill / spriteRect.width);
  112. int segmentCount = halfFillSegmentCount * 2 + 1;
  113. int vertexCount = segmentCount * 4;
  114. vertices.Capacity = vertexCount;
  115. uvs.Capacity = vertexCount;
  116. indices.Capacity = vertexCount;
  117. Vector3 offset = Vector3.zero;
  118. Vector3 offsetStep = Vector3.Scale(Vector3.right * spriteRect.width, scale);
  119. float distanceStep = spriteRect.width;
  120. float distanceToFill = halfDistanceToFill + distanceStep;
  121. int vertexIndex = 0;
  122. for (int i = 0; i <= halfFillSegmentCount; ++i)
  123. {
  124. float t = Mathf.Clamp01(distanceToFill / spriteRect.width);
  125. uvs.Add(uv0);
  126. uvs.Add(uv1);
  127. uvs.Add(Vector3.Lerp(uv0, uv2, t));
  128. uvs.Add(Vector3.Lerp(uv1, uv3, t));
  129. vertices.Add(v0 + offset);
  130. vertices.Add(v1 + offset);
  131. vertices.Add(Vector3.Lerp(v0, v2, t) + offset);
  132. vertices.Add(Vector3.Lerp(v1, v3, t) + offset);
  133. indices.Add(vertexIndex);
  134. indices.Add(vertexIndex + 2);
  135. indices.Add(vertexIndex + 1);
  136. indices.Add(vertexIndex + 2);
  137. indices.Add(vertexIndex + 3);
  138. indices.Add(vertexIndex + 1);
  139. vertexIndex += 4;
  140. if (i > 0)
  141. {
  142. uvs.Add(Vector2.Lerp(uv0, uv2, 1f - t));
  143. uvs.Add(Vector2.Lerp(uv1, uv3, 1f - t));
  144. uvs.Add(uv2);
  145. uvs.Add(uv3);
  146. vertices.Add(Vector3.Lerp(v0, v2, 1f - t) - offset);
  147. vertices.Add(Vector3.Lerp(v1, v3, 1f - t) - offset);
  148. vertices.Add(v2 - offset);
  149. vertices.Add(v3 - offset);
  150. indices.Add(vertexIndex);
  151. indices.Add(vertexIndex + 2);
  152. indices.Add(vertexIndex + 1);
  153. indices.Add(vertexIndex + 2);
  154. indices.Add(vertexIndex + 3);
  155. indices.Add(vertexIndex + 1);
  156. vertexIndex += 4;
  157. }
  158. offset += offsetStep;
  159. distanceToFill -= distanceStep;
  160. }
  161. }
  162. else
  163. {
  164. vertices.AddRange(new Vector3[] { v0, v1, v2, v3 });
  165. uvs.AddRange(new Vector2[] { uv0, uv1, uv2, uv3 });
  166. indices.AddRange(new int[] { 0, 2, 1, 2, 3, 1 });
  167. }
  168. }
  169. else
  170. {
  171. ushort[] triangles = sprite.triangles;
  172. indices.Capacity = triangles.Length;
  173. for (int i = 0; i < triangles.Length; ++i)
  174. indices.Add((int)triangles[i]);
  175. uvs.AddRange(GetOriginalSpriteUvs(sprite));
  176. vertices.Capacity = uvs.Count;
  177. for (int i = 0; i < uvs.Count; ++i)
  178. {
  179. Vector3 v = new Vector3(uvs[i].x * spriteTexture.width - spriteRect.position.x - spriteRect.width * 0.5f, uvs[i].y * spriteTexture.height - spriteRect.position.y - spriteRect.height * 0.5f, 0f);
  180. vertices.Add(Vector3.Scale(v, scale));
  181. }
  182. }
  183. mesh.SetVertices(vertices);
  184. mesh.SetUVs(0, uvs);
  185. mesh.SetTriangles(indices, 0);
  186. mesh.UploadMeshData(false);
  187. }
  188. public static void DrawMesh(Mesh mesh, Material material, Vector3 position, Quaternion rotation, Vector3 scale)
  189. {
  190. if (Event.current.type != EventType.Repaint)
  191. return;
  192. Matrix4x4 matrix = new Matrix4x4();
  193. matrix.SetTRS(position, rotation, scale);
  194. material.SetPass(0);
  195. Graphics.DrawMeshNow(mesh, matrix);
  196. }
  197. }
  198. }