暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

SpriteDrawUtility.cs 7.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. using System.Collections.Generic;
  2. using UnityEngine;
  3. namespace UnityEditor.UI
  4. {
  5. /// <summary>
  6. /// PropertyDrawer for [[SpriteState]].
  7. /// This is a PropertyDrawer for SpriteState it is implemented using the standard unity PropertyDrawer framework.
  8. /// </summary>
  9. internal class SpriteDrawUtility
  10. {
  11. static Texture2D s_ContrastTex;
  12. // Returns a usable texture that looks like a high-contrast checker board.
  13. static Texture2D contrastTexture
  14. {
  15. get
  16. {
  17. if (s_ContrastTex == null)
  18. s_ContrastTex = CreateCheckerTex(
  19. new Color(0f, 0.0f, 0f, 0.5f),
  20. new Color(1f, 1f, 1f, 0.5f));
  21. return s_ContrastTex;
  22. }
  23. }
  24. // Create a checker-background texture.
  25. static Texture2D CreateCheckerTex(Color c0, Color c1)
  26. {
  27. Texture2D tex = new Texture2D(16, 16);
  28. tex.name = "[Generated] Checker Texture";
  29. tex.hideFlags = HideFlags.DontSave;
  30. for (int y = 0; y < 8; ++y) for (int x = 0; x < 8; ++x) tex.SetPixel(x, y, c1);
  31. for (int y = 8; y < 16; ++y) for (int x = 0; x < 8; ++x) tex.SetPixel(x, y, c0);
  32. for (int y = 0; y < 8; ++y) for (int x = 8; x < 16; ++x) tex.SetPixel(x, y, c0);
  33. for (int y = 8; y < 16; ++y) for (int x = 8; x < 16; ++x) tex.SetPixel(x, y, c1);
  34. tex.Apply();
  35. tex.filterMode = FilterMode.Point;
  36. return tex;
  37. }
  38. // Create a gradient texture.
  39. static Texture2D CreateGradientTex()
  40. {
  41. Texture2D tex = new Texture2D(1, 16);
  42. tex.name = "[Generated] Gradient Texture";
  43. tex.hideFlags = HideFlags.DontSave;
  44. Color c0 = new Color(1f, 1f, 1f, 0f);
  45. Color c1 = new Color(1f, 1f, 1f, 0.4f);
  46. for (int i = 0; i < 16; ++i)
  47. {
  48. float f = Mathf.Abs((i / 15f) * 2f - 1f);
  49. f *= f;
  50. tex.SetPixel(0, i, Color.Lerp(c0, c1, f));
  51. }
  52. tex.Apply();
  53. tex.filterMode = FilterMode.Bilinear;
  54. return tex;
  55. }
  56. // Draws the tiled texture. Like GUI.DrawTexture() but tiled instead of stretched.
  57. static void DrawTiledTexture(Rect rect, Texture tex)
  58. {
  59. float u = rect.width / tex.width;
  60. float v = rect.height / tex.height;
  61. Rect texCoords = new Rect(0, 0, u, v);
  62. TextureWrapMode originalMode = tex.wrapMode;
  63. tex.wrapMode = TextureWrapMode.Repeat;
  64. GUI.DrawTextureWithTexCoords(rect, tex, texCoords);
  65. tex.wrapMode = originalMode;
  66. }
  67. // Draw the specified Image.
  68. public static void DrawSprite(Sprite sprite, Rect drawArea, Color color)
  69. {
  70. if (sprite == null)
  71. return;
  72. Texture2D tex = sprite.texture;
  73. if (tex == null)
  74. return;
  75. Rect outer = sprite.rect;
  76. Rect inner = outer;
  77. inner.xMin += sprite.border.x;
  78. inner.yMin += sprite.border.y;
  79. inner.xMax -= sprite.border.z;
  80. inner.yMax -= sprite.border.w;
  81. Vector4 uv4 = UnityEngine.Sprites.DataUtility.GetOuterUV(sprite);
  82. Rect uv = new Rect(uv4.x, uv4.y, uv4.z - uv4.x, uv4.w - uv4.y);
  83. Vector4 padding = UnityEngine.Sprites.DataUtility.GetPadding(sprite);
  84. padding.x /= outer.width;
  85. padding.y /= outer.height;
  86. padding.z /= outer.width;
  87. padding.w /= outer.height;
  88. DrawSprite(tex, drawArea, padding, outer, inner, uv, color, null);
  89. }
  90. // Draw the specified Image.
  91. public static void DrawSprite(Texture tex, Rect drawArea, Rect outer, Rect uv, Color color)
  92. {
  93. DrawSprite(tex, drawArea, Vector4.zero, outer, outer, uv, color, null);
  94. }
  95. // Draw the specified Image.
  96. private static void DrawSprite(Texture tex, Rect drawArea, Vector4 padding, Rect outer, Rect inner, Rect uv, Color color, Material mat)
  97. {
  98. // Create the texture rectangle that is centered inside rect.
  99. Rect outerRect = drawArea;
  100. outerRect.width = Mathf.Abs(outer.width);
  101. outerRect.height = Mathf.Abs(outer.height);
  102. if (outerRect.width > 0f)
  103. {
  104. float f = drawArea.width / outerRect.width;
  105. outerRect.width *= f;
  106. outerRect.height *= f;
  107. }
  108. if (drawArea.height > outerRect.height)
  109. {
  110. outerRect.y += (drawArea.height - outerRect.height) * 0.5f;
  111. }
  112. else if (outerRect.height > drawArea.height)
  113. {
  114. float f = drawArea.height / outerRect.height;
  115. outerRect.width *= f;
  116. outerRect.height *= f;
  117. }
  118. if (drawArea.width > outerRect.width)
  119. outerRect.x += (drawArea.width - outerRect.width) * 0.5f;
  120. // Draw the background
  121. EditorGUI.DrawTextureTransparent(outerRect, null, ScaleMode.ScaleToFit, outer.width / outer.height);
  122. // Draw the Image
  123. GUI.color = color;
  124. Rect paddedTexArea = new Rect(
  125. outerRect.x + outerRect.width * padding.x,
  126. outerRect.y + outerRect.height * padding.w,
  127. outerRect.width - (outerRect.width * (padding.z + padding.x)),
  128. outerRect.height - (outerRect.height * (padding.w + padding.y))
  129. );
  130. if (mat == null)
  131. {
  132. GUI.DrawTextureWithTexCoords(paddedTexArea, tex, uv, true);
  133. }
  134. else
  135. {
  136. // NOTE: There is an issue in Unity that prevents it from clipping the drawn preview
  137. // using BeginGroup/EndGroup, and there is no way to specify a UV rect...
  138. EditorGUI.DrawPreviewTexture(paddedTexArea, tex, mat);
  139. }
  140. // Draw the border indicator lines
  141. GUI.BeginGroup(outerRect);
  142. {
  143. tex = contrastTexture;
  144. GUI.color = Color.white;
  145. if (inner.xMin != outer.xMin)
  146. {
  147. float x = (inner.xMin - outer.xMin) / outer.width * outerRect.width - 1;
  148. DrawTiledTexture(new Rect(x, 0f, 1f, outerRect.height), tex);
  149. }
  150. if (inner.xMax != outer.xMax)
  151. {
  152. float x = (inner.xMax - outer.xMin) / outer.width * outerRect.width - 1;
  153. DrawTiledTexture(new Rect(x, 0f, 1f, outerRect.height), tex);
  154. }
  155. if (inner.yMin != outer.yMin)
  156. {
  157. // GUI.DrawTexture is top-left based rather than bottom-left
  158. float y = (inner.yMin - outer.yMin) / outer.height * outerRect.height - 1;
  159. DrawTiledTexture(new Rect(0f, outerRect.height - y, outerRect.width, 1f), tex);
  160. }
  161. if (inner.yMax != outer.yMax)
  162. {
  163. float y = (inner.yMax - outer.yMin) / outer.height * outerRect.height - 1;
  164. DrawTiledTexture(new Rect(0f, outerRect.height - y, outerRect.width, 1f), tex);
  165. }
  166. }
  167. GUI.EndGroup();
  168. }
  169. }
  170. }