diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/utils/TwoColorPolygonBatch.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/utils/TwoColorPolygonBatch.java index 22f713552..c1d8cf652 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/utils/TwoColorPolygonBatch.java +++ b/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; } diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Menus.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Menus.cs index 8859fecb1..c3b90295d 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Menus.cs +++ b/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("New SkeletonRenderer"); + SpineEditorUtilities.EditorInstantiation.InstantiateEmptySpineGameObject("New SkeletonRenderer"); } [MenuItem("GameObject/Spine/SkeletonAnimation", false, 10)] static public void CreateSkeletonAnimationGameObject () { - CreateSpineGameObject("New SkeletonAnimation"); - } - - static void CreateSpineGameObject (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("New SkeletonAnimation"); } } } diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonBaker.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonBaker.cs index bbed3b657..52faaafca 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonBaker.cs +++ b/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 keys = new List(); + var keys = new List(); 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 animEvents = new List(); - for (int i = 0; i < frames.Length; i++) { - var ev = events[i]; + var animEvents = new List(); + 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 + }; - 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(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. - 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); + animEvents.Add(unityAnimationEvent); } AnimationUtility.SetAnimationEvents(clip, animEvents.ToArray()); diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SpineEditorUtilities.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SpineEditorUtilities.cs index 8e40bb2c6..b6648ec2a 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/SpineEditorUtilities.cs +++ b/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 (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) { diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonPartsRendererInspector.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonPartsRendererInspector.cs index 81eda3f98..b6cebad64 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Modules/SkeletonRenderSeparator/Editor/SkeletonPartsRendererInspector.cs +++ b/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()); + 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(); - 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(); + if (srs != null && srs.partsRenderers.Contains(thisSkeletonPartsRenderer) && srs.SkeletonRenderer != null) + Selection.activeGameObject = srs.SkeletonRenderer.gameObject; + } } } } diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataAsset.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataAsset.cs index 0997082df..544a7a782 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataAsset.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Asset Types/SkeletonDataAsset.cs @@ -100,6 +100,7 @@ namespace Spine.Unity { stateData = null; } + /// 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. public SkeletonData GetSkeletonData (bool quiet) { if (skeletonJSON == null) { if (!quiet) diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/AnimationMatchModifier/AnimationMatchModifierAsset.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/AnimationMatchModifier/AnimationMatchModifierAsset.cs index 170679e73..1c87c61db 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/AnimationMatchModifier/AnimationMatchModifierAsset.cs +++ b/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]); diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/AttachmentTools/AttachmentTools.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/AttachmentTools/AttachmentTools.cs index 48ad8461d..926efbe32 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/AttachmentTools/AttachmentTools.cs +++ b/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); } /// @@ -1026,7 +1026,7 @@ namespace Spine.Unity.Modules.AttachmentTools { #region Runtime Linked MeshAttachments /// /// Returns a new linked mesh linked to this MeshAttachment. It will be mapped to the AtlasRegion provided. - 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) diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/BoundingBoxFollower/BoundingBoxFollower.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/BoundingBoxFollower/BoundingBoxFollower.cs index 54df52ea0..bc52a2c2e 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/BoundingBoxFollower/BoundingBoxFollower.cs +++ b/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; diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Ragdoll/SkeletonRagdoll2D.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Ragdoll/SkeletonRagdoll2D.cs index f66015a74..73593b46c 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/Ragdoll/SkeletonRagdoll2D.cs +++ b/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(); - 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); } } diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonExtensions.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonExtensions.cs index 567aa07ca..48460214f 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonExtensions.cs +++ b/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); } - /// Pose a skeleton according to a given time in an animation. + /// Pose a skeleton according to a given time in an animation. This is the simplified version of Animation.Apply(skeleton). 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 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonUtility/SkeletonUtility.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonUtility/SkeletonUtility.cs index f580f86f5..bcbf4cff3 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonUtility/SkeletonUtility.cs +++ b/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(); - if (rb == null) { - rb = gameObject.AddComponent(); - rb.isKinematic = isKinematic; - rb.gravityScale = gravityScale; - } - } - var collider = gameObject.AddComponent(); 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(); + if (rb == null) { + rb = gameObject.AddComponent(); + rb.isKinematic = isKinematic; + rb.gravityScale = gravityScale; + } + return rb; + } #endregion public delegate void SkeletonUtilityDelegate (); diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs index 771045010..b80c59672 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs +++ b/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); }