Browse Source

[csharp] Ported commits 549e9ae and 6e709a1, (format changes for 4.0.24-beta) "Added separate keying for translateX/Y, scaleX/Y, shearX/Y, and colorRGB/A.". Updated example skeletons.

Harald Csaszar 4 years ago
parent
commit
407c591a2c
25 changed files with 1081 additions and 185 deletions
  1. 686 17
      spine-csharp/src/Animation.cs
  2. 128 18
      spine-csharp/src/SkeletonBinary.cs
  3. 122 5
      spine-csharp/src/SkeletonJson.cs
  4. 8 8
      spine-unity/Assets/Spine Examples/Scripts/MecanimAnimationMatchModifier/AnimationMatchModifierAsset.cs
  5. 14 14
      spine-unity/Assets/Spine Examples/Spine Skeletons/Dragon/dragon.json
  6. 1 1
      spine-unity/Assets/Spine Examples/Spine Skeletons/Eyes/eyes.json
  7. 1 1
      spine-unity/Assets/Spine Examples/Spine Skeletons/FootSoldier/FootSoldier.json
  8. 3 3
      spine-unity/Assets/Spine Examples/Spine Skeletons/Gauge/Gauge.json
  9. 1 1
      spine-unity/Assets/Spine Examples/Spine Skeletons/Goblins/goblins.json
  10. 5 5
      spine-unity/Assets/Spine Examples/Spine Skeletons/Hero/hero-pro.json
  11. 1 1
      spine-unity/Assets/Spine Examples/Spine Skeletons/Raggedy Spineboy/raggedy spineboy.json
  12. 3 3
      spine-unity/Assets/Spine Examples/Spine Skeletons/Raptor/raptor.json
  13. 19 19
      spine-unity/Assets/Spine Examples/Spine Skeletons/Spineunitygirl/Doi.json
  14. 4 4
      spine-unity/Assets/Spine Examples/Spine Skeletons/Stretchyman/stretchyman.json
  15. 2 2
      spine-unity/Assets/Spine Examples/Spine Skeletons/mix-and-match/mix-and-match-pro.json
  16. 4 4
      spine-unity/Assets/Spine Examples/Spine Skeletons/raptor-pro-and-mask/raptor-pro.json
  17. 17 17
      spine-unity/Assets/Spine Examples/Spine Skeletons/spineboy-pro/spineboy-pro.json
  18. 37 37
      spine-unity/Assets/Spine Examples/Spine Skeletons/spineboy-unity/spineboy-unity.json
  19. 1 1
      spine-unity/Assets/Spine Examples/Spine Skeletons/whirlyblendmodes/whirlyblendmodes.json
  20. 4 4
      spine-unity/Modules/com.esotericsoftware.spine.lwrp-shaders/Spine Skeletons/RaptorLWRP/raptor-pro.json
  21. 4 4
      spine-unity/Modules/com.esotericsoftware.spine.lwrp-shaders/Spine Skeletons/StretchymanLWRP/stretchyman.json
  22. 4 4
      spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Examples/2D/Spine Skeletons/RaptorURP/raptor-pro.json
  23. 4 4
      spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Examples/2D/Spine Skeletons/StretchymanURP/stretchyman.json
  24. 4 4
      spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Examples/3D/Spine Skeletons/RaptorURP/raptor-pro.json
  25. 4 4
      spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Examples/3D/Spine Skeletons/StretchymanURP/stretchyman.json

+ 686 - 17
spine-csharp/src/Animation.cs

@@ -200,7 +200,7 @@ namespace Spine {
 
 	internal enum Property {
 		Rotate=0, TranslateX, TranslateY, ScaleX, ScaleY, ShearX, ShearY, //
-		RGBA, RGB2, //
+		RGB, Alpha, RGB2, //
 		Attachment, Deform, //
 		Event, DrawOrder, //
 		IkConstraint, TransformConstraint, //
@@ -588,6 +588,104 @@ namespace Spine {
 		}
 	}
 
+	/// <summary>Changes a bone's local <see cref"Bone.X"/>.</summary>
+	public class TranslateXTimeline : CurveTimeline1, IBoneTimeline {
+		readonly int boneIndex;
+
+		public TranslateXTimeline (int frameCount, int bezierCount, int boneIndex)
+			: base(frameCount, bezierCount, (int)Property.TranslateX + "|" + boneIndex) {
+			this.boneIndex = boneIndex;
+		}
+
+		public int BoneIndex {
+			get {
+				return boneIndex;
+			}
+		}
+
+		override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList<Event> 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) {
+					case MixBlend.Setup:
+						bone.x = bone.data.x;
+						return;
+					case MixBlend.First:
+						bone.x += (bone.data.x - bone.x) * alpha;
+						break;
+				}
+				return;
+			}
+
+			float x = GetCurveValue(time);
+			switch (blend) {
+				case MixBlend.Setup:
+					bone.x = bone.data.x + x * alpha;
+					break;
+				case MixBlend.First:
+				case MixBlend.Replace:
+					bone.x += (bone.data.x + x - bone.x) * alpha;
+					break;
+				case MixBlend.Add:
+					bone.x += x * alpha;
+					break;
+			}
+		}
+	}
+
+	/// <summary>Changes a bone's local <see cref"Bone.Y"/>.</summary>
+	public class TranslateYTimeline : CurveTimeline1, IBoneTimeline {
+		readonly int boneIndex;
+
+		public TranslateYTimeline (int frameCount, int bezierCount, int boneIndex)
+			: base(frameCount, bezierCount, (int)Property.TranslateY + "|" + boneIndex) {
+			this.boneIndex = boneIndex;
+		}
+
+		public int BoneIndex {
+			get {
+				return boneIndex;
+			}
+		}
+
+		override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList<Event> 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) {
+				case MixBlend.Setup:
+					bone.y = bone.data.y;
+					return;
+				case MixBlend.First:
+					bone.y += (bone.data.y - bone.y) * alpha;
+					break;
+				}
+				return;
+			}
+
+			float y = GetCurveValue(time);
+			switch (blend) {
+			case MixBlend.Setup:
+				bone.y = bone.data.y + y * alpha;
+				break;
+			case MixBlend.First:
+			case MixBlend.Replace:
+				bone.y += (bone.data.y + y - bone.y) * alpha;
+				break;
+			case MixBlend.Add:
+				bone.y += y * alpha;
+				break;
+			}
+		}
+	}
+
 	/// <summary>Changes a bone's local <see cref="Bone.ScaleX"> and <see cref="Bone.ScaleY">.</summary>
 	public class ScaleTimeline : CurveTimeline2, IBoneTimeline {
 		readonly int boneIndex;
@@ -708,6 +806,164 @@ namespace Spine {
 		}
 	}
 
+	/// <summary>Changes a bone's local <see cref="Bone.ScaleX">.</summary>
+	public class ScaleXTimeline : CurveTimeline1, IBoneTimeline {
+		readonly int boneIndex;
+
+		public ScaleXTimeline (int frameCount, int bezierCount, int boneIndex)
+			: base(frameCount, bezierCount, (int)Property.ScaleX + "|" + boneIndex) {
+			this.boneIndex = boneIndex;
+		}
+
+		public int BoneIndex {
+			get {
+				return boneIndex;
+			}
+		}
+
+		override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList<Event> 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) {
+				case MixBlend.Setup:
+					bone.scaleX = bone.data.scaleX;
+					return;
+				case MixBlend.First:
+					bone.scaleX += (bone.data.scaleX - bone.scaleX) * alpha;
+					break;
+				}
+				return;
+			}
+
+			float x = GetCurveValue(time) * bone.data.scaleX;
+			if (alpha == 1) {
+				if (blend == MixBlend.Add)
+					bone.scaleX += x - bone.data.scaleX;
+				else
+					bone.scaleX = x;
+			} else {
+				// Mixing out uses sign of setup or current pose, else use sign of key.
+				float bx;
+				if (direction == MixDirection.Out) {
+					switch (blend) {
+					case MixBlend.Setup:
+						bx = bone.data.scaleX;
+						bone.scaleX = bx + (Math.Abs(x) * Math.Sign(bx) - bx) * alpha;
+						break;
+					case MixBlend.First:
+					case MixBlend.Replace:
+						bx = bone.scaleX;
+						bone.scaleX = bx + (Math.Abs(x) * Math.Sign(bx) - bx) * alpha;
+						break;
+					case MixBlend.Add:
+						bx = bone.scaleX;
+						bone.scaleX = bx + (Math.Abs(x) * Math.Sign(bx) - bone.data.scaleX) * alpha;
+						break;
+					}
+				} else {
+					switch (blend) {
+					case MixBlend.Setup:
+						bx = Math.Abs(bone.data.scaleX) * Math.Sign(x);
+						bone.scaleX = bx + (x - bx) * alpha;
+						break;
+					case MixBlend.First:
+					case MixBlend.Replace:
+						bx = Math.Abs(bone.scaleX) * Math.Sign(x);
+						bone.scaleX = bx + (x - bx) * alpha;
+						break;
+					case MixBlend.Add:
+						bx = Math.Sign(x);
+						bone.scaleX = Math.Abs(bone.scaleX) * bx + (x - Math.Abs(bone.data.scaleX) * bx) * alpha;
+						break;
+					}
+				}
+			}
+		}
+	}
+
+	/// <summary>Changes a bone's local <see cref="Bone.ScaleY">.</summary>
+	public class ScaleYTimeline : CurveTimeline1, IBoneTimeline {
+		readonly int boneIndex;
+
+		public ScaleYTimeline (int frameCount, int bezierCount, int boneIndex)
+			: base(frameCount, bezierCount, (int)Property.ScaleY + "|" + boneIndex) {
+			this.boneIndex = boneIndex;
+		}
+
+		public int BoneIndex {
+			get {
+				return boneIndex;
+			}
+		}
+
+		override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList<Event> 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) {
+				case MixBlend.Setup:
+					bone.scaleY = bone.data.scaleY;
+					return;
+				case MixBlend.First:
+					bone.scaleY += (bone.data.scaleY - bone.scaleY) * alpha;
+					break;
+				}
+				return;
+			}
+
+			float y = GetCurveValue(time) * bone.data.scaleY;
+			if (alpha == 1) {
+				if (blend == MixBlend.Add)
+					bone.scaleY += y - bone.data.scaleY;
+				else
+					bone.scaleY = y;
+			} else {
+				// Mixing out uses sign of setup or current pose, else use sign of key.
+				float by;
+				if (direction == MixDirection.Out) {
+					switch (blend) {
+					case MixBlend.Setup:
+						by = bone.data.scaleY;
+						bone.scaleY = by + (Math.Abs(y) * Math.Sign(by) - by) * alpha;
+						break;
+					case MixBlend.First:
+					case MixBlend.Replace:
+						by = bone.scaleY;
+						bone.scaleY = by + (Math.Abs(y) * Math.Sign(by) - by) * alpha;
+						break;
+					case MixBlend.Add:
+						by = bone.scaleY;
+						bone.scaleY = by + (Math.Abs(y) * Math.Sign(by) - bone.data.scaleY) * alpha;
+						break;
+					}
+				} else {
+					switch (blend) {
+					case MixBlend.Setup:
+						by = Math.Abs(bone.data.scaleY) * Math.Sign(y);
+						bone.scaleY = by + (y - by) * alpha;
+						break;
+					case MixBlend.First:
+					case MixBlend.Replace:
+						by = Math.Abs(bone.scaleY) * Math.Sign(y);
+						bone.scaleY = by + (y - by) * alpha;
+						break;
+					case MixBlend.Add:
+						by = Math.Sign(y);
+						bone.scaleY = Math.Abs(bone.scaleY) * by + (y - Math.Abs(bone.data.scaleY) * by) * alpha;
+						break;
+					}
+				}
+			}
+		}
+	}
+
 	/// <summary>Changes a bone's local <see cref="Bone.ShearX"/> and <see cref="Bone.ShearY"/>.</summary>
 	public class ShearTimeline : CurveTimeline2, IBoneTimeline {
 		readonly int boneIndex;
@@ -785,16 +1041,115 @@ namespace Spine {
 		}
 	}
 
