Browse Source

Merge branch '3.7-beta' into 3.7-beta-cpp

badlogic 7 years ago
parent
commit
8f95417ac3

+ 67 - 68
spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/utils/TwoColorPolygonBatch.java

@@ -67,9 +67,13 @@ public class TwoColorPolygonBatch implements Batch {
 	private int blendDstFuncAlpha = GL20.GL_ONE_MINUS_SRC_ALPHA;
 	private boolean premultipliedAlpha;
 
-	private float light = Color.WHITE.toFloatBits();
-	private float dark = Color.BLACK.toFloatBits();
-	private Color tempColor = new Color(1, 1, 1, 1);
+	private final Color light = new Color(1, 1, 1, 1);
+	private final Color dark = new Color(0, 0, 0, 1);
+	private float lightPacked = Color.WHITE.toFloatBits();
+	private float darkPacked = Color.BLACK.toFloatBits();
+
+	/** Number of rendering calls, ever. Will not be reset unless set manually. **/
+	public int totalRenderCalls = 0;
 
 	public TwoColorPolygonBatch () {
 		this(2000);
@@ -122,61 +126,53 @@ public class TwoColorPolygonBatch implements Batch {
 
 	@Override
 	public void setColor (Color tint) {
-		light = tint.toFloatBits();
+		light.set(tint);
+		lightPacked = tint.toFloatBits();
 	}
 
 	@Override
 	public void setColor (float r, float g, float b, float a) {
-		int intBits = (int)(255 * a) << 24 | (int)(255 * b) << 16 | (int)(255 * g) << 8 | (int)(255 * r);
-		light = NumberUtils.intToFloatColor(intBits);
+		light.set(r, g, b, a);
+		lightPacked = light.toFloatBits();
 	}
 
 	@Override
-	public void setColor (float color) {
-		this.light = color;
+	public void setPackedColor (float packedColor) {
+		Color.rgba8888ToColor(light, NumberUtils.floatToIntColor(packedColor));
+		lightPacked = packedColor;
 	}
 
 	@Override
 	public Color getColor () {
-		int intBits = NumberUtils.floatToIntColor(light);
-		Color color = this.tempColor;
-		color.r = (intBits & 0xff) / 255f;
-		color.g = ((intBits >>> 8) & 0xff) / 255f;
-		color.b = ((intBits >>> 16) & 0xff) / 255f;
-		color.a = ((intBits >>> 24) & 0xff) / 255f;
-		return color;
+		return light;
 	}
 
 	@Override
 	public float getPackedColor () {
-		return light;
+		return lightPacked;
 	}
 
 	public void setDarkColor (Color tint) {
-		dark = tint.toFloatBits();
+		dark.set(tint);
+		darkPacked = tint.toFloatBits();
 	}
 
 	public void setDarkColor (float r, float g, float b, float a) {
-		int intBits = (int)(255 * a) << 24 | (int)(255 * b) << 16 | (int)(255 * g) << 8 | (int)(255 * r);
-		dark = NumberUtils.intToFloatColor(intBits);
+		dark.set(r, g, b, a);
+		darkPacked = dark.toFloatBits();
 	}
 
-	public void setDarkColor (float color) {
-		this.dark = color;
+	public void setPackedDarkColor (float packedColor) {
+		Color.rgba8888ToColor(dark, NumberUtils.floatToIntColor(packedColor));
+		this.darkPacked = packedColor;
 	}
 
 	public Color getDarkColor () {
-		int intBits = NumberUtils.floatToIntColor(dark);
-		Color color = this.tempColor;
-		color.r = (intBits & 0xff) / 255f;
-		color.g = ((intBits >>> 8) & 0xff) / 255f;
-		color.b = ((intBits >>> 16) & 0xff) / 255f;
-		color.a = ((intBits >>> 24) & 0xff) / 255f;
-		return color;
+		return dark;
 	}
 
 	public float getPackedDarkColor () {
-		return dark;
+		return darkPacked;
 	}
 
 	/** Draws a polygon region with the bottom left corner at x,y having the width and height of the region. */
@@ -193,7 +189,7 @@ public class TwoColorPolygonBatch implements Batch {
 		if (texture != lastTexture)
 			switchTexture(texture);
 		else if (triangleIndex + regionTrianglesLength > triangles.length
-				|| vertexIndex + regionVerticesLength * VERTEX_SIZE / 2 > vertices.length) flush();
+			|| vertexIndex + regionVerticesLength * VERTEX_SIZE / 2 > vertices.length) flush();
 
 		int triangleIndex = this.triangleIndex;
 		int vertexIndex = this.vertexIndex;
@@ -204,8 +200,8 @@ public class TwoColorPolygonBatch implements Batch {
 		this.triangleIndex = triangleIndex;
 
 		final float[] vertices = this.vertices;
-		final float light = this.light;
-		final float dark = this.dark;
+		final float light = this.lightPacked;
+		final float dark = this.darkPacked;
 		final float[] textureCoords = region.getTextureCoords();
 
 		for (int i = 0; i < regionVerticesLength; i += 2) {
@@ -234,7 +230,7 @@ public class TwoColorPolygonBatch implements Batch {
 		if (texture != lastTexture)
 			switchTexture(texture);
 		else if (triangleIndex + regionTrianglesLength > triangles.length
-				|| vertexIndex + regionVerticesLength * VERTEX_SIZE / 2 > vertices.length) flush();
+			|| vertexIndex + regionVerticesLength * VERTEX_SIZE / 2 > vertices.length) flush();
 
 		int triangleIndex = this.triangleIndex;
 		int vertexIndex = this.vertexIndex;
@@ -245,8 +241,8 @@ public class TwoColorPolygonBatch implements Batch {
 		this.triangleIndex = triangleIndex;
 
 		final float[] vertices = this.vertices;
-		final float light = this.light;
-		final float dark = this.dark;
+		final float light = this.lightPacked;
+		final float dark = this.darkPacked;
 		final float[] textureCoords = region.getTextureCoords();
 		final float sX = width / textureRegion.getRegionWidth();
 		final float sY = height / textureRegion.getRegionHeight();
@@ -267,7 +263,7 @@ public class TwoColorPolygonBatch implements Batch {
 	 * polygon region should be scaled around originX, originY. Rotation specifies the angle of counter clockwise rotation of the
 	 * rectangle around originX, originY. */
 	public void draw (PolygonRegion region, float x, float y, float originX, float originY, float width, float height,
-					  float scaleX, float scaleY, float rotation) {
+		float scaleX, float scaleY, float rotation) {
 		if (!drawing) throw new IllegalStateException("begin must be called before draw.");
 
 		final short[] triangles = this.triangles;
@@ -281,7 +277,7 @@ public class TwoColorPolygonBatch implements Batch {
 		if (texture != lastTexture)
 			switchTexture(texture);
 		else if (triangleIndex + regionTrianglesLength > triangles.length
-				|| vertexIndex + regionVerticesLength * VERTEX_SIZE / 2 > vertices.length) flush();
+			|| vertexIndex + regionVerticesLength * VERTEX_SIZE / 2 > vertices.length) flush();
 
 		int triangleIndex = this.triangleIndex;
 		int vertexIndex = this.vertexIndex;
@@ -292,8 +288,8 @@ public class TwoColorPolygonBatch implements Batch {
 		this.triangleIndex = triangleIndex;
 
 		final float[] vertices = this.vertices;
-		final float light = this.light;
-		final float dark = this.dark;
+		final float light = this.lightPacked;
+		final float dark = this.darkPacked;
 		final float[] textureCoords = region.getTextureCoords();
 
 		final float worldOriginX = x + originX;
@@ -343,7 +339,7 @@ public class TwoColorPolygonBatch implements Batch {
 
 	@Override
 	public void draw (Texture texture, float x, float y, float originX, float originY, float width, float height, float scaleX,
-					  float scaleY, float rotation, int srcX, int srcY, int srcWidth, int srcHeight, boolean flipX, boolean flipY) {
+		float scaleY, float rotation, int srcX, int srcY, int srcWidth, int srcHeight, boolean flipX, boolean flipY) {
 		if (!drawing) throw new IllegalStateException("begin must be called before draw.");
 
 		final short[] triangles = this.triangles;
@@ -455,8 +451,8 @@ public class TwoColorPolygonBatch implements Batch {
 			v2 = tmp;
 		}
 
-		float light = this.light;
-		float dark = this.dark;
+		float light = this.lightPacked;
+		float dark = this.darkPacked;
 		int idx = this.vertexIndex;
 		vertices[idx++] = x1;
 		vertices[idx++] = y1;
@@ -490,7 +486,7 @@ public class TwoColorPolygonBatch implements Batch {
 
 	@Override
 	public void draw (Texture texture, float x, float y, float width, float height, int srcX, int srcY, int srcWidth,
-					  int srcHeight, boolean flipX, boolean flipY) {
+		int srcHeight, boolean flipX, boolean flipY) {
 		if (!drawing) throw new IllegalStateException("begin must be called before draw.");
 
 		final short[] triangles = this.triangles;
@@ -530,8 +526,8 @@ public class TwoColorPolygonBatch implements Batch {
 			v2 = tmp;
 		}
 
-		float light = this.light;
-		float dark = this.dark;
+		float light = this.lightPacked;
+		float dark = this.darkPacked;
 		int idx = this.vertexIndex;
 		vertices[idx++] = x;
 		vertices[idx++] = y;
@@ -592,8 +588,8 @@ public class TwoColorPolygonBatch implements Batch {
 		final float fx2 = x + srcWidth;
 		final float fy2 = y + srcHeight;
 
-		float light = this.light;
-		float dark = this.dark;
+		float light = this.lightPacked;
+		float dark = this.darkPacked;
 		int idx = this.vertexIndex;
 		vertices[idx++] = x;
 		vertices[idx++] = y;
@@ -650,8 +646,8 @@ public class TwoColorPolygonBatch implements Batch {
 		final float fx2 = x + width;
 		final float fy2 = y + height;
 
-		float light = this.light;
-		float dark = this.dark;
+		float light = this.lightPacked;
+		float dark = this.darkPacked;
 		int idx = this.vertexIndex;
 		vertices[idx++] = x;
 		vertices[idx++] = y;
@@ -717,8 +713,8 @@ public class TwoColorPolygonBatch implements Batch {
 		final float u2 = 1;
 		final float v2 = 0;
 
-		float light = this.light;
-		float dark = this.dark;
+		float light = this.lightPacked;
+		float dark = this.darkPacked;
 		int idx = this.vertexIndex;
 		vertices[idx++] = x;
 		vertices[idx++] = y;
@@ -750,8 +746,9 @@ public class TwoColorPolygonBatch implements Batch {
 		this.vertexIndex = idx;
 	}
 
-	/** Draws a rectangle using the given vertices. There must be 4 vertices, each made up of 6 elements in this order: x, y, lightColor, darkColor,
-	 * u, v. The {@link #getColor()} and {@link #getDarkColor()} from the TwoColorPolygonBatch is not applied. */
+	/** Draws a rectangle using the given vertices. There must be 4 vertices, each made up of 6 elements in this order: x, y,
+	 * lightColor, darkColor, u, v. The {@link #getColor()} and {@link #getDarkColor()} from the TwoColorPolygonBatch is not
+	 * applied. */
 	@Override
 	public void draw (Texture texture, float[] spriteVertices, int offset, int count) {
 		if (!drawing) throw new IllegalStateException("begin must be called before draw.");
@@ -832,8 +829,8 @@ public class TwoColorPolygonBatch implements Batch {
 		final float u2 = region.getU2();
 		final float v2 = region.getV();
 
-		float light = this.light;
-		float dark = this.dark;
+		float light = this.lightPacked;
+		float dark = this.darkPacked;
 		int idx = this.vertexIndex;
 		vertices[idx++] = x;
 		vertices[idx++] = y;
@@ -867,7 +864,7 @@ public class TwoColorPolygonBatch implements Batch {
 
 	@Override
 	public void draw (TextureRegion region, float x, float y, float originX, float originY, float width, float height,
-					  float scaleX, float scaleY, float rotation) {
+		float scaleX, float scaleY, float rotation) {
 		if (!drawing) throw new IllegalStateException("begin must be called before draw.");
 
 		final short[] triangles = this.triangles;
@@ -968,8 +965,8 @@ public class TwoColorPolygonBatch implements Batch {
 		final float u2 = region.getU2();
 		final float v2 = region.getV();
 
-		float light = this.light;
-		float dark = this.dark;
+		float light = this.lightPacked;
+		float dark = this.darkPacked;
 		int idx = this.vertexIndex;
 		vertices[idx++] = x1;
 		vertices[idx++] = y1;
@@ -1003,7 +1000,7 @@ public class TwoColorPolygonBatch implements Batch {
 
 	@Override
 	public void draw (TextureRegion region, float x, float y, float originX, float originY, float width, float height,
-					  float scaleX, float scaleY, float rotation, boolean clockwise) {
+		float scaleX, float scaleY, float rotation, boolean clockwise) {
 		if (!drawing) throw new IllegalStateException("begin must be called before draw.");
 
 		final short[] triangles = this.triangles;
@@ -1120,8 +1117,8 @@ public class TwoColorPolygonBatch implements Batch {
 			v4 = region.getV2();
 		}
 
-		float light = this.light;
-		float dark = this.dark;
+		float light = this.lightPacked;
+		float dark = this.darkPacked;
 		int idx = this.vertexIndex;
 		vertices[idx++] = x1;
 		vertices[idx++] = y1;
@@ -1191,8 +1188,8 @@ public class TwoColorPolygonBatch implements Batch {
 		final float u2 = region.getU2();
 		final float v2 = region.getV();
 
-		float light = this.light;
-		float dark = this.dark;
+		float light = this.lightPacked;
+		float dark = this.darkPacked;
 		int idx = vertexIndex;
 		vertices[idx++] = x1;
 		vertices[idx++] = y1;
@@ -1228,6 +1225,8 @@ public class TwoColorPolygonBatch implements Batch {
 	public void flush () {
 		if (vertexIndex == 0) return;
 
+		totalRenderCalls++;
+
 		lastTexture.bind();
 		Mesh mesh = this.mesh;
 		mesh.setVertices(vertices, 0, vertexIndex);
@@ -1241,13 +1240,13 @@ public class TwoColorPolygonBatch implements Batch {
 	}
 
 	@Override
-	public void disableBlending() {
+	public void disableBlending () {
 		flush();
 		blendingDisabled = true;
 	}
 
 	@Override
-	public void enableBlending() {
+	public void enableBlending () {
 		flush();
 		blendingDisabled = false;
 	}
@@ -1323,7 +1322,7 @@ public class TwoColorPolygonBatch implements Batch {
 	}
 
 	@Override
-	public ShaderProgram getShader() {
+	public ShaderProgram getShader () {
 		return shader;
 	}
 
@@ -1366,12 +1365,12 @@ public class TwoColorPolygonBatch implements Batch {
 	}
 
 	@Override
-	public int getBlendSrcFuncAlpha() {
+	public int getBlendSrcFuncAlpha () {
 		return blendSrcFuncAlpha;
 	}
 
 	@Override
-	public int getBlendDstFuncAlpha() {
+	public int getBlendDstFuncAlpha () {
 		return blendDstFuncAlpha;
 	}
 

+ 2 - 13
spine-unity/Assets/Spine/Editor/spine-unity/Editor/Menus.cs

@@ -37,23 +37,12 @@ namespace Spine.Unity.Editor {
 	public static class Menus {
 		[MenuItem("GameObject/Spine/SkeletonRenderer", false, 10)]
 		static public void CreateSkeletonRendererGameObject () {
-			CreateSpineGameObject<SkeletonRenderer>("New SkeletonRenderer");
+			SpineEditorUtilities.EditorInstantiation.InstantiateEmptySpineGameObject<SkeletonRenderer>("New SkeletonRenderer");
 		}
 
 		[MenuItem("GameObject/Spine/SkeletonAnimation", false, 10)]
 		static public void CreateSkeletonAnimationGameObject () {
-			CreateSpineGameObject<SkeletonAnimation>("New SkeletonAnimation");
-		}
-
-		static void CreateSpineGameObject<T> (string name) where T : MonoBehaviour {
-			var parentGameObject = Selection.activeObject as GameObject;
-			var parentTransform = parentGameObject == null ? null : parentGameObject.transform;
-
-			var gameObject = new GameObject(name, typeof(T));
-			gameObject.transform.SetParent(parentTransform, false);
-			EditorUtility.FocusProjectWindow();
-			Selection.activeObject = gameObject;
-			EditorGUIUtility.PingObject(Selection.activeObject);
+			SpineEditorUtilities.EditorInstantiation.InstantiateEmptySpineGameObject<SkeletonAnimation>("New SkeletonAnimation");
 		}
 	}
 }

+ 20 - 28
spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonBaker.cs

@@ -1165,13 +1165,13 @@ namespace Spine.Unity.Editor {
 			var boneData = skeleton.Data.Bones.Items[timeline.BoneIndex];
 			var bone = skeleton.Bones.Items[timeline.BoneIndex];
 
-			AnimationCurve curve = new AnimationCurve();
+			var curve = new AnimationCurve();
 
 			float endTime = timeline.Frames[(timeline.FrameCount * 2) - 2];
 
 			float currentTime = timeline.Frames[0];
 
-			List<Keyframe> keys = new List<Keyframe>();
+			var keys = new List<Keyframe>();
 
 			float rotation = timeline.Frames[1] + boneData.Rotation;
 
@@ -1296,35 +1296,27 @@ namespace Spine.Unity.Editor {
 		}
 
 		static void ParseEventTimeline (EventTimeline timeline, AnimationClip clip, SendMessageOptions eventOptions) {
-
 			float[] frames = timeline.Frames;
 			var events = timeline.Events;
 
-			List<AnimationEvent> animEvents = new List<AnimationEvent>();
-			for (int i = 0; i < frames.Length; i++) {
-				var ev = events[i];
-
-				AnimationEvent ae = new AnimationEvent();
-				//MITCH: left todo:  Deal with Mecanim's zero-time missed event
-				ae.time = frames[i];
-				ae.functionName = ev.Data.Name;
-				ae.messageOptions = eventOptions;
-
-				if (!string.IsNullOrEmpty(ev.String)) {
-					ae.stringParameter = ev.String;
-				} else {
-					if (ev.Int == 0 && ev.Float == 0) {
-						//do nothing, raw function
-					} else {
-						if (ev.Int != 0)
-							ae.floatParameter = (float)ev.Int;
-						else
-							ae.floatParameter = ev.Float;
-					}
-
-				}
-
-				animEvents.Add(ae);
+			var animEvents = new List<AnimationEvent>();
+			for (int i = 0, n = frames.Length; i < n; i++) {
+				var spineEvent = events[i];
+				var unityAnimationEvent = new AnimationEvent {
+					time = frames[i],
+					functionName = spineEvent.Data.Name,
+					messageOptions = eventOptions
+				};
+
+				if (!string.IsNullOrEmpty(spineEvent.String)) {
+					unityAnimationEvent.stringParameter = spineEvent.String;
+				} else if (spineEvent.Int != 0) {
+					unityAnimationEvent.intParameter = spineEvent.Int;
+				} else if (spineEvent.Float != 0) {
+					unityAnimationEvent.floatParameter = spineEvent.Float;
+				} // else, paramless function/Action.
+
+				animEvents.Add(unityAnimationEvent);
 			}
 
 			AnimationUtility.SetAnimationEvents(clip, animEvents.ToArray());

+ 13 - 2
spine-unity/Assets/Spine/Editor/spine-unity/Editor/SpineEditorUtilities.cs

@@ -84,7 +84,6 @@ namespace Spine.Unity.Editor {
 			public static Texture2D skeletonDataAssetIcon;
 			public static Texture2D info;
 			public static Texture2D unity;
-//			public static Texture2D controllerIcon;
 
 			static Texture2D LoadIcon (string filename) {
 				return (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/" + filename);
@@ -131,7 +130,6 @@ namespace Spine.Unity.Editor {
 
 				info = EditorGUIUtility.FindTexture("console.infoicon.sml");
 				unity = EditorGUIUtility.FindTexture("SceneAsset Icon");
-//				controllerIcon = EditorGUIUtility.FindTexture("AnimatorController Icon");
 			}
 
 			public static Texture2D GetAttachmentIcon (Attachment attachment) {
@@ -381,6 +379,8 @@ namespace Spine.Unity.Editor {
 
 				foreach (var sr in activeSkeletonRenderers) {
 					sr.Initialize(true);
+					//Debug.Log(sr.name);
+					//Debug.Log(sr.valid);
 				}
 
 				foreach (var sg in activeSkeletonGraphics) {
@@ -1227,6 +1227,17 @@ namespace Spine.Unity.Editor {
 				return newSkeletonAnimation;
 			}
 
+			public static void InstantiateEmptySpineGameObject<T> (string name) where T : MonoBehaviour {
+				var parentGameObject = Selection.activeObject as GameObject;
+				var parentTransform = parentGameObject == null ? null : parentGameObject.transform;
+
+				var gameObject = new GameObject(name, typeof(T));
+				gameObject.transform.SetParent(parentTransform, false);
+				EditorUtility.FocusProjectWindow();
+				Selection.activeObject = gameObject;
+				EditorGUIUtility.PingObject(Selection.activeObject);
+			}
+
 			#region SkeletonMecanim
 			#if SPINE_SKELETONMECANIM
 			public static SkeletonMecanim InstantiateSkeletonMecanim (SkeletonDataAsset skeletonDataAsset, string skinName) {

+ 10 - 7
spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonPartsRendererInspector.cs

@@ -38,17 +38,20 @@ namespace Spine.Unity.Modules {
 		SpineInspectorUtility.SerializedSortingProperties sortingProperties;
 
 		void OnEnable () {			
-			sortingProperties = new SpineInspectorUtility.SerializedSortingProperties((target as Component).GetComponent<MeshRenderer>());
+			sortingProperties = new SpineInspectorUtility.SerializedSortingProperties(SpineInspectorUtility.GetRenderersSerializedObject(serializedObject));
 		}
 
 		public override void OnInspectorGUI () {
 			SpineInspectorUtility.SortingPropertyFields(sortingProperties, true);
-			EditorGUILayout.Space();
-			if (SpineInspectorUtility.LargeCenteredButton(new GUIContent("Select SkeletonRenderer", SpineEditorUtilities.Icons.spine))) {
-				var thisSkeletonPartsRenderer = target as SkeletonPartsRenderer;
-				var srs = thisSkeletonPartsRenderer.GetComponentInParent<SkeletonRenderSeparator>();
-				if (srs != null && srs.partsRenderers.Contains(thisSkeletonPartsRenderer) && srs.SkeletonRenderer != null)
-					Selection.activeGameObject = srs.SkeletonRenderer.gameObject;
+
+			if (!serializedObject.isEditingMultipleObjects) {
+				EditorGUILayout.Space();
+				if (SpineInspectorUtility.LargeCenteredButton(new GUIContent("Select SkeletonRenderer", SpineEditorUtilities.Icons.spine))) {
+					var thisSkeletonPartsRenderer = target as SkeletonPartsRenderer;
+					var srs = thisSkeletonPartsRenderer.GetComponentInParent<SkeletonRenderSeparator>();
+					if (srs != null && srs.partsRenderers.Contains(thisSkeletonPartsRenderer) && srs.SkeletonRenderer != null)
+						Selection.activeGameObject = srs.SkeletonRenderer.gameObject;
+				}
 			}
 		}
 	}

+ 1 - 0
spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataAsset.cs

@@ -100,6 +100,7 @@ namespace Spine.Unity {
 			stateData = null;
 		}
 
+		/// <summary>Loads, caches and returns the SkeletonData from the skeleton data file. Returns the cached SkeletonData after the first time it is called. Pass false to prevent direct errors from being logged.</summary>
 		public SkeletonData GetSkeletonData (bool quiet) {
 			if (skeletonJSON == null) {
 				if (!quiet)

+ 0 - 1
spine-unity/Assets/Spine/Runtime/spine-unity/Modules/AnimationMatchModifier/AnimationMatchModifierAsset.cs

@@ -206,7 +206,6 @@ namespace Spine.Unity.Modules {
 				var t = new DeformTimeline(1);
 				t.slotIndex = timeline.slotIndex;
 				t.attachment = timeline.attachment;
-				var slotData = skeletonData.slots.Items[t.slotIndex];
 
 				if (t.attachment.IsWeighted()) {
 					t.SetFrame(0, 0, new float[t.attachment.vertices.Length]);

+ 14 - 6
spine-unity/Assets/Spine/Runtime/spine-unity/Modules/AttachmentTools/AttachmentTools.cs

@@ -952,7 +952,7 @@ namespace Spine.Unity.Modules.AttachmentTools {
 		}
 
 		public static MeshAttachment GetLinkedClone (this MeshAttachment o, bool inheritDeform = true) {
-			return o.GetLinkedMesh(o.Name, o.RendererObject as AtlasRegion, inheritDeform);
+			return o.GetLinkedMesh(o.Name, o.RendererObject as AtlasRegion, inheritDeform, copyOriginalProperties: true);
 		}
 
 		/// <summary>
@@ -1026,7 +1026,7 @@ namespace Spine.Unity.Modules.AttachmentTools {
 		#region Runtime Linked MeshAttachments
 		/// <summary>
 		/// Returns a new linked mesh linked to this MeshAttachment. It will be mapped to the AtlasRegion provided.</summary>
-		public static MeshAttachment GetLinkedMesh (this MeshAttachment o, string newLinkedMeshName, AtlasRegion region, bool inheritDeform = true) {
+		public static MeshAttachment GetLinkedMesh (this MeshAttachment o, string newLinkedMeshName, AtlasRegion region, bool inheritDeform = true, bool copyOriginalProperties = false) {
 			//if (string.IsNullOrEmpty(attachmentName)) throw new System.ArgumentException("attachmentName cannot be null or empty", "attachmentName");
 			if (region == null) throw new System.ArgumentNullException("region");
 
@@ -1040,10 +1040,18 @@ namespace Spine.Unity.Modules.AttachmentTools {
 
 			// 2. (SkeletonJson.cs::ReadAttachment. case: LinkedMesh)
 			mesh.Path = newLinkedMeshName;
-			mesh.r = 1f;
-			mesh.g = 1f;
-			mesh.b = 1f;
-			mesh.a = 1f;
+			if (copyOriginalProperties) {
+				mesh.r = o.r;
+				mesh.g = o.g;
+				mesh.b = o.b;
+				mesh.a = o.a;
+			} else {
+				mesh.r = 1f;
+				mesh.g = 1f;
+				mesh.b = 1f;
+				mesh.a = 1f;
+			}
+			
 			//mesh.ParentMesh property call below sets mesh.Width and mesh.Height
 
 			// 3. Link mesh with parent. (SkeletonJson.cs)

+ 1 - 0
spine-unity/Assets/Spine/Runtime/spine-unity/Modules/BoundingBoxFollower/BoundingBoxFollower.cs

@@ -145,6 +145,7 @@ namespace Spine.Unity {
 				if (boundingBoxAttachment != null) {
 					if (!colliderTable.ContainsKey(boundingBoxAttachment)) {
 						var bbCollider = SkeletonUtility.AddBoundingBoxAsComponent(boundingBoxAttachment, slot, gameObject, isTrigger);
+
 						bbCollider.enabled = false;
 						bbCollider.hideFlags = HideFlags.NotEditable;
 						bbCollider.isTrigger = IsTrigger;

+ 10 - 4
spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Ragdoll/SkeletonRagdoll2D.cs

@@ -362,19 +362,25 @@ namespace Spine.Unity.Modules {
 			var skin = skeleton.Skin ?? skeleton.Data.DefaultSkin;
 
 			var attachments = new List<Attachment>();
-			foreach (Slot s in skeleton.Slots) {
-				if (s.bone == b) {
-					skin.FindAttachmentsForSlot(skeleton.Slots.IndexOf(s), attachments);
+			foreach (Slot slot in skeleton.Slots) {
+				if (slot.bone == b) {
+					skin.FindAttachmentsForSlot(skeleton.Slots.IndexOf(slot), attachments);
+
+					bool bbAttachmentAdded = false;
 					foreach (var a in attachments) {
 						var bbAttachment = a as BoundingBoxAttachment;
 						if (bbAttachment != null) {
 							if (!a.Name.ToLower().Contains(AttachmentNameMarker))
 								continue;
 
-							var bbCollider = SkeletonUtility.AddBoundingBoxAsComponent(bbAttachment, s, go, isTrigger: false, isKinematic: false, gravityScale: gravityScale);
+							bbAttachmentAdded = true;
+							var bbCollider = SkeletonUtility.AddBoundingBoxAsComponent(bbAttachment, slot, go, isTrigger: false);
 							colliders.Add(bbCollider);
 						}
 					}
+
+					if (bbAttachmentAdded)
+						SkeletonUtility.AddBoneRigidbody2D(go, isKinematic: false, gravityScale: gravityScale);
 				}
 			}
 

+ 4 - 1
spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonExtensions.cs

@@ -614,7 +614,7 @@ namespace Spine {
 			animation.Apply(skeleton, 0, time, loop, null, 1f, MixBlend.Setup, MixDirection.In);
 		}
 
-		/// <summary>Pose a skeleton according to a given time in an animation.</summary>
+		/// <summary>Pose a skeleton according to a given time in an animation. This is the simplified version of Animation.Apply(skeleton).</summary>
 		public static void PoseSkeleton (this Animation animation, Skeleton skeleton, float time, bool loop = false) {
 			animation.Apply(skeleton, 0, time, loop, null, 1f, MixBlend.Setup, MixDirection.In);
 		}
@@ -624,6 +624,9 @@ namespace Spine {
 			animation.Apply(skeleton, 0, 0, false, null, 0, MixBlend.Setup, MixDirection.Out);
 		}
 
+		public static void AllowImmediateQueue (this TrackEntry trackEntry) {
+			if (trackEntry.nextTrackLast < 0) trackEntry.nextTrackLast = 0;
+		}
 
 		#endregion
 

+ 11 - 11
spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonUtility/SkeletonUtility.cs

@@ -73,18 +73,8 @@ namespace Spine.Unity {
 			return AddBoundingBoxAsComponent(box, slot, go, isTrigger);
 		}
 
-		public static PolygonCollider2D AddBoundingBoxAsComponent (BoundingBoxAttachment box, Slot slot, GameObject gameObject, bool isTrigger = true, bool isKinematic = true, float gravityScale = 0f) {
+		public static PolygonCollider2D AddBoundingBoxAsComponent (BoundingBoxAttachment box, Slot slot, GameObject gameObject, bool isTrigger = true) {
 			if (box == null) return null;
-
-			if (slot.bone != slot.Skeleton.RootBone) {
-				var rb = gameObject.GetComponent<Rigidbody2D>();
-				if (rb == null) {
-					rb = gameObject.AddComponent<Rigidbody2D>();
-					rb.isKinematic = isKinematic;
-					rb.gravityScale = gravityScale;
-				}
-			}
-
 			var collider = gameObject.AddComponent<PolygonCollider2D>();
 			collider.isTrigger = isTrigger;
 			SetColliderPointsLocal(collider, slot, box);
@@ -114,6 +104,16 @@ namespace Spine.Unity {
 
 			return bounds;
 		}
+
+		public static Rigidbody2D AddBoneRigidbody2D (GameObject gameObject, bool isKinematic = true, float gravityScale = 0f) {
+			var rb = gameObject.GetComponent<Rigidbody2D>();
+			if (rb == null) {
+				rb = gameObject.AddComponent<Rigidbody2D>();
+				rb.isKinematic = isKinematic;
+				rb.gravityScale = gravityScale;
+			}
+			return rb;
+		}
 		#endregion
 
 		public delegate void SkeletonUtilityDelegate ();

+ 1 - 0
spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs

@@ -222,6 +222,7 @@ namespace Spine.Unity {
 		}
 
 		public void AddBoundingBox (string skinName, string slotName, string attachmentName) {
+			SkeletonUtility.AddBoneRigidbody2D(transform.gameObject);
 			SkeletonUtility.AddBoundingBoxGameObject(bone.skeleton, skinName, slotName, attachmentName, transform);
 		}