A game about forced loneliness, made by TACStudios
at master 730 lines 28 kB view raw
1using System; 2using System.Collections.Generic; 3using System.Linq; 4using UnityEngine; 5using UnityEditor.U2D.Common; 6using UnityEditor.U2D.Layout; 7using UnityEngine.U2D; 8 9namespace UnityEditor.U2D.Animation 10{ 11 internal interface ICopyToolStringStore 12 { 13 string stringStore { get; set; } 14 } 15 16 internal class SystemCopyBufferStringStore : ICopyToolStringStore 17 { 18 public string stringStore 19 { 20 get => EditorGUIUtility.systemCopyBuffer; 21 set => EditorGUIUtility.systemCopyBuffer = value; 22 } 23 } 24 25 internal class BoneStorage 26 { 27 public BoneCache[] bones; 28 public Dictionary<string, string> boneMapping; 29 30 public BoneStorage(BoneCache[] bones, Dictionary<string, string> boneMapping = null) 31 { 32 this.bones = bones; 33 this.boneMapping = boneMapping ?? new Dictionary<string, string>(); 34 } 35 } 36 37 internal class CopyTool : MeshToolWrapper 38 { 39 ICopyToolStringStore m_CopyToolStringStore; 40 CopyToolView m_CopyToolView; 41 bool m_HasValidCopyData = false; 42 int m_LastCopyDataHash; 43 44 public float pixelsPerUnit { private get; set; } 45 46 public bool hasValidCopiedData 47 { 48 get 49 { 50 var hashCode = m_CopyToolStringStore.stringStore.GetHashCode(); 51 if (hashCode != m_LastCopyDataHash) 52 { 53 m_HasValidCopyData = IsValidCopyData(m_CopyToolStringStore.stringStore); 54 m_LastCopyDataHash = hashCode; 55 } 56 57 return m_HasValidCopyData; 58 } 59 } 60 61 public ICopyToolStringStore copyToolStringStore 62 { 63 set => m_CopyToolStringStore = value; 64 } 65 66 internal override void OnCreate() 67 { 68 m_CopyToolView = new CopyToolView(); 69 m_CopyToolView.onPasteActivated += OnPasteActivated; 70 m_CopyToolStringStore = new SystemCopyBufferStringStore(); 71 disableMeshEditor = true; 72 } 73 74 public override void Initialize(LayoutOverlay layout) 75 { 76 m_CopyToolView.Initialize(layout); 77 } 78 79 protected override void OnActivate() 80 { 81 base.OnActivate(); 82 m_CopyToolView.Show(skinningCache.bonesReadOnly); 83 } 84 85 protected override void OnDeactivate() 86 { 87 base.OnDeactivate(); 88 m_CopyToolView.Hide(); 89 } 90 91 void CopyMeshFromSpriteCache(SpriteCache sprite, SkinningCopySpriteData skinningSpriteData) 92 { 93 if (meshTool == null) 94 return; 95 96 meshTool.SetupSprite(sprite); 97 skinningSpriteData.vertices = meshTool.mesh.vertices; 98 skinningSpriteData.vertexWeights = meshTool.mesh.vertexWeights; 99 skinningSpriteData.indices = meshTool.mesh.indices; 100 skinningSpriteData.edges = meshTool.mesh.edges; 101 skinningSpriteData.boneWeightGuids = new List<string>(meshTool.mesh.bones.Length); 102 skinningSpriteData.boneWeightNames = new List<string>(meshTool.mesh.bones.Length); 103 foreach (var bone in meshTool.mesh.bones) 104 { 105 skinningSpriteData.boneWeightGuids.Add(bone.guid); 106 skinningSpriteData.boneWeightNames.Add(bone.name); 107 } 108 } 109 110 public void OnCopyActivated() 111 { 112 SkinningCopyData skinningCopyData = null; 113 var selectedSprite = skinningCache.selectedSprite; 114 if (selectedSprite == null) 115 { 116 var sprites = skinningCache.GetSprites(); 117 if (!skinningCache.character || sprites.Length > 1) 118 skinningCopyData = CopyAll(); 119 else if (sprites.Length == 1) 120 skinningCopyData = CopySingle(sprites[0]); 121 } 122 else 123 { 124 skinningCopyData = CopySingle(selectedSprite); 125 } 126 127 if (skinningCopyData != null) 128 m_CopyToolStringStore.stringStore = SkinningCopyUtility.SerializeSkinningCopyDataToString(skinningCopyData); 129 skinningCache.events.copy.Invoke(); 130 } 131 132 SkinningCopyData CopyAll() 133 { 134 var skinningCopyData = new SkinningCopyData 135 { 136 pixelsPerUnit = pixelsPerUnit, 137 isCharacterData = skinningCache.hasCharacter, 138 characterBones = skinningCache.hasCharacter 139 ? skinningCache.character.skeleton.bones.ToSpriteBone(Matrix4x4.identity) 140 : null 141 }; 142 143 var sprites = skinningCache.GetSprites(); 144 foreach (var sprite in sprites) 145 skinningCopyData.copyData.Add(GetDataForSprite(sprite)); 146 147 if (meshTool != null) 148 meshTool.SetupSprite(null); 149 150 return skinningCopyData; 151 } 152 153 SkinningCopyData CopySingle(SpriteCache sprite) 154 { 155 var skinningCopyData = new SkinningCopyData 156 { 157 pixelsPerUnit = pixelsPerUnit, 158 isCharacterData = false, 159 characterBones = Array.Empty<SpriteBone>() 160 }; 161 skinningCopyData.copyData.Add(GetDataForSprite(sprite)); 162 163 return skinningCopyData; 164 } 165 166 SkinningCopySpriteData GetDataForSprite(SpriteCache sprite) 167 { 168 var skinningSpriteData = new SkinningCopySpriteData(); 169 skinningSpriteData.spriteName = sprite.name; 170 171 CopyMeshFromSpriteCache(sprite, skinningSpriteData); 172 173 // Bones 174 var rootBones = new List<BoneCache>(); 175 var boneCache = Array.Empty<BoneCache>(); 176 if (skinningCache.hasCharacter) 177 { 178 var characterPart = skinningCache.GetCharacterPart(sprite); 179 if (characterPart != null && characterPart.bones != null) 180 { 181 boneCache = characterPart.bones; 182 var bones = characterPart.bones.FindRoots(); 183 foreach (var bone in bones) 184 rootBones.Add(bone); 185 } 186 } 187 else 188 { 189 var skeleton = skinningCache.GetEffectiveSkeleton(sprite); 190 if (skeleton != null && skeleton.boneCount > 0) 191 { 192 boneCache = skeleton.bones; 193 var bones = boneCache.FindRoots(); 194 foreach (var bone in bones) 195 rootBones.Add(bone); 196 } 197 } 198 199 if (rootBones.Count > 0) 200 { 201 skinningSpriteData.spriteBones = new List<SpriteBoneCopyData>(); 202 foreach (var rootBone in rootBones) 203 { 204 var rootBoneIndex = skinningSpriteData.spriteBones.Count; 205 206 GetSpriteBoneDataRecursively(skinningSpriteData.spriteBones, rootBone, new List<BoneCache>(boneCache)); 207 if (skinningCache.hasCharacter) 208 { 209 // Offset the bones based on the currently selected Sprite in Character mode 210 var characterPart = sprite.GetCharacterPart(); 211 if (characterPart != null) 212 { 213 var offset = characterPart.position; 214 var rootSpriteBone = skinningSpriteData.spriteBones[rootBoneIndex]; 215 rootSpriteBone.spriteBone.position -= offset; 216 skinningSpriteData.spriteBones[rootBoneIndex] = rootSpriteBone; 217 } 218 } 219 } 220 } 221 222 return skinningSpriteData; 223 } 224 225 static void GetSpriteBoneDataRecursively(IList<SpriteBoneCopyData> bones, BoneCache rootBone, List<BoneCache> boneCache) 226 { 227 AppendSpriteBoneDataRecursively(bones, rootBone, -1, boneCache); 228 } 229 230 static void AppendSpriteBoneDataRecursively(IList<SpriteBoneCopyData> bones, BoneCache currentBone, int parentIndex, List<BoneCache> boneCache) 231 { 232 var currentParentIndex = bones.Count; 233 234 var boneCopyData = new SpriteBoneCopyData() 235 { 236 spriteBone = new SpriteBone() 237 { 238 name = currentBone.name, 239 guid = currentBone.guid, 240 color = currentBone.bindPoseColor, 241 parentId = parentIndex 242 }, 243 order = boneCache.FindIndex(x => x == currentBone) 244 }; 245 if (boneCopyData.order < 0) 246 { 247 boneCopyData.order = boneCache.Count; 248 boneCache.Add(currentBone); 249 } 250 251 if (parentIndex == -1 && currentBone.parentBone != null) 252 { 253 boneCopyData.spriteBone.position = currentBone.position; 254 boneCopyData.spriteBone.rotation = currentBone.rotation; 255 } 256 else 257 { 258 boneCopyData.spriteBone.position = currentBone.localPosition; 259 boneCopyData.spriteBone.rotation = currentBone.localRotation; 260 } 261 262 boneCopyData.spriteBone.position = new Vector3(boneCopyData.spriteBone.position.x, boneCopyData.spriteBone.position.y, currentBone.depth); 263 264 boneCopyData.spriteBone.length = currentBone.localLength; 265 bones.Add(boneCopyData); 266 foreach (var child in currentBone) 267 { 268 var childBone = child as BoneCache; 269 if (childBone != null) 270 AppendSpriteBoneDataRecursively(bones, childBone, currentParentIndex, boneCache); 271 } 272 } 273 274 public void OnPasteActivated(bool shouldPasteBones, bool shouldPasteMesh, bool shouldFlipX, bool shouldFlipY) 275 { 276 var copyBuffer = m_CopyToolStringStore.stringStore; 277 if (!IsValidCopyData(copyBuffer)) 278 return; 279 280 var skinningCopyData = SkinningCopyUtility.DeserializeStringToSkinningCopyData(copyBuffer); 281 if (skinningCopyData == null || skinningCopyData.copyData.Count == 0) 282 return; 283 284 var doesCopyContainMultipleSprites = skinningCopyData.copyData.Count > 1; 285 var sprites = skinningCache.GetSprites(); 286 287 if (doesCopyContainMultipleSprites && skinningCopyData.copyData.Count != sprites.Length && shouldPasteMesh) 288 { 289 Debug.Log(string.Format(TextContent.copyIncorrectNumberOfSprites, skinningCopyData.copyData.Count, sprites.Length)); 290 return; 291 } 292 293 var selectedSprite = skinningCache.selectedSprite; 294 using (skinningCache.UndoScope(TextContent.pasteData)) 295 { 296 var scale = skinningCopyData.pixelsPerUnit > 0f ? pixelsPerUnit / skinningCopyData.pixelsPerUnit : 1f; 297 var pastedBonesToSelect = new HashSet<BoneCache>(); 298 299 var characterBones = Array.Empty<BoneCache>(); 300 var replaceCharacterSkeleton = shouldPasteBones && skinningCache.hasCharacter && skinningCopyData.isCharacterData; 301 if (replaceCharacterSkeleton) 302 { 303 var spriteBones = skinningCopyData.characterBones; 304 characterBones = PasteBonesInCharacter(skinningCache, spriteBones, shouldFlipX, shouldFlipY, scale); 305 foreach (var newBone in characterBones) 306 pastedBonesToSelect.Add(newBone); 307 } 308 309 var pastedToSprites = new List<SpriteCache>(); 310 foreach (var copySpriteData in skinningCopyData.copyData) 311 { 312 SpriteCache sprite = null; 313 if (selectedSprite != null && !doesCopyContainMultipleSprites) 314 sprite = selectedSprite; 315 if (sprite == null && !string.IsNullOrEmpty(copySpriteData.spriteName)) 316 sprite = FindSpriteWithName(sprites.Except(pastedToSprites).ToList(), copySpriteData.spriteName) ?? FindSpriteWithName(sprites, copySpriteData.spriteName); 317 318 if (sprite == null) 319 continue; 320 321 pastedToSprites.Add(sprite); 322 323 var boneMapping = new Dictionary<string, string>(); 324 if (shouldPasteBones && !replaceCharacterSkeleton) 325 { 326 var bonesToPaste = GetBonesInCorrectOrder(copySpriteData.spriteBones); 327 var boneStorage = PasteBonesInSprite(skinningCache, sprite, bonesToPaste, characterBones, shouldFlipX, shouldFlipY, scale); 328 if (boneStorage != null) 329 { 330 boneMapping = boneStorage.boneMapping; 331 if (skinningCache.hasCharacter || sprite == selectedSprite) 332 { 333 foreach (var newBone in boneStorage.bones) 334 pastedBonesToSelect.Add(newBone); 335 } 336 } 337 } 338 339 if (shouldPasteMesh) 340 PasteMeshInSprite(meshTool, sprite, copySpriteData, shouldFlipX, shouldFlipY, scale, boneMapping); 341 } 342 343 var refreshSelection = skinningCache.hasCharacter || skinningCache.selectedSprite != null; 344 if (refreshSelection) 345 { 346 var newBoneSelection = new BoneCache[pastedBonesToSelect.Count]; 347 pastedBonesToSelect.CopyTo(newBoneSelection); 348 349 meshTool.SetupSprite(selectedSprite); // This is to refresh the selected Sprite in meshTool. 350 skinningCache.skeletonSelection.elements = newBoneSelection; 351 skinningCache.events.boneSelectionChanged.Invoke(); 352 } 353 } 354 355 skinningCache.events.paste.Invoke(shouldPasteBones, shouldPasteMesh, shouldFlipX, shouldFlipY); 356 } 357 358 static bool IsValidCopyData(string copyBuffer) 359 { 360 return SkinningCopyUtility.CanDeserializeStringToSkinningCopyData(copyBuffer); 361 } 362 363 static Vector3 GetFlippedBonePosition(BoneCache bone, Vector2 startPosition, Rect spriteRect, bool flipX, bool flipY) 364 { 365 Vector3 position = startPosition; 366 if (flipX) 367 position.x += spriteRect.width - bone.position.x; 368 else 369 position.x += bone.position.x; 370 371 if (flipY) 372 position.y += spriteRect.height - bone.position.y; 373 else 374 position.y += bone.position.y; 375 376 position.z = bone.position.z; 377 return position; 378 } 379 380 static Quaternion GetFlippedBoneRotation(BoneCache bone, bool flipX, bool flipY) 381 { 382 var euler = bone.rotation.eulerAngles; 383 if (flipX) 384 { 385 if (euler.z <= 180) 386 euler.z = 180 - euler.z; 387 else 388 euler.z = 540 - euler.z; 389 } 390 391 if (flipY) 392 euler.z = 360 - euler.z; 393 return Quaternion.Euler(euler); 394 } 395 396 static void SetBonePositionAndRotation(BoneCache[] boneCache, TransformCache bone, Vector3[] position, Quaternion[] rotation) 397 { 398 var index = Array.FindIndex(boneCache, x => x == bone); 399 if (index >= 0) 400 { 401 bone.position = position[index]; 402 bone.rotation = rotation[index]; 403 } 404 405 foreach (var child in bone.children) 406 { 407 SetBonePositionAndRotation(boneCache, child, position, rotation); 408 } 409 } 410 411 static BoneCache[] PasteBonesInCharacter(SkinningCache skinningCache, SpriteBone[] spriteBones, bool shouldFlipX, bool shouldFlipY, float scale) 412 { 413 if (!skinningCache.hasCharacter) 414 return null; 415 416 var boneCache = skinningCache.CreateBoneCacheFromSpriteBones(spriteBones, scale); 417 if (shouldFlipX || shouldFlipY) 418 { 419 var characterRect = new Rect(Vector2.zero, skinningCache.character.dimension); 420 var newPositions = new Vector3[boneCache.Length]; 421 var newRotations = new Quaternion[boneCache.Length]; 422 for (var i = 0; i < boneCache.Length; ++i) 423 { 424 newPositions[i] = GetFlippedBonePosition(boneCache[i], Vector2.zero, characterRect, shouldFlipX, shouldFlipY); 425 newRotations[i] = GetFlippedBoneRotation(boneCache[i], shouldFlipX, shouldFlipY); 426 } 427 428 for (var i = 0; i < boneCache.Length; ++i) 429 { 430 boneCache[i].position = newPositions[i]; 431 boneCache[i].rotation = newRotations[i]; 432 } 433 } 434 435 var skeleton = skinningCache.character.skeleton; 436 skeleton.SetBones(boneCache); 437 skinningCache.events.skeletonTopologyChanged.Invoke(skeleton); 438 439 return boneCache; 440 } 441 442 static BoneStorage PasteBonesInSprite(SkinningCache skinningCache, SpriteCache sprite, SpriteBone[] newBones, BoneCache[] characterBones, bool shouldFlipX, bool shouldFlipY, float scale) 443 { 444 if (sprite == null || skinningCache.mode == SkinningMode.SpriteSheet && skinningCache.hasCharacter) 445 return null; 446 447 var spriteRect = sprite.textureRect; 448 var skeleton = skinningCache.GetEffectiveSkeleton(sprite); 449 450 var newBonesCache = skinningCache.CreateBoneCacheFromSpriteBones(newBones, scale); 451 if (newBonesCache.Length == 0) 452 return null; 453 454 Vector2 rectPosition; 455 if (skinningCache.mode == SkinningMode.Character) 456 { 457 var characterPart = sprite.GetCharacterPart(); 458 if (characterPart == null) 459 return null; 460 rectPosition = characterPart.position; 461 } 462 else 463 rectPosition = spriteRect.position; 464 465 var newPositions = new Vector3[newBonesCache.Length]; 466 var newRotations = new Quaternion[newBonesCache.Length]; 467 for (var i = 0; i < newBonesCache.Length; ++i) 468 { 469 newPositions[i] = GetFlippedBonePosition(newBonesCache[i], rectPosition, spriteRect, shouldFlipX, shouldFlipY); 470 newRotations[i] = GetFlippedBoneRotation(newBonesCache[i], shouldFlipX, shouldFlipY); 471 } 472 473 foreach (var bone in newBonesCache) 474 { 475 if (bone.parent == null) 476 { 477 SetBonePositionAndRotation(newBonesCache, bone, newPositions, newRotations); 478 if (skinningCache.mode == SkinningMode.Character) 479 bone.SetParent(skeleton); 480 } 481 } 482 483 var boneNameMapping = new Dictionary<string, string>(); 484 if (skinningCache.mode == SkinningMode.SpriteSheet) 485 { 486 skeleton.SetBones(newBonesCache); 487 skeleton.SetDefaultPose(); 488 } 489 else 490 { 491 boneNameMapping = AddBonesToSkeletonWithUniqueNames(characterBones, newBonesCache, skeleton); 492 skeleton.SetDefaultPose(); 493 } 494 495 skinningCache.events.skeletonTopologyChanged.Invoke(skeleton); 496 return new BoneStorage(newBonesCache, boneNameMapping); 497 } 498 499 static Dictionary<string, string> AddBonesToSkeletonWithUniqueNames(IList<BoneCache> characterBones, IList<BoneCache> newBones, SkeletonCache skeleton) 500 { 501 var nameMapping = new Dictionary<string, string>(); 502 503 var existingBoneGuids = new HashSet<string>(); 504 var existingBoneNames = new HashSet<string>(skeleton.boneCount); 505 for (var i = 0; i < characterBones.Count; i++) 506 { 507 if (!string.IsNullOrEmpty(characterBones[i].guid)) 508 existingBoneGuids.Add(characterBones[i].guid); 509 } 510 511 for (var i = 0; i < skeleton.boneCount; i++) 512 existingBoneNames.Add(skeleton.bones[i].name); 513 514 foreach (var newBone in newBones) 515 { 516 var guid = newBone.guid; 517 if (string.IsNullOrEmpty(guid) || existingBoneGuids.Contains(guid)) 518 continue; 519 520 var boneName = newBone.name; 521 if (existingBoneNames.Contains(boneName)) 522 newBone.name = SkeletonController.AutoNameBoneCopy(boneName, skeleton.bones); 523 524 existingBoneGuids.Add(newBone.guid); 525 existingBoneNames.Add(newBone.name); 526 nameMapping[boneName] = newBone.name; 527 skeleton.AddBone(newBone); 528 } 529 530 return nameMapping; 531 } 532 533 static void PasteMeshInSprite(MeshTool meshTool, SpriteCache sprite, SkinningCopySpriteData copySpriteData, bool shouldFlipX, bool shouldFlipY, float scale, Dictionary<string, string> boneMapping) 534 { 535 if (meshTool == null || sprite == null) 536 return; 537 538 var vertices = copySpriteData.vertices ?? Array.Empty<Vector2>(); 539 var vertexWeights = copySpriteData.vertexWeights ?? Array.Empty<EditableBoneWeight>(); 540 541 meshTool.SetupSprite(sprite); 542 meshTool.mesh.SetVertices(vertices, vertexWeights); 543 if (!Mathf.Approximately(scale, 1f) || shouldFlipX || shouldFlipY) 544 { 545 var spriteRect = sprite.textureRect; 546 for (var i = 0; i < meshTool.mesh.vertexCount; ++i) 547 { 548 var position = meshTool.mesh.vertices[i]; 549 if (!Mathf.Approximately(scale, 1f)) 550 position *= scale; 551 if (shouldFlipX) 552 position.x = spriteRect.width - meshTool.mesh.vertices[i].x; 553 if (shouldFlipY) 554 position.y = spriteRect.height - meshTool.mesh.vertices[i].y; 555 meshTool.mesh.vertices[i] = position; 556 } 557 } 558 559 meshTool.mesh.SetIndices(copySpriteData.indices); 560 meshTool.mesh.SetEdges(copySpriteData.edges); 561 562 var skinningCache = meshTool.skinningCache; 563 var skeleton = skinningCache.GetEffectiveSkeleton(sprite); 564 var hasGuids = copySpriteData.boneWeightGuids.Count > 0; 565 for (var i = 0; i < copySpriteData.boneWeightGuids.Count; i++) 566 { 567 if (string.IsNullOrEmpty(copySpriteData.boneWeightGuids[i])) 568 { 569 hasGuids = false; 570 break; 571 } 572 } 573 574 var skeletonBones = skeleton.bones; 575 var influenceBones = hasGuids ? GetBonesFromGuids(copySpriteData, skeletonBones, boneMapping) : GetBonesFromNames(copySpriteData, skeletonBones, boneMapping); 576 577 // Update associated bones for mesh 578 meshTool.mesh.SetCompatibleBoneSet(influenceBones); 579 meshTool.mesh.bones = influenceBones; // Fixes weights for bones that do not exist 580 581 // Update associated bones for character 582 if (skinningCache.hasCharacter) 583 { 584 var characterPart = sprite.GetCharacterPart(); 585 if (characterPart != null) 586 { 587 characterPart.bones = influenceBones; 588 skinningCache.events.characterPartChanged.Invoke(characterPart); 589 } 590 } 591 592 meshTool.UpdateMesh(); 593 } 594 595 static BoneCache[] GetBonesFromGuids(SkinningCopySpriteData copySpriteData, IList<BoneCache> skeletonBones, Dictionary<string, string> boneMapping) 596 { 597 var spriteBones = new List<BoneCache>(); 598 for (var i = 0; i < copySpriteData.boneWeightGuids.Count; i++) 599 { 600 var bone = FindBoneWithGuid(skeletonBones, copySpriteData.boneWeightGuids[i]); 601 if (bone == null) 602 continue; 603 604 if (boneMapping != null && boneMapping.ContainsKey(bone.name)) 605 { 606 bone = FindBoneWithName(skeletonBones, boneMapping[bone.name]); 607 if (bone == null) 608 continue; 609 } 610 611 spriteBones.Add(bone); 612 } 613 614 return spriteBones.ToArray(); 615 } 616 617 static BoneCache[] GetBonesFromNames(SkinningCopySpriteData copySpriteData, IList<BoneCache> skeletonBones, Dictionary<string, string> boneMapping) 618 { 619 var spriteBones = new List<BoneCache>(); 620 for (var i = 0; i < copySpriteData.boneWeightNames.Count; ++i) 621 { 622 var boneName = copySpriteData.boneWeightNames[i]; 623 if (boneMapping != null && boneMapping.ContainsKey(boneName)) 624 boneName = boneMapping[boneName]; 625 626 var bone = FindBoneWithName(skeletonBones, boneName); 627 if (bone == null) 628 continue; 629 630 spriteBones.Add(bone); 631 } 632 633 return spriteBones.ToArray(); 634 } 635 636 static SpriteBone[] GetBonesInCorrectOrder(IList<SpriteBoneCopyData> spriteBones) 637 { 638 var orderedBones = new SpriteBone[spriteBones.Count]; 639 for (var i = 0; i < spriteBones.Count; ++i) 640 { 641 var order = spriteBones[i].order; 642 if (order >= 0) 643 { 644 orderedBones[order] = spriteBones[i].spriteBone; 645 var parentId = orderedBones[order].parentId; 646 if (parentId >= 0) 647 orderedBones[order].parentId = spriteBones[parentId].order; 648 } 649 else 650 { 651 orderedBones[i] = spriteBones[i].spriteBone; 652 } 653 } 654 655 return orderedBones; 656 } 657 658 static SpriteCache FindSpriteWithName(IList<SpriteCache> sprites, string spriteName) 659 { 660 for (var i = 0; i < sprites.Count; i++) 661 { 662 var sprite = sprites[i]; 663 if (sprite.name == spriteName) 664 return sprite; 665 } 666 667 return null; 668 } 669 670 static BoneCache FindBoneWithName(IList<BoneCache> bones, string boneName) 671 { 672 for (var i = 0; i < bones.Count; i++) 673 { 674 var bone = bones[i]; 675 if (bone.name == boneName) 676 return bone; 677 } 678 679 return null; 680 } 681 682 static BoneCache FindBoneWithGuid(IList<BoneCache> bones, string guid) 683 { 684 for (var i = 0; i < bones.Count; i++) 685 { 686 var bone = bones[i]; 687 if (bone.guid == guid) 688 return bone; 689 } 690 691 return null; 692 } 693 } 694 695 internal class CopyToolView 696 { 697 PastePanel m_PastePanel; 698 699 public event Action<bool, bool, bool, bool> onPasteActivated = (bone, mesh, flipX, flipY) => { }; 700 701 public void Show(bool readonlyBone) 702 { 703 m_PastePanel.SetHiddenFromLayout(false); 704 m_PastePanel.BonePasteEnable(!readonlyBone); 705 } 706 707 public void Hide() 708 { 709 m_PastePanel.SetHiddenFromLayout(true); 710 } 711 712 public void Initialize(LayoutOverlay layoutOverlay) 713 { 714 m_PastePanel = PastePanel.GenerateFromUXML(); 715 BindElements(); 716 layoutOverlay.rightOverlay.Add(m_PastePanel); 717 m_PastePanel.SetHiddenFromLayout(true); 718 } 719 720 void BindElements() 721 { 722 m_PastePanel.onPasteActivated += OnPasteActivated; 723 } 724 725 void OnPasteActivated(bool bone, bool mesh, bool flipX, bool flipY) 726 { 727 onPasteActivated(bone, mesh, flipX, flipY); 728 } 729 } 730}