+	/// <summary>Changes a bone's local <see cref="Bone.ShearX"/>.</summary>
+	public class ShearXTimeline : CurveTimeline1, IBoneTimeline {
+		readonly int boneIndex;
+
+		public ShearXTimeline (int frameCount, int bezierCount, int boneIndex)
+			: base(frameCount, bezierCount, (int)Property.ShearX + "|" + boneIndex) {
+			this.boneIndex = boneIndex;
+		}
+
+		public int BoneIndex {
+			get {
+				return boneIndex;
+			}
+		}
+
+		override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList<Event> 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) {
+				case MixBlend.Setup:
+					bone.shearX = bone.data.shearX;
+					return;
+				case MixBlend.First:
+					bone.shearX += (bone.data.shearX - bone.shearX) * alpha;
+					break;
+				}
+				return;
+			}
+
+			float x = GetCurveValue(time);
+			switch (blend) {
+			case MixBlend.Setup:
+				bone.shearX = bone.data.shearX + x * alpha;
+				break;
+			case MixBlend.First:
+			case MixBlend.Replace:
+				bone.shearX += (bone.data.shearX + x - bone.shearX) * alpha;
+				break;
+			case MixBlend.Add:
+				bone.shearX += x * alpha;
+				break;
+			}
+		}
+	}
+
+	/// <summary>Changes a bone's local <see cref="Bone.ShearY"/>.</summary>
+	public class ShearYTimeline : CurveTimeline1, IBoneTimeline {
+		readonly int boneIndex;
+
+		public ShearYTimeline (int frameCount, int bezierCount, int boneIndex)
+			: base(frameCount, bezierCount, (int)Property.ShearY + "|" + boneIndex) {
+			this.boneIndex = boneIndex;
+		}
+
+		public int BoneIndex {
+			get {
+				return boneIndex;
+			}
+		}
+
+		override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList<Event> 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) {
+				case MixBlend.Setup:
+					bone.shearY = bone.data.shearY;
+					return;
+				case MixBlend.First:
+					bone.shearY += (bone.data.shearY - bone.shearY) * alpha;
+					break;
+				}
+				return;
+			}
+
+			float y = GetCurveValue(time);
+			switch (blend) {
+			case MixBlend.Setup:
+				bone.shearY = bone.data.shearY + y * alpha;
+				break;
+			case MixBlend.First:
+			case MixBlend.Replace:
+				bone.shearY += (bone.data.shearY + y - bone.shearY) * alpha;
+				break;
+			case MixBlend.Add:
+				bone.shearY += y * alpha;
+				break;
+			}
+		}
+	}
+
 	/// <summary>Changes a slot's <see cref="Slot.Color"/>.</summary>
-	public class ColorTimeline : CurveTimeline, ISlotTimeline {
+	public class RGBATimeline : CurveTimeline, ISlotTimeline {
 		public const int ENTRIES = 5;
 		protected const int R = 1, G = 2, B = 3, A = 4;
 
 		readonly int slotIndex;
 
-		public ColorTimeline (int frameCount, int bezierCount, int slotIndex)
+		public RGBATimeline (int frameCount, int bezierCount, int slotIndex)
 			: base(frameCount, bezierCount, //
-				(int)Property.RGBA + "|" + slotIndex) {
+				(int)Property.RGB + "|" + slotIndex, //
+				(int)Property.Alpha + "|" + slotIndex) {
 			this.slotIndex = slotIndex;
 		}
 		public override int FrameEntries {
@@ -826,19 +1181,19 @@ namespace Spine {
 
 			float[] frames = this.frames;
 			if (time < frames[0]) { // Time is before first frame.
-				var slotData = slot.data;
+				var setup = slot.data;
 				switch (blend) {
 				case MixBlend.Setup:
-					slot.r = slotData.r;
-					slot.g = slotData.g;
-					slot.b = slotData.b;
-					slot.a = slotData.a;
+					slot.r = setup.r;
+					slot.g = setup.g;
+					slot.b = setup.b;
+					slot.a = setup.a;
 					return;
 				case MixBlend.First:
-					slot.r += (slotData.r - slot.r) * alpha;
-					slot.g += (slotData.g - slot.g) * alpha;
-					slot.b += (slotData.b - slot.b) * alpha;
-					slot.a += (slotData.a - slot.a) * alpha;
+					slot.r += (setup.r - slot.r) * alpha;
+					slot.g += (setup.g - slot.g) * alpha;
+					slot.b += (setup.b - slot.b) * alpha;
+					slot.a += (setup.a - slot.a) * alpha;
 					slot.ClampColor();
 					return;
 				}
@@ -902,17 +1257,175 @@ namespace Spine {
 		}
 	}
 
+	/// <summary>Changes the RGB for a slot's <see cref="Slot.Color"/>.</summary>
+	public class RGBTimeline : CurveTimeline, ISlotTimeline {
+		public const int ENTRIES = 4;
+		protected const int R = 1, G = 2, B = 3;
+
+		readonly int slotIndex;
+
+		public RGBTimeline (int frameCount, int bezierCount, int slotIndex)
+			: base(frameCount, bezierCount, //
+				(int)Property.RGB + "|" + slotIndex) {
+			this.slotIndex = slotIndex;
+		}
+		public override int FrameEntries {
+			get { return ENTRIES; }
+		}
+
+		public int SlotIndex {
+			get {
+				return slotIndex;
+			}
+		}
+
+		/// <summary>Sets the time and color for the specified frame.</summary>
+		/// <param name="frame">Between 0 and <code>frameCount</code>, inclusive.</param>
+		/// <param name="time">The frame time in seconds.</param>
+		public void SetFrame (int frame, float time, float r, float g, float b) {
+			frame <<= 2;
+			frames[frame] = time;
+			frames[frame + R] = r;
+			frames[frame + G] = g;
+			frames[frame + B] = b;
+		}
+
+		override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList<Event> 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 setup = slot.data;
+				switch (blend) {
+					case MixBlend.Setup:
+						slot.r = setup.r;
+						slot.g = setup.g;
+						slot.b = setup.b;
+						return;
+					case MixBlend.First:
+						slot.r += (setup.r - slot.r) * alpha;
+						slot.g += (setup.g - slot.g) * alpha;
+						slot.b += (setup.b - slot.b) * alpha;
+						slot.ClampColor();
+						return;
+				}
+				return;
+			}
+
+			float r, g, b;
+			int i = Animation.Search(frames, time, ENTRIES), curveType = (int)curves[i >> 2];
+			switch (curveType) {
+				case LINEAR:
+					float before = frames[i];
+					r = frames[i + R];
+					g = frames[i + G];
+					b = frames[i + B];
+					float t = (time - before) / (frames[i + ENTRIES] - before);
+					r += (frames[i + ENTRIES + R] - r) * t;
+					g += (frames[i + ENTRIES + G] - g) * t;
+					b += (frames[i + ENTRIES + B] - b) * t;
+					break;
+				case STEPPED:
+					r = frames[i + R];
+					g = frames[i + G];
+					b = frames[i + B];
+					break;
+				default:
+					r = GetBezierValue(time, i, R, curveType - BEZIER);
+					g = GetBezierValue(time, i, G, curveType + BEZIER_SIZE - BEZIER);
+					b = GetBezierValue(time, i, B, curveType + BEZIER_SIZE * 2 - BEZIER);
+					break;
+			}
+
+			if (alpha == 1) {
+				slot.r = r;
+				slot.g = g;
+				slot.b = b;
+				slot.ClampColor();
+			}
+			else {
+				float br, bg, bb;
+				if (blend == MixBlend.Setup) {
+					var setup = slot.data;
+					br = setup.r;
+					bg = setup.g;
+					bb = setup.b;
+				}
+				else {
+					br = slot.r;
+					bg = slot.g;
+					bb = slot.b;
+				}
+				slot.r = br + ((r - br) * alpha);
+				slot.g = bg + ((g - bg) * alpha);
+				slot.b = bb + ((b - bb) * alpha);
+				slot.ClampColor();
+			}
+		}
+	}
+
+	/// <summary>Changes the alpha for a slot's <see cref="Slot.Color"/>.</summary>
+	public class AlphaTimeline : CurveTimeline1, ISlotTimeline {
+		readonly int slotIndex;
+
+		public AlphaTimeline (int frameCount, int bezierCount, int slotIndex)
+			: base(frameCount, bezierCount, (int)Property.Alpha + "|" + slotIndex) {
+			this.slotIndex = slotIndex;
+		}
+
+		public int SlotIndex {
+			get {
+				return slotIndex;
+			}
+		}
+
+		override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList<Event> 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 setup = slot.data;
+				switch (blend) {
+					case MixBlend.Setup:
+						slot.a = setup.a;
+						return;
+					case MixBlend.First:
+						slot.a += (setup.a - slot.a) * alpha;
+						slot.ClampColor();
+						return;
+				}
+				return;
+			}
+
+			float a = GetCurveValue(time);
+			if (alpha == 1) {
+				slot.a = a;
+				slot.ClampColor();
+			}
+			else {
+				if (blend == MixBlend.Setup) slot.a = slot.data.a;
+				slot.a += (a - slot.a) * alpha;
+				slot.ClampColor();
+			}
+		}
+	}
+
 	/// <summary>Changes a slot's <see cref="Slot.Color"/> and <see cref="Slot.DarkColor"/> for two color tinting.</summary>
