SelectionTool.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEditor.U2D.Layout;
  5. using UnityEditor.U2D.Sprites;
  6. using UnityEngine;
  7. namespace UnityEditor.U2D.Animation
  8. {
  9. internal class SelectionTool : BaseTool
  10. {
  11. private bool m_ForceSelectedToSpriteEditor = false;
  12. public event Func<bool> CanSelect = () => true;
  13. private List<SpriteCache> m_Sprites;
  14. public ISpriteEditor spriteEditor { get; set; }
  15. private SpriteCache selectedSprite
  16. {
  17. get { return skinningCache.selectedSprite; }
  18. set
  19. {
  20. if (selectedSprite != value)
  21. {
  22. skinningCache.vertexSelection.Clear();
  23. if (skinningCache.mode == SkinningMode.SpriteSheet)
  24. {
  25. skinningCache.skeletonSelection.Clear();
  26. skinningCache.events.boneSelectionChanged.Invoke();
  27. }
  28. skinningCache.selectedSprite = value;
  29. SetToSpriteEditor();
  30. skinningCache.events.selectedSpriteChanged.Invoke(value);
  31. }
  32. }
  33. }
  34. private string selectedSpriteAssetID
  35. {
  36. get
  37. {
  38. var sprite = Selection.activeObject as Sprite;
  39. if (sprite != null)
  40. return sprite.GetSpriteID().ToString();
  41. return "";
  42. }
  43. }
  44. protected override void OnAfterDeserialize()
  45. {
  46. m_ForceSelectedToSpriteEditor = true;
  47. }
  48. public override void Initialize(LayoutOverlay layoutOverlay)
  49. {
  50. m_Sprites = new List<SpriteCache>(skinningCache.GetSprites());
  51. SetFromSpriteEditor();
  52. }
  53. protected override void OnActivate()
  54. {
  55. SetToSpriteEditor();
  56. skinningCache.events.selectedSpriteChanged.AddListener(OnSpriteSelectionChange);
  57. Selection.selectionChanged -= OnSelectionChanged;
  58. Selection.selectionChanged += OnSelectionChanged;
  59. }
  60. protected override void OnDeactivate()
  61. {
  62. skinningCache.events.selectedSpriteChanged.RemoveListener(OnSpriteSelectionChange);
  63. Selection.selectionChanged -= OnSelectionChanged;
  64. }
  65. private void OnSpriteSelectionChange(SpriteCache sprite)
  66. {
  67. skinningCache.events.selectedSpriteChanged.RemoveListener(OnSpriteSelectionChange);
  68. selectedSprite = sprite;
  69. skinningCache.events.selectedSpriteChanged.AddListener(OnSpriteSelectionChange);
  70. }
  71. private void OnSelectionChanged()
  72. {
  73. if (m_ForceSelectedToSpriteEditor)
  74. {
  75. SetToSpriteEditor();
  76. m_ForceSelectedToSpriteEditor = false;
  77. }
  78. else
  79. {
  80. using (skinningCache.UndoScope(TextContent.selectionChange))
  81. {
  82. SetFromSpriteEditor();
  83. }
  84. }
  85. }
  86. private void SetFromSpriteEditor()
  87. {
  88. if (selectedSprite == null)
  89. selectedSprite = skinningCache.GetSprite(selectedSpriteAssetID);
  90. spriteEditor.RequestRepaint();
  91. }
  92. private void SetToSpriteEditor()
  93. {
  94. var id = "";
  95. if (selectedSprite != null)
  96. id = selectedSprite.id;
  97. spriteEditor.selectedSpriteRect = new SpriteRect() { spriteID = new GUID(id) };
  98. }
  99. protected override void OnGUI()
  100. {
  101. HandleSpriteSelection();
  102. }
  103. private void HandleSpriteSelection()
  104. {
  105. Debug.Assert(Event.current != null);
  106. if (Event.current.type == EventType.MouseDown && Event.current.button == 0 && GUIUtility.hotControl == 0 &&
  107. !Event.current.alt && Event.current.clickCount == 2 && CanSelect())
  108. {
  109. var mousePosition = Handles.inverseMatrix.MultiplyPoint(Event.current.mousePosition);
  110. var newSelected = TrySelect(mousePosition);
  111. if (selectedSprite != newSelected)
  112. {
  113. using (skinningCache.UndoScope(TextContent.selectionChange))
  114. {
  115. selectedSprite = newSelected;
  116. }
  117. Event.current.Use();
  118. Event.current.clickCount = 0;
  119. }
  120. }
  121. }
  122. private SpriteCache TrySelect(Vector2 mousePosition)
  123. {
  124. m_Sprites.Remove(selectedSprite);
  125. if (selectedSprite != null)
  126. m_Sprites.Add(selectedSprite);
  127. var currentSelectedIndex = m_Sprites.FindIndex(x => x == selectedSprite) + 1;
  128. var notVisiblePart = skinningCache.hasCharacter && skinningCache.mode == SkinningMode.Character
  129. ? skinningCache.character.parts.Where(x => !x.isVisible).Select(x => x.sprite) : new SpriteCache[0];
  130. for (int index = 0; index < m_Sprites.Count; ++index)
  131. {
  132. var sprite = m_Sprites[(currentSelectedIndex + index) % m_Sprites.Count];
  133. var meshPreview = sprite.GetMeshPreview();
  134. if (notVisiblePart.Contains(sprite))
  135. continue;
  136. Debug.Assert(meshPreview != null);
  137. var spritePosition = sprite.GetLocalToWorldMatrixFromMode().MultiplyPoint3x4(Vector3.zero);
  138. var ray = new Ray((Vector3)mousePosition - spritePosition + Vector3.back, Vector3.forward);
  139. var bounds = meshPreview.mesh.bounds;
  140. if (sprite.GetMesh().indices.Count >= 3)
  141. {
  142. if (bounds.IntersectRay(ray))
  143. {
  144. var mesh = sprite.GetMesh();
  145. Debug.Assert(mesh != null);
  146. var indices = mesh.indices;
  147. for (var i = 0; i < indices.Count; i += 3)
  148. {
  149. var p1 = meshPreview.vertices[indices[i]];
  150. var p2 = meshPreview.vertices[indices[i + 1]];
  151. var p3 = meshPreview.vertices[indices[i + 2]];
  152. if (MathUtility.Intersect(p1, p2, p3, ray))
  153. return sprite;
  154. }
  155. }
  156. }
  157. else
  158. {
  159. if (meshPreview.defaultMesh.bounds.IntersectRay(ray))
  160. {
  161. return sprite;
  162. }
  163. }
  164. }
  165. return null;
  166. }
  167. }
  168. }