SpriteShapeEditor.cs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656
  1. using UnityEngine;
  2. using UnityEngine.U2D;
  3. using UnityEditor;
  4. using UnityEditor.AnimatedValues;
  5. using UnityEditorInternal;
  6. using UnityEditor.U2D.Common;
  7. using System.Collections.Generic;
  8. using UnityEditor.U2D.SpriteShape;
  9. namespace UnityEditor.U2D
  10. {
  11. [CustomEditor(typeof(UnityEngine.U2D.SpriteShape)), CanEditMultipleObjects]
  12. public class SpriteShapeEditor : Editor, IAngleRangeCache
  13. {
  14. private static class Contents
  15. {
  16. public static readonly GUIContent fillTextureLabel = new GUIContent("Texture", "Fill texture used for Shape Fill.");
  17. public static readonly GUIContent fillScaleLabel = new GUIContent("Offset", "Determines Border Offset for Shape.");
  18. public static readonly GUIContent useSpriteBorderLabel = new GUIContent("Use Sprite Borders", "Draw Sprite Borders on discontinuities");
  19. public static readonly GUIContent cornerTypeLabel = new GUIContent("Corner Type", "Corner type sprite used.");
  20. public static readonly GUIContent controlPointsLabel = new GUIContent("Control Points");
  21. public static readonly GUIContent fillLabel = new GUIContent("Fill");
  22. public static readonly GUIContent cornerLabel = new GUIContent("Corners");
  23. public static readonly GUIContent cornerListLabel = new GUIContent("Corner List");
  24. public static readonly GUIContent cornerSpriteTypeLabel = new GUIContent("Corner Sprite");
  25. public static readonly GUIContent angleRangesLabel = new GUIContent("Angle Ranges");
  26. public static readonly GUIContent spritesLabel = new GUIContent("Sprites");
  27. public static readonly GUIContent angleRangeLabel = new GUIContent("Angle Range ({0})");
  28. public static readonly GUIContent wrapModeErrorLabel = new GUIContent("Fill texture must have wrap modes set to Repeat. Please re-import.");
  29. public static readonly Color proBackgroundColor = new Color32(49, 77, 121, 255);
  30. public static readonly Color proBackgroundRangeColor = new Color32(25, 25, 25, 128);
  31. public static readonly Color proColor1 = new Color32(10, 46, 42, 255);
  32. public static readonly Color proColor2 = new Color32(33, 151, 138, 255);
  33. public static readonly Color defaultColor1 = new Color32(25, 61, 57, 255);
  34. public static readonly Color defaultColor2 = new Color32(47, 166, 153, 255);
  35. public static readonly Color defaultBackgroundColor = new Color32(64, 92, 136, 255);
  36. }
  37. private SerializedProperty m_FillTextureProp;
  38. private SerializedProperty m_AngleRangesProp;
  39. private SerializedProperty m_CornerSpritesProp;
  40. private SerializedProperty m_FillOffsetProp;
  41. private SerializedProperty m_UseSpriteBordersProp;
  42. private ReorderableList m_AngleRangeSpriteList = null;
  43. private ReorderableList m_EmptySpriteList = null;
  44. [SerializeField]
  45. private float m_PreviewAngle = 0f;
  46. [SerializeField]
  47. private int m_SelectedIndex;
  48. private const int kInvalidMinimum = -1;
  49. private Rect m_AngleRangeRect;
  50. private AngleRangeController controller;
  51. private AngleRange m_CurrentAngleRange;
  52. private Dictionary<int, int> m_SpriteSelection = new Dictionary<int, int>();
  53. private Sprite m_PreviewSprite;
  54. private Mesh m_PreviewSpriteMesh;
  55. private Mesh previewSpriteMesh
  56. {
  57. get
  58. {
  59. if (m_PreviewSpriteMesh == null)
  60. {
  61. m_PreviewSpriteMesh = new Mesh();
  62. m_PreviewSpriteMesh.MarkDynamic();
  63. m_PreviewSpriteMesh.hideFlags = HideFlags.DontSave;
  64. }
  65. return m_PreviewSpriteMesh;
  66. }
  67. }
  68. public List<AngleRange> angleRanges
  69. {
  70. get
  71. {
  72. if (spriteShape == null)
  73. return new List<AngleRange>();
  74. Debug.Assert(spriteShape != null);
  75. return spriteShape.angleRanges;
  76. }
  77. }
  78. public int selectedIndex
  79. {
  80. get { return m_SelectedIndex; }
  81. set { m_SelectedIndex = value; }
  82. }
  83. bool isSelectedIndexValid
  84. {
  85. get { return (selectedIndex != kInvalidMinimum && selectedIndex < angleRanges.Count); }
  86. }
  87. public float previewAngle
  88. {
  89. get { return m_PreviewAngle; }
  90. set
  91. {
  92. m_PreviewAngle = value;
  93. SessionState.SetFloat("SpriteShape/PreviewAngle/" + target.GetInstanceID(), value);
  94. }
  95. }
  96. public UnityEngine.U2D.SpriteShape spriteShape
  97. {
  98. get
  99. {
  100. if (target == null)
  101. return null;
  102. return target as UnityEngine.U2D.SpriteShape;
  103. }
  104. }
  105. public void RegisterUndo(string name)
  106. {
  107. Undo.RegisterCompleteObjectUndo(spriteShape, name);
  108. Undo.RegisterCompleteObjectUndo(this, name);
  109. EditorUtility.SetDirty(spriteShape);
  110. }
  111. public void OnEnable()
  112. {
  113. if (targets == null || targets.Length == 0)
  114. return;
  115. m_PreviewAngle = SessionState.GetFloat("SpriteShape/PreviewAngle/" + target.GetInstanceID(), m_PreviewAngle);
  116. m_FillTextureProp = this.serializedObject.FindProperty("m_FillTexture");
  117. m_UseSpriteBordersProp = serializedObject.FindProperty("m_UseSpriteBorders");
  118. m_AngleRangesProp = this.serializedObject.FindProperty("m_Angles");
  119. m_CornerSpritesProp = this.serializedObject.FindProperty("m_CornerSprites");
  120. m_FillOffsetProp = this.serializedObject.FindProperty("m_FillOffset");
  121. selectedIndex = SpriteShapeEditorUtility.GetRangeIndexFromAngle(angleRanges, m_PreviewAngle);
  122. SetupAngleRangeController();
  123. Undo.undoRedoPerformed += UndoRedoPerformed;
  124. }
  125. public override bool RequiresConstantRepaint()
  126. {
  127. return true;
  128. }
  129. private void SetupAngleRangeController()
  130. {
  131. var radius = 125f;
  132. var angleOffset = -90f;
  133. var color1 = Contents.defaultColor1;
  134. var color2 = Contents.defaultColor2;
  135. if (!EditorGUIUtility.isProSkin)
  136. {
  137. color1 = Contents.proColor1;
  138. color2 = Contents.proColor2;
  139. }
  140. controller = new AngleRangeController();
  141. controller.view = new AngleRangeView();
  142. controller.cache = this;
  143. controller.radius = radius;
  144. controller.angleOffset = angleOffset;
  145. controller.gradientMin = color1;
  146. controller.gradientMid = color2;
  147. controller.gradientMax = color1;
  148. controller.snap = true;
  149. controller.selectionChanged += OnSelectionChange;
  150. OnSelectionChange();
  151. }
  152. private void OnSelectionChange()
  153. {
  154. CreateReorderableSpriteList();
  155. EditorApplication.delayCall += () =>
  156. {
  157. m_CurrentAngleRange = controller.selectedAngleRange;
  158. };
  159. }
  160. private void OnDestroy()
  161. {
  162. if (m_PreviewSpriteMesh)
  163. Object.DestroyImmediate(m_PreviewSpriteMesh);
  164. Undo.undoRedoPerformed -= UndoRedoPerformed;
  165. }
  166. private void UndoRedoPerformed()
  167. {
  168. OnSelectionChange();
  169. }
  170. private void OnSelelectSpriteCallback(ReorderableList list)
  171. {
  172. if (selectedIndex >= 0)
  173. {
  174. SetPreviewSpriteIndex(selectedIndex, list.index);
  175. }
  176. }
  177. private bool OnCanAddCallback(ReorderableList list)
  178. {
  179. return (list.count < 64);
  180. }
  181. private void OnRemoveSprite(ReorderableList list)
  182. {
  183. var count = list.count;
  184. var index = list.index;
  185. ReorderableList.defaultBehaviours.DoRemoveButton(list);
  186. if (list.count < count && list.count > 0)
  187. {
  188. list.index = Mathf.Clamp(index, 0, list.count - 1);
  189. OnSelelectSpriteCallback(list);
  190. }
  191. }
  192. private void DrawSpriteListHeader(Rect rect)
  193. {
  194. EditorGUI.LabelField(rect, Contents.spritesLabel);
  195. HandleAngleSpriteListGUI(rect);
  196. }
  197. private void DrawSpriteListElement(Rect rect, int index, bool selected, bool focused)
  198. {
  199. rect.y += 2f;
  200. rect.height = EditorGUIUtility.singleLineHeight;
  201. var sprite = m_AngleRangesProp.GetArrayElementAtIndex(selectedIndex).FindPropertyRelative("m_Sprites").GetArrayElementAtIndex(index);
  202. EditorGUI.BeginChangeCheck();
  203. EditorGUI.PropertyField(rect, sprite, GUIContent.none);
  204. if (EditorGUI.EndChangeCheck())
  205. {
  206. m_AngleRangeSpriteList.index = index;
  207. OnSelelectSpriteCallback(m_AngleRangeSpriteList);
  208. }
  209. }
  210. public void DrawHeader(GUIContent content)
  211. {
  212. EditorGUILayout.LabelField(content, EditorStyles.boldLabel);
  213. }
  214. private void SetPreviewSpriteIndex(int rangeIndex, int index)
  215. {
  216. m_SpriteSelection[rangeIndex] = index;
  217. }
  218. private int GetPreviewSpriteIndex(int rangeIndex)
  219. {
  220. int index;
  221. m_SpriteSelection.TryGetValue(rangeIndex, out index);
  222. return index;
  223. }
  224. public override void OnInspectorGUI()
  225. {
  226. serializedObject.Update();
  227. EditorGUILayout.Space();
  228. DrawHeader(Contents.controlPointsLabel);
  229. EditorGUILayout.PropertyField(m_UseSpriteBordersProp, Contents.useSpriteBorderLabel);
  230. EditorGUILayout.Space();
  231. DrawHeader(Contents.fillLabel);
  232. EditorGUILayout.PropertyField(m_FillTextureProp, Contents.fillTextureLabel);
  233. EditorGUILayout.Slider(m_FillOffsetProp, -0.5f, 0.5f, Contents.fillScaleLabel);
  234. if (m_FillTextureProp.objectReferenceValue != null)
  235. {
  236. var fillTex = m_FillTextureProp.objectReferenceValue as Texture2D;
  237. if (fillTex.wrapModeU != TextureWrapMode.Repeat || fillTex.wrapModeV != TextureWrapMode.Repeat)
  238. EditorGUILayout.HelpBox(Contents.wrapModeErrorLabel.text, MessageType.Warning);
  239. }
  240. EditorGUILayout.Space();
  241. DrawHeader(Contents.angleRangesLabel);
  242. DoRangesGUI();
  243. if (targets.Length == 1)
  244. {
  245. DoRangeInspector();
  246. DoCreateRangeButton();
  247. }
  248. EditorGUILayout.Space();
  249. DrawHeader(Contents.cornerLabel);
  250. HashSet<Sprite> tightMeshSprites = new HashSet<Sprite>();
  251. for (int i = 0; i < angleRanges.Count; ++i)
  252. {
  253. AngleRange angleRange = angleRanges[i];
  254. foreach (Sprite sprite in angleRange.sprites)
  255. {
  256. if (sprite != null)
  257. {
  258. string assetPath = AssetDatabase.GetAssetPath(sprite);
  259. TextureImporter importer = AssetImporter.GetAtPath(assetPath) as TextureImporter;
  260. if (importer != null)
  261. {
  262. TextureImporterSettings textureSettings = new TextureImporterSettings();
  263. importer.ReadTextureSettings(textureSettings);
  264. if (textureSettings.spriteMeshType == SpriteMeshType.Tight)
  265. tightMeshSprites.Add(sprite);
  266. }
  267. }
  268. }
  269. }
  270. EditorGUIUtility.labelWidth = EditorGUIUtility.labelWidth + 20f;
  271. for (int i = 0; i < m_CornerSpritesProp.arraySize; ++i)
  272. {
  273. var m_CornerProp = m_CornerSpritesProp.GetArrayElementAtIndex(i);
  274. var m_CornerType = m_CornerProp.FindPropertyRelative("m_CornerType");
  275. var m_CornerSprite = m_CornerProp.FindPropertyRelative("m_Sprites").GetArrayElementAtIndex(0);
  276. EditorGUILayout.PropertyField(m_CornerSprite, new GUIContent(m_CornerType.enumDisplayNames[m_CornerType.intValue]));
  277. var sprite = m_CornerSprite.objectReferenceValue as Sprite;
  278. if (sprite != null)
  279. {
  280. string assetPath = AssetDatabase.GetAssetPath(sprite);
  281. TextureImporter importer = AssetImporter.GetAtPath(assetPath) as TextureImporter;
  282. if (importer != null)
  283. {
  284. TextureImporterSettings textureSettings = new TextureImporterSettings();
  285. importer.ReadTextureSettings(textureSettings);
  286. if (textureSettings.spriteMeshType == SpriteMeshType.Tight)
  287. tightMeshSprites.Add(sprite);
  288. }
  289. }
  290. }
  291. EditorGUIUtility.labelWidth = 0;
  292. serializedObject.ApplyModifiedProperties();
  293. if (tightMeshSprites.Count > 0)
  294. {
  295. int i = 0;
  296. string tightSpriteWarning = "The following sprites ( ";
  297. foreach (var sprite in tightMeshSprites)
  298. {
  299. string appendString = (i < tightMeshSprites.Count - 1) ? ", " : " ) ";
  300. tightSpriteWarning += (sprite.name + appendString);
  301. ++i;
  302. }
  303. tightSpriteWarning += "are imported as Sprites using Tight mesh. This can lead to Rendering Artifacts. Please use Full Rect.";
  304. EditorGUILayout.HelpBox(tightSpriteWarning, MessageType.Warning);
  305. }
  306. controller.view.DoCreateRangeTooltip();
  307. }
  308. private void DoRangeInspector()
  309. {
  310. var start = 0f;
  311. var end = 0f;
  312. var order = 0;
  313. if (m_CurrentAngleRange != null)
  314. {
  315. start = m_CurrentAngleRange.start;
  316. end = m_CurrentAngleRange.end;
  317. order = m_CurrentAngleRange.order;
  318. }
  319. using (new EditorGUI.DisabledGroupScope(m_CurrentAngleRange == null))
  320. {
  321. DrawHeader(new GUIContent(string.Format(Contents.angleRangeLabel.text, (end - start))));
  322. EditorGUIUtility.labelWidth = 0f;
  323. EditorGUI.BeginChangeCheck();
  324. RangeField(ref start, ref end, ref order);
  325. if (EditorGUI.EndChangeCheck() && m_CurrentAngleRange != null)
  326. {
  327. RegisterUndo("Set Range");
  328. m_CurrentAngleRange.order = order;
  329. controller.SetRange(m_CurrentAngleRange, start, end);
  330. if (start >= end)
  331. controller.RemoveInvalidRanges();
  332. }
  333. EditorGUILayout.Space();
  334. var arSize = m_AngleRangesProp.arraySize;
  335. if (m_AngleRangeSpriteList != null && arSize > 0)
  336. m_AngleRangeSpriteList.DoLayoutList();
  337. else
  338. m_EmptySpriteList.DoLayoutList();
  339. }
  340. }
  341. private void DoCreateRangeButton()
  342. {
  343. if (selectedIndex != kInvalidMinimum && angleRanges.Count != 0)
  344. return;
  345. EditorGUILayout.BeginHorizontal();
  346. GUILayout.FlexibleSpace();
  347. if (GUILayout.Button("Create Range", GUILayout.MaxWidth(100f)))
  348. {
  349. RegisterUndo("Create Range");
  350. controller.CreateRange();
  351. }
  352. GUILayout.FlexibleSpace();
  353. EditorGUILayout.EndHorizontal();
  354. }
  355. private void RangeField(ref float start, ref float end, ref int order)
  356. {
  357. var values = new int[] { Mathf.RoundToInt(-start), Mathf.RoundToInt(-end), order };
  358. var labels = new GUIContent[] { new GUIContent("Start"), new GUIContent("End"), new GUIContent("Order") };
  359. var position = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight);
  360. EditorGUI.BeginChangeCheck();
  361. SpriteShapeEditorGUI.MultiDelayedIntField(position, labels, values, 40f);
  362. if (EditorGUI.EndChangeCheck())
  363. {
  364. start = -1f * values[0];
  365. end = -1f * values[1];
  366. order = values[2];
  367. }
  368. }
  369. private void HandleAngleSpriteListGUI(Rect rect)
  370. {
  371. if (m_CurrentAngleRange == null || !isSelectedIndexValid)
  372. return;
  373. var currentEvent = Event.current;
  374. var usedEvent = false;
  375. var sprites = m_AngleRangesProp.GetArrayElementAtIndex(selectedIndex).FindPropertyRelative("m_Sprites");
  376. switch (currentEvent.type)
  377. {
  378. case EventType.DragExited:
  379. if (GUI.enabled)
  380. HandleUtility.Repaint();
  381. break;
  382. case EventType.DragUpdated:
  383. case EventType.DragPerform:
  384. if (rect.Contains(currentEvent.mousePosition) && GUI.enabled)
  385. {
  386. // Check each single object, so we can add multiple objects in a single drag.
  387. var didAcceptDrag = false;
  388. var references = DragAndDrop.objectReferences;
  389. foreach (var obj in references)
  390. {
  391. if (obj is Sprite)
  392. {
  393. Sprite spr = obj as Sprite;
  394. if (spr.texture != null)
  395. {
  396. DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
  397. if (currentEvent.type == EventType.DragPerform && sprites.arraySize < 64)
  398. {
  399. sprites.InsertArrayElementAtIndex(sprites.arraySize);
  400. var spriteProp = sprites.GetArrayElementAtIndex(sprites.arraySize - 1);
  401. spriteProp.objectReferenceValue = obj;
  402. didAcceptDrag = true;
  403. DragAndDrop.activeControlID = 0;
  404. }
  405. }
  406. }
  407. }
  408. serializedObject.ApplyModifiedProperties();
  409. if (didAcceptDrag)
  410. {
  411. GUI.changed = true;
  412. DragAndDrop.AcceptDrag();
  413. usedEvent = true;
  414. }
  415. }
  416. break;
  417. }
  418. if (usedEvent)
  419. currentEvent.Use();
  420. }
  421. private void DoRangesGUI()
  422. {
  423. var radius = controller.radius;
  424. EditorGUILayout.Space();
  425. EditorGUILayout.Space();
  426. var rect = EditorGUILayout.GetControlRect(false, radius * 2f);
  427. if (Event.current.type == EventType.Repaint)
  428. m_AngleRangeRect = rect;
  429. { //Draw background
  430. var backgroundColor = Contents.proBackgroundColor;
  431. var backgroundRangeColor = Contents.proBackgroundRangeColor;
  432. if (!EditorGUIUtility.isProSkin)
  433. {
  434. backgroundColor = Contents.defaultBackgroundColor;
  435. backgroundRangeColor.a = 0.1f;
  436. }
  437. var c = Handles.color;
  438. Handles.color = backgroundRangeColor;
  439. SpriteShapeHandleUtility.DrawSolidArc(rect.center, Vector3.forward, Vector3.right, 360f, radius, AngleRangeGUI.kRangeWidth);
  440. Handles.color = backgroundColor;
  441. Handles.DrawSolidDisc(rect.center, Vector3.forward, radius - AngleRangeGUI.kRangeWidth + 1f);
  442. Handles.color = c;
  443. }
  444. if (targets.Length == 1)
  445. {
  446. { //Draw fill texture and sprite preview
  447. SpriteShapeHandleUtility.DrawTextureArc(
  448. m_FillTextureProp.objectReferenceValue as Texture, 100.0f,
  449. rect.center, Vector3.forward, Quaternion.AngleAxis(m_PreviewAngle, Vector3.forward) * Vector3.right, 180f,
  450. radius - AngleRangeGUI.kRangeWidth);
  451. var rectSize = Vector2.one * (radius - AngleRangeGUI.kRangeWidth) * 2f;
  452. rectSize.y *= 0.33f;
  453. var spriteRect = new Rect(rect.center - rectSize * 0.5f, rectSize);
  454. DrawSpritePreview(spriteRect);
  455. HandleSpritePreviewCycle(spriteRect);
  456. }
  457. controller.rect = m_AngleRangeRect;
  458. controller.OnGUI();
  459. }
  460. EditorGUILayout.Space();
  461. EditorGUILayout.Space();
  462. }
  463. private void CreateReorderableSpriteList()
  464. {
  465. if (m_EmptySpriteList == null)
  466. {
  467. m_EmptySpriteList = new ReorderableList(new List<Sprite>(), typeof(Sprite), false, true, false, false)
  468. {
  469. drawHeaderCallback = (Rect rect) => { EditorGUI.LabelField(rect, Contents.spritesLabel); }
  470. };
  471. }
  472. m_AngleRangeSpriteList = null;
  473. serializedObject.UpdateIfRequiredOrScript();
  474. Debug.Assert(angleRanges.Count == m_AngleRangesProp.arraySize);
  475. Debug.Assert(selectedIndex < angleRanges.Count || selectedIndex == 0);
  476. if (targets.Length == 1 && isSelectedIndexValid)
  477. {
  478. var spritesProp = m_AngleRangesProp.GetArrayElementAtIndex(selectedIndex).FindPropertyRelative("m_Sprites");
  479. m_AngleRangeSpriteList = new ReorderableList(spritesProp.serializedObject, spritesProp)
  480. {
  481. drawElementCallback = DrawSpriteListElement,
  482. drawHeaderCallback = DrawSpriteListHeader,
  483. onSelectCallback = OnSelelectSpriteCallback,
  484. onRemoveCallback = OnRemoveSprite,
  485. onCanAddCallback = OnCanAddCallback,
  486. elementHeight = EditorGUIUtility.singleLineHeight + 6f
  487. };
  488. }
  489. }
  490. private void DrawSpritePreview(Rect rect)
  491. {
  492. if (Event.current.type != EventType.Repaint)
  493. return;
  494. if (!isSelectedIndexValid)
  495. return;
  496. var sprites = angleRanges[selectedIndex].sprites;
  497. if (sprites.Count == 0)
  498. return;
  499. var selectedSpriteIndex = GetPreviewSpriteIndex(selectedIndex);
  500. if (selectedSpriteIndex == kInvalidMinimum || selectedSpriteIndex >= sprites.Count)
  501. return;
  502. var sprite = sprites[selectedSpriteIndex];
  503. if (sprite == null)
  504. return;
  505. if (m_PreviewSprite != sprite)
  506. {
  507. m_PreviewSprite = sprite;
  508. EditorSpriteGUIUtility.DrawSpriteInRectPrepare(rect, sprite, EditorSpriteGUIUtility.FitMode.Tiled, true, true, previewSpriteMesh);
  509. }
  510. var material = EditorSpriteGUIUtility.spriteMaterial;
  511. material.mainTexture = EditorSpriteGUIUtility.GetOriginalSpriteTexture(sprite);
  512. EditorSpriteGUIUtility.DrawMesh(previewSpriteMesh, material, rect.center, Quaternion.AngleAxis(m_PreviewAngle, Vector3.forward), new Vector3(1f, -1f, 1f));
  513. }
  514. private void HandleSpritePreviewCycle(Rect rect)
  515. {
  516. if (!isSelectedIndexValid)
  517. return;
  518. Debug.Assert(m_AngleRangeSpriteList != null);
  519. var spriteIndex = GetPreviewSpriteIndex(selectedIndex);
  520. var sprites = angleRanges[selectedIndex].sprites;
  521. var ev = Event.current;
  522. if (ev.type == EventType.MouseDown && ev.button == 0 && HandleUtility.nearestControl == 0 &&
  523. ContainsPosition(rect, ev.mousePosition, m_PreviewAngle) && spriteIndex != kInvalidMinimum && sprites.Count > 0)
  524. {
  525. spriteIndex = Mathf.RoundToInt(Mathf.Repeat(spriteIndex + 1f, sprites.Count));
  526. SetPreviewSpriteIndex(selectedIndex, spriteIndex);
  527. m_AngleRangeSpriteList.GrabKeyboardFocus();
  528. m_AngleRangeSpriteList.index = spriteIndex;
  529. ev.Use();
  530. }
  531. }
  532. private bool ContainsPosition(Rect rect, Vector2 position, float angle)
  533. {
  534. Vector2 delta = position - rect.center;
  535. position = (Vector2)(Quaternion.AngleAxis(-angle, Vector3.forward) * (Vector3)delta) + rect.center;
  536. return rect.Contains(position);
  537. }
  538. }
  539. }