-	public class TwoColorTimeline : CurveTimeline, ISlotTimeline {
+	public class RGBA2Timeline : CurveTimeline, ISlotTimeline {
 		public const int ENTRIES = 8;
 		protected const int R = 1, G = 2, B = 3, A = 4, R2 = 5, G2 = 6, B2 = 7;
 
 		readonly int slotIndex;
 
-		public TwoColorTimeline (int frameCount, int bezierCount, int slotIndex)
+		public RGBA2Timeline (int frameCount, int bezierCount, int slotIndex)
 			: base(frameCount, bezierCount, //
-				(int)Property.RGBA + "|" + slotIndex, //
-				(int) Property.RGB2 + "|" + slotIndex) {
+				(int)Property.RGB + "|" + slotIndex, //
+				(int)Property.Alpha + "|" + slotIndex, //
+				(int)Property.RGB2 + "|" + slotIndex) {
 			this.slotIndex = slotIndex;
 		}
 
@@ -1064,7 +1577,163 @@ namespace Spine {
 				slot.ClampSecondColor();
 			}
 		}
+	}
+
+	/// <summary>Changes the RGB for a slot's <see cref="Slot.Color"/> and <see cref="Slot.DarkColor"/> for two color tinting.</summary>
+	public class RGB2Timeline : CurveTimeline, ISlotTimeline {
+		public const int ENTRIES = 7;
+		protected const int R = 1, G = 2, B = 3, R2 = 4, G2 = 5, B2 = 6;
+
+		readonly int slotIndex;
+
+		public RGB2Timeline (int frameCount, int bezierCount, int slotIndex)
+			: base(frameCount, bezierCount, //
+				(int)Property.RGB + "|" + slotIndex, //
+				(int)Property.RGB2 + "|" + slotIndex) {
+			this.slotIndex = slotIndex;
+		}
+
+		public override int FrameEntries {
+			get {
+				return ENTRIES;
+			}
+		}
+
+		/// <summary>
+		/// The index of the slot in <see cref="Skeleton.Slots"/> that will be changed when this timeline is applied. The
+		/// <see cref="Slot"/> must have a dark color available.</summary>
+		public int SlotIndex {
+			get {
+				return slotIndex;
+			}
+		}
 
+		/// <summary>Sets the time, light color, and dark color for the specified frame.</summary>
+		/// <param name="frame">Between 0 and <code>frameCount</code>, inclusive.</param>
+		/// <param name="time">The frame time in seconds.</param>
+		public void SetFrame (int frame, float time, float r, float g, float b, float r2, float g2, float b2) {
+			frame *= ENTRIES;
+			frames[frame] = time;
+			frames[frame + R] = r;
+			frames[frame + G] = g;
+			frames[frame + B] = b;
+			frames[frame + R2] = r2;
+			frames[frame + G2] = g2;
+			frames[frame + B2] = b2;
+		}
+
+		override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList<Event> 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;
+				switch (blend) {
+					case MixBlend.Setup:
+						//	slot.color.set(slot.data.color);
+						//	slot.darkColor.set(slot.data.darkColor);
+						slot.r = slotData.r;
+						slot.g = slotData.g;
+						slot.b = slotData.b;
+						slot.ClampColor();
+						slot.r2 = slotData.r2;
+						slot.g2 = slotData.g2;
+						slot.b2 = slotData.b2;
+						slot.ClampSecondColor();
+						return;
+					case MixBlend.First:
+						slot.r += (slot.r - slotData.r) * alpha;
+						slot.g += (slot.g - slotData.g) * alpha;
+						slot.b += (slot.b - slotData.b) * alpha;
+						slot.ClampColor();
+						slot.r2 += (slot.r2 - slotData.r2) * alpha;
+						slot.g2 += (slot.g2 - slotData.g2) * alpha;
+						slot.b2 += (slot.b2 - slotData.b2) * alpha;
+						slot.ClampSecondColor();
+						return;
+				}
+				return;
+			}
+
+			float r, g, b, r2, g2, b2;
+			int i = Animation.Search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES];
+			switch (curveType) {
+				case LINEAR:
+					float before = frames[i];
+					r = frames[i + R];
+					g = frames[i + G];
+					b = frames[i + B];
+					r2 = frames[i + R2];
+					g2 = frames[i + G2];
+					b2 = frames[i + B2];
+					float t = (time - before) / (frames[i + ENTRIES] - before);
+					r += (frames[i + ENTRIES + R] - r) * t;
+					g += (frames[i + ENTRIES + G] - g) * t;
+					b += (frames[i + ENTRIES + B] - b) * t;
+					r2 += (frames[i + ENTRIES + R2] - r2) * t;
+					g2 += (frames[i + ENTRIES + G2] - g2) * t;
+					b2 += (frames[i + ENTRIES + B2] - b2) * t;
+					break;
+				case STEPPED:
+					r = frames[i + R];
+					g = frames[i + G];
+					b = frames[i + B];
+					r2 = frames[i + R2];
+					g2 = frames[i + G2];
+					b2 = frames[i + B2];
+					break;
+				default:
+					r = GetBezierValue(time, i, R, curveType - BEZIER);
+					g = GetBezierValue(time, i, G, curveType + BEZIER_SIZE - BEZIER);
+					b = GetBezierValue(time, i, B, curveType + BEZIER_SIZE * 2 - BEZIER);
+					r2 = GetBezierValue(time, i, R2, curveType + BEZIER_SIZE * 3 - BEZIER);
+					g2 = GetBezierValue(time, i, G2, curveType + BEZIER_SIZE * 4 - BEZIER);
+					b2 = GetBezierValue(time, i, B2, curveType + BEZIER_SIZE * 5 - BEZIER);
+					break;
+			}
+
+			if (alpha == 1) {
+				slot.r = r;
+				slot.g = g;
+				slot.b = b;
+				slot.ClampColor();
+				slot.r2 = r2;
+				slot.g2 = g2;
+				slot.b2 = b2;
+				slot.ClampSecondColor();
+			}
+			else {
+				float br, bg, bb, ba, br2, bg2, bb2;
+				if (blend == MixBlend.Setup) {
+					br = slot.data.r;
+					bg = slot.data.g;
+					bb = slot.data.b;
+					ba = slot.data.a;
+					br2 = slot.data.r2;
+					bg2 = slot.data.g2;
+					bb2 = slot.data.b2;
+				}
+				else {
+					br = slot.r;
+					bg = slot.g;
+					bb = slot.b;
+					ba = slot.a;
+					br2 = slot.r2;
+					bg2 = slot.g2;
+					bb2 = slot.b2;
+				}
+				slot.r = br + ((r - br) * alpha);
+				slot.g = bg + ((g - bg) * alpha);
+				slot.b = bb + ((b - bb) * alpha);
+				slot.ClampColor();
+				slot.r2 = br2 + ((r2 - br2) * alpha);
+				slot.g2 = bg2 + ((g2 - bg2) * alpha);
+				slot.b2 = bb2 + ((b2 - bb2) * alpha);
+				slot.ClampSecondColor();
+			}
+		}
 	}
 
 	/// <summary>Changes a slot's <see cref="Slot.Attachment"/>.</summary>

+ 128 - 18
spine-csharp/src/SkeletonBinary.cs

