diff --git a/spine-csharp/src/Skeleton.cs b/spine-csharp/src/Skeleton.cs index c8c26df69..e92c4a7e6 100644 --- a/spine-csharp/src/Skeleton.cs +++ b/spine-csharp/src/Skeleton.cs @@ -139,12 +139,14 @@ namespace Spine { /// Updates the world transform for each bone and applies IK constraints. public void UpdateWorldTransform () { ExposedList bones = this.bones; - for (int ii = 0, nn = bones.Count; ii < nn; ii++) { - Bone bone = bones.Items[ii]; - bone.rotationIK = bone.rotation; - } - ExposedList> boneCache = this.boneCache; - ExposedList ikConstraints = this.ikConstraints; + ExposedList ikConstraints = this.ikConstraints; + if (ikConstraints.Count > 0) { + for (int ii = 0, nn = bones.Count; ii < nn; ii++) { + Bone bone = bones.Items[ii]; + bone.rotationIK = bone.rotation; + } + } + ExposedList> boneCache = this.boneCache; int i = 0, last = boneCache.Count - 1; while (true) { ExposedList updateBones = boneCache.Items[i]; diff --git a/spine-unity/Assets/spine-unity/SkeletonAnimator.cs b/spine-unity/Assets/spine-unity/SkeletonAnimator.cs index 4adba2684..1017de4aa 100644 --- a/spine-unity/Assets/spine-unity/SkeletonAnimator.cs +++ b/spine-unity/Assets/spine-unity/SkeletonAnimator.cs @@ -63,6 +63,7 @@ public class SkeletonAnimator : SkeletonRenderer, ISkeletonAnimation { protected event UpdateBonesDelegate _UpdateComplete; Dictionary animationTable = new Dictionary(); + Dictionary clipNameTable = new Dictionary(); Animator animator; public override void Reset () { @@ -71,6 +72,7 @@ public class SkeletonAnimator : SkeletonRenderer, ISkeletonAnimation { return; animationTable.Clear(); + clipNameTable.Clear(); var data = skeletonDataAsset.GetSkeletonData(true); @@ -122,7 +124,7 @@ public class SkeletonAnimator : SkeletonRenderer, ISkeletonAnimation { continue; float time = stateInfo.normalizedTime * info.clip.length; - animationTable[info.clip.name].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, stateInfo.loop, null, weight); + animationTable[GetAnimationClipName(info.clip)].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, stateInfo.loop, null, weight); } foreach (var info in nextClipInfo) { @@ -131,7 +133,7 @@ public class SkeletonAnimator : SkeletonRenderer, ISkeletonAnimation { continue; float time = nextStateInfo.normalizedTime * info.clip.length; - animationTable[info.clip.name].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, nextStateInfo.loop, null, weight); + animationTable[GetAnimationClipName(info.clip)].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, nextStateInfo.loop, null, weight); } } else if (mode >= MixMode.MixNext) { //apply first non-zero weighted clip @@ -144,7 +146,7 @@ public class SkeletonAnimator : SkeletonRenderer, ISkeletonAnimation { continue; float time = stateInfo.normalizedTime * info.clip.length; - animationTable[info.clip.name].Apply(skeleton, Mathf.Max(0, time - deltaTime), time, stateInfo.loop, null); + animationTable[GetAnimationClipName(info.clip)].Apply(skeleton, Mathf.Max(0, time - deltaTime), time, stateInfo.loop, null); break; } @@ -156,7 +158,7 @@ public class SkeletonAnimator : SkeletonRenderer, ISkeletonAnimation { continue; float time = stateInfo.normalizedTime * info.clip.length; - animationTable[info.clip.name].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, stateInfo.loop, null, weight); + animationTable[GetAnimationClipName(info.clip)].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, stateInfo.loop, null, weight); } c = 0; @@ -170,7 +172,7 @@ public class SkeletonAnimator : SkeletonRenderer, ISkeletonAnimation { continue; float time = nextStateInfo.normalizedTime * info.clip.length; - animationTable[info.clip.name].Apply(skeleton, Mathf.Max(0, time - deltaTime), time, nextStateInfo.loop, null); + animationTable[GetAnimationClipName(info.clip)].Apply(skeleton, Mathf.Max(0, time - deltaTime), time, nextStateInfo.loop, null); break; } } @@ -183,7 +185,7 @@ public class SkeletonAnimator : SkeletonRenderer, ISkeletonAnimation { continue; float time = nextStateInfo.normalizedTime * info.clip.length; - animationTable[info.clip.name].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, nextStateInfo.loop, null, weight); + animationTable[GetAnimationClipName(info.clip)].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, nextStateInfo.loop, null, weight); } } } @@ -202,4 +204,14 @@ public class SkeletonAnimator : SkeletonRenderer, ISkeletonAnimation { _UpdateComplete(this); } } + + private string GetAnimationClipName(AnimationClip clip) { + string clipName; + if (!clipNameTable.TryGetValue(clip, out clipName)) { + clipName = clip.name; + clipNameTable.Add(clip, clipName); + } + + return clipName; + } } diff --git a/spine-unity/Assets/spine-unity/SkeletonRenderer.cs b/spine-unity/Assets/spine-unity/SkeletonRenderer.cs index 524e9ef12..900918be0 100644 --- a/spine-unity/Assets/spine-unity/SkeletonRenderer.cs +++ b/spine-unity/Assets/spine-unity/SkeletonRenderer.cs @@ -173,8 +173,9 @@ public class SkeletonRenderer : MonoBehaviour { int submeshTriangleCount = 0, submeshFirstVertex = 0, submeshStartSlotIndex = 0; Material lastMaterial = null; submeshMaterials.Clear(); - ExposedList drawOrder = skeleton.DrawOrder; + ExposedList drawOrder = skeleton.drawOrder; int drawOrderCount = drawOrder.Count; + int submeshSeparatorSlotsCount = submeshSeparatorSlots.Count; bool renderMeshes = this.renderMeshes; for (int i = 0; i < drawOrderCount; i++) { Slot slot = drawOrder.Items[i]; @@ -183,33 +184,34 @@ public class SkeletonRenderer : MonoBehaviour { object rendererObject; int attachmentVertexCount, attachmentTriangleCount; - if (attachment is RegionAttachment) { - rendererObject = ((RegionAttachment)attachment).RendererObject; + RegionAttachment regionAttachment = attachment as RegionAttachment; + if (regionAttachment != null) { + rendererObject = regionAttachment.RendererObject; attachmentVertexCount = 4; attachmentTriangleCount = 6; } else { if (!renderMeshes) continue; - MeshAttachment meshAttachment = attachment as MeshAttachment; - if (meshAttachment != null) { + MeshAttachment meshAttachment = attachment as MeshAttachment; + if (meshAttachment != null) { rendererObject = meshAttachment.RendererObject; attachmentVertexCount = meshAttachment.vertices.Length >> 1; attachmentTriangleCount = meshAttachment.triangles.Length; } else { - SkinnedMeshAttachment skinnedMeshAttachment = attachment as SkinnedMeshAttachment; - if (skinnedMeshAttachment != null) { - rendererObject = skinnedMeshAttachment.RendererObject; - attachmentVertexCount = skinnedMeshAttachment.uvs.Length >> 1; - attachmentTriangleCount = skinnedMeshAttachment.triangles.Length; - } else - continue; - } + SkinnedMeshAttachment skinnedMeshAttachment = attachment as SkinnedMeshAttachment; + if (skinnedMeshAttachment != null) { + rendererObject = skinnedMeshAttachment.RendererObject; + attachmentVertexCount = skinnedMeshAttachment.uvs.Length >> 1; + attachmentTriangleCount = skinnedMeshAttachment.triangles.Length; + } else + continue; + } } // Populate submesh when material changes. Material material = (Material)((AtlasRegion)rendererObject).page.rendererObject; - - if ((lastMaterial != material && lastMaterial != null) || submeshSeparatorSlots.Contains(slot)) { + if ((lastMaterial != null && lastMaterial.GetInstanceID() != material.GetInstanceID()) || + (submeshSeparatorSlotsCount > 0 && submeshSeparatorSlots.Contains(slot))) { AddSubmesh(lastMaterial, submeshStartSlotIndex, i, submeshTriangleCount, submeshFirstVertex, false); submeshTriangleCount = 0; submeshFirstVertex = vertexCount; @@ -258,15 +260,23 @@ public class SkeletonRenderer : MonoBehaviour { for (int i = 0; i < drawOrderCount; i++) { Slot slot = drawOrder.Items[i]; Attachment attachment = slot.attachment; - if (attachment is RegionAttachment) { - RegionAttachment regionAttachment = (RegionAttachment)attachment; + RegionAttachment regionAttachment = attachment as RegionAttachment; + if (regionAttachment != null) { regionAttachment.ComputeWorldVertices(slot.bone, tempVertices); float z = i * zSpacing; - vertices[vertexIndex] = new Vector3(tempVertices[RegionAttachment.X1], tempVertices[RegionAttachment.Y1], z); - vertices[vertexIndex + 1] = new Vector3(tempVertices[RegionAttachment.X4], tempVertices[RegionAttachment.Y4], z); - vertices[vertexIndex + 2] = new Vector3(tempVertices[RegionAttachment.X2], tempVertices[RegionAttachment.Y2], z); - vertices[vertexIndex + 3] = new Vector3(tempVertices[RegionAttachment.X3], tempVertices[RegionAttachment.Y3], z); + vertices[vertexIndex].x = tempVertices[RegionAttachment.X1]; + vertices[vertexIndex].y = tempVertices[RegionAttachment.Y1]; + vertices[vertexIndex].z = z; + vertices[vertexIndex + 1].x = tempVertices[RegionAttachment.X4]; + vertices[vertexIndex + 1].y = tempVertices[RegionAttachment.Y4]; + vertices[vertexIndex + 1].z = z; + vertices[vertexIndex + 2].x = tempVertices[RegionAttachment.X2]; + vertices[vertexIndex + 2].y = tempVertices[RegionAttachment.Y2]; + vertices[vertexIndex + 2].z = z; + vertices[vertexIndex + 3].x = tempVertices[RegionAttachment.X3]; + vertices[vertexIndex + 3].y = tempVertices[RegionAttachment.Y3]; + vertices[vertexIndex + 3].z = z; color.a = (byte)(a * slot.a * regionAttachment.a); color.r = (byte)(r * slot.r * regionAttachment.r * color.a); @@ -280,10 +290,14 @@ public class SkeletonRenderer : MonoBehaviour { colors[vertexIndex + 3] = color; float[] regionUVs = regionAttachment.uvs; - uvs[vertexIndex] = new Vector2(regionUVs[RegionAttachment.X1], regionUVs[RegionAttachment.Y1]); - uvs[vertexIndex + 1] = new Vector2(regionUVs[RegionAttachment.X4], regionUVs[RegionAttachment.Y4]); - uvs[vertexIndex + 2] = new Vector2(regionUVs[RegionAttachment.X2], regionUVs[RegionAttachment.Y2]); - uvs[vertexIndex + 3] = new Vector2(regionUVs[RegionAttachment.X3], regionUVs[RegionAttachment.Y3]); + uvs[vertexIndex].x = regionUVs[RegionAttachment.X1]; + uvs[vertexIndex].y = regionUVs[RegionAttachment.Y1]; + uvs[vertexIndex + 1].x = regionUVs[RegionAttachment.X4]; + uvs[vertexIndex + 1].y = regionUVs[RegionAttachment.Y4]; + uvs[vertexIndex + 2].x = regionUVs[RegionAttachment.X2]; + uvs[vertexIndex + 2].y = regionUVs[RegionAttachment.Y2]; + uvs[vertexIndex + 3].x = regionUVs[RegionAttachment.X3]; + uvs[vertexIndex + 3].y = regionUVs[RegionAttachment.Y3]; vertexIndex += 4; } else { @@ -306,9 +320,12 @@ public class SkeletonRenderer : MonoBehaviour { float[] meshUVs = meshAttachment.uvs; float z = i * zSpacing; for (int ii = 0; ii < meshVertexCount; ii += 2, vertexIndex++) { - vertices[vertexIndex] = new Vector3(tempVertices[ii], tempVertices[ii + 1], z); + vertices[vertexIndex].x = tempVertices[ii]; + vertices[vertexIndex].y = tempVertices[ii + 1]; + vertices[vertexIndex].z = z; colors[vertexIndex] = color; - uvs[vertexIndex] = new Vector2(meshUVs[ii], meshUVs[ii + 1]); + uvs[vertexIndex].x = meshUVs[ii]; + uvs[vertexIndex].y = meshUVs[ii + 1]; } } else if (attachment is SkinnedMeshAttachment) { SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment; @@ -327,9 +344,12 @@ public class SkeletonRenderer : MonoBehaviour { float[] meshUVs = meshAttachment.uvs; float z = i * zSpacing; for (int ii = 0; ii < meshVertexCount; ii += 2, vertexIndex++) { - vertices[vertexIndex] = new Vector3(tempVertices[ii], tempVertices[ii + 1], z); + vertices[vertexIndex].x = tempVertices[ii]; + vertices[vertexIndex].y = tempVertices[ii + 1]; + vertices[vertexIndex].z = z; colors[vertexIndex] = color; - uvs[vertexIndex] = new Vector2(meshUVs[ii], meshUVs[ii + 1]); + uvs[vertexIndex].x = meshUVs[ii]; + uvs[vertexIndex].y = meshUVs[ii + 1]; } } } @@ -420,7 +440,12 @@ public class SkeletonRenderer : MonoBehaviour { Slot slot = drawOrder.Items[i]; Attachment attachment = slot.attachment; Bone bone = slot.bone; - bool flip = frontFacing && ((bone.WorldFlipX != bone.WorldFlipY) != (Mathf.Sign(bone.WorldScaleX) != Mathf.Sign(bone.WorldScaleY))); + + bool worldScaleXIsPositive = bone.worldScaleX >= 0f; + bool worldScaleYIsPositive = bone.worldScaleY >= 0f; + bool worldScaleIsSameSigns = (worldScaleXIsPositive && worldScaleYIsPositive) || + (!worldScaleXIsPositive && !worldScaleYIsPositive); + bool flip = frontFacing && ((bone.worldFlipX != bone.worldFlipY) != worldScaleIsSameSigns); if (attachment is RegionAttachment) { if (!flip) { @@ -445,16 +470,18 @@ public class SkeletonRenderer : MonoBehaviour { } int[] attachmentTriangles; int attachmentVertexCount; - if (attachment is MeshAttachment) { - MeshAttachment meshAttachment = (MeshAttachment)attachment; + MeshAttachment meshAttachment = attachment as MeshAttachment; + if (meshAttachment != null) { attachmentVertexCount = meshAttachment.vertices.Length >> 1; attachmentTriangles = meshAttachment.triangles; - } else if (attachment is SkinnedMeshAttachment) { - SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment; - attachmentVertexCount = meshAttachment.uvs.Length >> 1; - attachmentTriangles = meshAttachment.triangles; - } else - continue; + } else { + SkinnedMeshAttachment skinnedMeshAttachment = attachment as SkinnedMeshAttachment; + if (skinnedMeshAttachment != null) { + attachmentVertexCount = skinnedMeshAttachment.uvs.Length >> 1; + attachmentTriangles = skinnedMeshAttachment.triangles; + } else + continue; + } if (flip) { for (int ii = 0, nn = attachmentTriangles.Length; ii < nn; ii += 3, triangleIndex += 3) {