Эх сурвалжийг харах

[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.

Harald Csaszar 5 жил өмнө
parent
commit
f2a8c9a3c1

+ 5 - 0
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<SkinEntry>`. 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).

+ 1 - 2
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);
 			}
 		}

+ 44 - 24
spine-csharp/src/Skin.cs

@@ -39,12 +39,13 @@ namespace Spine {
 	/// </summary>
 	public class Skin {
 		internal string name;
-		private OrderedDictionary<SkinEntry, Attachment> attachments = new OrderedDictionary<SkinEntry, Attachment>(SkinEntryComparer.Instance);
+		private OrderedDictionary<SkinKey, SkinEntry> attachments = new OrderedDictionary<SkinKey, SkinEntry>(SkinKeyComparer.Instance);
 		internal readonly ExposedList<BoneData> bones = new ExposedList<BoneData>();
 		internal readonly ExposedList<ConstraintData> constraints = new ExposedList<ConstraintData>();
 
 		public string Name { get { return name; } }
-		public OrderedDictionary<SkinEntry, Attachment> Attachments { get { return attachments; } }
+		///<summary>Returns all attachments contained in this skin.</summary>
+		public ICollection<SkinEntry> Attachments { get { return attachments.Values; } }
 		public ExposedList<BoneData> Bones { get { return bones; } }
 		public ExposedList<ConstraintData> 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);
 		}
 
 		///<summary>Adds all attachments, bones, and constraints from the specified skin to this skin.</summary>
@@ -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 {
 		/// <summary>Returns the attachment for the specified slot index and name, or null.</summary>
 		/// <returns>May be null.</returns>
 		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;
 		}
 
 		/// <summary> Removes the attachment in the skin for the specified slot index and name, if any.</summary>
 		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);
 		}
 
-		///<summary>Returns all attachments contained in this skin.</summary>
-		public ICollection<SkinEntry> GetAttachments () {
-			return this.attachments.Keys;
-		}
-
 		/// <summary>Returns all attachments in this skin for the specified slot index.</summary>
 		/// <param name="slotIndex">The target slotIndex. To find the slot index, use <see cref="Spine.Skeleton.FindSlotIndex"/> or <see cref="Spine.SkeletonData.FindSlotIndex"/>
 		public void GetAttachments (int slotIndex, List<SkinEntry> 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 {
 
 		/// <summary>Attach all attachments from this skin if the corresponding attachment from the old skin is currently attached.</summary>
 		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<SkinEntry> {
-			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;
+
+			public SkinKey (int slotIndex, string name) {
+				this.slotIndex = slotIndex;
+				this.name = name;
+			}
+
+			public int SlotIndex {
+				get {
+					return slotIndex;
+				}
+			}
+
+			/// <summary>The name the attachment is associated with, equivalent to the skin placeholder name in the Spine editor.</summary>
+			public String Name {
+				get {
+					return name;
+				}
+			}
+		}
+
+		class SkinKeyComparer : IEqualityComparer<SkinKey> {
+			internal static readonly SkinKeyComparer Instance = new SkinKeyComparer();
 
-			bool IEqualityComparer<SkinEntry>.Equals (SkinEntry e1, SkinEntry e2) {
+			bool IEqualityComparer<SkinKey>.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<SkinEntry>.GetHashCode (SkinEntry e) {
+			int IEqualityComparer<SkinKey>.GetHashCode (SkinKey e) {
 				return e.Name.GetHashCode() + e.SlotIndex * 37;
 			}
 		}

+ 3 - 3
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);

+ 2 - 2
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);

+ 2 - 2
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 {

+ 1 - 1
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);

+ 2 - 3
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);
 				}
 			}

+ 1 - 1
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++) {

+ 9 - 104
spine-unity/Assets/Spine/Runtime/spine-unity/Utility/AtlasUtilities.cs

@@ -219,96 +219,6 @@ namespace Spine.Unity.AttachmentTools {
 		}
 
 		#region Runtime Repacking
-		/// <summary>
-		/// 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.</summary>
-		/// <param name="sourceAttachments">The list of attachments to be repacked.</param>
-		/// <param name = "outputAttachments">The List(Attachment) to populate with the newly created Attachment objects.</param>
-		///
-		/// <param name="materialPropertySource">May be null. If no Material property source is provided, no special </param>
-		public static void GetRepackedAttachments (List<Attachment> sourceAttachments, List<Attachment> 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<AtlasRegion, int>();
-			var regionIndexes = new List<int>();
-			var texturesToPack = new List<Texture2D>();
-			var originalRegions = new List<AtlasRegion>();
-
-			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<AtlasRegion>();
-			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;
-		}
-
 		/// <summary>
 		/// 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.</summary>
@@ -363,14 +273,13 @@ namespace Spine.Unity.AttachmentTools {
 			var originalRegions = new List<AtlasRegion>();
 			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;
-		}
-
 		/// <summary>
 		/// Get a rect with flipped Y so that a Spine atlas rect gets converted to a Unity Sprite rect and vice versa.</summary>
 		static Rect SpineUnityFlipRect (this Rect rect, int textureHeight) {

+ 1 - 40
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 {
-		/// <summary>
-		/// Clones the attachment.</summary>
-		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
-		/// <summary>
-		/// Returns a new linked mesh linked to this MeshAttachment. It will be mapped to the AtlasRegion provided.</summary>
-		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;
-		}
-
-		/// <summary>
-		/// 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)</summary>
-		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());
-		}
-
-		/// <summary>
-		/// 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)</summary>
-		public static MeshAttachment GetLinkedMesh (this MeshAttachment o, Sprite sprite, Material materialPropertySource) {
-			return o.GetLinkedMesh(sprite, materialPropertySource.shader, materialPropertySource);
-		}
-		#endregion
 
 		#region RemappedClone Convenience Methods
 		/// <summary>
@@ -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
 	}

+ 0 - 152
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;
-			}
-		}
-
-		/// <summary>Resets the DrawOrder to the Setup Pose's draw order</summary>
-		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);
-		}
-
-		/// <summary>Resets all the slots on the skeleton to their Setup Pose attachments but does not reset slot colors.</summary>
-		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);
-			}
-		}
-
-		/// <summary>Resets the color of a slot to Setup Pose value.</summary>
-		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;
-		}
-
-		/// <summary>Sets a slot's attachment to setup pose. If you have the slotIndex, Skeleton.SetSlotAttachmentToSetupPose is faster.</summary>
-		public static void SetAttachmentToSetupPose (this Slot slot) {
-			var slotData = slot.data;
-			slot.Attachment = slot.bone.skeleton.GetAttachment(slotData.name, slotData.attachmentName);
-		}
-
-		/// <summary>Resets the attachment of slot at a given slotIndex to setup pose. This is faster than Slot.SetAttachmentToSetupPose.</summary>
-		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;
-			}
-		}
-
-		/// <summary>Resets Skeleton parts to Setup Pose according to a Spine.Animation's keyed items.</summary>
-		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
 	}
 }

+ 0 - 165
spine-unity/Assets/Spine/Runtime/spine-unity/Utility/SkinUtilities.cs

@@ -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
-		/// <summary>
-		/// Convenience method for duplicating a skeleton's current active skin so changes to it will not affect other skeleton instances. .</summary>
-		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
-
-		/// <summary>
-		/// Gets a shallow copy of the skin. The cloned skin's attachments are shared with the original skin.</summary>
-		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;
-		}
-
-		/// <summary>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.</summary>
-		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);
-		}
-
-		/// <summary>Adds skin items from another skin. For items that already exist, the previous values are replaced.</summary>
-		public static void AddAttachments (this Skin skin, Skin otherSkin) {
-			if (otherSkin == null) return;
-			otherSkin.CopyTo(skin, true, false);
-		}
-
-		/// <summary>Gets an attachment from the skin for the specified slot index and name.</summary>
-		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);
-		}
-
-		/// <summary>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.</summary>
-		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);
-		}
-	}
-}

+ 0 - 12
spine-unity/Assets/Spine/Runtime/spine-unity/Utility/SkinUtilities.cs.meta

@@ -1,12 +0,0 @@
-fileFormatVersion: 2
-guid: f4692b9527684d048862210ba3f9834e
-timeCreated: 1563321428
-licenseType: Free
-MonoImporter:
-  serializedVersion: 2
-  defaultReferences: []
-  executionOrder: 0
-  icon: {instanceID: 0}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 

+ 1 - 1
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);
 					}