From bfeac4069c280c9327ae010097a1e26e9fd3fc57 Mon Sep 17 00:00:00 2001 From: Harald Csaszar Date: Thu, 26 Sep 2019 13:40:25 +0200 Subject: [PATCH 1/2] [unity] Renamed misleading `MixMode.SpineStyle` enum name at SkeletonMecanim to `MixMode.Hard`. SkeletonMecanim `Layer Mix Mode` now defaults to `MixMode.MixNext` instead of `MixMode.Hard` for new instances. Closes #1505. --- CHANGELOG.md | 3 ++- .../Runtime/spine-unity/Components/SkeletonMecanim.cs | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08ae32428..163bb8b97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -152,6 +152,7 @@ a) the `Packages` directory in your project where it will automatically be loaded, or b) to an arbitrary directory outside the Assets directory and then open Package Manager in Unity, select the `+` icon, choose `Add package from disk..` and point it to the package.json file. The Project panel should now show an entry `Spine Timeline Extensions` under `Packages`. If the directory is not yet listed, you will need to close and re-open Unity to have it display the directory and its contents. + * `SkeletonMecanim`'s `Layer Mix Mode` enum name `MixMode.SpineStyle` has been renamed to `MixMode.Hard`. This is most likely not set via code and thus unlikely to be a problem. Serialized scenes and prefabs are unaffected. * **Additions** * **Spine Preferences stored in Assets/Editor/SpineSettings.asset** Now Spine uses the new `SettingsProvider` API, storing settings in a SpineSettings.asset file which can be shared with team members. Your old preferences are automatically migrated to the new system. @@ -184,7 +185,7 @@ You can leave this parameter disabled when everything is drawn correctly to save the additional performance cost. * **Changes of default values** - * `SkeletonMecanim`'s `Layer Mix Mode` now defaults to `MixMode.SpineStyle` instead of `MixMode.MixAlways`. + * `SkeletonMecanim`'s `Layer Mix Mode` now defaults to `MixMode.MixNext` instead of `MixMode.MixAlways`. * `BlendModeMaterialAsset` and it's instance `Default BlendModeMaterials.asset` now have `Apply Additive Material` set to `true` by default in order to apply all blend modes by default. * **Deprecated** 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 8de48117c..be4c93a48 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonMecanim.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonMecanim.cs @@ -116,7 +116,7 @@ namespace Spine.Unity { public MixBlend[] layerBlendModes = new MixBlend[0]; #endregion - public enum MixMode { AlwaysMix, MixNext, SpineStyle } + public enum MixMode { AlwaysMix, MixNext, Hard } readonly Dictionary animationTable = new Dictionary(IntEqualityComparer.Instance); readonly Dictionary clipNameHashCodeTable = new Dictionary(AnimationClipEqualityComparer.Instance); @@ -161,7 +161,7 @@ namespace Spine.Unity { public void Apply (Skeleton skeleton) { if (layerMixModes.Length < animator.layerCount) { System.Array.Resize(ref layerMixModes, animator.layerCount); - layerMixModes[animator.layerCount-1] = MixMode.SpineStyle; + layerMixModes[animator.layerCount-1] = MixMode.MixNext; } #if UNITY_EDITOR @@ -266,7 +266,7 @@ namespace Spine.Unity { interruptingStateInfo.loop, null, weight, layerBlendMode, MixDirection.In); } } - } else { // case MixNext || SpineStyle + } else { // case MixNext || Hard // Apply first non-zero weighted clip int c = 0; for (; c < clipInfoCount; c++) { @@ -283,7 +283,7 @@ namespace Spine.Unity { c = 0; if (hasNext) { // Apply next clip directly instead of mixing (ie: no crossfade, ignores mecanim transition weights) - if (mode == MixMode.SpineStyle) { + if (mode == MixMode.Hard) { for (; c < nextClipInfoCount; c++) { var info = nextClipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue; GetAnimation(info.clip).Apply(skeleton, 0, AnimationTime(nextStateInfo.normalizedTime, info.clip.length, nextStateInfo.speed < 0), nextStateInfo.loop, null, 1f, layerBlendMode, MixDirection.In); @@ -300,7 +300,7 @@ namespace Spine.Unity { c = 0; if (isInterruptionActive) { // Apply next clip directly instead of mixing (ie: no crossfade, ignores mecanim transition weights) - if (mode == MixMode.SpineStyle) { + if (mode == MixMode.Hard) { for (; c < interruptingClipInfoCount; c++) { var info = interruptingClipInfo[c]; float clipWeight = shallInterpolateWeightTo1 ? (info.weight + 1.0f) * 0.5f : info.weight; From 679a012cc311c6ae639fa34dbd15075377320c17 Mon Sep 17 00:00:00 2001 From: badlogic Date: Thu, 26 Sep 2019 14:29:43 +0200 Subject: [PATCH 2/2] [libgdx] SkinEntry equals and hashCode do not take the attachment field into account. When setting a new SkinEntry for an existing slot + name combination, the old key with the old attachment stays in the keys table of the OrderedMap. Upon a call to getAttachments() that keys table is returned, which means the old attachment is returned instead of the newly set attachment. This commit fixes this buggy behaviour by storing SkinEntries as values, giving us access to the re-used key on which we can then update the attachment field. I'm sorry. Closes #1485. --- .../src/com/esotericsoftware/spine/Skin.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Skin.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Skin.java index f3bd7df4e..70a0e5704 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Skin.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Skin.java @@ -31,7 +31,6 @@ package com.esotericsoftware.spine; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.OrderedMap; - import com.esotericsoftware.spine.attachments.Attachment; import com.esotericsoftware.spine.attachments.MeshAttachment; @@ -41,7 +40,7 @@ import com.esotericsoftware.spine.attachments.MeshAttachment; * Runtime skins in the Spine Runtimes Guide. */ public class Skin { final String name; - final OrderedMap attachments = new OrderedMap(); + final OrderedMap attachments = new OrderedMap(); final Array bones = new Array(); final Array constraints = new Array(); private final SkinEntry lookup = new SkinEntry(); @@ -56,7 +55,11 @@ public class Skin { public void setAttachment (int slotIndex, String name, Attachment attachment) { if (slotIndex < 0) throw new IllegalArgumentException("slotIndex must be >= 0."); if (attachment == null) throw new IllegalArgumentException("attachment cannot be null."); - attachments.put(new SkinEntry(slotIndex, name, attachment), attachment); + SkinEntry newEntry = new SkinEntry(slotIndex, name, attachment); + SkinEntry oldEntry = attachments.put(newEntry, newEntry); + if (oldEntry != null) { + oldEntry.attachment = attachment; + } } /** Adds all attachments, bones, and constraints from the specified skin to this skin. */ @@ -96,7 +99,8 @@ public class Skin { public Attachment getAttachment (int slotIndex, String name) { if (slotIndex < 0) throw new IllegalArgumentException("slotIndex must be >= 0."); lookup.set(slotIndex, name); - return attachments.get(lookup); + SkinEntry entry = attachments.get(lookup); + return entry != null ? entry.attachment : null; } /** Removes the attachment in the skin for the specified slot index and name, if any. */