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