A game about forced loneliness, made by TACStudios
at master 611 lines 25 kB view raw
1using UnityEngine; 2using System; 3using System.Linq; 4using System.Collections.Generic; 5using UnityEditor.U2D.Sprites; 6 7namespace UnityEditor.U2D.Animation 8{ 9 [RequireSpriteDataProvider(typeof(ISpriteMeshDataProvider), typeof(ISpriteBoneDataProvider))] 10 internal partial class SkinningModule : SpriteEditorModuleBase 11 { 12 private static class Styles 13 { 14 public static string moduleName = L10n.Tr("Skinning Editor"); 15 } 16 17 private SkinningCache m_SkinningCache; 18 private int m_PrevNearestControl = -1; 19 private SpriteOutlineRenderer m_SpriteOutlineRenderer; 20 private MeshPreviewTool m_MeshPreviewTool; 21 private SkinningMode m_PreviousSkinningMode; 22 private SpriteBoneInfluenceTool m_CharacterSpriteTool; 23 private HorizontalToggleTools m_HorizontalToggleTools; 24 private AnimationAnalytics m_Analytics; 25 private ModuleToolGroup m_ModuleToolGroup; 26 IMeshPreviewBehaviour m_MeshPreviewBehaviourOverride = null; 27 bool m_CollapseToolbar; 28 bool m_HasUnsavedChanges = false; 29 Texture2D m_WorkspaceBackgroundTexture; 30 31 internal SkinningCache skinningCache 32 { 33 get { return m_SkinningCache; } 34 } 35 36 private BaseTool currentTool 37 { 38 get { return skinningCache.selectedTool; } 39 set { skinningCache.selectedTool = value; } 40 } 41 42 private BaseTool previousTool { get; set; } 43 44 public override string moduleName 45 { 46 get { return Styles.moduleName; } 47 } 48 49 public override void OnModuleActivate() 50 { 51 m_SkinningCache = Cache.Create<SkinningCache>(); 52 m_WorkspaceBackgroundTexture = new Texture2D(1, 1, TextureFormat.RGBAHalf, false, true); 53 54 m_WorkspaceBackgroundTexture.hideFlags = HideFlags.HideAndDontSave; 55 m_WorkspaceBackgroundTexture.SetPixel(1, 1, new Color(0, 0, 0, 0)); 56 m_WorkspaceBackgroundTexture.Apply(); 57 58 AddMainUI(spriteEditor.GetMainVisualContainer()); 59 60 using (skinningCache.DisableUndoScope()) 61 { 62 skinningCache.Create(spriteEditor.GetDataProvider<ISpriteEditorDataProvider>(), SkinningCachePersistentState.instance); 63 skinningCache.CreateToolCache(spriteEditor, m_LayoutOverlay); 64 m_CharacterSpriteTool = skinningCache.CreateTool<SpriteBoneInfluenceTool>(); 65 m_CharacterSpriteTool.Initialize(m_LayoutOverlay); 66 m_MeshPreviewTool = skinningCache.CreateTool<MeshPreviewTool>(); 67 SetupModuleToolGroup(); 68 m_MeshPreviewTool.Activate(); 69 70 m_SpriteOutlineRenderer = new SpriteOutlineRenderer(skinningCache.events); 71 72 spriteEditor.enableMouseMoveEvent = true; 73 EditorApplication.playModeStateChanged += PlayModeStateChanged; 74 75 Undo.undoRedoPerformed += UndoRedoPerformed; 76 skinningCache.events.skeletonTopologyChanged.AddListener(SkeletonTopologyChanged); 77 skinningCache.events.skeletonPreviewPoseChanged.AddListener(SkeletonPreviewPoseChanged); 78 skinningCache.events.skeletonBindPoseChanged.AddListener(SkeletonBindPoseChanged); 79 skinningCache.events.characterPartChanged.AddListener(CharacterPartChanged); 80 skinningCache.events.skinningModeChanged.AddListener(OnViewModeChanged); 81 skinningCache.events.meshChanged.AddListener(OnMeshChanged); 82 skinningCache.events.boneNameChanged.AddListener(OnBoneNameChanged); 83 skinningCache.events.boneDepthChanged.AddListener(OnBoneDepthChanged); 84 skinningCache.events.boneColorChanged.AddListener(OnBoneColorChanged); 85 skinningCache.events.meshPreviewBehaviourChange.AddListener(OnMeshPreviewBehaviourChange); 86 skinningCache.events.pivotChange.AddListener(OnPivotChanged); 87 88 skinningCache.RestoreFromPersistentState(); 89 ActivateTool(skinningCache.selectedTool); 90 skinningCache.RestoreToolStateFromPersistentState(); 91 92 // Set state for Switch Mode tool 93 m_PreviousSkinningMode = skinningCache.mode; 94 if (skinningCache.mode == SkinningMode.Character) 95 { 96 skinningCache.GetTool(Tools.SwitchMode).Deactivate(); 97 } 98 else 99 { 100 skinningCache.GetTool(Tools.SwitchMode).Activate(); 101 } 102 103 SetupSpriteEditor(true); 104 105 m_HorizontalToggleTools = new HorizontalToggleTools(skinningCache) 106 { 107 onActivateTool = (b) => 108 { 109 using (skinningCache.UndoScope(TextContent.setTool)) 110 { 111 ActivateTool(b); 112 } 113 } 114 }; 115 116 var ai = spriteEditor.GetDataProvider<ISpriteEditorDataProvider>() as AssetImporter; 117 m_Analytics = new AnimationAnalytics(new UnityAnalyticsStorage(), 118 skinningCache.events, 119 new SkinningModuleAnalyticsModel(skinningCache), 120 ai == null ? -1 : ai.GetInstanceID()); 121 122 UpdateCollapseToolbar(); 123 } 124 } 125 126 public override void OnModuleDeactivate() 127 { 128 if (m_SpriteOutlineRenderer != null) 129 m_SpriteOutlineRenderer.Dispose(); 130 131 spriteEditor.enableMouseMoveEvent = false; 132 EditorApplication.playModeStateChanged -= PlayModeStateChanged; 133 134 Undo.undoRedoPerformed -= UndoRedoPerformed; 135 skinningCache.events.skeletonTopologyChanged.RemoveListener(SkeletonTopologyChanged); 136 skinningCache.events.skeletonPreviewPoseChanged.RemoveListener(SkeletonPreviewPoseChanged); 137 skinningCache.events.skeletonBindPoseChanged.RemoveListener(SkeletonBindPoseChanged); 138 skinningCache.events.characterPartChanged.RemoveListener(CharacterPartChanged); 139 skinningCache.events.skinningModeChanged.RemoveListener(OnViewModeChanged); 140 skinningCache.events.meshChanged.RemoveListener(OnMeshChanged); 141 skinningCache.events.boneNameChanged.RemoveListener(OnBoneNameChanged); 142 skinningCache.events.boneDepthChanged.RemoveListener(OnBoneDepthChanged); 143 skinningCache.events.boneColorChanged.RemoveListener(OnBoneColorChanged); 144 skinningCache.events.meshPreviewBehaviourChange.RemoveListener(OnMeshPreviewBehaviourChange); 145 skinningCache.events.pivotChange.RemoveListener(OnPivotChanged); 146 147 RemoveMainUI(spriteEditor.GetMainVisualContainer()); 148 RestoreSpriteEditor(); 149 m_Analytics.Dispose(); 150 m_Analytics = null; 151 152 Cache.Destroy(m_SkinningCache); 153 } 154 155 void PlayModeStateChanged(PlayModeStateChange newState) 156 { 157 if (newState == PlayModeStateChange.ExitingEditMode && m_HasUnsavedChanges) 158 { 159 var shouldApply = EditorUtility.DisplayDialog(TextContent.savePopupTitle, TextContent.savePopupMessage, TextContent.savePopupOptionYes, TextContent.savePopupOptionNo); 160 spriteEditor.ApplyOrRevertModification(shouldApply); 161 } 162 } 163 164 private void UpdateCollapseToolbar() 165 { 166 m_CollapseToolbar = SkinningModuleSettings.compactToolBar; 167 m_PoseToolbar.CollapseToolBar(m_CollapseToolbar); 168 m_WeightToolbar.CollapseToolBar(m_CollapseToolbar); 169 m_MeshToolbar.CollapseToolBar(m_CollapseToolbar); 170 m_BoneToolbar.CollapseToolBar(m_CollapseToolbar); 171 m_RigToolbar.CollapseToolBar(m_CollapseToolbar); 172 m_LayoutOverlay.verticalToolbar.Collapse(m_CollapseToolbar); 173 m_HorizontalToggleTools.collapseToolbar = m_CollapseToolbar; 174 } 175 176 private void OnBoneNameChanged(BoneCache bone) 177 { 178 var character = skinningCache.character; 179 180 if (character != null && character.skeleton == bone.skeleton) 181 skinningCache.SyncSpriteSheetSkeletons(); 182 DataModified(); 183 } 184 185 private void OnBoneDepthChanged(BoneCache bone) 186 { 187 var sprites = skinningCache.GetSprites(); 188 var controller = new SpriteMeshDataController(); 189 190 foreach (var sprite in sprites) 191 { 192 var mesh = sprite.GetMesh(); 193 194 if (mesh.ContainsBone(bone)) 195 { 196 controller.spriteMeshData = mesh; 197 controller.SortTrianglesByDepth(); 198 skinningCache.events.meshChanged.Invoke(mesh); 199 } 200 } 201 202 DataModified(); 203 } 204 205 private void OnBoneColorChanged(BoneCache bone) 206 { 207 DataModified(); 208 } 209 210 private void OnMeshChanged(MeshCache mesh) 211 { 212 DataModified(); 213 } 214 215 private void OnPivotChanged() 216 { 217 DataModified(); 218 } 219 220 void DataModified() 221 { 222 spriteEditor.SetDataModified(); 223 m_HasUnsavedChanges = true; 224 } 225 226 private void OnViewModeChanged(SkinningMode mode) 227 { 228 SetupSpriteEditor(); 229 } 230 231 private void SetupSpriteEditor(bool setPreviewTexture = false) 232 { 233 var textureProvider = spriteEditor.GetDataProvider<ITextureDataProvider>(); 234 if (textureProvider == null) 235 return; 236 237 int width = 0, height = 0; 238 if (skinningCache.mode == SkinningMode.SpriteSheet) 239 { 240 textureProvider.GetTextureActualWidthAndHeight(out width, out height); 241 } 242 else 243 { 244 width = skinningCache.character.dimension.x; 245 height = skinningCache.character.dimension.y; 246 } 247 248 if (m_PreviousSkinningMode != skinningCache.mode || setPreviewTexture) 249 { 250 spriteEditor.SetPreviewTexture(m_WorkspaceBackgroundTexture, width, height); 251 if (m_PreviousSkinningMode != skinningCache.mode) 252 { 253 m_PreviousSkinningMode = skinningCache.mode; 254 spriteEditor.ResetZoomAndScroll(); 255 } 256 } 257 258 spriteEditor.spriteRects = new List<SpriteRect>(); 259 } 260 261 private void RestoreSpriteEditor() 262 { 263 var textureProvider = spriteEditor.GetDataProvider<ITextureDataProvider>(); 264 265 if (textureProvider != null) 266 { 267 int width, height; 268 textureProvider.GetTextureActualWidthAndHeight(out width, out height); 269 270 var texture = textureProvider.previewTexture; 271 spriteEditor.SetPreviewTexture(texture, width, height); 272 } 273 274 var spriteRectProvider = spriteEditor.GetDataProvider<ISpriteEditorDataProvider>(); 275 276 if (spriteRectProvider != null) 277 spriteEditor.spriteRects = new List<SpriteRect>(spriteRectProvider.GetSpriteRects()); 278 } 279 280 public override bool CanBeActivated() 281 { 282 var dataProvider = spriteEditor.GetDataProvider<ISpriteEditorDataProvider>(); 283 return dataProvider == null ? false : dataProvider.spriteImportMode != SpriteImportMode.None; 284 } 285 286 public override void DoPostGUI() 287 { 288 if (!spriteEditor.windowDimension.Contains(Event.current.mousePosition)) 289 HandleUtility.nearestControl = 0; 290 291 if (Event.current.type == EventType.Layout && m_PrevNearestControl != HandleUtility.nearestControl) 292 { 293 m_PrevNearestControl = HandleUtility.nearestControl; 294 spriteEditor.RequestRepaint(); 295 } 296 297 skinningCache.EndUndoOperation(); 298 } 299 300 public override void DoMainGUI() 301 { 302 Debug.Assert(currentTool != null); 303 304 DoViewGUI(); 305 306 if (!spriteEditor.editingDisabled) 307 skinningCache.selectionTool.DoGUI(); 308 309 m_MeshPreviewTool.previewBehaviourOverride = m_MeshPreviewBehaviourOverride != null ? m_MeshPreviewBehaviourOverride : currentTool.previewBehaviour; 310 m_MeshPreviewTool.DoGUI(); 311 m_MeshPreviewTool.DrawOverlay(); 312 313 if (Event.current.type == EventType.Repaint) 314 m_SpriteOutlineRenderer.RenderSpriteOutline(spriteEditor, skinningCache.selectedSprite); 315 316 m_MeshPreviewTool.OverlayWireframe(); 317 318 if (!spriteEditor.editingDisabled) 319 { 320 currentTool.DoGUI(); 321 DoCopyPasteKeyboardEventHandling(); 322 } 323 324 DrawRectGizmos(); 325 326 if (SkinningModuleSettings.compactToolBar != m_CollapseToolbar) 327 UpdateCollapseToolbar(); 328 } 329 330 public override void DoToolbarGUI(Rect drawArea) 331 { 332 m_HorizontalToggleTools.DoGUI(drawArea, currentTool, spriteEditor.editingDisabled); 333 } 334 335 void DoCopyPasteKeyboardEventHandling() 336 { 337 var evt = Event.current; 338 if (evt.type == EventType.ValidateCommand) 339 { 340 if (evt.commandName == "Copy" || evt.commandName == "Paste") 341 evt.Use(); 342 return; 343 } 344 345 if (evt.type == EventType.ExecuteCommand) 346 { 347 var copyTool = skinningCache.GetTool(Tools.CopyPaste) as CopyTool; 348 if (copyTool != null && evt.commandName == "Copy") 349 { 350 copyTool.OnCopyActivated(); 351 evt.Use(); 352 } 353 else if (copyTool != null && evt.commandName == "Paste") 354 { 355 var boneReadOnly = skinningCache.bonesReadOnly; 356 copyTool.OnPasteActivated(!boneReadOnly, true, false, false); 357 evt.Use(); 358 } 359 } 360 } 361 362 private void DrawRectGizmos() 363 { 364 if (Event.current.type == EventType.Repaint) 365 { 366 var selectedSprite = skinningCache.selectedSprite; 367 var sprites = skinningCache.GetSprites(); 368 var unselectedRectColor = new Color(1f, 1f, 1f, 0.5f); 369 370 foreach (var sprite in sprites) 371 { 372 var skeleton = skinningCache.GetEffectiveSkeleton(sprite); 373 374 Debug.Assert(skeleton != null); 375 376 if (skeleton.isPosePreview) 377 continue; 378 379 var color = unselectedRectColor; 380 381 if (sprite == selectedSprite) 382 color = DrawingUtility.spriteBorderColor; 383 384 if (skinningCache.mode == SkinningMode.Character 385 && sprite != selectedSprite) 386 continue; 387 388 var matrix = sprite.GetLocalToWorldMatrixFromMode(); 389 var rect = new Rect(matrix.MultiplyPoint3x4(Vector3.zero), sprite.textureRect.size); 390 391 DrawingUtility.BeginLines(color); 392 DrawingUtility.DrawBox(rect); 393 DrawingUtility.EndLines(); 394 } 395 } 396 } 397 398 private void UndoRedoPerformed() 399 { 400 using (new DisableUndoScope(skinningCache)) 401 { 402 UpdateToggleState(); 403 skinningCache.UndoRedoPerformed(); 404 SetupSpriteEditor(); 405 } 406 } 407 408 #region CharacterConsistency 409 410 //TODO: Bring this to a better place, maybe CharacterController 411 private void SkeletonPreviewPoseChanged(SkeletonCache skeleton) 412 { 413 var character = skinningCache.character; 414 415 if (character != null && character.skeleton == skeleton) 416 skinningCache.SyncSpriteSheetSkeletons(); 417 } 418 419 private void SkeletonBindPoseChanged(SkeletonCache skeleton) 420 { 421 var character = skinningCache.character; 422 423 if (character != null && character.skeleton == skeleton) 424 skinningCache.SyncSpriteSheetSkeletons(); 425 DataModified(); 426 } 427 428 private void SkeletonTopologyChanged(SkeletonCache skeleton) 429 { 430 var character = skinningCache.character; 431 432 if (character == null) 433 { 434 var sprite = FindSpriteFromSkeleton(skeleton); 435 436 Debug.Assert(sprite != null); 437 438 sprite.UpdateMesh(skeleton.bones); 439 440 DataModified(); 441 } 442 else if (character.skeleton == skeleton) 443 { 444 skinningCache.CreateSpriteSheetSkeletons(); 445 DataModified(); 446 } 447 } 448 449 private void CharacterPartChanged(CharacterPartCache characterPart) 450 { 451 var character = skinningCache.character; 452 453 Debug.Assert(character != null); 454 455 using (new DefaultPoseScope(character.skeleton)) 456 { 457 skinningCache.CreateSpriteSheetSkeleton(characterPart); 458 DataModified(); 459 } 460 461 if (skinningCache.mode == SkinningMode.Character) 462 characterPart.SyncSpriteSheetSkeleton(); 463 } 464 465 private SpriteCache FindSpriteFromSkeleton(SkeletonCache skeleton) 466 { 467 var sprites = skinningCache.GetSprites(); 468 return sprites.FirstOrDefault(sprite => sprite.GetSkeleton() == skeleton); 469 } 470 471 #endregion 472 473 public override bool ApplyRevert(bool apply) 474 { 475 if (apply) 476 { 477 m_Analytics.FlushEvent(); 478 ApplyChanges(skinningCache, spriteEditor.GetDataProvider<ISpriteEditorDataProvider>()); 479 DoApplyAnalytics(); 480 } 481 else 482 skinningCache.Revert(); 483 484 m_HasUnsavedChanges = false; 485 return true; 486 } 487 488 internal static void ApplyChanges(SkinningCache skinningCache, ISpriteEditorDataProvider dataProvider) 489 { 490 skinningCache.applyingChanges = true; 491 skinningCache.RestoreBindPose(); 492 ApplyBone(skinningCache, dataProvider); 493 ApplyMesh(skinningCache, dataProvider); 494 ApplyCharacter(skinningCache, dataProvider); 495 skinningCache.applyingChanges = false; 496 } 497 498 private void DoApplyAnalytics() 499 { 500 var sprites = skinningCache.GetSprites(); 501 var spriteBoneCount = sprites.Select(s => s.GetSkeleton().boneCount).ToArray(); 502 BoneCache[] bones = null; 503 504 if (skinningCache.hasCharacter) 505 bones = skinningCache.character.skeleton.bones; 506 else 507 bones = sprites.SelectMany(s => s.GetSkeleton().bones).ToArray(); 508 509 m_Analytics.SendApplyEvent(sprites.Length, spriteBoneCount, bones); 510 } 511 512 static void ApplyBone(SkinningCache skinningCache, ISpriteEditorDataProvider dataProvider) 513 { 514 var boneDataProvider = dataProvider.GetDataProvider<ISpriteBoneDataProvider>(); 515 if (boneDataProvider != null) 516 { 517 var sprites = skinningCache.GetSprites(); 518 foreach (var sprite in sprites) 519 { 520 var bones = sprite.GetSkeleton().bones; 521 boneDataProvider.SetBones(new GUID(sprite.id), bones.ToSpriteBone(sprite.localToWorldMatrix).ToList()); 522 } 523 } 524 } 525 526 static void ApplyMesh(SkinningCache skinningCache, ISpriteEditorDataProvider dataProvider) 527 { 528 var meshDataProvider = dataProvider.GetDataProvider<ISpriteMeshDataProvider>(); 529 if (meshDataProvider != null) 530 { 531 var sprites = skinningCache.GetSprites(); 532 foreach (var sprite in sprites) 533 { 534 var mesh = sprite.GetMesh(); 535 var guid = new GUID(sprite.id); 536 537 var vertices = new Vertex2DMetaData[mesh.vertexCount]; 538 for (var i = 0; i < vertices.Length; ++i) 539 { 540 vertices[i].position = mesh.vertices[i]; 541 vertices[i].boneWeight = mesh.vertexWeights[i].ToBoneWeight(false); 542 } 543 544 meshDataProvider.SetVertices(guid, vertices); 545 meshDataProvider.SetIndices(guid, mesh.indices); 546 547 var edgeVectArr = EditorUtilities.ToVector2Int(mesh.edges); 548 meshDataProvider.SetEdges(guid, edgeVectArr); 549 } 550 } 551 } 552 553 static void ApplyCharacter(SkinningCache skinningCache, ISpriteEditorDataProvider dataProvider) 554 { 555 var characterDataProvider = dataProvider.GetDataProvider<ICharacterDataProvider>(); 556 var character = skinningCache.character; 557 if (characterDataProvider != null && character != null) 558 { 559 var data = new CharacterData(); 560 var characterBones = character.skeleton.bones; 561 data.bones = characterBones.ToSpriteBone(Matrix4x4.identity); 562 data.pivot = character.pivot; 563 var parts = character.parts; 564 data.parts = parts.Select(x => 565 new CharacterPart() 566 { 567 spriteId = x.sprite.id, 568 spritePosition = new RectInt((int)x.position.x, (int)x.position.y, (int)x.sprite.textureRect.width, (int)x.sprite.textureRect.height), 569 bones = x.bones.Select(bone => Array.IndexOf(characterBones, bone)).Where(bone => bone != -1).ToArray() 570 } 571 ).ToArray(); 572 573 characterDataProvider.SetCharacterData(data); 574 575 } 576 } 577 578 void OnMeshPreviewBehaviourChange(IMeshPreviewBehaviour meshPreviewBehaviour) 579 { 580 m_MeshPreviewBehaviourOverride = meshPreviewBehaviour; 581 } 582 583 private void SetupModuleToolGroup() 584 { 585 m_ModuleToolGroup = new ModuleToolGroup(); 586 m_ModuleToolGroup.AddToolToGroup(0, skinningCache.GetTool(Tools.Visibility), null); 587 m_ModuleToolGroup.AddToolToGroup(1, skinningCache.GetTool(Tools.EditGeometry), () => currentTool = skinningCache.GetTool(Tools.EditGeometry)); 588 m_ModuleToolGroup.AddToolToGroup(1, skinningCache.GetTool(Tools.CreateVertex), () => currentTool = skinningCache.GetTool(Tools.CreateVertex)); 589 m_ModuleToolGroup.AddToolToGroup(1, skinningCache.GetTool(Tools.CreateEdge), () => currentTool = skinningCache.GetTool(Tools.CreateEdge)); 590 m_ModuleToolGroup.AddToolToGroup(1, skinningCache.GetTool(Tools.SplitEdge), () => currentTool = skinningCache.GetTool(Tools.SplitEdge)); 591 m_ModuleToolGroup.AddToolToGroup(1, skinningCache.GetTool(Tools.GenerateGeometry), () => currentTool = skinningCache.GetTool(Tools.GenerateGeometry)); 592 m_ModuleToolGroup.AddToolToGroup(1, skinningCache.GetTool(Tools.EditPose), () => currentTool = skinningCache.GetTool(Tools.EditPose)); 593 m_ModuleToolGroup.AddToolToGroup(1, skinningCache.GetTool(Tools.EditJoints), () => currentTool = skinningCache.GetTool(Tools.EditJoints)); 594 m_ModuleToolGroup.AddToolToGroup(1, skinningCache.GetTool(Tools.CreateBone), () => currentTool = skinningCache.GetTool(Tools.CreateBone)); 595 m_ModuleToolGroup.AddToolToGroup(1, skinningCache.GetTool(Tools.SplitBone), () => currentTool = skinningCache.GetTool(Tools.SplitBone)); 596 m_ModuleToolGroup.AddToolToGroup(1, skinningCache.GetTool(Tools.WeightSlider), () => currentTool = skinningCache.GetTool(Tools.WeightSlider)); 597 m_ModuleToolGroup.AddToolToGroup(1, skinningCache.GetTool(Tools.WeightBrush), () => currentTool = skinningCache.GetTool(Tools.WeightBrush)); 598 m_ModuleToolGroup.AddToolToGroup(1, skinningCache.GetTool(Tools.GenerateWeights), () => currentTool = skinningCache.GetTool(Tools.GenerateWeights)); 599 m_ModuleToolGroup.AddToolToGroup(1, skinningCache.GetTool(Tools.BoneInfluence), () => currentTool = skinningCache.GetTool(Tools.BoneInfluence)); 600 m_ModuleToolGroup.AddToolToGroup(1, skinningCache.GetTool(Tools.SpriteInfluence), () => currentTool = skinningCache.GetTool(Tools.SpriteInfluence)); 601 m_ModuleToolGroup.AddToolToGroup(1, skinningCache.GetTool(Tools.CopyPaste), () => currentTool = skinningCache.GetTool(Tools.CopyPaste)); 602 m_ModuleToolGroup.AddToolToGroup(1, skinningCache.GetTool(Tools.CharacterPivotTool), () => 603 { 604 if (skinningCache.hasCharacter) 605 currentTool = skinningCache.GetTool(Tools.CharacterPivotTool); 606 else 607 ActivateTool(skinningCache.GetTool(Tools.EditPose)); 608 }); 609 } 610 } 611}