From f2a8c9a3c1a9c0aad2bd560ec0f183084bf6323d Mon Sep 17 00:00:00 2001 From: Harald Csaszar Date: Fri, 29 Nov 2019 12:31:39 +0100 Subject: [PATCH] [unity][csharp] API Cleanup: removed many redundant extension methods that are now obsolete with Skin and Attachment API of 3.8. Closes #1557. Fixed an error in `Skin` where `Skin.setAttachment()` did not work as expected (See #1485). C# implementation is different to ref-impl here as struct keys do not allow for changing key.Attachment later without removing and readding the entry to the dictionary. --- CHANGELOG.md | 5 + spine-csharp/src/Skeleton.cs | 3 +- spine-csharp/src/Skin.cs | 68 +++++--- .../EquipsVisualsComponentExample.cs | 6 +- .../Spine Examples/Scripts/MixAndMatch.cs | 4 +- .../Scripts/MixAndMatchGraphic.cs | 4 +- .../Scripts/Sample Components/CombinedSkin.cs | 2 +- .../Components/PointFollowerInspector.cs | 5 +- .../spine-unity/Components/SkeletonMecanim.cs | 2 +- .../spine-unity/Utility/AtlasUtilities.cs | 113 +----------- .../Utility/AttachmentCloneExtensions.cs | 41 +---- .../spine-unity/Utility/SkeletonExtensions.cs | 152 ---------------- .../spine-unity/Utility/SkinUtilities.cs | 165 ------------------ .../spine-unity/Utility/SkinUtilities.cs.meta | 12 -- .../SpineAnimationStateMixerBehaviour.cs | 2 +- 15 files changed, 72 insertions(+), 512 deletions(-) delete mode 100644 spine-unity/Assets/Spine/Runtime/spine-unity/Utility/SkinUtilities.cs delete mode 100644 spine-unity/Assets/Spine/Runtime/spine-unity/Utility/SkinUtilities.cs.meta diff --git a/CHANGELOG.md b/CHANGELOG.md index bc18d34b2..db4d14796 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,11 @@ ### Unity * **Breaking changes** + * Removed all `Spine.Unity.AttachmentTools.SkinUtilities` Skin extension methods. These have become obsoleted and error-prone since the introduction of the new Skin API in 3.8. To fix any compile errors, replace any usage of `Skin` extension methods with their counterparts, e.g. replace occurrances of `skin.AddAttachments()` with `skin.AddSkin()`. + * Removed redundant `Spine.Unity.AttachmentTools` extension method `Skin.GetRepackedAttachments()`. Please use `Skin.GetRepackedSkin()` instead. + * Removed redundant `Spine.Unity.AttachmentTools.AttachmentCloneExtensions` extension methods `Attachment.GetCopy()` and `Attachment.GetLinkedMesh()`. To fix any compile errors, replace any occurrances with `Attachment.Copy()` and `Attachment.NewLinkedMesh()`. + * Removed redundant `Spine.SkeletonExtensions` extension methods `Skeleton.Set*ToSetupPose()`. Also removed less commonly used extension methods `TrackEntry.AllowImmediateQueue()` and `Attachment.IsRenderable()`. + * `Skin.Attachments` now replaces `Skin.GetAttachments()`, returning an `ICollection`. This makes access more consistent and intuitive. To fix any compile errors, replace any occurrances of `skin.GetAttachments()` by `skin.Attachments`. * **Additions** * Additional **Fix Draw Order** parameter at SkeletonRenderer, defaults to `disabled` (previous behaviour). diff --git a/spine-csharp/src/Skeleton.cs b/spine-csharp/src/Skeleton.cs index 846b1dd8f..0f86535e4 100644 --- a/spine-csharp/src/Skeleton.cs +++ b/spine-csharp/src/Skeleton.cs @@ -260,8 +260,7 @@ namespace Spine { } private void SortPathConstraintAttachment (Skin skin, int slotIndex, Bone slotBone) { - foreach (var entryObj in skin.Attachments.Keys) { - var entry = (Skin.SkinEntry)entryObj; + foreach (var entry in skin.Attachments) { if (entry.SlotIndex == slotIndex) SortPathConstraintAttachment(entry.Attachment, slotBone); } } diff --git a/spine-csharp/src/Skin.cs b/spine-csharp/src/Skin.cs index c21190499..11e91d8b8 100644 --- a/spine-csharp/src/Skin.cs +++ b/spine-csharp/src/Skin.cs @@ -39,12 +39,13 @@ namespace Spine { /// public class Skin { internal string name; - private OrderedDictionary attachments = new OrderedDictionary(SkinEntryComparer.Instance); + private OrderedDictionary attachments = new OrderedDictionary(SkinKeyComparer.Instance); internal readonly ExposedList bones = new ExposedList(); internal readonly ExposedList constraints = new ExposedList(); public string Name { get { return name; } } - public OrderedDictionary Attachments { get { return attachments; } } + ///Returns all attachments contained in this skin. + public ICollection Attachments { get { return attachments.Values; } } public ExposedList Bones { get { return bones; } } public ExposedList Constraints { get { return constraints; } } @@ -58,7 +59,7 @@ namespace Spine { public void SetAttachment (int slotIndex, string name, Attachment attachment) { if (attachment == null) throw new ArgumentNullException("attachment", "attachment cannot be null."); if (slotIndex < 0) throw new ArgumentNullException("slotIndex", "slotIndex must be >= 0."); - attachments[new SkinEntry(slotIndex, name, attachment)] = attachment; + attachments[new SkinKey(slotIndex, name)] = new SkinEntry(slotIndex, name, attachment); } ///Adds all attachments, bones, and constraints from the specified skin to this skin. @@ -69,7 +70,7 @@ namespace Spine { foreach (ConstraintData data in skin.constraints) if (!constraints.Contains(data)) constraints.Add(data); - foreach (SkinEntry entry in skin.attachments.Keys) + foreach (SkinEntry entry in skin.attachments.Values) SetAttachment(entry.SlotIndex, entry.Name, entry.Attachment); } @@ -81,7 +82,7 @@ namespace Spine { foreach (ConstraintData data in skin.constraints) if (!constraints.Contains(data)) constraints.Add(data); - foreach (SkinEntry entry in skin.attachments.Keys) { + foreach (SkinEntry entry in skin.attachments.Values) { if (entry.Attachment is MeshAttachment) SetAttachment(entry.SlotIndex, entry.Name, entry.Attachment != null ? ((MeshAttachment)entry.Attachment).NewLinkedMesh() : null); @@ -93,28 +94,23 @@ namespace Spine { /// Returns the attachment for the specified slot index and name, or null. /// May be null. public Attachment GetAttachment (int slotIndex, string name) { - var lookup = new SkinEntry(slotIndex, name, null); - Attachment attachment = null; - bool containsKey = attachments.TryGetValue(lookup, out attachment); - return containsKey ? attachment : null; + var lookup = new SkinKey(slotIndex, name); + SkinEntry entry; + bool containsKey = attachments.TryGetValue(lookup, out entry); + return containsKey ? entry.Attachment : null; } /// Removes the attachment in the skin for the specified slot index and name, if any. public void RemoveAttachment (int slotIndex, string name) { if (slotIndex < 0) throw new ArgumentOutOfRangeException("slotIndex", "slotIndex must be >= 0"); - var lookup = new SkinEntry(slotIndex, name, null); + var lookup = new SkinKey(slotIndex, name); attachments.Remove(lookup); } - ///Returns all attachments contained in this skin. - public ICollection GetAttachments () { - return this.attachments.Keys; - } - /// Returns all attachments in this skin for the specified slot index. /// The target slotIndex. To find the slot index, use or public void GetAttachments (int slotIndex, List attachments) { - foreach (SkinEntry entry in this.attachments.Keys) + foreach (SkinEntry entry in this.attachments.Values) if (entry.SlotIndex == slotIndex) attachments.Add(entry); } @@ -131,7 +127,7 @@ namespace Spine { /// Attach all attachments from this skin if the corresponding attachment from the old skin is currently attached. internal void AttachAll (Skeleton skeleton, Skin oldSkin) { - foreach (SkinEntry entry in oldSkin.attachments.Keys) { + foreach (SkinEntry entry in oldSkin.attachments.Values) { int slotIndex = entry.SlotIndex; Slot slot = skeleton.slots.Items[slotIndex]; if (slot.Attachment == entry.Attachment) { @@ -146,13 +142,11 @@ namespace Spine { private readonly int slotIndex; private readonly string name; private readonly Attachment attachment; - internal readonly int hashCode; public SkinEntry (int slotIndex, string name, Attachment attachment) { this.slotIndex = slotIndex; this.name = name; this.attachment = attachment; - this.hashCode = this.name.GetHashCode() + this.slotIndex * 37; } public int SlotIndex { @@ -175,17 +169,43 @@ namespace Spine { } } - // Avoids boxing in the dictionary and is necessary to omit entry.attachment in the comparison. - class SkinEntryComparer : IEqualityComparer { - internal static readonly SkinEntryComparer Instance = new SkinEntryComparer(); + /// Note: not present in libgdx reference implementation. + /// SkinKey contains slot index and name only, as a once-added SkinEntry cannot have its Attachment changed + /// (SkinEntry is a value type as opposed to the java reference implementation) without removing and + /// re-adding it to a dictionary, leading to problems in order and unnecessary operations. + private struct SkinKey { + private readonly int slotIndex; + private readonly string name; - bool IEqualityComparer.Equals (SkinEntry e1, SkinEntry e2) { + public SkinKey (int slotIndex, string name) { + this.slotIndex = slotIndex; + this.name = name; + } + + public int SlotIndex { + get { + return slotIndex; + } + } + + /// The name the attachment is associated with, equivalent to the skin placeholder name in the Spine editor. + public String Name { + get { + return name; + } + } + } + + class SkinKeyComparer : IEqualityComparer { + internal static readonly SkinKeyComparer Instance = new SkinKeyComparer(); + + bool IEqualityComparer.Equals (SkinKey e1, SkinKey e2) { if (e1.SlotIndex != e2.SlotIndex) return false; if (!string.Equals(e1.Name, e2.Name, StringComparison.Ordinal)) return false; return true; } - int IEqualityComparer.GetHashCode (SkinEntry e) { + int IEqualityComparer.GetHashCode (SkinKey e) { return e.Name.GetHashCode() + e.SlotIndex * 37; } } diff --git a/spine-unity/Assets/Spine Examples/Scripts/Mix and Match Character Customize/EquipsVisualsComponentExample.cs b/spine-unity/Assets/Spine Examples/Scripts/Mix and Match Character Customize/EquipsVisualsComponentExample.cs index d7b3b8092..31d0d97ec 100644 --- a/spine-unity/Assets/Spine Examples/Scripts/Mix and Match Character Customize/EquipsVisualsComponentExample.cs +++ b/spine-unity/Assets/Spine Examples/Scripts/Mix and Match Character Customize/EquipsVisualsComponentExample.cs @@ -53,7 +53,7 @@ namespace Spine.Unity.Examples { // OPTIONAL: Add all the attachments from the template skin. var templateSkin = skeletonAnimation.Skeleton.Data.FindSkin(templateSkinName); if (templateSkin != null) - equipsSkin.AddAttachments(templateSkin); + equipsSkin.AddSkin(templateSkin); skeletonAnimation.Skeleton.Skin = equipsSkin; RefreshSkeletonAttachments(); @@ -69,8 +69,8 @@ namespace Spine.Unity.Examples { // 1. Collect all the attachments of all active skins. collectedSkin = collectedSkin ?? new Skin("Collected skin"); collectedSkin.Clear(); - collectedSkin.AddAttachments(skeletonAnimation.Skeleton.Data.DefaultSkin); - collectedSkin.AddAttachments(equipsSkin); + collectedSkin.AddSkin(skeletonAnimation.Skeleton.Data.DefaultSkin); + collectedSkin.AddSkin(equipsSkin); // 2. Create a repacked skin. var repackedSkin = collectedSkin.GetRepackedSkin("Repacked skin", skeletonAnimation.SkeletonDataAsset.atlasAssets[0].PrimaryMaterial, out runtimeMaterial, out runtimeAtlas); diff --git a/spine-unity/Assets/Spine Examples/Scripts/MixAndMatch.cs b/spine-unity/Assets/Spine Examples/Scripts/MixAndMatch.cs index f835645de..bfba80a8b 100644 --- a/spine-unity/Assets/Spine Examples/Scripts/MixAndMatch.cs +++ b/spine-unity/Assets/Spine Examples/Scripts/MixAndMatch.cs @@ -119,8 +119,8 @@ namespace Spine.Unity.Examples { // call Skin.GetRepackedSkin to get a cloned skin with cloned attachments that all use one texture. if (repack) { var repackedSkin = new Skin("repacked skin"); - repackedSkin.AddAttachments(skeleton.Data.DefaultSkin); // Include the "default" skin. (everything outside of skin placeholders) - repackedSkin.AddAttachments(customSkin); // Include your new custom skin. + repackedSkin.AddSkin(skeleton.Data.DefaultSkin); // Include the "default" skin. (everything outside of skin placeholders) + repackedSkin.AddSkin(customSkin); // Include your new custom skin. repackedSkin = repackedSkin.GetRepackedSkin("repacked skin", sourceMaterial, out runtimeMaterial, out runtimeAtlas); // Pack all the items in the skin. skeleton.SetSkin(repackedSkin); // Assign the repacked skin to your Skeleton. if (bbFollower != null) bbFollower.Initialize(true); diff --git a/spine-unity/Assets/Spine Examples/Scripts/MixAndMatchGraphic.cs b/spine-unity/Assets/Spine Examples/Scripts/MixAndMatchGraphic.cs index 612323932..1252fb1d7 100644 --- a/spine-unity/Assets/Spine Examples/Scripts/MixAndMatchGraphic.cs +++ b/spine-unity/Assets/Spine Examples/Scripts/MixAndMatchGraphic.cs @@ -117,8 +117,8 @@ namespace Spine.Unity.Examples { // call Skin.GetRepackedSkin to get a cloned skin with cloned attachments that all use one texture. if (repack) { var repackedSkin = new Skin("repacked skin"); - repackedSkin.AddAttachments(skeleton.Data.DefaultSkin); - repackedSkin.AddAttachments(customSkin); + repackedSkin.AddSkin(skeleton.Data.DefaultSkin); + repackedSkin.AddSkin(customSkin); repackedSkin = repackedSkin.GetRepackedSkin("repacked skin", sourceMaterial, out runtimeMaterial, out runtimeAtlas); skeleton.SetSkin(repackedSkin); } else { diff --git a/spine-unity/Assets/Spine Examples/Scripts/Sample Components/CombinedSkin.cs b/spine-unity/Assets/Spine Examples/Scripts/Sample Components/CombinedSkin.cs index 903a9f273..2dfd31c5f 100644 --- a/spine-unity/Assets/Spine Examples/Scripts/Sample Components/CombinedSkin.cs +++ b/spine-unity/Assets/Spine Examples/Scripts/Sample Components/CombinedSkin.cs @@ -49,7 +49,7 @@ namespace Spine.Unity.Examples { combinedSkin.Clear(); foreach (var skinName in skinsToCombine) { var skin = skeleton.Data.FindSkin(skinName); - if (skin != null) combinedSkin.AddAttachments(skin); + if (skin != null) combinedSkin.AddSkin(skin); } skeleton.SetSkin(combinedSkin); diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/PointFollowerInspector.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/PointFollowerInspector.cs index 0dbbe8ee5..fcf7d5f89 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/PointFollowerInspector.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/PointFollowerInspector.cs @@ -112,10 +112,9 @@ namespace Spine.Unity.Editor { static void DrawPointsInSkin (Skin skin, Skeleton skeleton, Transform transform) { foreach (var skinEntry in skin.Attachments) { - var attachment = skinEntry.Value as PointAttachment; + var attachment = skinEntry.Attachment as PointAttachment; if (attachment != null) { - var skinKey = (Skin.SkinEntry)skinEntry.Key; - var slot = skeleton.Slots.Items[skinKey.SlotIndex]; + var slot = skeleton.Slots.Items[skinEntry.SlotIndex]; DrawPointAttachmentWithLabel(attachment, slot.Bone, transform); } } diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonMecanim.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonMecanim.cs index be4c93a48..0678d2ad8 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonMecanim.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonMecanim.cs @@ -180,7 +180,7 @@ namespace Spine.Unity { if (autoReset) { var previousAnimations = this.previousAnimations; for (int i = 0, n = previousAnimations.Count; i < n; i++) - previousAnimations[i].SetKeyedItemsToSetupPose(skeleton); + previousAnimations[i].Apply(skeleton, 0, 0, false, null, 0, MixBlend.Setup, MixDirection.Out); // SetKeyedItemsToSetupPose previousAnimations.Clear(); for (int layer = 0, n = animator.layerCount; layer < n; layer++) { diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/AtlasUtilities.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/AtlasUtilities.cs index 6468962ae..3bd102dc1 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/AtlasUtilities.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/AtlasUtilities.cs @@ -219,96 +219,6 @@ namespace Spine.Unity.AttachmentTools { } #region Runtime Repacking - /// - /// Fills the outputAttachments list with new attachment objects based on the attachments in sourceAttachments, but mapped to a new single texture using the same material. - /// The list of attachments to be repacked. - /// The List(Attachment) to populate with the newly created Attachment objects. - /// - /// May be null. If no Material property source is provided, no special - public static void GetRepackedAttachments (List sourceAttachments, List outputAttachments, Material materialPropertySource, out Material outputMaterial, out Texture2D outputTexture, int maxAtlasSize = 1024, int padding = 2, TextureFormat textureFormat = SpineTextureFormat, bool mipmaps = UseMipMaps, string newAssetName = "Repacked Attachments", bool clearCache = false, bool useOriginalNonrenderables = true) { - if (sourceAttachments == null) throw new System.ArgumentNullException("sourceAttachments"); - if (outputAttachments == null) throw new System.ArgumentNullException("outputAttachments"); - - // Use these to detect and use shared regions. - var existingRegions = new Dictionary(); - var regionIndexes = new List(); - var texturesToPack = new List(); - var originalRegions = new List(); - - outputAttachments.Clear(); - outputAttachments.AddRange(sourceAttachments); - - int newRegionIndex = 0; - for (int i = 0, n = sourceAttachments.Count; i < n; i++) { - var originalAttachment = sourceAttachments[i]; - - if (IsRenderable(originalAttachment)) { - var newAttachment = originalAttachment.GetCopy(true); - var region = newAttachment.GetRegion(); - int existingIndex; - if (existingRegions.TryGetValue(region, out existingIndex)) { - regionIndexes.Add(existingIndex); // Store the region index for the eventual new attachment. - } else { - originalRegions.Add(region); - texturesToPack.Add(region.ToTexture()); // Add the texture to the PackTextures argument - existingRegions.Add(region, newRegionIndex); // Add the region to the dictionary of known regions - regionIndexes.Add(newRegionIndex); // Store the region index for the eventual new attachment. - newRegionIndex++; - } - - outputAttachments[i] = newAttachment; - } else { - outputAttachments[i] = useOriginalNonrenderables ? originalAttachment : originalAttachment.GetCopy(true); - regionIndexes.Add(NonrenderingRegion); // Output attachments pairs with regionIndexes list 1:1. Pad with a sentinel if the attachment doesn't have a region. - } - } - - // Fill a new texture with the collected attachment textures. - var newTexture = new Texture2D(maxAtlasSize, maxAtlasSize, textureFormat, mipmaps); - newTexture.mipMapBias = AtlasUtilities.DefaultMipmapBias; - newTexture.name = newAssetName; - // Copy settings - if (texturesToPack.Count > 0) { - var sourceTexture = texturesToPack[0]; - newTexture.CopyTextureAttributesFrom(sourceTexture); - } - var rects = newTexture.PackTextures(texturesToPack.ToArray(), padding, maxAtlasSize); - - // Rehydrate the repacked textures as a Material, Spine atlas and Spine.AtlasAttachments - Shader shader = materialPropertySource == null ? Shader.Find("Spine/Skeleton") : materialPropertySource.shader; - var newMaterial = new Material(shader); - if (materialPropertySource != null) { - newMaterial.CopyPropertiesFromMaterial(materialPropertySource); - newMaterial.shaderKeywords = materialPropertySource.shaderKeywords; - } - - newMaterial.name = newAssetName; - newMaterial.mainTexture = newTexture; - var page = newMaterial.ToSpineAtlasPage(); - page.name = newAssetName; - - var repackedRegions = new List(); - for (int i = 0, n = originalRegions.Count; i < n; i++) { - var oldRegion = originalRegions[i]; - var newRegion = UVRectToAtlasRegion(rects[i], oldRegion, page); - repackedRegions.Add(newRegion); - } - - // Map the cloned attachments to the repacked atlas. - for (int i = 0, n = outputAttachments.Count; i < n; i++) { - var a = outputAttachments[i]; - if (IsRenderable(a)) - a.SetRegion(repackedRegions[regionIndexes[i]]); - } - - // Clean up. - if (clearCache) - AtlasUtilities.ClearCache(); - - outputTexture = newTexture; - outputMaterial = newMaterial; - } - /// /// Creates and populates a duplicate skin with cloned attachments that are backed by a new packed texture atlas /// comprised of all the regions from the original skin. @@ -363,14 +273,13 @@ namespace Spine.Unity.AttachmentTools { var originalRegions = new List(); int newRegionIndex = 0; - foreach (var skinEntry in skinAttachments) { - var originalKey = skinEntry.Key; - var originalAttachment = skinEntry.Value; + foreach (var originalSkinEntry in skinAttachments) { + var originalAttachment = originalSkinEntry.Attachment; - Attachment newAttachment; - if (IsRenderable(originalAttachment)) { - newAttachment = originalAttachment.GetCopy(true); - var region = newAttachment.GetRegion(); + if (originalAttachment is IHasRendererObject) { + var originalMeshAttachment = originalAttachment as MeshAttachment; + Attachment newAttachment = (originalMeshAttachment != null) ? originalMeshAttachment.NewLinkedMesh() : originalAttachment.Copy(); + var region = ((IHasRendererObject)newAttachment).RendererObject as AtlasRegion; int existingIndex; if (existingRegions.TryGetValue(region, out existingIndex)) { regionIndexes.Add(existingIndex); // Store the region index for the eventual new attachment. @@ -386,9 +295,9 @@ namespace Spine.Unity.AttachmentTools { } repackedAttachments.Add(newAttachment); - newSkin.SetAttachment(originalKey.SlotIndex, originalKey.Name, newAttachment); + newSkin.SetAttachment(originalSkinEntry.SlotIndex, originalSkinEntry.Name, newAttachment); } else { - newSkin.SetAttachment(originalKey.SlotIndex, originalKey.Name, useOriginalNonrenderables ? originalAttachment : originalAttachment.GetCopy(true)); + newSkin.SetAttachment(originalSkinEntry.SlotIndex, originalSkinEntry.Name, useOriginalNonrenderables ? originalAttachment : originalAttachment.Copy()); } } @@ -436,7 +345,7 @@ namespace Spine.Unity.AttachmentTools { // Map the cloned attachments to the repacked atlas. for (int i = 0, n = repackedAttachments.Count; i < n; i++) { var a = repackedAttachments[i]; - if (IsRenderable(a)) + if (a is IHasRendererObject) a.SetRegion(repackedRegions[regionIndexes[i]]); } @@ -523,10 +432,6 @@ namespace Spine.Unity.AttachmentTools { } } - static bool IsRenderable (Attachment a) { - return a is IHasRendererObject; - } - /// /// Get a rect with flipped Y so that a Spine atlas rect gets converted to a Unity Sprite rect and vice versa. static Rect SpineUnityFlipRect (this Rect rect, int textureHeight) { diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/AttachmentCloneExtensions.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/AttachmentCloneExtensions.cs index e5d8663b4..c411cf68a 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/AttachmentCloneExtensions.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/AttachmentCloneExtensions.cs @@ -34,44 +34,6 @@ using System.Collections; namespace Spine.Unity.AttachmentTools { public static class AttachmentCloneExtensions { - /// - /// Clones the attachment. - public static Attachment GetCopy (this Attachment o, bool cloneMeshesAsLinked) { - var meshAttachment = o as MeshAttachment; - if (meshAttachment != null && cloneMeshesAsLinked) - return meshAttachment.NewLinkedMesh(); - return o.Copy(); - } - - #region Runtime Linked MeshAttachments - /// - /// Returns a new linked mesh linked to this MeshAttachment. It will be mapped to the AtlasRegion provided. - public static MeshAttachment GetLinkedMesh (this MeshAttachment o, string newLinkedMeshName, AtlasRegion region) { - if (region == null) throw new System.ArgumentNullException("region"); - MeshAttachment mesh = o.NewLinkedMesh(); - mesh.SetRegion(region, false); - return mesh; - } - - /// - /// Returns a new linked mesh linked to this MeshAttachment. It will be mapped to an AtlasRegion generated from a Sprite. The AtlasRegion will be mapped to a new Material based on the shader. - /// For better caching and batching, use GetLinkedMesh(string, AtlasRegion, bool) - public static MeshAttachment GetLinkedMesh (this MeshAttachment o, Sprite sprite, Shader shader, Material materialPropertySource = null) { - var m = new Material(shader); - if (materialPropertySource != null) { - m.CopyPropertiesFromMaterial(materialPropertySource); - m.shaderKeywords = materialPropertySource.shaderKeywords; - } - return o.GetLinkedMesh(sprite.name, sprite.ToAtlasRegion()); - } - - /// - /// Returns a new linked mesh linked to this MeshAttachment. It will be mapped to an AtlasRegion generated from a Sprite. The AtlasRegion will be mapped to a new Material based on the shader. - /// For better caching and batching, use GetLinkedMesh(string, AtlasRegion, bool) - public static MeshAttachment GetLinkedMesh (this MeshAttachment o, Sprite sprite, Material materialPropertySource) { - return o.GetLinkedMesh(sprite, materialPropertySource.shader, materialPropertySource); - } - #endregion #region RemappedClone Convenience Methods /// @@ -115,8 +77,7 @@ namespace Spine.Unity.AttachmentTools { return newAttachment; } } - - return o.GetCopy(true); // Non-renderable Attachments will return as normal cloned attachments. + return o.Copy(); } #endregion } diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/SkeletonExtensions.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/SkeletonExtensions.cs index a451b91f6..41a7060a4 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/SkeletonExtensions.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/SkeletonExtensions.cs @@ -447,10 +447,6 @@ namespace Spine { return va.bones != null && va.bones.Length > 0; } - public static bool IsRenderable (this Attachment a) { - return a is IHasRendererObject; - } - #region Transform Modes public static bool InheritsRotation (this TransformMode mode) { const int RotationBit = 0; @@ -462,153 +458,5 @@ namespace Spine { return ((int)mode & (1U << ScaleBit)) == 0; } #endregion - - #region Posing - internal static void SetPropertyToSetupPose (this Skeleton skeleton, int propertyID) { - int tt = propertyID >> 24; - var timelineType = (TimelineType)tt; - int i = propertyID - (tt << 24); - - Bone bone; - IkConstraint ikc; - PathConstraint pc; - - switch (timelineType) { - // Bone - case TimelineType.Rotate: - bone = skeleton.bones.Items[i]; - bone.rotation = bone.data.rotation; - break; - case TimelineType.Translate: - bone = skeleton.bones.Items[i]; - bone.x = bone.data.x; - bone.y = bone.data.y; - break; - case TimelineType.Scale: - bone = skeleton.bones.Items[i]; - bone.scaleX = bone.data.scaleX; - bone.scaleY = bone.data.scaleY; - break; - case TimelineType.Shear: - bone = skeleton.bones.Items[i]; - bone.shearX = bone.data.shearX; - bone.shearY = bone.data.shearY; - break; - - // Slot - case TimelineType.Attachment: - skeleton.SetSlotAttachmentToSetupPose(i); - break; - case TimelineType.Color: - skeleton.slots.Items[i].SetColorToSetupPose(); - break; - case TimelineType.TwoColor: - skeleton.slots.Items[i].SetColorToSetupPose(); - break; - case TimelineType.Deform: - skeleton.slots.Items[i].Deform.Clear(); - break; - - // Skeleton - case TimelineType.DrawOrder: - skeleton.SetDrawOrderToSetupPose(); - break; - - // IK Constraint - case TimelineType.IkConstraint: - ikc = skeleton.ikConstraints.Items[i]; - ikc.mix = ikc.data.mix; - ikc.softness = ikc.data.softness; - ikc.bendDirection = ikc.data.bendDirection; - ikc.stretch = ikc.data.stretch; - break; - - // TransformConstraint - case TimelineType.TransformConstraint: - var tc = skeleton.transformConstraints.Items[i]; - var tcData = tc.data; - tc.rotateMix = tcData.rotateMix; - tc.translateMix = tcData.translateMix; - tc.scaleMix = tcData.scaleMix; - tc.shearMix = tcData.shearMix; - break; - - // Path Constraint - case TimelineType.PathConstraintPosition: - pc = skeleton.pathConstraints.Items[i]; - pc.position = pc.data.position; - break; - case TimelineType.PathConstraintSpacing: - pc = skeleton.pathConstraints.Items[i]; - pc.spacing = pc.data.spacing; - break; - case TimelineType.PathConstraintMix: - pc = skeleton.pathConstraints.Items[i]; - pc.rotateMix = pc.data.rotateMix; - pc.translateMix = pc.data.translateMix; - break; - } - } - - /// Resets the DrawOrder to the Setup Pose's draw order - public static void SetDrawOrderToSetupPose (this Skeleton skeleton) { - var slotsItems = skeleton.slots.Items; - int n = skeleton.slots.Count; - - var drawOrder = skeleton.drawOrder; - drawOrder.Clear(false); - drawOrder.EnsureCapacity(n); - drawOrder.Count = n; - System.Array.Copy(slotsItems, drawOrder.Items, n); - } - - /// Resets all the slots on the skeleton to their Setup Pose attachments but does not reset slot colors. - public static void SetSlotAttachmentsToSetupPose (this Skeleton skeleton) { - var slotsItems = skeleton.slots.Items; - for (int i = 0; i < skeleton.slots.Count; i++) { - Slot slot = slotsItems[i]; - string attachmentName = slot.data.attachmentName; - slot.Attachment = string.IsNullOrEmpty(attachmentName) ? null : skeleton.GetAttachment(i, attachmentName); - } - } - - /// Resets the color of a slot to Setup Pose value. - public static void SetColorToSetupPose (this Slot slot) { - slot.r = slot.data.r; - slot.g = slot.data.g; - slot.b = slot.data.b; - slot.a = slot.data.a; - slot.r2 = slot.data.r2; - slot.g2 = slot.data.g2; - slot.b2 = slot.data.b2; - } - - /// Sets a slot's attachment to setup pose. If you have the slotIndex, Skeleton.SetSlotAttachmentToSetupPose is faster. - public static void SetAttachmentToSetupPose (this Slot slot) { - var slotData = slot.data; - slot.Attachment = slot.bone.skeleton.GetAttachment(slotData.name, slotData.attachmentName); - } - - /// Resets the attachment of slot at a given slotIndex to setup pose. This is faster than Slot.SetAttachmentToSetupPose. - public static void SetSlotAttachmentToSetupPose (this Skeleton skeleton, int slotIndex) { - var slot = skeleton.slots.Items[slotIndex]; - string attachmentName = slot.data.attachmentName; - if (string.IsNullOrEmpty(attachmentName)) { - slot.Attachment = null; - } else { - var attachment = skeleton.GetAttachment(slotIndex, attachmentName); - slot.Attachment = attachment; - } - } - - /// Resets Skeleton parts to Setup Pose according to a Spine.Animation's keyed items. - public static void SetKeyedItemsToSetupPose (this Animation animation, Skeleton skeleton) { - animation.Apply(skeleton, 0, 0, false, null, 0, MixBlend.Setup, MixDirection.Out); - } - - public static void AllowImmediateQueue (this TrackEntry trackEntry) { - if (trackEntry.nextTrackLast < 0) trackEntry.nextTrackLast = 0; - } - #endregion } } diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/SkinUtilities.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/SkinUtilities.cs deleted file mode 100644 index 57112c8b4..000000000 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/SkinUtilities.cs +++ /dev/null @@ -1,165 +0,0 @@ -/****************************************************************************** - * Spine Runtimes License Agreement - * Last updated May 1, 2019. Replaces all prior versions. - * - * Copyright (c) 2013-2019, Esoteric Software LLC - * - * Integration of the Spine Runtimes into software or otherwise creating - * derivative works of the Spine Runtimes is permitted under the terms and - * conditions of Section 2 of the Spine Editor License Agreement: - * http://esotericsoftware.com/spine-editor-license - * - * Otherwise, it is permitted to integrate the Spine Runtimes into software - * or otherwise create derivative works of the Spine Runtimes (collectively, - * "Products"), provided that each user of the Products must obtain their own - * Spine Editor license and redistribution of the Products in any form must - * include this license and copyright notice. - * - * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS - * INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - *****************************************************************************/ - -using UnityEngine; -using System.Collections.Generic; -using System.Collections; - -namespace Spine.Unity.AttachmentTools { - - public static class SkinUtilities { - - #region Skeleton Skin Extensions - /// - /// Convenience method for duplicating a skeleton's current active skin so changes to it will not affect other skeleton instances. . - public static Skin UnshareSkin (this Skeleton skeleton, bool includeDefaultSkin, bool unshareAttachments, AnimationState state = null) { - // 1. Copy the current skin and set the skeleton's skin to the new one. - var newSkin = skeleton.GetClonedSkin("cloned skin", includeDefaultSkin, unshareAttachments, true); - skeleton.SetSkin(newSkin); - - // 2. Apply correct attachments: skeleton.SetToSetupPose + animationState.Apply - if (state != null) { - skeleton.SetToSetupPose(); - state.Apply(skeleton); - } - - // 3. Return unshared skin. - return newSkin; - } - - public static Skin GetClonedSkin (this Skeleton skeleton, string newSkinName, bool includeDefaultSkin = false, bool cloneAttachments = false, bool cloneMeshesAsLinked = true) { - var newSkin = new Skin(newSkinName); // may have null name. Harmless. - var defaultSkin = skeleton.data.DefaultSkin; - var activeSkin = skeleton.skin; - - if (includeDefaultSkin) - defaultSkin.CopyTo(newSkin, true, cloneAttachments, cloneMeshesAsLinked); - - if (activeSkin != null) - activeSkin.CopyTo(newSkin, true, cloneAttachments, cloneMeshesAsLinked); - - return newSkin; - } - #endregion - - /// - /// Gets a shallow copy of the skin. The cloned skin's attachments are shared with the original skin. - public static Skin GetClone (this Skin original) { - var newSkin = new Skin(original.name + " clone"); - var newSkinAttachments = newSkin.Attachments; - var newSkinBones = newSkin.Bones; - var newSkinConstraints = newSkin.Constraints; - - foreach (var a in original.Attachments) - newSkinAttachments[a.Key] = a.Value; - - newSkinBones.AddRange(original.bones); - newSkinConstraints.AddRange(original.constraints); - return newSkin; - } - - /// Adds an attachment to the skin for the specified slot index and name. If the name already exists for the slot, the previous value is replaced. - public static void SetAttachment (this Skin skin, string slotName, string keyName, Attachment attachment, Skeleton skeleton) { - int slotIndex = skeleton.FindSlotIndex(slotName); - if (skeleton == null) throw new System.ArgumentNullException("skeleton", "skeleton cannot be null."); - if (slotIndex == -1) throw new System.ArgumentException(string.Format("Slot '{0}' does not exist in skeleton.", slotName), "slotName"); - skin.SetAttachment(slotIndex, keyName, attachment); - } - - /// Adds skin items from another skin. For items that already exist, the previous values are replaced. - public static void AddAttachments (this Skin skin, Skin otherSkin) { - if (otherSkin == null) return; - otherSkin.CopyTo(skin, true, false); - } - - /// Gets an attachment from the skin for the specified slot index and name. - public static Attachment GetAttachment (this Skin skin, string slotName, string keyName, Skeleton skeleton) { - int slotIndex = skeleton.FindSlotIndex(slotName); - if (skeleton == null) throw new System.ArgumentNullException("skeleton", "skeleton cannot be null."); - if (slotIndex == -1) throw new System.ArgumentException(string.Format("Slot '{0}' does not exist in skeleton.", slotName), "slotName"); - return skin.GetAttachment(slotIndex, keyName); - } - - /// Adds an attachment to the skin for the specified slot index and name. If the name already exists for the slot, the previous value is replaced. - public static void SetAttachment (this Skin skin, int slotIndex, string keyName, Attachment attachment) { - skin.SetAttachment(slotIndex, keyName, attachment); - } - - public static void RemoveAttachment (this Skin skin, string slotName, string keyName, SkeletonData skeletonData) { - int slotIndex = skeletonData.FindSlotIndex(slotName); - if (skeletonData == null) throw new System.ArgumentNullException("skeletonData", "skeletonData cannot be null."); - if (slotIndex == -1) throw new System.ArgumentException(string.Format("Slot '{0}' does not exist in skeleton.", slotName), "slotName"); - skin.RemoveAttachment(slotIndex, keyName); - } - - public static void Clear (this Skin skin) { - skin.Attachments.Clear(); - } - - //[System.Obsolete] - public static void Append (this Skin destination, Skin source) { - source.CopyTo(destination, true, false); - } - - public static void CopyTo (this Skin source, Skin destination, bool overwrite, bool cloneAttachments, bool cloneMeshesAsLinked = true) { - var sourceAttachments = source.Attachments; - var destinationAttachments = destination.Attachments; - var destinationBones = destination.Bones; - var destinationConstraints = destination.Constraints; - - if (cloneAttachments) { - if (overwrite) { - foreach (var e in sourceAttachments) - destinationAttachments[e.Key] = e.Value.GetCopy(cloneMeshesAsLinked); - } else { - foreach (var e in sourceAttachments) { - if (destinationAttachments.ContainsKey(e.Key)) continue; - destinationAttachments.Add(e.Key, e.Value.GetCopy(cloneMeshesAsLinked)); - } - } - } else { - if (overwrite) { - foreach (var e in sourceAttachments) - destinationAttachments[e.Key] = e.Value; - } else { - foreach (var e in sourceAttachments) { - if (destinationAttachments.ContainsKey(e.Key)) continue; - destinationAttachments.Add(e.Key, e.Value); - } - } - } - - foreach (BoneData data in source.bones) - if (!destinationBones.Contains(data)) destinationBones.Add(data); - - foreach (ConstraintData data in source.constraints) - if (!destinationConstraints.Contains(data)) destinationConstraints.Add(data); - } - } -} diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/SkinUtilities.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/SkinUtilities.cs.meta deleted file mode 100644 index 5ac1f297b..000000000 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/SkinUtilities.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: f4692b9527684d048862210ba3f9834e -timeCreated: 1563321428 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/spine-unity/Modules/com.esotericsoftware.spine.timeline/Runtime/SpineAnimationState/SpineAnimationStateMixerBehaviour.cs b/spine-unity/Modules/com.esotericsoftware.spine.timeline/Runtime/SpineAnimationState/SpineAnimationStateMixerBehaviour.cs index 3d03d275c..219209945 100644 --- a/spine-unity/Modules/com.esotericsoftware.spine.timeline/Runtime/SpineAnimationState/SpineAnimationStateMixerBehaviour.cs +++ b/spine-unity/Modules/com.esotericsoftware.spine.timeline/Runtime/SpineAnimationState/SpineAnimationStateMixerBehaviour.cs @@ -161,7 +161,7 @@ namespace Spine.Unity.Playables { if (!isAnimationTransitionMatch) { dummyAnimationState.ClearTracks(); fromTrack = dummyAnimationState.SetAnimation(0, fromAnimation, fromClipLoop); - fromTrack.AllowImmediateQueue(); + if (fromTrack.nextTrackLast < 0) fromTrack.nextTrackLast = 0; // fromTrack.AllowImmediateQueue if (toAnimation != null) toTrack = dummyAnimationState.SetAnimation(0, toAnimation, clipData.loop); }