diff --git a/spine-csharp/src/Animation.cs b/spine-csharp/src/Animation.cs index d10be09dd..1288d6dbf 100644 --- a/spine-csharp/src/Animation.cs +++ b/spine-csharp/src/Animation.cs @@ -336,7 +336,7 @@ namespace Spine { override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList firedEvents, float alpha, MixBlend blend, MixDirection direction) { Bone bone = skeleton.bones.Items[boneIndex]; - + if (!bone.active) return; float[] frames = this.frames; if (time < frames[0]) { // Time is before first frame. switch (blend) { @@ -438,7 +438,7 @@ namespace Spine { override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList firedEvents, float alpha, MixBlend blend, MixDirection direction) { Bone bone = skeleton.bones.Items[boneIndex]; - + if (!bone.active) return; float[] frames = this.frames; if (time < frames[0]) { // Time is before first frame. switch (blend) { @@ -501,7 +501,7 @@ namespace Spine { override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList firedEvents, float alpha, MixBlend blend, MixDirection direction) { Bone bone = skeleton.bones.Items[boneIndex]; - + if (!bone.active) return; float[] frames = this.frames; if (time < frames[0]) { // Time is before first frame. switch (blend) { @@ -606,6 +606,7 @@ namespace Spine { override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList firedEvents, float alpha, MixBlend blend, MixDirection direction) { Bone bone = skeleton.bones.Items[boneIndex]; + if (!bone.active) return; float[] frames = this.frames; if (time < frames[0]) { // Time is before first frame. switch (blend) { @@ -699,6 +700,7 @@ namespace Spine { override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList firedEvents, float alpha, MixBlend blend, MixDirection direction) { Slot slot = skeleton.slots.Items[slotIndex]; + if (!slot.bone.active) return; float[] frames = this.frames; if (time < frames[0]) { // Time is before first frame. var slotData = slot.data; @@ -816,6 +818,7 @@ namespace Spine { override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList firedEvents, float alpha, MixBlend blend, MixDirection direction) { Slot slot = skeleton.slots.Items[slotIndex]; + if (!slot.bone.active) return; float[] frames = this.frames; if (time < frames[0]) { // Time is before first frame. var slotData = slot.data; @@ -960,6 +963,7 @@ namespace Spine { MixDirection direction) { string attachmentName; Slot slot = skeleton.slots.Items[slotIndex]; + if (!slot.bone.active) return; if (direction == MixDirection.Out && blend == MixBlend.Setup) { attachmentName = slot.data.attachmentName; slot.Attachment = attachmentName == null ? null : skeleton.GetAttachment(slotIndex, attachmentName); @@ -1033,6 +1037,7 @@ namespace Spine { override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList firedEvents, float alpha, MixBlend blend, MixDirection direction) { Slot slot = skeleton.slots.Items[slotIndex]; + if (!slot.bone.active) return; VertexAttachment vertexAttachment = slot.attachment as VertexAttachment; if (vertexAttachment == null || vertexAttachment.DeformAttachment != attachment) return; @@ -1393,6 +1398,7 @@ namespace Spine { override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList firedEvents, float alpha, MixBlend blend, MixDirection direction) { IkConstraint constraint = skeleton.ikConstraints.Items[ikConstraintIndex]; + if (!constraint.active) return; float[] frames = this.frames; if (time < frames[0]) { // Time is before first frame. switch (blend) { @@ -1508,6 +1514,7 @@ namespace Spine { override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList firedEvents, float alpha, MixBlend blend, MixDirection direction) { TransformConstraint constraint = skeleton.transformConstraints.Items[transformConstraintIndex]; + if (!constraint.active) return; float[] frames = this.frames; if (time < frames[0]) { // Time is before first frame. TransformConstraintData data = constraint.data; @@ -1608,6 +1615,7 @@ namespace Spine { override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList firedEvents, float alpha, MixBlend blend, MixDirection direction) { PathConstraint constraint = skeleton.pathConstraints.Items[pathConstraintIndex]; + if (!constraint.active) return; float[] frames = this.frames; if (time < frames[0]) { // Time is before first frame. switch (blend) { @@ -1654,6 +1662,7 @@ namespace Spine { override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList events, float alpha, MixBlend blend, MixDirection direction) { PathConstraint constraint = skeleton.pathConstraints.Items[pathConstraintIndex]; + if (!constraint.active) return; float[] frames = this.frames; if (time < frames[0]) { // Time is before first frame. switch (blend) { @@ -1731,6 +1740,7 @@ namespace Spine { override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList firedEvents, float alpha, MixBlend blend, MixDirection direction) { PathConstraint constraint = skeleton.pathConstraints.Items[pathConstraintIndex]; + if (!constraint.active) return; float[] frames = this.frames; if (time < frames[0]) { // Time is before first frame. switch (blend) { diff --git a/spine-csharp/src/AnimationState.cs b/spine-csharp/src/AnimationState.cs index f07d274e3..36fa0541e 100644 --- a/spine-csharp/src/AnimationState.cs +++ b/spine-csharp/src/AnimationState.cs @@ -351,18 +351,20 @@ namespace Spine { return mix; } - static private void ApplyRotateTimeline (RotateTimeline rotateTimeline, Skeleton skeleton, float time, float alpha, MixBlend blend, + static private void ApplyRotateTimeline (RotateTimeline timeline, Skeleton skeleton, float time, float alpha, MixBlend blend, float[] timelinesRotation, int i, bool firstFrame) { if (firstFrame) timelinesRotation[i] = 0; if (alpha == 1) { - rotateTimeline.Apply(skeleton, 0, time, null, 1, blend, MixDirection.In); + timeline.Apply(skeleton, 0, time, null, 1, blend, MixDirection.In); return; } - Bone bone = skeleton.bones.Items[rotateTimeline.boneIndex]; - float[] frames = rotateTimeline.frames; + Bone bone = skeleton.bones.Items[timeline.boneIndex]; + if (!bone.active) return; + + float[] frames = timeline.frames; float r1, r2; if (time < frames[0]) { // Time is before first frame. switch (blend) { @@ -385,7 +387,7 @@ namespace Spine { int frame = Animation.BinarySearch(frames, time, RotateTimeline.ENTRIES); float prevRotation = frames[frame + RotateTimeline.PREV_ROTATION]; float frameTime = frames[frame]; - float percent = rotateTimeline.GetCurvePercent((frame >> 1) - 1, + float percent = timeline.GetCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + RotateTimeline.PREV_TIME] - frameTime)); r2 = frames[frame + RotateTimeline.ROTATION] - prevRotation; diff --git a/spine-csharp/src/Bone.cs b/spine-csharp/src/Bone.cs index a91d3978e..7bf4335ba 100644 --- a/spine-csharp/src/Bone.cs +++ b/spine-csharp/src/Bone.cs @@ -52,12 +52,15 @@ namespace Spine { internal float a, b, worldX; internal float c, d, worldY; - internal bool sorted, update; + internal bool sorted, active; public BoneData Data { get { return data; } } public Skeleton Skeleton { get { return skeleton; } } public Bone Parent { get { return parent; } } public ExposedList Children { get { return children; } } + /// Returns false when the bone has not been computed because is true and the + /// active skin does not contain this bone. + public bool Active { get { return active; } } /// The local X translation. public float X { get { return x; } set { x = value; } } /// The local Y translation. diff --git a/spine-csharp/src/IUpdatable.cs b/spine-csharp/src/IUpdatable.cs index 3c2e6021a..4c480d777 100644 --- a/spine-csharp/src/IUpdatable.cs +++ b/spine-csharp/src/IUpdatable.cs @@ -28,7 +28,15 @@ *****************************************************************************/ namespace Spine { + + ///The interface for items updated by . public interface IUpdatable { void Update (); + + ///Returns false when this item has not been updated because a skin is required and the active + /// skin does not contain this item. + /// + /// + bool Active { get; } } } diff --git a/spine-csharp/src/IkConstraint.cs b/spine-csharp/src/IkConstraint.cs index 92b51f2a7..f30cfdfc0 100644 --- a/spine-csharp/src/IkConstraint.cs +++ b/spine-csharp/src/IkConstraint.cs @@ -45,6 +45,8 @@ namespace Spine { internal bool compress, stretch; internal float mix = 1; + internal bool active; + public IkConstraint (IkConstraintData data, Skeleton skeleton) { if (data == null) throw new ArgumentNullException("data", "data cannot be null."); if (skeleton == null) throw new ArgumentNullException("skeleton", "skeleton cannot be null."); @@ -131,6 +133,10 @@ namespace Spine { set { stretch = value; } } + public bool Active { + get { return active; } + } + /// The IK constraint's setup pose data. public IkConstraintData Data { get { return data; } diff --git a/spine-csharp/src/PathConstraint.cs b/spine-csharp/src/PathConstraint.cs index efaa29a7d..268e3c098 100644 --- a/spine-csharp/src/PathConstraint.cs +++ b/spine-csharp/src/PathConstraint.cs @@ -47,6 +47,8 @@ namespace Spine { internal Slot target; internal float position, spacing, rotateMix, translateMix; + internal bool active; + internal ExposedList spaces = new ExposedList(), positions = new ExposedList(); internal ExposedList world = new ExposedList(), curves = new ExposedList(), lengths = new ExposedList(); internal float[] segments = new float[10]; @@ -458,6 +460,7 @@ namespace Spine { public ExposedList Bones { get { return bones; } } /// The slot whose path attachment will be used to constrained the bones. public Slot Target { get { return target; } set { target = value; } } + public bool Active { get { return active; } } /// The path constraint's setup pose data. public PathConstraintData Data { get { return data; } } } diff --git a/spine-csharp/src/Skeleton.cs b/spine-csharp/src/Skeleton.cs index 20a879201..4dcf13f97 100644 --- a/spine-csharp/src/Skeleton.cs +++ b/spine-csharp/src/Skeleton.cs @@ -118,8 +118,8 @@ namespace Spine { UpdateWorldTransform(); } - /// Caches information about bones and constraints. Must be called if the skin is modified or if bones, constraints, or - /// weighted path attachments are added or removed. + /// Caches information about bones and constraints. Must be called if the is modified or if bones, constraints, or + /// constraints, or weighted path attachments are added or removed. public void UpdateCache () { var updateCache = this.updateCache; updateCache.Clear(); @@ -129,8 +129,19 @@ namespace Spine { var bones = this.bones; for (int i = 0; i < boneCount; i++) { Bone bone = bones.Items[i]; - bone.update = !bone.data.skinRequired || (skin != null && skin.bones.Contains(bone.data)); - bone.sorted = !bone.update; + bone.sorted = bone.data.skinRequired; + bone.active = !bone.sorted; + } + if (skin != null) { + Object[] skinBones = skin.bones.Items; + for (int i = 0, n = skin.bones.Count; i < n; i++) { + Bone bone = (Bone)bones.Items[((BoneData)skinBones[i]).index]; + do { + bone.sorted = false; + bone.active = true; + bone = bone.parent; + } while (bone != null); + } } int ikCount = this.ikConstraints.Count, transformCount = this.transformConstraints.Count, pathCount = this.pathConstraints.Count; @@ -169,7 +180,9 @@ namespace Spine { } private void SortIkConstraint (IkConstraint constraint) { - if (constraint.data.skinRequired && (skin == null || !skin.constraints.Contains(constraint.data))) return; + constraint.active = constraint.target.active + && (!constraint.data.skinRequired || (skin != null && skin.constraints.Contains(constraint.data))); + if (!constraint.active) return; Bone target = constraint.target; SortBone(target); @@ -191,7 +204,9 @@ namespace Spine { } private void SortPathConstraint (PathConstraint constraint) { - if (constraint.data.skinRequired && (skin == null || !skin.constraints.Contains(constraint.data))) return; + constraint.active = constraint.target.bone.active + && (!constraint.data.skinRequired || (skin != null && skin.constraints.Contains(constraint.data))); + if (!constraint.active) return; Slot slot = constraint.target; int slotIndex = slot.data.index; @@ -217,7 +232,9 @@ namespace Spine { } private void SortTransformConstraint (TransformConstraint constraint) { - if (constraint.data.skinRequired && (skin == null || !skin.constraints.Contains(constraint.data))) return; + constraint.active = constraint.target.active + && (!constraint.data.skinRequired || (skin != null && skin.constraints.Contains(constraint.data))); + if (!constraint.active) return; SortBone(constraint.target); @@ -277,7 +294,7 @@ namespace Spine { var bonesItems = bones.Items; for (int i = 0, n = bones.Count; i < n; i++) { Bone bone = bonesItems[i]; - if (!bone.update) continue; + if (!bone.active) continue; if (bone.sorted) SortReset(bone.children); bone.sorted = false; } @@ -574,8 +591,9 @@ namespace Spine { temp = temp ?? new float[8]; var drawOrderItems = this.drawOrder.Items; float minX = int.MaxValue, minY = int.MaxValue, maxX = int.MinValue, maxY = int.MinValue; - for (int i = 0, n = this.drawOrder.Count; i < n; i++) { + for (int i = 0, n = drawOrderItems.Length; i < n; i++) { Slot slot = drawOrderItems[i]; + if (!slot.bone.active) continue; int verticesLength = 0; float[] vertices = null; Attachment attachment = slot.attachment; diff --git a/spine-csharp/src/TransformConstraint.cs b/spine-csharp/src/TransformConstraint.cs index 9ab64cdf0..9fdd7a3c7 100644 --- a/spine-csharp/src/TransformConstraint.cs +++ b/spine-csharp/src/TransformConstraint.cs @@ -42,6 +42,8 @@ namespace Spine { internal ExposedList bones; internal Bone target; internal float rotateMix, translateMix, scaleMix, shearMix; + + internal bool active; public TransformConstraint (TransformConstraintData data, Skeleton skeleton) { if (data == null) throw new ArgumentNullException("data", "data cannot be null."); @@ -300,6 +302,7 @@ namespace Spine { public float ScaleMix { get { return scaleMix; } set { scaleMix = value; } } /// A percentage (0-1) that controls the mix between the constrained and unconstrained scales. public float ShearMix { get { return shearMix; } set { shearMix = value; } } + public bool Active { get { return active; } } /// The transform constraint's setup pose data. public TransformConstraintData Data { get { return data; } } diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Skeleton.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Skeleton.java index 04bdfca6d..af8e53440 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Skeleton.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Skeleton.java @@ -666,6 +666,7 @@ public class Skeleton { float minX = Integer.MAX_VALUE, minY = Integer.MAX_VALUE, maxX = Integer.MIN_VALUE, maxY = Integer.MIN_VALUE; for (int i = 0, n = drawOrder.size; i < n; i++) { Slot slot = drawOrder.get(i); + if (!slot.bone.active) continue; int verticesLength = 0; float[] vertices = null; Attachment attachment = slot.attachment; diff --git a/spine-libgdx/spine-skeletonviewer/src/com/esotericsoftware/spine/JsonRollback.java b/spine-libgdx/spine-skeletonviewer/src/com/esotericsoftware/spine/JsonRollback.java index e597ef48b..95d3faa5b 100644 --- a/spine-libgdx/spine-skeletonviewer/src/com/esotericsoftware/spine/JsonRollback.java +++ b/spine-libgdx/spine-skeletonviewer/src/com/esotericsoftware/spine/JsonRollback.java @@ -33,10 +33,12 @@ import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Json; import com.badlogic.gdx.utils.JsonValue; +import com.badlogic.gdx.utils.JsonValue.ValueType; import com.badlogic.gdx.utils.JsonWriter.OutputType; -/** Takes Spine JSON data and transforms it to work with an older version of Spine. It supports going from version 3.3.xx to - * 2.1.27. +/** Takes Spine JSON data and transforms it to work with an older version of Spine. Target versions:
+ * 2.1: supports going from version 3.3.xx to 2.1.27.
+ * 3.7: supports going from version 3.8.xx to 3.7.94. *

* Data can be exported from a Spine project, processed with JsonRollback, then imported into an older version of Spine. However, * JsonRollback may remove data for features not supported by the older Spine version. Because of this, JsonRollback is only @@ -47,67 +49,107 @@ import com.badlogic.gdx.utils.JsonWriter.OutputType; * the runtime is updated to support a newer Spine version should animators update their Spine editor version to match. */ public class JsonRollback { static public void main (String[] args) throws Exception { - if (args.length == 0) { - System.out.println("Usage: [outputFile]"); + if (args.length != 2 && args.length != 3) { + System.out.println("Usage: [outputFile]"); + System.exit(0); + } + + String version = args[1]; + if (!version.equals("2.1") && !version.equals("3.7")) { + System.out.println("ERROR: Target version must be: 2.1 or 3.7"); + System.out.println("Usage: [outputFile]"); System.exit(0); } JsonValue root = new Json().fromJson(null, new FileHandle(args[0])); - // In 3.2 skinnedmesh was renamed to weightedmesh. - setValue(root, "skinnedmesh", "skins", "*", "*", "*", "type", "weightedmesh"); + if (version.equals("2.1")) { + // In 3.2 skinnedmesh was renamed to weightedmesh. + setValue(root, "skinnedmesh", "skins", "*", "*", "*", "type", "weightedmesh"); - // In 3.2 shear was added. - delete(root, "animations", "*", "bones", "*", "shear"); + // In 3.2 shear was added. + delete(root, "animations", "*", "bones", "*", "shear"); - // In 3.3 ffd was renamed to deform. - rename(root, "ffd", "animations", "*", "deform"); + // In 3.3 ffd was renamed to deform. + rename(root, "ffd", "animations", "*", "deform"); - // In 3.3 mesh is now a single type, previously they were skinnedmesh if they had weights. - for (JsonValue value : find(root, new Array(), 0, "skins", "*", "*", "*", "type", "mesh")) - if (value.parent.get("uvs").size != value.parent.get("vertices").size) value.set("skinnedmesh"); + // In 3.3 mesh is now a single type, previously they were skinnedmesh if they had weights. + for (JsonValue value : find(root, new Array(), 0, "skins", "*", "*", "*", "type", "mesh")) + if (value.parent.get("uvs").size != value.parent.get("vertices").size) value.set("skinnedmesh"); - // In 3.3 linkedmesh is now a single type, previously they were linkedweightedmesh if they had weights. - for (JsonValue value : find(root, new Array(), 0, "skins", "*", "*", "*", "type", "linkedmesh")) { - String slot = value.parent.parent.name.replaceAll("", ""); - String skinName = value.parent.getString("skin", "default"); - String parentName = value.parent.getString("parent"); - if (find(root, new Array(), 0, - ("skins~~" + skinName + "~~" + slot + "~~" + parentName + "~~type~~skinnedmesh").split("~~")).size > 0) - value.set("weightedlinkedmesh"); + // In 3.3 linkedmesh is now a single type, previously they were linkedweightedmesh if they had weights. + for (JsonValue value : find(root, new Array(), 0, "skins", "*", "*", "*", "type", "linkedmesh")) { + String slot = value.parent.parent.name.replaceAll("", ""); + String skinName = value.parent.getString("skin", "default"); + String parentName = value.parent.getString("parent"); + if (find(root, new Array(), 0, + ("skins~~" + skinName + "~~" + slot + "~~" + parentName + "~~type~~skinnedmesh").split("~~")).size > 0) + value.set("weightedlinkedmesh"); + } + + // In 3.3 bounding boxes can be weighted. + for (JsonValue value : find(root, new Array(), 0, "skins", "*", "*", "*", "type", "boundingbox")) + if (value.parent.getInt("vertexCount") * 2 != value.parent.get("vertices").size) + value.parent.parent.remove(value.parent.name); + + // In 3.3 paths were added. + for (JsonValue value : find(root, new Array(), 0, "skins", "*", "*", "*", "type", "path")) { + String attachment = value.parent.name; + value.parent.parent.remove(attachment); + String slot = value.parent.parent.name; + // Also remove path deform timelines. + delete(root, "animations", "*", "ffd", "*", slot, attachment); + } + + // In 3.3 IK constraint timelines no longer require bendPositive. + for (JsonValue value : find(root, new Array(), 0, "animations", "*", "ik", "*")) + for (JsonValue child = value.child; child != null; child = child.next) + if (!child.has("bendPositive")) child.addChild("bendPositive", new JsonValue(true)); + + // In 3.3 transform constraints can have more than 1 bone. + for (JsonValue child = root.getChild("transform"); child != null; child = child.next) { + JsonValue bones = child.remove("bones"); + if (bones != null) child.addChild("bone", new JsonValue(bones.child.asString())); + } + } else if (version.equals("3.7")) { + JsonValue skins = root.get("skins"); + if (skins != null && skins.isArray()) { + JsonValue newSkins = new JsonValue(ValueType.object); + for (JsonValue skinMap = skins.child; skinMap != null; skinMap = skinMap.next) + newSkins.addChild(skinMap.getString("name"), skinMap.get("attachments")); + root.remove("skins"); + root.addChild("skins", newSkins); + } + + rollbackCurves(root.get("animations")); } - // In 3.3 bounding boxes can be weighted. - for (JsonValue value : find(root, new Array(), 0, "skins", "*", "*", "*", "type", "boundingbox")) - if (value.parent.getInt("vertexCount") * 2 != value.parent.get("vertices").size) - value.parent.parent.remove(value.parent.name); - - // In 3.3 paths were added. - for (JsonValue value : find(root, new Array(), 0, "skins", "*", "*", "*", "type", "path")) { - String attachment = value.parent.name; - value.parent.parent.remove(attachment); - String slot = value.parent.parent.name; - // Also remove path deform timelines. - delete(root, "animations", "*", "ffd", "*", slot, attachment); - } - - // In 3.3 IK constraint timelines no longer require bendPositive. - for (JsonValue value : find(root, new Array(), 0, "animations", "*", "ik", "*")) - for (JsonValue child = value.child; child != null; child = child.next) - if (!child.has("bendPositive")) child.addChild("bendPositive", new JsonValue(true)); - - // In 3.3 transform constraints can have more than 1 bone. - for (JsonValue child = root.getChild("transform"); child != null; child = child.next) { - JsonValue bones = child.remove("bones"); - if (bones != null) child.addChild("bone", new JsonValue(bones.child.asString())); - } - - if (args.length > 1) - new FileHandle(args[1]).writeString(root.prettyPrint(OutputType.json, 130), false, "UTF-8"); + if (args.length == 3) + new FileHandle(args[2]).writeString(root.prettyPrint(OutputType.json, 130), false, "UTF-8"); else System.out.println(root.prettyPrint(OutputType.json, 130)); } + static private void rollbackCurves (JsonValue map) { + if (map == null) return; + JsonValue curve = map.get("curve"); + if (curve == null) { + for (map = map.child; map != null; map = map.next) + rollbackCurves(map); + return; + } + if (curve.isNumber()) { + curve.addChild(new JsonValue(curve.asFloat())); + curve.setType(ValueType.array); + curve.addChild(new JsonValue(map.getFloat("c2", 0))); + curve.addChild(new JsonValue(map.getFloat("c3", 0))); + curve.addChild(new JsonValue(map.getFloat("c4", 0))); + map.remove("c2"); + map.remove("c3"); + map.remove("c4"); + } + } + static void setValue (JsonValue root, String newValue, String... path) { for (JsonValue value : find(root, new Array(), 0, path)) value.set(newValue); diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonDebugWindow.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonDebugWindow.cs index 17bab0cd3..ff8a44916 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonDebugWindow.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonDebugWindow.cs @@ -481,7 +481,10 @@ namespace Spine.Unity.Editor { if (Application.isPlaying) { foreach (var slot in skeleton.DrawOrder) { if (skeletonRenderer.separatorSlots.Contains(slot)) EditorGUILayout.LabelField(SeparatorString); - EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(slot.Data.Name, Icons.slot), GUILayout.ExpandWidth(false)); + + using (new EditorGUI.DisabledScope(!slot.Bone.Active)) { + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(slot.Data.Name, Icons.slot), GUILayout.ExpandWidth(false)); + } } } else { foreach (var slot in skeleton.DrawOrder) { @@ -492,7 +495,9 @@ namespace Spine.Unity.Editor { break; } } - EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(slot.Data.Name, Icons.slot), GUILayout.ExpandWidth(false)); + using (new EditorGUI.DisabledScope(!slot.Bone.Active)) { + EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(slot.Data.Name, Icons.slot), GUILayout.ExpandWidth(false)); + } } } diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SpineEditorUtilities.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SpineEditorUtilities.cs index 4ac4655bd..facc85c01 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SpineEditorUtilities.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SpineEditorUtilities.cs @@ -2294,6 +2294,7 @@ namespace Spine.Unity.Editor { public static void DrawBoneNames (Transform transform, Skeleton skeleton, float positionScale = 1f) { GUIStyle style = BoneNameStyle; foreach (Bone b in skeleton.Bones) { + if (!b.Active) continue; var pos = new Vector3(b.WorldX * positionScale, b.WorldY * positionScale, 0) + (new Vector3(b.A, b.C) * (b.Data.Length * 0.5f)); pos = transform.TransformPoint(pos); Handles.Label(pos, b.Data.Name, style); @@ -2305,6 +2306,7 @@ namespace Spine.Unity.Editor { DrawCrosshairs2D(skeleton.Bones.Items[0].GetWorldPosition(transform), 0.08f, positionScale); foreach (Bone b in skeleton.Bones) { + if (!b.Active) continue; DrawBone(transform, b, boneScale, positionScale); boneScale = 1f; } diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/SpineMesh.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/SpineMesh.cs index fb1408112..85e7dfe47 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/SpineMesh.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/SpineMesh.cs @@ -211,6 +211,7 @@ namespace Spine.Unity { var drawOrderItems = drawOrder.Items; for (int i = 0; i < drawOrderCount; i++) { Slot slot = drawOrderItems[i]; + if (!slot.bone.active) continue; Attachment attachment = slot.attachment; workingAttachmentsItems[i] = attachment; @@ -285,6 +286,7 @@ namespace Spine.Unity { var drawOrderItems = drawOrder.Items; for (int i = 0; i < drawOrderCount; i++) { Slot slot = drawOrderItems[i]; + if (!slot.bone.active) continue; Attachment attachment = slot.attachment; #if SPINE_TRIANGLECHECK workingAttachmentsItems[i] = attachment; @@ -495,6 +497,7 @@ namespace Spine.Unity { for (int slotIndex = instruction.startSlot; slotIndex < instruction.endSlot; slotIndex++) { var slot = drawOrderItems[slotIndex]; + if (!slot.bone.active) continue; var attachment = slot.attachment; float z = zSpacing * slotIndex; @@ -701,7 +704,7 @@ namespace Spine.Unity { for (int si = 0, n = instruction.submeshInstructions.Count; si < n; si++) { var submesh = instruction.submeshInstructions.Items[si]; var skeleton = submesh.skeleton; - var skeletonDrawOrderItems = skeleton.drawOrder.Items; + var drawOrderItems = skeleton.drawOrder.Items; float a = skeleton.a * 255, r = skeleton.r, g = skeleton.g, b = skeleton.b; int endSlot = submesh.endSlot; @@ -729,7 +732,8 @@ namespace Spine.Unity { var uv3i = uv3.Items; for (int slotIndex = startSlot; slotIndex < endSlot; slotIndex++) { - var slot = skeletonDrawOrderItems[slotIndex]; + var slot = drawOrderItems[slotIndex]; + if (!slot.bone.active) continue; var attachment = slot.attachment; rg.x = slot.r2; //r @@ -756,7 +760,8 @@ namespace Spine.Unity { } for (int slotIndex = startSlot; slotIndex < endSlot; slotIndex++) { - var slot = skeletonDrawOrderItems[slotIndex]; + var slot = drawOrderItems[slotIndex]; + if (!slot.bone.active) continue; var attachment = slot.attachment; float z = slotIndex * settings.zSpacing; @@ -909,9 +914,12 @@ namespace Spine.Unity { var tris = currentSubmeshBuffer.Items; int triangleIndex = 0; var skeleton = submeshInstruction.skeleton; - var skeletonDrawOrderItems = skeleton.drawOrder.Items; - for (int a = submeshInstruction.startSlot, endSlot = submeshInstruction.endSlot; a < endSlot; a++) { - var attachment = skeletonDrawOrderItems[a].attachment; + var drawOrderItems = skeleton.drawOrder.Items; + for (int slotIndex = submeshInstruction.startSlot, endSlot = submeshInstruction.endSlot; slotIndex < endSlot; slotIndex++) { + var slot = drawOrderItems[slotIndex]; + if (!slot.bone.active) continue; + + var attachment = drawOrderItems[slotIndex].attachment; if (attachment is RegionAttachment) { tris[triangleIndex] = attachmentFirstVertex; tris[triangleIndex + 1] = attachmentFirstVertex + 2; @@ -1475,9 +1483,13 @@ namespace Spine.Unity { attachments.Resize(attachmentCount); var attachmentsItems = attachments.Items; - var drawOrder = instructionsItems[0].skeleton.drawOrder.Items; - for (int i = 0; i < attachmentCount; i++) - attachmentsItems[i] = drawOrder[startSlot + i].attachment; + var drawOrderItems = instructionsItems[0].skeleton.drawOrder.Items; + for (int i = 0; i < attachmentCount; i++) { + Slot slot = drawOrderItems[startSlot + i]; + if (!slot.bone.active) continue; + attachmentsItems[i] = slot.attachment; + } + #endif }