@@ -45,12 +45,21 @@ namespace Spine {
 	public class SkeletonBinary : SkeletonLoader {
 		public const int BONE_ROTATE = 0;
 		public const int BONE_TRANSLATE = 1;
-		public const int BONE_SCALE = 2;
-		public const int BONE_SHEAR = 3;
+		public const int BONE_TRANSLATEX = 2;
+		public const int BONE_TRANSLATEY = 3;
+		public const int BONE_SCALE = 4;
+		public const int BONE_SCALEX = 5;
+		public const int BONE_SCALEY = 6;
+		public const int BONE_SHEAR = 7;
+		public const int BONE_SHEARX = 8;
+		public const int BONE_SHEARY = 9;
 
 		public const int SLOT_ATTACHMENT = 0;
-		public const int SLOT_COLOR = 1;
-		public const int SLOT_TWO_COLOR = 2;
+		public const int SLOT_RGBA = 1;
+		public const int SLOT_RGB = 2;
+		public const int SLOT_ALPHA = 3;
+		public const int SLOT_RGBA2 = 4;
+		public const int SLOT_RGB2 = 5;
 
 		public const int PATH_POSITION = 0;
 		public const int PATH_SPACING = 1;
@@ -589,8 +598,8 @@ namespace Spine {
 								timelines.Add(timeline);
 								break;
 							}
-						case SLOT_COLOR: {
-								ColorTimeline timeline = new ColorTimeline(frameCount, input.ReadInt(true), slotIndex);
+						case SLOT_RGBA: {
+								RGBATimeline timeline = new RGBATimeline(frameCount, input.ReadInt(true), slotIndex);
 								float time = input.ReadFloat();
 								float r = input.Read() / 255f, g = input.Read() / 255f;
 								float b = input.Read() / 255f, a = input.Read() / 255f;
@@ -620,21 +629,47 @@ namespace Spine {
 								timelines.Add(timeline);
 								break;
 							}
-						case SLOT_TWO_COLOR: {
-								TwoColorTimeline timeline = new TwoColorTimeline(frameCount, input.ReadInt(true), slotIndex);
+						case SLOT_RGB: {
+								RGBTimeline timeline = new RGBTimeline(frameCount, input.ReadInt(true), slotIndex);
+								float time = input.ReadFloat();
+								float r = input.Read() / 255f, g = input.Read() / 255f, b = input.Read() / 255f;
+								for (int frame = 0, bezier = 0; ; frame++) {
+									timeline.SetFrame(frame, time, r, g, b);
+									if (frame == frameLast) break;
+									float time2 = input.ReadFloat();
+									float r2 = input.Read() / 255f, g2 = input.Read() / 255f;
+									float b2 = input.Read() / 255f, a2 = input.Read() / 255f;
+									switch (input.ReadByte()) {
+										case CURVE_STEPPED:
+											timeline.SetStepped(frame);
+											break;
+										case CURVE_BEZIER:
+											SetBezier(input, timeline, bezier++, frame, 0, time, time2, r, r2, 1);
+											SetBezier(input, timeline, bezier++, frame, 1, time, time2, g, g2, 1);
+											SetBezier(input, timeline, bezier++, frame, 2, time, time2, b, b2, 1);
+											break;
+									}
+									time = time2;
+									r = r2;
+									g = g2;
+									b = b2;
+								}
+								timelines.Add(timeline);
+								break;
+							}
+						case SLOT_RGBA2: {
+								RGBA2Timeline timeline = new RGBA2Timeline(frameCount, input.ReadInt(true), slotIndex);
 								float time = input.ReadFloat();
 								float r = input.Read() / 255f, g = input.Read() / 255f;
 								float b = input.Read() / 255f, a = input.Read() / 255f;
-								float r2 = input.Read() / 255f, g2 = input.Read() / 255f;
-								float b2 = input.Read() / 255f;
+								float r2 = input.Read() / 255f, g2 = input.Read() / 255f, b2 = input.Read() / 255f;
 								for (int frame = 0, bezier = 0; ; frame++) {
 									timeline.SetFrame(frame, time, r, g, b, a, r2, g2, b2);
 									if (frame == frameLast) break;
 									float time2 = input.ReadFloat();
 									float nr = input.Read() / 255f, ng = input.Read() / 255f;
 									float nb = input.Read() / 255f, na = input.Read() / 255f;
-									float nr2 = input.Read() / 255f, ng2 = input.Read() / 255f;
-									float nb2 = input.Read() / 255f;
+									float nr2 = input.Read() / 255f, ng2 = input.Read() / 255f, nb2 = input.Read() / 255f;
 									switch (input.ReadByte()) {
 										case CURVE_STEPPED:
 											timeline.SetStepped(frame);
@@ -661,6 +696,63 @@ namespace Spine {
 								timelines.Add(timeline);
 								break;
 							}
+						case SLOT_RGB2: {
+								RGB2Timeline timeline = new RGB2Timeline(frameCount, input.ReadInt(true), slotIndex);
+								float time = input.ReadFloat();
+								float r = input.Read() / 255f, g = input.Read() / 255f, b = input.Read() / 255f;
+								float r2 = input.Read() / 255f, g2 = input.Read() / 255f, b2 = input.Read() / 255f;
+								for (int frame = 0, bezier = 0; ; frame++) {
+									timeline.SetFrame(frame, time, r, g, b, r2, g2, b2);
+									if (frame == frameLast) break;
+									float time2 = input.ReadFloat();
+									float nr = input.Read() / 255f, ng = input.Read() / 255f, nb = input.Read() / 255f;
+									float nr2 = input.Read() / 255f, ng2 = input.Read() / 255f, nb2 = input.Read() / 255f;
+									switch (input.ReadByte()) {
+										case CURVE_STEPPED:
+											timeline.SetStepped(frame);
+											break;
+										case CURVE_BEZIER:
+											SetBezier(input, timeline, bezier++, frame, 0, time, time2, r, nr, 1);
+											SetBezier(input, timeline, bezier++, frame, 1, time, time2, g, ng, 1);
+											SetBezier(input, timeline, bezier++, frame, 2, time, time2, b, nb, 1);
+											SetBezier(input, timeline, bezier++, frame, 3, time, time2, r2, nr2, 1);
+											SetBezier(input, timeline, bezier++, frame, 4, time, time2, g2, ng2, 1);
+											SetBezier(input, timeline, bezier++, frame, 5, time, time2, b2, nb2, 1);
+											break;
+									}
+									time = time2;
+									r = nr;
+									g = ng;
+									b = nb;
+									r2 = nr2;
+									g2 = ng2;
+									b2 = nb2;
+								}
+								timelines.Add(timeline);
+								break;
+							}
+						case SLOT_ALPHA: {
+								AlphaTimeline timeline = new AlphaTimeline(frameCount, input.ReadInt(true), slotIndex);
+								float time = input.ReadFloat(), a = input.Read() / 255f;
+								for (int frame = 0, bezier = 0; ; frame++) {
+									timeline.SetFrame(frame, time, a);
+									if (frame == frameLast) break;
+									float time2 = input.ReadFloat();
+									float a2 = input.Read() / 255f;
+									switch (input.ReadByte()) {
+										case CURVE_STEPPED:
+											timeline.SetStepped(frame);
+											break;
+										case CURVE_BEZIER:
+											SetBezier(input, timeline, bezier++, frame, 0, time, time2, a, a2, 1);
+											break;
+									}
+									time = time2;
+									a = a2;
+								}
+								timelines.Add(timeline);
+								break;
+							}
 					}
 				}
 			}
@@ -669,19 +761,37 @@ namespace Spine {
 			for (int i = 0, n = input.ReadInt(true); i < n; i++) {
 				int boneIndex = input.ReadInt(true);
 				for (int ii = 0, nn = input.ReadInt(true); ii < nn; ii++) {
-					switch (input.ReadByte()) {
+					int type = input.ReadByte(), frameCount = input.ReadInt(true), bezierCount = input.ReadInt(true);
+					switch (type) {
 						case BONE_ROTATE:
-							timelines.Add(ReadTimeline(input, new RotateTimeline(input.ReadInt(true), input.ReadInt(true), boneIndex), 1));
+							timelines.Add(ReadTimeline(input, new RotateTimeline(frameCount, bezierCount, boneIndex), 1));
 							break;
 						case BONE_TRANSLATE:
-							timelines
-								.Add(ReadTimeline(input, new TranslateTimeline(input.ReadInt(true), input.ReadInt(true), boneIndex), scale));
+							timelines.Add(ReadTimeline(input, new TranslateTimeline(frameCount, bezierCount, boneIndex), scale));
+							break;
+						case BONE_TRANSLATEX:
+							timelines.Add(ReadTimeline(input, new TranslateXTimeline(frameCount, bezierCount, boneIndex), scale));
+							break;
+						case BONE_TRANSLATEY:
+							timelines.Add(ReadTimeline(input, new TranslateYTimeline(frameCount, bezierCount, boneIndex), scale));
 							break;
 						case BONE_SCALE:
-							timelines.Add(ReadTimeline(input, new ScaleTimeline(input.ReadInt(true), input.ReadInt(true), boneIndex), 1));
+							timelines.Add(ReadTimeline(input, new ScaleTimeline(frameCount, bezierCount, boneIndex), 1));
+							break;
+						case BONE_SCALEX:
+							timelines.Add(ReadTimeline(input, new ScaleXTimeline(frameCount, bezierCount, boneIndex), 1));
+							break;
+						case BONE_SCALEY:
+							timelines.Add(ReadTimeline(input, new ScaleYTimeline(frameCount, bezierCount, boneIndex), 1));
 							break;
 						case BONE_SHEAR:
-							timelines.Add(ReadTimeline(input, new ShearTimeline(input.ReadInt(true), input.ReadInt(true), boneIndex), 1));
+							timelines.Add(ReadTimeline(input, new ShearTimeline(frameCount, bezierCount, boneIndex), 1));
+							break;
+						case BONE_SHEARX:
+							timelines.Add(ReadTimeline(input, new ShearXTimeline(frameCount, bezierCount, boneIndex), 1));
+							break;
+						case BONE_SHEARY:
+							timelines.Add(ReadTimeline(input, new ShearYTimeline(frameCount, bezierCount, boneIndex), 1));
 							break;
 					}
 				}

+ 122 - 5
spine-csharp/src/SkeletonJson.cs

@@ -542,8 +542,8 @@ namespace Spine {
 							}
 							timelines.Add(timeline);
 
-						} else if (timelineName == "color") {
-							var timeline = new ColorTimeline(values.Count, values.Count << 2, slotIndex);
+						} else if (timelineName == "rgba") {
+							var timeline = new RGBATimeline(values.Count, values.Count << 2, slotIndex);
 
 							var keyMapEnumerator = values.GetEnumerator();
 							keyMapEnumerator.MoveNext();
@@ -586,8 +586,54 @@ namespace Spine {
 							}
 							timelines.Add(timeline);
 
-						} else if (timelineName == "twoColor") {
-							var timeline = new TwoColorTimeline(values.Count, values.Count * 7, slotIndex);
+						}
+						else if (timelineName == "rgb") {
+							var timeline = new RGBTimeline(values.Count, values.Count * 3, slotIndex);
+
+							var keyMapEnumerator = values.GetEnumerator();
+							keyMapEnumerator.MoveNext();
+							var keyMap = (Dictionary<string, Object>)keyMapEnumerator.Current;
+							float time = GetFloat(keyMap, "time", 0);
+							string color = (string)keyMap["color"];
+							float r = ToColor(color, 0);
+							float g = ToColor(color, 1);
+							float b = ToColor(color, 2);
+							for (int frame = 0, bezier = 0; ; frame++) {
+								timeline.SetFrame(frame, time, r, g, b);
+								bool hasNext = keyMapEnumerator.MoveNext();
+								if (!hasNext) {
+									timeline.Shrink(bezier);
+									break;
+								}
+								var nextMap = (Dictionary<string, Object>)keyMapEnumerator.Current;
+
+								float time2 = GetFloat(nextMap, "time", 0);
+								color = (string)nextMap["color"];
+								float nr = ToColor(color, 0);
+								float ng = ToColor(color, 1);
+								float nb = ToColor(color, 2);
+
+								if (keyMap.ContainsKey("curve")) {
+									object curve = keyMap["curve"];
+									bezier = ReadCurve(curve, timeline, bezier, frame, 0, time, time2, r, nr, 1);
+									bezier = ReadCurve(curve, timeline, bezier, frame, 1, time, time2, g, ng, 1);
+									bezier = ReadCurve(curve, timeline, bezier, frame, 2, time, time2, b, nb, 1);
+								}
+								time = time2;
+								r = nr;
+								g = ng;
+								b = nb;
+								keyMap = nextMap;
+							}
+							timelines.Add(timeline);
+
+						} else if (timelineName == "alpha") {
+							var keyMapEnumerator = values.GetEnumerator();
+							keyMapEnumerator.MoveNext();
+							timelines.Add(ReadTimeline(ref keyMapEnumerator, new AlphaTimeline(values.Count, values.Count, slotIndex), 0, 1));
+
+						}  else if (timelineName == "rgba2") {
+							var timeline = new RGBA2Timeline(values.Count, values.Count * 7, slotIndex);
 
 							var keyMapEnumerator = values.GetEnumerator();
 							keyMapEnumerator.MoveNext();
@@ -644,6 +690,60 @@ namespace Spine {
 							}
 							timelines.Add(timeline);
 
+						} else if (timelineName == "rgb2") {
+							var timeline = new RGB2Timeline(values.Count, values.Count * 6, slotIndex);
+
+							var keyMapEnumerator = values.GetEnumerator();
+							keyMapEnumerator.MoveNext();
+							var keyMap = (Dictionary<string, Object>)keyMapEnumerator.Current;
+							float time = GetFloat(keyMap, "time", 0);
+							string color = (string)keyMap["light"];
+							float r = ToColor(color, 0);
+							float g = ToColor(color, 1);
+							float b = ToColor(color, 2);
+							color = (string)keyMap["dark"];
+							float r2 = ToColor(color, 0);
+							float g2 = ToColor(color, 1);
+							float b2 = ToColor(color, 2);
+							for (int frame = 0, bezier = 0; ; frame++) {
+								timeline.SetFrame(frame, time, r, g, b, r2, g2, b2);
+								bool hasNext = keyMapEnumerator.MoveNext();
+								if (!hasNext) {
+									timeline.Shrink(bezier);
+									break;
+								}
+								var nextMap = (Dictionary<string, Object>)keyMapEnumerator.Current;
+
+								float time2 = GetFloat(nextMap, "time", 0);
+								color = (string)nextMap["light"];
+								float nr = ToColor(color, 0);
+								float ng = ToColor(color, 1);
+								float nb = ToColor(color, 2);
+								color = (string)nextMap["dark"];
+								float nr2 = ToColor(color, 0);
+								float ng2 = ToColor(color, 1);
+								float nb2 = ToColor(color, 2);
+
+								if (keyMap.ContainsKey("curve")) {
+									object curve = keyMap["curve"];
+									bezier = ReadCurve(curve, timeline, bezier, frame, 0, time, time2, r, nr, 1);
+									bezier = ReadCurve(curve, timeline, bezier, frame, 1, time, time2, g, ng, 1);
+									bezier = ReadCurve(curve, timeline, bezier, frame, 2, time, time2, b, nb, 1);
+									bezier = ReadCurve(curve, timeline, bezier, frame, 3, time, time2, r2, nr2, 1);
+									bezier = ReadCurve(curve, timeline, bezier, frame, 4, time, time2, g2, ng2, 1);
+									bezier = ReadCurve(curve, timeline, bezier, frame, 5, time, time2, b2, nb2, 1);
+								}
+								time = time2;
+								r = nr;
+								g = ng;
+								b = nb;
+								r2 = nr2;
+								g2 = ng2;
+								b2 = nb2;
+								keyMap = nextMap;
+							}
+							timelines.Add(timeline);
+
 						} else
 							throw new Exception("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")");
 					}
@@ -669,14 +769,31 @@ namespace Spine {
 							TranslateTimeline timeline = new TranslateTimeline(values.Count, values.Count << 1, boneIndex);
 							timelines.Add(ReadTimeline(ref keyMapEnumerator, timeline, "x", "y", 0, scale));
 						}
+						else if (timelineName == "translatex") {
+							timelines
+								.Add(ReadTimeline(ref keyMapEnumerator, new TranslateXTimeline(values.Count, values.Count, boneIndex), 0, scale));
+						}
+						else if (timelineName == "translatey") {
+							timelines
+								.Add(ReadTimeline(ref keyMapEnumerator, new TranslateYTimeline(values.Count, values.Count, boneIndex), 0, scale));
+						}
 						else if (timelineName == "scale") {
 							ScaleTimeline timeline = new ScaleTimeline(values.Count, values.Count << 1, boneIndex);
 							timelines.Add(ReadTimeline(ref keyMapEnumerator, timeline, "x", "y", 1, 1));
 						}
+						else if (timelineName == "scalex")
+							timelines.Add(ReadTimeline(ref keyMapEnumerator, new ScaleXTimeline(values.Count, values.Count, boneIndex), 1, 1));
+						else if (timelineName == "scaley")
+							timelines.Add(ReadTimeline(ref keyMapEnumerator, new ScaleYTimeline(values.Count, values.Count, boneIndex), 1, 1));
 						else if (timelineName == "shear") {
 							ShearTimeline timeline = new ShearTimeline(values.Count, values.Count << 1, boneIndex);
 							timelines.Add(ReadTimeline(ref keyMapEnumerator, timeline, "x", "y", 0, 1));
-						} else
+						}
+						else if (timelineName == "shearx")
+							timelines.Add(ReadTimeline(ref keyMapEnumerator, new ShearXTimeline(values.Count, values.Count, boneIndex), 0, 1));
+						else if (timelineName == "sheary")
+							timelines.Add(ReadTimeline(ref keyMapEnumerator, new ShearYTimeline(values.Count, values.Count, boneIndex), 0, 1));
+						else
 							throw new Exception("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")");
 					}
 				}

+ 8 - 8
spine-unity/Assets/Spine Examples/Scripts/MecanimAnimationMatchModifier/AnimationMatchModifierAsset.cs

@@ -113,10 +113,10 @@ namespace Spine.Unity.Examples {
 					return GetFillerTimeline((ShearTimeline)timeline, skeletonData);
 				if (timeline is AttachmentTimeline)
 					return GetFillerTimeline((AttachmentTimeline)timeline, skeletonData);
-				if (timeline is ColorTimeline)
-					return GetFillerTimeline((ColorTimeline)timeline, skeletonData);
-				if (timeline is TwoColorTimeline)
-					return GetFillerTimeline((TwoColorTimeline)timeline, skeletonData);
+				if (timeline is RGBATimeline)
+					return GetFillerTimeline((RGBATimeline)timeline, skeletonData);
+				if (timeline is RGBA2Timeline)
+					return GetFillerTimeline((RGBA2Timeline)timeline, skeletonData);
 				if (timeline is DeformTimeline)
 					return GetFillerTimeline((DeformTimeline)timeline, skeletonData);
 				if (timeline is DrawOrderTimeline)
@@ -165,15 +165,15 @@ namespace Spine.Unity.Examples {
 				return t;
 			}
 
-			static ColorTimeline GetFillerTimeline (ColorTimeline timeline, SkeletonData skeletonData) {
-				var t = new ColorTimeline(1, 0, timeline.SlotIndex);
+			static RGBATimeline GetFillerTimeline (RGBATimeline timeline, SkeletonData skeletonData) {
+				var t = new RGBATimeline(1, 0, timeline.SlotIndex);
 				var slotData = skeletonData.Slots.Items[t.SlotIndex];
 				t.SetFrame(0, 0, slotData.R, slotData.G, slotData.B, slotData.A);
 				return t;
 			}
 
-			static TwoColorTimeline GetFillerTimeline (TwoColorTimeline timeline, SkeletonData skeletonData) {
-				var t = new TwoColorTimeline(1, 0, timeline.SlotIndex);
+			static RGBA2Timeline GetFillerTimeline (RGBA2Timeline timeline, SkeletonData skeletonData) {
+				var t = new RGBA2Timeline(1, 0, timeline.SlotIndex);
 				var slotData = skeletonData.Slots.Items[t.SlotIndex];
 				t.SetFrame(0, 0, slotData.R, slotData.G, slotData.B, slotData.A, slotData.R2, slotData.G2, slotData.B2);
 				return t;

+ 14 - 14
spine-unity/Assets/Spine Examples/Spine Skeletons/Dragon/dragon.json

@@ -1,7 +1,7 @@
 {
 "skeleton": {
-	"hash": "W2x0sFWHxCE",
-	"spine": "4.0.11-beta",
+	"hash": "UIFpNNbbcQI",
+	"spine": "4.0.24-beta",
 	"x": -366.31,
 	"y": -286.62,
 	"width": 660.39,
@@ -708,13 +708,13 @@
 			"left-front-toe2": {
 				"scale": [
 					{
-						"curve": [ 0.125, 1, 0.375, 1.33, 0.125, 1, 0.375, 1.03 ]
+						"curve": [ 0.125, 1, 0.375, 1.331, 0.125, 1, 0.375, 1.029 ]
 					},
 					{
 						"time": 0.5,
 						"x": 1.331,
 						"y": 1.029,
-						"curve": [ 0.625, 1.33, 0.875, 1, 0.625, 1.03, 0.875, 1 ]
+						"curve": [ 0.625, 1.331, 0.875, 1, 0.625, 1.029, 0.875, 1 ]
 					},
 					{ "time": 1 }
 				]
@@ -733,13 +733,13 @@
 				],
 				"scale": [
 					{
-						"curve": [ 0.125, 1, 0.375, 1.21, 0.125, 1, 0.375, 0.99 ]
+						"curve": [ 0.125, 1, 0.375, 1.211, 0.125, 1, 0.375, 0.993 ]
 					},
 					{
 						"time": 0.5,
 						"x": 1.211,
 						"y": 0.993,
-						"curve": [ 0.625, 1.21, 0.875, 1, 0.625, 0.99, 0.875, 1 ]
+						"curve": [ 0.625, 1.211, 0.875, 1, 0.625, 0.993, 0.875, 1 ]
 					},
 					{ "time": 1 }
 				]
@@ -758,13 +758,13 @@
 				],
 				"scale": [
 					{
-						"curve": [ 0.125, 1, 0.375, 1.35, 0.125, 1, 0.375, 1.01 ]
+						"curve": [ 0.125, 1, 0.375, 1.355, 0.125, 1, 0.375, 1.008 ]
 					},
 					{
 						"time": 0.5,
 						"x": 1.355,
 						"y": 1.008,
-						"curve": [ 0.625, 1.35, 0.875, 1, 0.625, 1.01, 0.875, 1 ]
+						"curve": [ 0.625, 1.355, 0.875, 1, 0.625, 1.008, 0.875, 1 ]
 					},
 					{ "time": 1 }
 				]
@@ -811,12 +811,12 @@
 				],
 				"scale": [
 					{
-						"curve": [ 0.125, 1, 0.375, 1.41, 0.125, 1, 0.375, 1 ]
+						"curve": [ 0.125, 1, 0.375, 1.412, 0.125, 1, 0.375, 1 ]
 					},
 					{
 						"time": 0.5,
 						"x": 1.412,
-						"curve": [ 0.625, 1.41, 0.875, 1, 0.625, 1, 0.875, 1 ]
+						"curve": [ 0.625, 1.412, 0.875, 1, 0.625, 1, 0.875, 1 ]
 					},
 					{ "time": 1 }
 				]
@@ -845,13 +845,13 @@
 				],
 				"scale": [
 					{
-						"curve": [ 0.125, 1, 0.375, 1.41, 0.125, 1, 0.375, 1.06 ]
+						"curve": [ 0.125, 1, 0.375, 1.407, 0.125, 1, 0.375, 1.058 ]
 					},
 					{
 						"time": 0.5,
 						"x": 1.407,
 						"y": 1.058,
-						"curve": [ 0.625, 1.41, 0.875, 1, 0.625, 1.06, 0.875, 1 ]
+						"curve": [ 0.625, 1.407, 0.875, 1, 0.625, 1.058, 0.875, 1 ]
 					},
 					{ "time": 1 }
 				]
@@ -880,13 +880,13 @@
 				],
 				"scale": [
 					{
-						"curve": [ 0.125, 1, 0.375, 1.33, 0.125, 1, 0.375, 1.18 ]
+						"curve": [ 0.125, 1, 0.375, 1.33, 0.125, 1, 0.375, 1.182 ]
 					},
 					{
 						"time": 0.5,
 						"x": 1.33,
 						"y": 1.182,
-						"curve": [ 0.625, 1.33, 0.875, 1, 0.625, 1.18, 0.875, 1 ]
+						"curve": [ 0.625, 1.33, 0.875, 1, 0.625, 1.182, 0.875, 1 ]
 					},
 					{ "time": 1 }
 				]

+ 1 - 1
spine-unity/Assets/Spine Examples/Spine Skeletons/Eyes/eyes.json

@@ -1,7 +1,7 @@
 {
 "skeleton": {
 	"hash": "wNwtgzmTRJY",
-	"spine": "4.0.11-beta",
+	"spine": "4.0.24-beta",
 	"x": -434,
 	"y": -133,
 	"width": 868,

+ 1 - 1
spine-unity/Assets/Spine Examples/Spine Skeletons/FootSoldier/FootSoldier.json

@@ -1,7 +1,7 @@
 {
 "skeleton": {
 	"hash": "Buu7RaVrgIg",
-	"spine": "4.0.11-beta",
+	"spine": "4.0.24-beta",
 	"x": -79.83,
 	"y": -0.99,
 	"width": 147.64,

+ 3 - 3
spine-unity/Assets/Spine Examples/Spine Skeletons/Gauge/Gauge.json

@@ -1,7 +1,7 @@
 {
 "skeleton": {
-	"hash": "WGQ8e/U+7iU",
-	"spine": "4.0.11-beta",
+	"hash": "iIOUMGPAhCc",
+	"spine": "4.0.24-beta",
 	"x": -125,
 	"y": -30,
 	"width": 250,
@@ -42,7 +42,7 @@
 				"scale": [
 					{
 						"x": 0.002,
-						"curve": [ 0.25, 0, 0.75, 1, 0.25, 1, 0.75, 1 ]
+						"curve": [ 0.25, 0.002, 0.75, 1, 0.25, 1, 0.75, 1 ]
 					},
 					{ "time": 1 }
 				]

+ 1 - 1
spine-unity/Assets/Spine Examples/Spine Skeletons/Goblins/goblins.json

@@ -1,7 +1,7 @@
 {
 "skeleton": {
 	"hash": "PtTAK+zF95I",
-	"spine": "4.0.11-beta",
+	"spine": "4.0.24-beta",
 	"x": -134.12,
 	"y": -3.28,
 	"width": 266.94,

+ 5 - 5
spine-unity/Assets/Spine Examples/Spine Skeletons/Hero/hero-pro.json

@@ -1,7 +1,7 @@
 {
 "skeleton": {
-	"hash": "8eBALFopJu4",
-	"spine": "4.0.11-beta",
+	"hash": "n95hcZ5Stxo",
+	"spine": "4.0.24-beta",
 	"x": -85.7,
 	"y": -0.02,
 	"width": 321.77,
@@ -3449,7 +3449,7 @@
 				],
 				"scale": [
 					{
-						"curve": [ 0, 1, 0.019, 1, 0, 0.98, 0.019, 0.98 ]
+						"curve": [ 0, 1, 0.019, 1, 0, 0.982, 0.019, 0.98 ]
 					},
 					{ "time": 0.0333, "y": 0.98 },
 					{ "time": 0.2667 }
@@ -3885,12 +3885,12 @@
 			"root": {
 				"scale": [
 					{
-						"curve": [ 0, 1, 0.019, 1, 0, 0.98, 0.019, 0.98 ]
+						"curve": [ 0, 1, 0.019, 1, 0, 0.982, 0.019, 0.98 ]
 					},
 					{
 						"time": 0.0333,
 						"y": 0.98,
-						"curve": [ 0.067, 1, 0.167, 1, 0.067, 0.98, 0.167, 1.03 ]
+						"curve": [ 0.067, 1, 0.167, 1, 0.067, 0.98, 0.167, 1.025 ]
 					},
 					{ "time": 0.1667, "y": 1.05 },
 					{ "time": 0.3 }

+ 1 - 1
spine-unity/Assets/Spine Examples/Spine Skeletons/Raggedy Spineboy/raggedy spineboy.json

@@ -1,7 +1,7 @@
 {
 "skeleton": {
 	"hash": "M5CWyRHHnyE",
-	"spine": "4.0.11-beta",
+	"spine": "4.0.24-beta",
 	"x": -78.45,
 	"y": -9.66,
 	"width": 157.48,

+ 3 - 3
spine-unity/Assets/Spine Examples/Spine Skeletons/Raptor/raptor.json

@@ -1,7 +1,7 @@
 {
 "skeleton": {
-	"hash": "aUVkIREPuuE",
-	"spine": "4.0.11-beta",
+	"hash": "PK6GViUN7hw",
+	"spine": "4.0.24-beta",
 	"x": -402.84,
 	"y": -35.99,
 	"width": 611.87,
@@ -1998,7 +1998,7 @@
 	"debugfade": {
 		"slots": {
 			"raptor_body": {
-				"color": [
+				"rgba": [
 					{ "color": "0000803f", "curve": "stepped" },
 					{ "time": 1, "color": "0000803f" }
 				]

+ 19 - 19
spine-unity/Assets/Spine Examples/Spine Skeletons/Spineunitygirl/Doi.json

@@ -1,7 +1,7 @@
 {
 "skeleton": {
-	"hash": "UHEtfZlIwiw",
-	"spine": "4.0.11-beta",
+	"hash": "/xtyDEt85/s",
+	"spine": "4.0.24-beta",
 	"x": -214.04,
 	"y": -80.91,
 	"width": 519.95,
@@ -661,7 +661,7 @@
 					{
 						"time": 0.0667,
 						"y": 0.895,
-						"curve": [ 0.107, 1, 0.158, 1, 0.107, 0.89, 0.158, 1 ]
+						"curve": [ 0.107, 1, 0.158, 1, 0.107, 0.894, 0.158, 1 ]
 					},
 					{ "time": 0.3333 }
 				]
@@ -731,13 +731,13 @@
 				],
 				"scale": [
 					{
-						"curve": [ 0.56, 1, 0.499, 0.98, 0.56, 1, 0.499, 1.05 ]
+						"curve": [ 0.56, 1, 0.499, 0.983, 0.56, 1, 0.499, 1.047 ]
 					},
 					{
 						"time": 1.0333,
 						"x": 0.983,
 						"y": 1.047,
-						"curve": [ 1.557, 0.98, 1.5, 1, 1.557, 1.05, 1.5, 1 ]
+						"curve": [ 1.557, 0.983, 1.5, 1, 1.557, 1.047, 1.5, 1 ]
 					},
 					{ "time": 2 }
 				]
@@ -1019,13 +1019,13 @@
 				],
 				"scale": [
 					{
-						"curve": [ 0.353, 1, 0.655, 1.01, 0.353, 1, 0.655, 0.98 ]
+						"curve": [ 0.353, 1, 0.655, 1.007, 0.353, 1, 0.655, 0.98 ]
 					},
 					{
 						"time": 1,
 						"x": 1.007,
 						"y": 0.98,
-						"curve": [ 1.353, 1.01, 1.655, 1, 1.353, 0.98, 1.655, 1 ]
+						"curve": [ 1.353, 1.007, 1.655, 1, 1.353, 0.98, 1.655, 1 ]
 					},
 					{ "time": 2 }
 				]
@@ -1156,21 +1156,21 @@
 				],
 				"scale": [
 					{
-						"curve": [ 0.212, 1, 0.393, 1, 0.212, 1, 0.393, 1.12 ]
+						"curve": [ 0.212, 1, 0.393, 1, 0.212, 1, 0.393, 1.119 ]
 					},
 					{
 						"time": 0.6,
 						"y": 1.119,
-						"curve": [ 0.741, 1, 0.862, 1, 0.741, 1.12, 0.862, 1 ]
+						"curve": [ 0.741, 1, 0.862, 1, 0.741, 1.119, 0.862, 1 ]
 					},
 					{
 						"time": 1,
-						"curve": [ 1.212, 1, 1.393, 1, 1.212, 1, 1.393, 1.12 ]
+						"curve": [ 1.212, 1, 1.393, 1, 1.212, 1, 1.393, 1.119 ]
 					},
 					{
 						"time": 1.6,
 						"y": 1.119,
-						"curve": [ 1.741, 1, 1.862, 1, 1.741, 1.12, 1.862, 1 ]
+						"curve": [ 1.741, 1, 1.862, 1, 1.741, 1.119, 1.862, 1 ]
 					},
 					{ "time": 2 }
 				]
@@ -1274,13 +1274,13 @@
 				"scale": [
 					{
 						"y": 1.03,
-						"curve": [ 0.164, 1, 0.327, 1, 0.164, 1.01, 0.327, 1 ]
+						"curve": [ 0.164, 1, 0.327, 1, 0.164, 1.015, 0.327, 1 ]
 					},
 					{ "time": 0.5 },
 					{
 						"time": 1.5,
 						"y": 1.06,
-						"curve": [ 1.676, 1, 1.838, 1, 1.676, 1.06, 1.838, 1.04 ]
+						"curve": [ 1.676, 1, 1.838, 1, 1.676, 1.06, 1.838, 1.045 ]
 					},
 					{ "time": 2, "y": 1.03 }
 				]
@@ -1301,14 +1301,14 @@
 					{
 						"x": 1.003,
 						"y": 1.016,
-						"curve": [ 0.093, 1, 0.202, 1, 0.093, 1.01, 0.202, 1 ]
+						"curve": [ 0.093, 1.001, 0.202, 1, 0.093, 1.007, 0.202, 1 ]
 					},
 					{ "time": 0.4 },
 					{
 						"time": 1.4,
 						"x": 1.01,
 						"y": 1.051,
-						"curve": [ 1.736, 1.01, 1.849, 1.01, 1.736, 1.05, 1.849, 1.03 ]
+						"curve": [ 1.736, 1.01, 1.849, 1.006, 1.736, 1.051, 1.849, 1.031 ]
 					},
 					{ "time": 2, "x": 1.003, "y": 1.016 }
 				]
@@ -1376,13 +1376,13 @@
 				],
 				"scale": [
 					{
-						"curve": [ 0.353, 1, 0.655, 0.85, 0.353, 1, 0.655, 0.96 ]
+						"curve": [ 0.353, 1, 0.655, 0.848, 0.353, 1, 0.655, 0.958 ]
 					},
 					{
 						"time": 1,
 						"x": 0.848,
 						"y": 0.958,
-						"curve": [ 1.353, 0.85, 1.655, 1, 1.353, 0.96, 1.655, 1 ]
+						"curve": [ 1.353, 0.848, 1.655, 1, 1.353, 0.958, 1.655, 1 ]
 					},
 					{ "time": 2 }
 				]
@@ -1638,14 +1638,14 @@
 					{
 						"x": 0.97,
 						"y": 0.993,
-						"curve": [ 0.127, 0.99, 0.245, 1, 0.127, 1, 0.245, 1 ]
+						"curve": [ 0.127, 0.987, 0.245, 1, 0.127, 0.997, 0.245, 1 ]
 					},
 					{ "time": 0.3333 },
 					{
 						"time": 1.3333,
 						"x": 0.893,
 						"y": 0.977,
-						"curve": [ 1.495, 0.89, 1.766, 0.94, 1.495, 0.98, 1.766, 0.99 ]
+						"curve": [ 1.495, 0.893, 1.766, 0.939, 1.495, 0.977, 1.766, 0.987 ]
 					},
 					{ "time": 2, "x": 0.97, "y": 0.993 }
 				],

File diff suppressed because it is too large
+ 4 - 4
spine-unity/Assets/Spine Examples/Spine Skeletons/Stretchyman/stretchyman.json


+ 2 - 2
spine-unity/Assets/Spine Examples/Spine Skeletons/mix-and-match/mix-and-match-pro.json

@@ -1,7 +1,7 @@
 {
 "skeleton": {
-	"hash": "nE4g85mprlE",
-	"spine": "4.0.11-beta",
+	"hash": "wzdCiOAbaQQ",
+	"spine": "4.0.24-beta",
 	"x": -240.58,
 	"y": -3.38,
 	"width": 410.36,

File diff suppressed because it is too large
+ 4 - 4
spine-unity/Assets/Spine Examples/Spine Skeletons/raptor-pro-and-mask/raptor-pro.json


+ 17 - 17
spine-unity/Assets/Spine Examples/Spine Skeletons/spineboy-pro/spineboy-pro.json

@@ -1,7 +1,7 @@
 {
 "skeleton": {
-	"hash": "P4z2I8983b8",
-	"spine": "4.0.11-beta",
+	"hash": "OByFm07eTFQ",
+	"spine": "4.0.24-beta",
 	"x": -190.61,
 	"y": -7.99,
 	"width": 419.76,
@@ -1942,7 +1942,7 @@
 				"scale": [
 					{
 						"x": 0.94,
-						"curve": [ 0, 0.99, 0.125, 1, 0, 1, 0.125, 1 ]
+						"curve": [ 0, 0.989, 0.125, 1, 0, 1, 0.125, 1 ]
 					},
 					{ "time": 0.2667 }
 				]
@@ -2921,19 +2921,19 @@
 				],
 				"scale": [
 					{
-						"curve": [ 0.167, 1, 0.5, 1.05, 0.167, 1, 0.5, 1.05 ]
+						"curve": [ 0.167, 1, 0.5, 1.053, 0.167, 1, 0.5, 1.053 ]
 					},
 					{
 						"time": 0.6667,
 						"x": 1.053,
 						"y": 1.053,
-						"curve": [ 0.833, 1.05, 1.167, 0.99, 0.833, 1.05, 1.167, 0.99 ]
+						"curve": [ 0.833, 1.053, 1.167, 0.986, 0.833, 1.053, 1.167, 0.986 ]
 					},
 					{
 						"time": 1.3333,
 						"x": 0.986,
 						"y": 0.986,
-						"curve": [ 1.5, 0.99, 1.833, 1.05, 1.5, 0.99, 1.833, 1.05 ]
+						"curve": [ 1.5, 0.986, 1.833, 1.053, 1.5, 0.986, 1.833, 1.053 ]
 					},
 					{ "time": 2, "x": 1.053, "y": 1.053 }
 				]
@@ -2976,13 +2976,13 @@
 					{
 						"x": 0.003,
 						"y": 0.006,
-						"curve": [ 0.329, 0.04, 0.347, 0.12, 0.329, 0.1, 0.347, 0.26 ]
+						"curve": [ 0.329, 0.044, 0.347, 0.117, 0.329, 0.097, 0.347, 0.257 ]
 					},
 					{
 						"time": 0.4,
 						"x": 0.175,
 						"y": 0.387,
-						"curve": [ 0.836, 1.02, 0.803, 0.64, 0.836, 2.26, 0.803, 1.42 ]
+						"curve": [ 0.836, 1.021, 0.803, 0.64, 0.836, 2.257, 0.803, 1.416 ]
 					},
 					{ "time": 1, "x": 0.645, "y": 1.426 },
 					{ "time": 1.2333, "x": 0.685, "y": 1.516 },
@@ -2993,7 +2993,7 @@
 						"time": 2.5,
 						"x": 0.645,
 						"y": 1.426,
-						"curve": [ 3.088, 0.81, 2.93, 0.01, 3.088, 1.79, 2.93, 0.01 ]
+						"curve": [ 3.088, 0.811, 2.93, 0.007, 3.088, 1.793, 2.93, 0.015 ]
 					},
 					{ "time": 3.1, "x": 0.007, "y": 0.015 }
 				]
@@ -3326,7 +3326,7 @@
 	"run": {
 		"slots": {
 			"dust": {
-				"color": [
+				"rgba": [
 					{ "color": "ffffff3e" },
 					{ "time": 0.0667, "color": "ffffff00", "curve": "stepped" },
 					{ "time": 0.1333, "color": "ffffff00" },
@@ -4062,7 +4062,7 @@
 					{
 						"x": 0.963,
 						"y": 1.074,
-						"curve": [ 0.067, 0.96, 0.132, 1, 0.067, 1.07, 0.132, 1 ]
+						"curve": [ 0.067, 0.963, 0.132, 1, 0.067, 1.074, 0.132, 1 ]
 					},
 					{ "time": 0.2667 }
 				]
@@ -4106,7 +4106,7 @@
 	"shoot": {
 		"slots": {
 			"muzzle": {
-				"color": [
+				"rgba": [
 					{ "time": 0.1333, "color": "ffffffff" },
 					{ "time": 0.1667, "color": "ffffff62" }
 				],
@@ -4120,7 +4120,7 @@
 				]
 			},
 			"muzzle-glow": {
-				"color": [
+				"rgba": [
 					{ "color": "ff0c0c00" },
 					{
 						"time": 0.0333,
@@ -4135,7 +4135,7 @@
 				]
 			},
 			"muzzle-ring": {
-				"color": [
+				"rgba": [
 					{
 						"time": 0.0333,
 						"color": "d8baffff",
@@ -4149,7 +4149,7 @@
 				]
 			},
 			"muzzle-ring2": {
-				"color": [
+				"rgba": [
 					{
 						"time": 0.0333,
 						"color": "d8baffff",
@@ -4163,7 +4163,7 @@
 				]
 			},
 			"muzzle-ring3": {
-				"color": [
+				"rgba": [
 					{
 						"time": 0.0333,
 						"color": "d8baffff",
@@ -4177,7 +4177,7 @@
 				]
 			},
 			"muzzle-ring4": {
-				"color": [
+				"rgba": [
 					{
 						"time": 0.0333,
 						"color": "d8baffff",

+ 37 - 37
spine-unity/Assets/Spine Examples/Spine Skeletons/spineboy-unity/spineboy-unity.json

@@ -1,7 +1,7 @@
 {
 "skeleton": {
-	"hash": "eVAT/2cki1I",
-	"spine": "4.0.11-beta",
+	"hash": "DWHhdt1Xuys",
+	"spine": "4.0.24-beta",
 	"x": -221.22,
 	"y": -8.55,
 	"width": 371.09,
@@ -730,7 +730,7 @@
 						"time": 0.0667,
 						"x": 1.363,
 						"y": 1.725,
-						"curve": [ 0.089, 1.03, 0.317, 1, 0.089, 1.06, 0.317, 1 ]
+						"curve": [ 0.089, 1.029, 0.317, 1, 0.089, 1.058, 0.317, 1 ]
 					},
 					{ "time": 0.4 }
 				]
@@ -755,7 +755,7 @@
 					{
 						"time": 0.1333,
 						"y": 1.435,
-						"curve": [ 0.145, 1, 0.258, 1, 0.145, 1.03, 0.258, 1 ]
+						"curve": [ 0.145, 1, 0.258, 1, 0.145, 1.035, 0.258, 1 ]
 					},
 					{ "time": 0.3 }
 				]
@@ -890,7 +890,7 @@
 						"time": 0.1333,
 						"x": 1.286,
 						"y": 0.849,
-						"curve": [ 0.156, 0.67, 0.259, 1.07, 0.156, 1.17, 0.259, 0.97 ]
+						"curve": [ 0.156, 0.674, 0.259, 1.066, 0.156, 1.172, 0.259, 0.965 ]
 					},
 					{ "time": 0.4, "curve": "stepped" },
 					{ "time": 1.1667 }
@@ -940,7 +940,7 @@
 				]
 			},
 			"muzzle": {
-				"color": [
+				"rgba": [
 					{ "color": "00008000", "curve": "stepped" },
 					{ "time": 0.7667, "color": "ffffffff", "curve": "stepped" },
 					{ "time": 0.8, "color": "ffffff00", "curve": "stepped" },
@@ -1189,27 +1189,27 @@
 					{ "curve": "stepped" },
 					{
 						"time": 0.7667,
-						"curve": [ 0.814, 1, 0.799, 1.25, 0.814, 1, 0.799, 1.52 ]
+						"curve": [ 0.814, 1, 0.799, 1.247, 0.814, 1, 0.799, 1.517 ]
 					},
 					{ "time": 0.8333, "x": 1.247, "y": 1.517 },
 					{
 						"time": 0.8667,
-						"curve": [ 0.914, 1, 0.899, 1.25, 0.914, 1, 0.899, 1.52 ]
+						"curve": [ 0.914, 1, 0.899, 1.247, 0.914, 1, 0.899, 1.517 ]
 					},
 					{ "time": 0.9333, "x": 1.247, "y": 1.517 },
 					{
 						"time": 0.9667,
-						"curve": [ 1.014, 1, 0.999, 1.25, 1.014, 1, 0.999, 1.52 ]
+						"curve": [ 1.014, 1, 0.999, 1.247, 1.014, 1, 0.999, 1.517 ]
 					},
 					{ "time": 1.0333, "x": 1.247, "y": 1.517 },
 					{
 						"time": 1.0667,
-						"curve": [ 1.114, 1, 1.099, 1.25, 1.114, 1, 1.099, 1.52 ]
+						"curve": [ 1.114, 1, 1.099, 1.247, 1.114, 1, 1.099, 1.517 ]
 					},
 					{ "time": 1.1333, "x": 1.247, "y": 1.517 },
 					{
 						"time": 1.2,
-						"curve": [ 1.294, 1, 1.265, 1.25, 1.294, 1, 1.265, 1.52 ]
+						"curve": [ 1.294, 1, 1.265, 1.247, 1.294, 1, 1.265, 1.517 ]
 					},
 					{ "time": 1.3333, "x": 1.247, "y": 1.517, "curve": "stepped" },
 					{ "time": 2.5333, "x": 1.247, "y": 1.517 }
@@ -2349,7 +2349,7 @@
 				],
 				"scale": [
 					{
-						"curve": [ 0.05, 1, 0.055, 0.9, 0.05, 1, 0.055, 1 ]
+						"curve": [ 0.05, 1, 0.055, 0.897, 0.05, 1, 0.055, 1 ]
 					},
 					{ "time": 0.2, "x": 0.897 }
 				]
@@ -2398,7 +2398,7 @@
 				],
 				"scale": [
 					{
-						"curve": [ 0.05, 1, 0.055, 0.75, 0.05, 1, 0.055, 1.31 ]
+						"curve": [ 0.05, 1, 0.055, 0.755, 0.05, 1, 0.055, 1.31 ]
 					},
 					{ "time": 0.2, "x": 0.755, "y": 1.31 }
 				]
@@ -2595,13 +2595,13 @@
 				],
 				"scale": [
 					{
-						"curve": [ 0.167, 1, 0.5, 0.8, 0.167, 1, 0.5, 1.1 ]
+						"curve": [ 0.167, 1, 0.5, 0.8, 0.167, 1, 0.5, 1.101 ]
 					},
 					{
 						"time": 0.6667,
 						"x": 0.8,
 						"y": 1.101,
-						"curve": [ 0.917, 0.8, 1.417, 1, 0.917, 1.1, 1.417, 1 ]
+						"curve": [ 0.917, 0.8, 1.417, 1, 0.917, 1.101, 1.417, 1 ]
 					},
 					{ "time": 1.6667 }
 				]
@@ -2687,12 +2687,12 @@
 				"scale": [
 					{
 						"x": 0.897,
-						"curve": [ 0.157, 0.9, 0.373, 0.83, 0.157, 1, 0.373, 1 ]
+						"curve": [ 0.157, 0.896, 0.373, 0.827, 0.157, 1, 0.373, 1 ]
 					},
 					{
 						"time": 0.6667,
 						"x": 0.826,
-						"curve": [ 1.262, 0.83, 1.32, 0.9, 1.262, 1, 1.32, 1 ]
+						"curve": [ 1.262, 0.826, 1.32, 0.897, 1.262, 1, 1.32, 1 ]
 					},
 					{ "time": 1.6667, "x": 0.897 }
 				]
@@ -2703,12 +2703,12 @@
 				],
 				"scale": [
 					{
-						"curve": [ 0.157, 1, 0.373, 0.99, 0.157, 1, 0.373, 1 ]
+						"curve": [ 0.157, 1, 0.373, 0.994, 0.157, 1, 0.373, 1 ]
 					},
 					{
 						"time": 0.6667,
 						"x": 0.994,
-						"curve": [ 1.262, 0.99, 1.32, 1, 1.262, 1, 1.32, 1 ]
+						"curve": [ 1.262, 0.994, 1.32, 1, 1.262, 1, 1.32, 1 ]
 					},
 					{ "time": 1.6667 }
 				]
@@ -2869,13 +2869,13 @@
 				],
 				"scale": [
 					{
-						"curve": [ 0.167, 1, 0.5, 0.8, 0.167, 1, 0.5, 1.1 ]
+						"curve": [ 0.167, 1, 0.5, 0.8, 0.167, 1, 0.5, 1.101 ]
 					},
 					{
 						"time": 0.6667,
 						"x": 0.8,
 						"y": 1.101,
-						"curve": [ 0.917, 0.8, 1.417, 1, 0.917, 1.1, 1.417, 1 ]
+						"curve": [ 0.917, 0.8, 1.417, 1, 0.917, 1.101, 1.417, 1 ]
 					},
 					{ "time": 1.6667 }
 				]
@@ -2937,12 +2937,12 @@
 				"scale": [
 					{
 						"x": 0.897,
-						"curve": [ 0.157, 0.9, 0.373, 0.83, 0.157, 1, 0.373, 1 ]
+						"curve": [ 0.157, 0.896, 0.373, 0.827, 0.157, 1, 0.373, 1 ]
 					},
 					{
 						"time": 0.6667,
 						"x": 0.826,
-						"curve": [ 1.262, 0.83, 1.32, 0.9, 1.262, 1, 1.32, 1 ]
+						"curve": [ 1.262, 0.826, 1.32, 0.897, 1.262, 1, 1.32, 1 ]
 					},
 					{ "time": 1.6667, "x": 0.897 }
 				]
@@ -2953,12 +2953,12 @@
 				],
 				"scale": [
 					{
-						"curve": [ 0.157, 1, 0.373, 0.99, 0.157, 1, 0.373, 1 ]
+						"curve": [ 0.157, 1, 0.373, 0.994, 0.157, 1, 0.373, 1 ]
 					},
 					{
 						"time": 0.6667,
 						"x": 0.994,
-						"curve": [ 1.262, 0.99, 1.32, 1, 1.262, 1, 1.32, 1 ]
+						"curve": [ 1.262, 0.994, 1.32, 1, 1.262, 1, 1.32, 1 ]
 					},
 					{ "time": 1.6667 }
 				]
@@ -3119,13 +3119,13 @@
 				],
 				"scale": [
 					{
-						"curve": [ 0.167, 1, 0.5, 0.8, 0.167, 1, 0.5, 1.1 ]
+						"curve": [ 0.167, 1, 0.5, 0.8, 0.167, 1, 0.5, 1.101 ]
 					},
 					{
 						"time": 0.6667,
 						"x": 0.8,
 						"y": 1.101,
-						"curve": [ 0.917, 0.8, 1.417, 1, 0.917, 1.1, 1.417, 1 ]
+						"curve": [ 0.917, 0.8, 1.417, 1, 0.917, 1.101, 1.417, 1 ]
 					},
 					{ "time": 1.6667 }
 				]
@@ -3211,12 +3211,12 @@
 				"scale": [
 					{
 						"x": 0.897,
-						"curve": [ 0.157, 0.9, 0.373, 0.83, 0.157, 1, 0.373, 1 ]
+						"curve": [ 0.157, 0.896, 0.373, 0.827, 0.157, 1, 0.373, 1 ]
 					},
 					{
 						"time": 0.6667,
 						"x": 0.826,
-						"curve": [ 1.262, 0.83, 1.32, 0.9, 1.262, 1, 1.32, 1 ]
+						"curve": [ 1.262, 0.826, 1.32, 0.897, 1.262, 1, 1.32, 1 ]
 					},
 					{ "time": 1.6667, "x": 0.897 }
 				]
@@ -3227,12 +3227,12 @@
 				],
 				"scale": [
 					{
-						"curve": [ 0.157, 1, 0.373, 0.99, 0.157, 1, 0.373, 1 ]
+						"curve": [ 0.157, 1, 0.373, 0.994, 0.157, 1, 0.373, 1 ]
 					},
 					{
 						"time": 0.6667,
 						"x": 0.994,
-						"curve": [ 1.262, 0.99, 1.32, 1, 1.262, 1, 1.32, 1 ]
+						"curve": [ 1.262, 0.994, 1.32, 1, 1.262, 1, 1.32, 1 ]
 					},
 					{ "time": 1.6667 }
 				]
@@ -4399,7 +4399,7 @@
 						"time": 0.1667,
 						"x": 1.264,
 						"y": 1.264,
-						"curve": [ 0.2, 1.26, 0.227, 1, 0.2, 1.26, 0.227, 1 ]
+						"curve": [ 0.2, 1.264, 0.227, 1, 0.2, 1.264, 0.227, 1 ]
 					},
 					{ "time": 0.3 }
 				]
@@ -4657,7 +4657,7 @@
 						"time": 0.1333,
 						"x": 1.277,
 						"y": 1.277,
-						"curve": [ 0.175, 1.28, 0.2, 1, 0.175, 1.28, 0.2, 1 ]
+						"curve": [ 0.175, 1.277, 0.2, 1, 0.175, 1.277, 0.2, 1 ]
 					},
 					{ "time": 0.3 }
 				]
@@ -4724,7 +4724,7 @@
 					{
 						"time": 0.1144,
 						"x": 1.164,
-						"curve": [ 0.123, 1.08, 0.154, 1, 0.123, 1, 0.154, 1 ]
+						"curve": [ 0.123, 1.084, 0.154, 1, 0.123, 1, 0.154, 1 ]
 					},
 					{ "time": 0.2333 }
 				]
@@ -5491,7 +5491,7 @@
 				]
 			},
 			"muzzle": {
-				"color": [
+				"rgba": [
 					{
 						"time": 0.0225,
 						"color": "ffad76ff",
@@ -5512,7 +5512,7 @@
 				]
 			},
 			"muzzle2": {
-				"color": [
+				"rgba": [
 					{
 						"time": 0.0225,
 						"color": "ffad76ff",
@@ -5538,7 +5538,7 @@
 				"scale": [
 					{
 						"time": 0.0333,
-						"curve": [ 0.127, 1, 0.099, 1.25, 0.127, 1, 0.099, 1.52 ]
+						"curve": [ 0.127, 1, 0.099, 1.247, 0.127, 1, 0.099, 1.517 ]
 					},
 					{ "time": 0.1667, "x": 1.247, "y": 1.517 }
 				]

+ 1 - 1
spine-unity/Assets/Spine Examples/Spine Skeletons/whirlyblendmodes/whirlyblendmodes.json

@@ -1,7 +1,7 @@
 {
 "skeleton": {
 	"hash": "M7buRYUnWiw",
-	"spine": "4.0.11-beta",
+	"spine": "4.0.24-beta",
 	"x": -252.71,
 	"y": -232.55,
 	"width": 456.71,

File diff suppressed because it is too large
+ 4 - 4
spine-unity/Modules/com.esotericsoftware.spine.lwrp-shaders/Spine Skeletons/RaptorLWRP/raptor-pro.json


File diff suppressed because it is too large
+ 4 - 4
spine-unity/Modules/com.esotericsoftware.spine.lwrp-shaders/Spine Skeletons/StretchymanLWRP/stretchyman.json


File diff suppressed because it is too large
+ 4 - 4
spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Examples/2D/Spine Skeletons/RaptorURP/raptor-pro.json


File diff suppressed because it is too large
+ 4 - 4
spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Examples/2D/Spine Skeletons/StretchymanURP/stretchyman.json


File diff suppressed because it is too large
+ 4 - 4
spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Examples/3D/Spine Skeletons/RaptorURP/raptor-pro.json


File diff suppressed because it is too large
+ 4 - 4
spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Examples/3D/Spine Skeletons/StretchymanURP/stretchyman.json


Some files were not shown because too many files changed in this diff