From 14803b4fab189e4cb258a19c0456566a8225c9dd Mon Sep 17 00:00:00 2001 From: Tomasz Jaworski Date: Thu, 18 Jun 2015 18:01:59 +0200 Subject: [PATCH 1/7] Windows Phone 8 complation fixed (BufferedStream changed to FileStream) RaggedySpineboy - changed fixedAngle to freezeRotation for Unity 5.1 Changed SkeletonRagdoll2D #if UNITY_5_0 to UNITY_5 --- spine-csharp/src/SkeletonBinary.cs | 8 +++++++- spine-unity/Assets/Examples/Scripts/RaggedySpineboy.cs | 4 ++++ .../Assets/spine-unity/Ragdoll/SkeletonRagdoll2D.cs | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/spine-csharp/src/SkeletonBinary.cs b/spine-csharp/src/SkeletonBinary.cs index ab12c506f..310d7e766 100644 --- a/spine-csharp/src/SkeletonBinary.cs +++ b/spine-csharp/src/SkeletonBinary.cs @@ -86,7 +86,13 @@ namespace Spine { using (var input = new BufferedStream(Microsoft.Xna.Framework.TitleContainer.OpenStream(path))) { #else - using (var input = new BufferedStream(new FileStream(path, FileMode.Open))) { +#if UNITY_WP8 || UNITY_WP8_1 + using (var input = new FileStream(path, FileMode.Open)) + { +#else + using (var input = new BufferedStream(new FileStream(path, FileMode.Open))) + { +#endif #endif SkeletonData skeletonData = ReadSkeletonData(input); skeletonData.name = Path.GetFileNameWithoutExtension(path); diff --git a/spine-unity/Assets/Examples/Scripts/RaggedySpineboy.cs b/spine-unity/Assets/Examples/Scripts/RaggedySpineboy.cs index f15e773fc..8599c9598 100644 --- a/spine-unity/Assets/Examples/Scripts/RaggedySpineboy.cs +++ b/spine-unity/Assets/Examples/Scripts/RaggedySpineboy.cs @@ -18,7 +18,11 @@ public class RaggedySpineboy : MonoBehaviour { void AddRigidbody () { var rb = gameObject.AddComponent(); +#if UNITY_5_1 + rb.freezeRotation = true; +#else rb.fixedAngle = true; +#endif naturalCollider.enabled = true; } diff --git a/spine-unity/Assets/spine-unity/Ragdoll/SkeletonRagdoll2D.cs b/spine-unity/Assets/spine-unity/Ragdoll/SkeletonRagdoll2D.cs index 690e10dd2..962acf543 100644 --- a/spine-unity/Assets/spine-unity/Ragdoll/SkeletonRagdoll2D.cs +++ b/spine-unity/Assets/spine-unity/Ragdoll/SkeletonRagdoll2D.cs @@ -280,7 +280,7 @@ public class SkeletonRagdoll2D : MonoBehaviour { if (colliders.Count == 0) { var box = go.AddComponent(); box.size = new Vector2(length, thickness); -#if UNITY_5_0 +#if UNITY_5 box.offset = new Vector2((b.WorldFlipX ? -length : length) / 2, 0); #else box.center = new Vector2((b.WorldFlipX ? -length : length) / 2, 0); From 7d60e4e255847565bc9e70277757cfa779cf0e96 Mon Sep 17 00:00:00 2001 From: Serhii Yolkin Date: Sun, 11 Oct 2015 20:26:42 +0200 Subject: [PATCH 2/7] improved handling of Reimport All and some other weird asset import cases --- .../AssetDatabaseAvailabilityDetector.cs | 21 +++++++ .../AssetDatabaseAvailabilityDetector.cs.meta | 12 ++++ .../Assets/spine-unity/Editor/Resources.meta | 9 +++ .../Resources/SpriteSharpPersistentMarker.txt | 1 + .../SpriteSharpPersistentMarker.txt.meta | 8 +++ .../Editor/SpineEditorUtilities.cs | 58 +++++++++++++++++-- 6 files changed, 104 insertions(+), 5 deletions(-) create mode 100644 spine-unity/Assets/spine-unity/Editor/AssetDatabaseAvailabilityDetector.cs create mode 100644 spine-unity/Assets/spine-unity/Editor/AssetDatabaseAvailabilityDetector.cs.meta create mode 100644 spine-unity/Assets/spine-unity/Editor/Resources.meta create mode 100644 spine-unity/Assets/spine-unity/Editor/Resources/SpriteSharpPersistentMarker.txt create mode 100644 spine-unity/Assets/spine-unity/Editor/Resources/SpriteSharpPersistentMarker.txt.meta diff --git a/spine-unity/Assets/spine-unity/Editor/AssetDatabaseAvailabilityDetector.cs b/spine-unity/Assets/spine-unity/Editor/AssetDatabaseAvailabilityDetector.cs new file mode 100644 index 000000000..5b8c7a4ab --- /dev/null +++ b/spine-unity/Assets/spine-unity/Editor/AssetDatabaseAvailabilityDetector.cs @@ -0,0 +1,21 @@ +using UnityEngine; + +namespace Spine { + public static class AssetDatabaseAvailabilityDetector { + const string MARKER_RESOURCE_NAME = "SpineAssetDatabaseMarker"; + private static bool _isMarkerLoaded; + + public static bool IsAssetDatabaseAvailable (bool forceCheck = false) { + if (!forceCheck && _isMarkerLoaded) + return true; + + TextAsset markerTextAsset = Resources.Load(MARKER_RESOURCE_NAME); + _isMarkerLoaded = markerTextAsset != null; + if (markerTextAsset != null) { + Resources.UnloadAsset(markerTextAsset); + } + + return _isMarkerLoaded; + } + } +} diff --git a/spine-unity/Assets/spine-unity/Editor/AssetDatabaseAvailabilityDetector.cs.meta b/spine-unity/Assets/spine-unity/Editor/AssetDatabaseAvailabilityDetector.cs.meta new file mode 100644 index 000000000..00b99c134 --- /dev/null +++ b/spine-unity/Assets/spine-unity/Editor/AssetDatabaseAvailabilityDetector.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 25086cd81e3158b439761b73d7366c47 +timeCreated: 1444587791 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/spine-unity/Assets/spine-unity/Editor/Resources.meta b/spine-unity/Assets/spine-unity/Editor/Resources.meta new file mode 100644 index 000000000..8d1a705d5 --- /dev/null +++ b/spine-unity/Assets/spine-unity/Editor/Resources.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 24903fdac57ee784b9597fcb751ec22f +folderAsset: yes +timeCreated: 1444565388 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/spine-unity/Assets/spine-unity/Editor/Resources/SpriteSharpPersistentMarker.txt b/spine-unity/Assets/spine-unity/Editor/Resources/SpriteSharpPersistentMarker.txt new file mode 100644 index 000000000..1a3c1a3ea --- /dev/null +++ b/spine-unity/Assets/spine-unity/Editor/Resources/SpriteSharpPersistentMarker.txt @@ -0,0 +1 @@ +DO NOT MOVE OR DELETE THIS FILE \ No newline at end of file diff --git a/spine-unity/Assets/spine-unity/Editor/Resources/SpriteSharpPersistentMarker.txt.meta b/spine-unity/Assets/spine-unity/Editor/Resources/SpriteSharpPersistentMarker.txt.meta new file mode 100644 index 000000000..7569884b2 --- /dev/null +++ b/spine-unity/Assets/spine-unity/Editor/Resources/SpriteSharpPersistentMarker.txt.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 57281c00bdd90ad4392f811f2b9f0da1 +timeCreated: 1444565392 +licenseType: Pro +TextScriptImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs b/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs index 36dc47ae3..b2ea647ae 100644 --- a/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs +++ b/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs @@ -149,6 +149,7 @@ public class SpineEditorUtilities : AssetPostprocessor { public static string editorPath = ""; public static string editorGUIPath = ""; + static HashSet assetsImportedInWrongState; static Dictionary skeletonRendererTable; static Dictionary skeletonUtilityBoneTable; static Dictionary boundingBoxFollowerTable; @@ -173,6 +174,7 @@ public class SpineEditorUtilities : AssetPostprocessor { Icons.Initialize(); + assetsImportedInWrongState = new HashSet(); skeletonRendererTable = new Dictionary(); skeletonUtilityBoneTable = new Dictionary(); boundingBoxFollowerTable = new Dictionary(); @@ -254,8 +256,34 @@ public class SpineEditorUtilities : AssetPostprocessor { } static void OnPostprocessAllAssets (string[] imported, string[] deleted, string[] moved, string[] movedFromAssetPaths) { - ImportSpineContent(imported, false); + if (imported.Length == 0) + return; + + // In case user used "Assets -> Reimport All", during the import process, + // asset database is not initialized until some point. During that period, + // all attempts to load any assets using API (i.e. AssetDatabase.LoadAssetAtPath) + // will return null, and as result, assets won't be loaded even if they actually exists, + // which may lead to numerous importing errors. + // This situation also happens if Library folder is deleted from the project, which is a pretty + // common case, since when using version control systems, the Library folder must be excluded. + // + // So to avoid this, in case asset database is not available, we delay loading the assets + // until next time. + // + // Unity *always* reimports some internal assets after the process is done, so this method + // is always called once again in a state when asset database is available. + // + // Checking whether AssetDatabase is initialized is done by attempting to load + // a known "marker" asset that should always be available. Failing to load this asset + // means that AssetDatabase is not initialized. + assetsImportedInWrongState.UnionWith(imported); + if (AssetDatabaseAvailabilityDetector.IsAssetDatabaseAvailable()) { + string[] combinedAssets = assetsImportedInWrongState.ToArray(); + assetsImportedInWrongState.Clear(); + ImportSpineContent(combinedAssets); + } } + public static void ImportSpineContent (string[] imported, bool reimport = false) { List atlasPaths = new List(); List imagePaths = new List(); @@ -408,14 +436,34 @@ public class SpineEditorUtilities : AssetPostprocessor { skeletonDataAsset.Reset(); string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(skeletonDataAsset)); - string lastHash = EditorPrefs.GetString(guid + "_hash"); - - if (lastHash != skeletonDataAsset.GetSkeletonData(true).Hash) { + string lastHash = EditorPrefs.GetString(guid + "_hash"); + + // For some weird reason sometimes Unity loses the internal Object pointer, + // and as a result, all comparisons with null returns true. + // But the C# wrapper is still alive, so we can "restore" the object + // by reloading it from its Instance ID. + AtlasAsset[] skeletonDataAtlasAssets = skeletonDataAsset.atlasAssets; + if (skeletonDataAtlasAssets != null) { + for (int i = 0; i < skeletonDataAtlasAssets.Length; i++) { + if (!ReferenceEquals(null, skeletonDataAtlasAssets[i]) && + skeletonDataAtlasAssets[i].Equals(null) && + skeletonDataAtlasAssets[i].GetInstanceID() != 0 + ) { + skeletonDataAtlasAssets[i] = EditorUtility.InstanceIDToObject(skeletonDataAtlasAssets[i].GetInstanceID()) as AtlasAsset; + } + } + } + + SkeletonData skeletonData = skeletonDataAsset.GetSkeletonData(true); + string currentHash = skeletonData != null ? skeletonData.Hash : null; + if (currentHash == null || lastHash != currentHash) { //do any upkeep on synchronized assets UpdateMecanimClips(skeletonDataAsset); } - EditorPrefs.SetString(guid + "_hash", skeletonDataAsset.GetSkeletonData(true).Hash); + if (currentHash != null) { + EditorPrefs.SetString(guid + "_hash", currentHash); + } } } } From 3cbf42d743a5be5c2d6aac5a6ef363aa4176f2dc Mon Sep 17 00:00:00 2001 From: Serhii Yolkin Date: Tue, 13 Oct 2015 00:00:38 +0200 Subject: [PATCH 3/7] derp --- ...riteSharpPersistentMarker.txt => SpineAssetDatabaseMarker.txt} | 0 ...ersistentMarker.txt.meta => SpineAssetDatabaseMarker.txt.meta} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename spine-unity/Assets/spine-unity/Editor/Resources/{SpriteSharpPersistentMarker.txt => SpineAssetDatabaseMarker.txt} (100%) rename spine-unity/Assets/spine-unity/Editor/Resources/{SpriteSharpPersistentMarker.txt.meta => SpineAssetDatabaseMarker.txt.meta} (100%) diff --git a/spine-unity/Assets/spine-unity/Editor/Resources/SpriteSharpPersistentMarker.txt b/spine-unity/Assets/spine-unity/Editor/Resources/SpineAssetDatabaseMarker.txt similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/Resources/SpriteSharpPersistentMarker.txt rename to spine-unity/Assets/spine-unity/Editor/Resources/SpineAssetDatabaseMarker.txt diff --git a/spine-unity/Assets/spine-unity/Editor/Resources/SpriteSharpPersistentMarker.txt.meta b/spine-unity/Assets/spine-unity/Editor/Resources/SpineAssetDatabaseMarker.txt.meta similarity index 100% rename from spine-unity/Assets/spine-unity/Editor/Resources/SpriteSharpPersistentMarker.txt.meta rename to spine-unity/Assets/spine-unity/Editor/Resources/SpineAssetDatabaseMarker.txt.meta From 990eb6a8f0b540a3a48f5cbf4d2d44c467dc3df0 Mon Sep 17 00:00:00 2001 From: Serhii Yolkin Date: Sat, 21 Nov 2015 17:33:00 +0100 Subject: [PATCH 4/7] fix occasional broken frame at the moment node transition happened --- .../Assets/spine-unity/SkeletonAnimator.cs | 50 +++++++++++-------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/spine-unity/Assets/spine-unity/SkeletonAnimator.cs b/spine-unity/Assets/spine-unity/SkeletonAnimator.cs index cd8d7726a..0fb1b9482 100644 --- a/spine-unity/Assets/spine-unity/SkeletonAnimator.cs +++ b/spine-unity/Assets/spine-unity/SkeletonAnimator.cs @@ -102,7 +102,8 @@ public class SkeletonAnimator : SkeletonRenderer, ISkeletonAnimation { if (mode == MixMode.AlwaysMix) { //always use Mix instead of Applying the first non-zero weighted clip - foreach (var info in clipInfo) { + for (int c = 0; c < clipInfo.Length; c++) { + var info = clipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue; @@ -111,13 +112,16 @@ public class SkeletonAnimator : SkeletonRenderer, ISkeletonAnimation { animationTable[GetAnimationClipNameHashCode(info.clip)].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, stateInfo.loop, null, weight); } - foreach (var info in nextClipInfo) { - float weight = info.weight * layerWeight; - if (weight == 0) - continue; + if (nextStateInfo.fullPathHash != 0) { + for (int c = 0; c < nextClipInfo.Length; c++) { + var info = nextClipInfo[c]; + float weight = info.weight * layerWeight; + if (weight == 0) + continue; - float time = nextStateInfo.normalizedTime * info.clip.length; - animationTable[GetAnimationClipNameHashCode(info.clip)].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, nextStateInfo.loop, null, weight); + float time = nextStateInfo.normalizedTime * info.clip.length; + animationTable[GetAnimationClipNameHashCode(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 @@ -147,8 +151,22 @@ public class SkeletonAnimator : SkeletonRenderer, ISkeletonAnimation { c = 0; - //apply next clip directly instead of mixing (ie: no crossfade, ignores mecanim transition weights) - if (mode == MixMode.SpineStyle) { + if (nextStateInfo.fullPathHash != 0) { + //apply next clip directly instead of mixing (ie: no crossfade, ignores mecanim transition weights) + if (mode == MixMode.SpineStyle) { + for (; c < nextClipInfo.Length; c++) { + var info = nextClipInfo[c]; + float weight = info.weight * layerWeight; + if (weight == 0) + continue; + + float time = nextStateInfo.normalizedTime * info.clip.length; + animationTable[GetAnimationClipNameHashCode(info.clip)].Apply(skeleton, Mathf.Max(0, time - deltaTime), time, nextStateInfo.loop, null); + break; + } + } + + //mix the rest for (; c < nextClipInfo.Length; c++) { var info = nextClipInfo[c]; float weight = info.weight * layerWeight; @@ -156,21 +174,9 @@ public class SkeletonAnimator : SkeletonRenderer, ISkeletonAnimation { continue; float time = nextStateInfo.normalizedTime * info.clip.length; - animationTable[GetAnimationClipNameHashCode(info.clip)].Apply(skeleton, Mathf.Max(0, time - deltaTime), time, nextStateInfo.loop, null); - break; + animationTable[GetAnimationClipNameHashCode(info.clip)].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, nextStateInfo.loop, null, weight); } } - - //mix the rest - for (; c < nextClipInfo.Length; c++) { - var info = nextClipInfo[c]; - float weight = info.weight * layerWeight; - if (weight == 0) - continue; - - float time = nextStateInfo.normalizedTime * info.clip.length; - animationTable[GetAnimationClipNameHashCode(info.clip)].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, nextStateInfo.loop, null, weight); - } } } From 8ebf27de24b6886908c86d2afe9f1953eec05a09 Mon Sep 17 00:00:00 2001 From: Serhii Yolkin Date: Sat, 21 Nov 2015 17:56:14 +0100 Subject: [PATCH 5/7] some refactoring --- .../Assets/spine-unity/SkeletonRenderer.cs | 134 ++++++++---------- 1 file changed, 59 insertions(+), 75 deletions(-) diff --git a/spine-unity/Assets/spine-unity/SkeletonRenderer.cs b/spine-unity/Assets/spine-unity/SkeletonRenderer.cs index 3a36eded3..7f1024216 100644 --- a/spine-unity/Assets/spine-unity/SkeletonRenderer.cs +++ b/spine-unity/Assets/spine-unity/SkeletonRenderer.cs @@ -71,7 +71,7 @@ public class SkeletonRenderer : MonoBehaviour { private readonly ExposedList submeshMaterials = new ExposedList(); private readonly ExposedList submeshes = new ExposedList(); private SkeletonUtilitySubmeshRenderer[] submeshRenderers; - private LastState lastState = new LastState(); + private MeshState meshState = new MeshState(); public virtual void Reset () { if (meshFilter != null) @@ -94,7 +94,7 @@ public class SkeletonRenderer : MonoBehaviour { DestroyImmediate(mesh2); } - lastState = new LastState(); + meshState = new MeshState(); mesh1 = null; mesh2 = null; vertices = null; @@ -193,15 +193,10 @@ public class SkeletonRenderer : MonoBehaviour { bool renderMeshes = this.renderMeshes; // Clear last state of attachments and submeshes - ExposedList attachmentsTriangleCountTemp = lastState.attachmentsTriangleCountTemp; - attachmentsTriangleCountTemp.GrowIfNeeded(drawOrderCount); - attachmentsTriangleCountTemp.Count = drawOrderCount; - ExposedList attachmentsFlipStateTemp = lastState.attachmentsFlipStateTemp; - attachmentsFlipStateTemp.GrowIfNeeded(drawOrderCount); - attachmentsFlipStateTemp.Count = drawOrderCount; + MeshState.SingleMeshState stateTemp = meshState.stateTemp; + stateTemp.UpdateDrawOrderCount(drawOrderCount); - ExposedList addSubmeshArgumentsTemp = lastState.addSubmeshArgumentsTemp; - addSubmeshArgumentsTemp.Clear(false); + stateTemp.addSubmeshArguments.Clear(false); for (int i = 0; i < drawOrderCount; i++) { Slot slot = drawOrder.Items[i]; Bone bone = slot.bone; @@ -214,9 +209,9 @@ public class SkeletonRenderer : MonoBehaviour { bool worldScaleIsSameSigns = (worldScaleXIsPositive && worldScaleYIsPositive) || (!worldScaleXIsPositive && !worldScaleYIsPositive); bool flip = frontFacing && ((bone.worldFlipX != bone.worldFlipY) == worldScaleIsSameSigns); - attachmentsFlipStateTemp.Items[i] = flip; + stateTemp.attachmentsFlipState.Items[i] = flip; - attachmentsTriangleCountTemp.Items[i] = -1; + stateTemp.attachmentsTriangleCount.Items[i] = -1; RegionAttachment regionAttachment = attachment as RegionAttachment; if (regionAttachment != null) { rendererObject = regionAttachment.RendererObject; @@ -249,8 +244,8 @@ public class SkeletonRenderer : MonoBehaviour { #endif if ((lastMaterial != null && lastMaterial.GetInstanceID() != material.GetInstanceID()) || (submeshSeparatorSlotsCount > 0 && submeshSeparatorSlots.Contains(slot))) { - addSubmeshArgumentsTemp.Add( - new LastState.AddSubmeshArguments(lastMaterial, submeshStartSlotIndex, i, submeshTriangleCount, submeshFirstVertex, false) + stateTemp.addSubmeshArguments.Add( + new MeshState.AddSubmeshArguments(lastMaterial, submeshStartSlotIndex, i, submeshTriangleCount, submeshFirstVertex, false) ); submeshTriangleCount = 0; submeshFirstVertex = vertexCount; @@ -261,17 +256,17 @@ public class SkeletonRenderer : MonoBehaviour { submeshTriangleCount += attachmentTriangleCount; vertexCount += attachmentVertexCount; - attachmentsTriangleCountTemp.Items[i] = attachmentTriangleCount; + stateTemp.attachmentsTriangleCount.Items[i] = attachmentTriangleCount; } - addSubmeshArgumentsTemp.Add( - new LastState.AddSubmeshArguments(lastMaterial, submeshStartSlotIndex, drawOrderCount, submeshTriangleCount, submeshFirstVertex, true) + stateTemp.addSubmeshArguments.Add( + new MeshState.AddSubmeshArguments(lastMaterial, submeshStartSlotIndex, drawOrderCount, submeshTriangleCount, submeshFirstVertex, true) ); - bool mustUpdateMeshStructure = CheckIfMustUpdateMeshStructure(attachmentsTriangleCountTemp, attachmentsFlipStateTemp, addSubmeshArgumentsTemp); + bool mustUpdateMeshStructure = CheckIfMustUpdateMeshStructure(stateTemp.attachmentsTriangleCount, stateTemp.attachmentsFlipState, stateTemp.addSubmeshArguments); if (mustUpdateMeshStructure) { submeshMaterials.Clear(); - for (int i = 0, n = addSubmeshArgumentsTemp.Count; i < n; i++) { - LastState.AddSubmeshArguments arguments = addSubmeshArgumentsTemp.Items[i]; + for (int i = 0, n = stateTemp.addSubmeshArguments.Count; i < n; i++) { + MeshState.AddSubmeshArguments arguments = stateTemp.addSubmeshArguments.Items[i]; AddSubmesh( arguments.material, arguments.startSlot, @@ -279,7 +274,7 @@ public class SkeletonRenderer : MonoBehaviour { arguments.triangleCount, arguments.firstVertex, arguments.lastSubmesh, - attachmentsFlipStateTemp + stateTemp.attachmentsFlipState ); } @@ -305,10 +300,10 @@ public class SkeletonRenderer : MonoBehaviour { } else { // Too many vertices, zero the extra. Vector3 zero = Vector3.zero; - for (int i = vertexCount, n = lastState.vertexCount; i < n; i++) + for (int i = vertexCount, n = meshState.vertexCount; i < n; i++) vertices[i] = zero; } - lastState.vertexCount = vertexCount; + meshState.vertexCount = vertexCount; // Setup mesh. float zSpacing = this.zSpacing; @@ -534,32 +529,20 @@ public class SkeletonRenderer : MonoBehaviour { } // Update previous state - ExposedList attachmentsTriangleCountCurrentMesh; - ExposedList attachmentsFlipStateCurrentMesh; - ExposedList addSubmeshArgumentsCurrentMesh; - if (useMesh1) { - attachmentsTriangleCountCurrentMesh = lastState.attachmentsTriangleCountMesh1; - addSubmeshArgumentsCurrentMesh = lastState.addSubmeshArgumentsMesh1; - attachmentsFlipStateCurrentMesh = lastState.attachmentsFlipStateMesh1; - lastState.immutableTrianglesMesh1 = immutableTriangles; - } else { - attachmentsTriangleCountCurrentMesh = lastState.attachmentsTriangleCountMesh2; - addSubmeshArgumentsCurrentMesh = lastState.addSubmeshArgumentsMesh2; - attachmentsFlipStateCurrentMesh = lastState.attachmentsFlipStateMesh2; - lastState.immutableTrianglesMesh2 = immutableTriangles; - } + MeshState.SingleMeshState currentMeshState = useMesh1 ? meshState.stateMesh1 : meshState.stateMesh2; + currentMeshState.immutableTriangles = immutableTriangles; - attachmentsTriangleCountCurrentMesh.GrowIfNeeded(attachmentsTriangleCountTemp.Capacity); - attachmentsTriangleCountCurrentMesh.Count = attachmentsTriangleCountTemp.Count; - attachmentsTriangleCountTemp.CopyTo(attachmentsTriangleCountCurrentMesh.Items, 0); + currentMeshState.attachmentsTriangleCount.GrowIfNeeded(stateTemp.attachmentsTriangleCount.Capacity); + currentMeshState.attachmentsTriangleCount.Count = stateTemp.attachmentsTriangleCount.Count; + stateTemp.attachmentsTriangleCount.CopyTo(currentMeshState.attachmentsTriangleCount.Items); - attachmentsFlipStateCurrentMesh.GrowIfNeeded(attachmentsFlipStateTemp.Capacity); - attachmentsFlipStateCurrentMesh.Count = attachmentsFlipStateTemp.Count; - attachmentsFlipStateTemp.CopyTo(attachmentsFlipStateCurrentMesh.Items, 0); + currentMeshState.attachmentsFlipState.GrowIfNeeded(stateTemp.attachmentsFlipState.Capacity); + currentMeshState.attachmentsFlipState.Count = stateTemp.attachmentsFlipState.Count; + stateTemp.attachmentsFlipState.CopyTo(currentMeshState.attachmentsFlipState.Items); - addSubmeshArgumentsCurrentMesh.GrowIfNeeded(addSubmeshArgumentsTemp.Count); - addSubmeshArgumentsCurrentMesh.Count = addSubmeshArgumentsTemp.Count; - addSubmeshArgumentsTemp.CopyTo(addSubmeshArgumentsCurrentMesh.Items); + currentMeshState.addSubmeshArguments.GrowIfNeeded(stateTemp.addSubmeshArguments.Capacity); + currentMeshState.addSubmeshArguments.Count = stateTemp.addSubmeshArguments.Count; + stateTemp.addSubmeshArguments.CopyTo(currentMeshState.addSubmeshArguments.Items); if (submeshRenderers.Length > 0) { for (int i = 0; i < submeshRenderers.Length; i++) { @@ -575,31 +558,25 @@ public class SkeletonRenderer : MonoBehaviour { useMesh1 = !useMesh1; } - private bool CheckIfMustUpdateMeshStructure (ExposedList attachmentsTriangleCountTemp, ExposedList attachmentsFlipStateTemp, ExposedList addSubmeshArgumentsTemp) { + private bool CheckIfMustUpdateMeshStructure (ExposedList attachmentsTriangleCountTemp, ExposedList attachmentsFlipStateTemp, ExposedList addSubmeshArgumentsTemp) { +#if UNITY_EDITOR + if (!Application.isPlaying) + return true; +#endif + // Check if any mesh settings were changed bool mustUpdateMeshStructure = - immutableTriangles != (useMesh1 ? lastState.immutableTrianglesMesh1 : lastState.immutableTrianglesMesh2); -#if UNITY_EDITOR - mustUpdateMeshStructure |= !Application.isPlaying; -#endif + immutableTriangles != (useMesh1 ? meshState.stateMesh1.immutableTriangles : meshState.stateMesh2.immutableTriangles); if (mustUpdateMeshStructure) return true; // Check if any attachments were enabled/disabled // or submesh structures has changed - ExposedList attachmentsTriangleCountCurrentMesh; - ExposedList attachmentsFlipStateCurrentMesh; - ExposedList addSubmeshArgumentsCurrentMesh; - if (useMesh1) { - attachmentsTriangleCountCurrentMesh = lastState.attachmentsTriangleCountMesh1; - addSubmeshArgumentsCurrentMesh = lastState.addSubmeshArgumentsMesh1; - attachmentsFlipStateCurrentMesh = lastState.attachmentsFlipStateMesh1; - } else { - attachmentsTriangleCountCurrentMesh = lastState.attachmentsTriangleCountMesh2; - addSubmeshArgumentsCurrentMesh = lastState.addSubmeshArgumentsMesh2; - attachmentsFlipStateCurrentMesh = lastState.attachmentsFlipStateMesh2; - } + MeshState.SingleMeshState currentMeshState = useMesh1 ? meshState.stateMesh1 : meshState.stateMesh2; + ExposedList attachmentsTriangleCountCurrentMesh = currentMeshState.attachmentsTriangleCount; + ExposedList addSubmeshArgumentsCurrentMesh = currentMeshState.addSubmeshArguments; + ExposedList attachmentsFlipStateCurrentMesh = currentMeshState.attachmentsFlipState; // Check attachments int attachmentCount = attachmentsTriangleCountTemp.Count; @@ -749,19 +726,26 @@ public class SkeletonRenderer : MonoBehaviour { } #endif - private class LastState { - public bool immutableTrianglesMesh1; - public bool immutableTrianglesMesh2; + private class MeshState { public int vertexCount; - public readonly ExposedList attachmentsFlipStateTemp = new ExposedList(); - public readonly ExposedList attachmentsFlipStateMesh1 = new ExposedList(); - public readonly ExposedList attachmentsFlipStateMesh2 = new ExposedList(); - public readonly ExposedList attachmentsTriangleCountTemp = new ExposedList(); - public readonly ExposedList attachmentsTriangleCountMesh1 = new ExposedList(); - public readonly ExposedList attachmentsTriangleCountMesh2 = new ExposedList(); - public readonly ExposedList addSubmeshArgumentsTemp = new ExposedList(); - public readonly ExposedList addSubmeshArgumentsMesh1 = new ExposedList(); - public readonly ExposedList addSubmeshArgumentsMesh2 = new ExposedList(); + public readonly SingleMeshState stateTemp = new SingleMeshState(); + public readonly SingleMeshState stateMesh1 = new SingleMeshState(); + public readonly SingleMeshState stateMesh2 = new SingleMeshState(); + + public class SingleMeshState { + public bool immutableTriangles; + public readonly ExposedList attachmentsFlipState = new ExposedList(); + public readonly ExposedList attachmentsTriangleCount = new ExposedList(); + public readonly ExposedList addSubmeshArguments = new ExposedList(); + + public void UpdateDrawOrderCount(int drawOrderCount) { + attachmentsFlipState.GrowIfNeeded(drawOrderCount); + attachmentsFlipState.Count = drawOrderCount; + + attachmentsTriangleCount.GrowIfNeeded(drawOrderCount); + attachmentsTriangleCount.Count = drawOrderCount; + } + } public struct AddSubmeshArguments { public Material material; From 3218c78239bd2f48f896020b68841c32ad929235 Mon Sep 17 00:00:00 2001 From: Serhii Yolkin Date: Sat, 21 Nov 2015 18:08:17 +0100 Subject: [PATCH 6/7] compare references to attachments instead of comparing attachment properties --- .../Assets/spine-unity/SkeletonRenderer.cs | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/spine-unity/Assets/spine-unity/SkeletonRenderer.cs b/spine-unity/Assets/spine-unity/SkeletonRenderer.cs index 7f1024216..de919317e 100644 --- a/spine-unity/Assets/spine-unity/SkeletonRenderer.cs +++ b/spine-unity/Assets/spine-unity/SkeletonRenderer.cs @@ -194,6 +194,7 @@ public class SkeletonRenderer : MonoBehaviour { // Clear last state of attachments and submeshes MeshState.SingleMeshState stateTemp = meshState.stateTemp; + stateTemp.attachments.Clear(true); stateTemp.UpdateDrawOrderCount(drawOrderCount); stateTemp.addSubmeshArguments.Clear(false); @@ -211,7 +212,7 @@ public class SkeletonRenderer : MonoBehaviour { bool flip = frontFacing && ((bone.worldFlipX != bone.worldFlipY) == worldScaleIsSameSigns); stateTemp.attachmentsFlipState.Items[i] = flip; - stateTemp.attachmentsTriangleCount.Items[i] = -1; + stateTemp.attachments.Items[i] = attachment; RegionAttachment regionAttachment = attachment as RegionAttachment; if (regionAttachment != null) { rendererObject = regionAttachment.RendererObject; @@ -255,14 +256,12 @@ public class SkeletonRenderer : MonoBehaviour { submeshTriangleCount += attachmentTriangleCount; vertexCount += attachmentVertexCount; - - stateTemp.attachmentsTriangleCount.Items[i] = attachmentTriangleCount; } stateTemp.addSubmeshArguments.Add( new MeshState.AddSubmeshArguments(lastMaterial, submeshStartSlotIndex, drawOrderCount, submeshTriangleCount, submeshFirstVertex, true) ); - bool mustUpdateMeshStructure = CheckIfMustUpdateMeshStructure(stateTemp.attachmentsTriangleCount, stateTemp.attachmentsFlipState, stateTemp.addSubmeshArguments); + bool mustUpdateMeshStructure = CheckIfMustUpdateMeshStructure(stateTemp.attachments, stateTemp.attachmentsFlipState, stateTemp.addSubmeshArguments); if (mustUpdateMeshStructure) { submeshMaterials.Clear(); for (int i = 0, n = stateTemp.addSubmeshArguments.Count; i < n; i++) { @@ -532,9 +531,10 @@ public class SkeletonRenderer : MonoBehaviour { MeshState.SingleMeshState currentMeshState = useMesh1 ? meshState.stateMesh1 : meshState.stateMesh2; currentMeshState.immutableTriangles = immutableTriangles; - currentMeshState.attachmentsTriangleCount.GrowIfNeeded(stateTemp.attachmentsTriangleCount.Capacity); - currentMeshState.attachmentsTriangleCount.Count = stateTemp.attachmentsTriangleCount.Count; - stateTemp.attachmentsTriangleCount.CopyTo(currentMeshState.attachmentsTriangleCount.Items); + currentMeshState.attachments.Clear(true); + currentMeshState.attachments.GrowIfNeeded(stateTemp.attachments.Capacity); + currentMeshState.attachments.Count = stateTemp.attachments.Count; + stateTemp.attachments.CopyTo(currentMeshState.attachments.Items); currentMeshState.attachmentsFlipState.GrowIfNeeded(stateTemp.attachmentsFlipState.Capacity); currentMeshState.attachmentsFlipState.Count = stateTemp.attachmentsFlipState.Count; @@ -558,7 +558,7 @@ public class SkeletonRenderer : MonoBehaviour { useMesh1 = !useMesh1; } - private bool CheckIfMustUpdateMeshStructure (ExposedList attachmentsTriangleCountTemp, ExposedList attachmentsFlipStateTemp, ExposedList addSubmeshArgumentsTemp) { + private bool CheckIfMustUpdateMeshStructure (ExposedList attachmentsTemp, ExposedList attachmentsFlipStateTemp, ExposedList addSubmeshArgumentsTemp) { #if UNITY_EDITOR if (!Application.isPlaying) return true; @@ -574,17 +574,17 @@ public class SkeletonRenderer : MonoBehaviour { // Check if any attachments were enabled/disabled // or submesh structures has changed MeshState.SingleMeshState currentMeshState = useMesh1 ? meshState.stateMesh1 : meshState.stateMesh2; - ExposedList attachmentsTriangleCountCurrentMesh = currentMeshState.attachmentsTriangleCount; + ExposedList attachmentsCurrentMesh = currentMeshState.attachments; ExposedList addSubmeshArgumentsCurrentMesh = currentMeshState.addSubmeshArguments; ExposedList attachmentsFlipStateCurrentMesh = currentMeshState.attachmentsFlipState; // Check attachments - int attachmentCount = attachmentsTriangleCountTemp.Count; - if (attachmentsTriangleCountCurrentMesh.Count != attachmentCount) + int attachmentCount = attachmentsTemp.Count; + if (attachmentsCurrentMesh.Count != attachmentCount) return true; for (int i = 0; i < attachmentCount; i++) { - if (attachmentsTriangleCountCurrentMesh.Items[i] != attachmentsTriangleCountTemp.Items[i]) + if (attachmentsCurrentMesh.Items[i] != attachmentsTemp.Items[i]) return true; } @@ -734,16 +734,16 @@ public class SkeletonRenderer : MonoBehaviour { public class SingleMeshState { public bool immutableTriangles; + public readonly ExposedList attachments = new ExposedList(); public readonly ExposedList attachmentsFlipState = new ExposedList(); - public readonly ExposedList attachmentsTriangleCount = new ExposedList(); public readonly ExposedList addSubmeshArguments = new ExposedList(); public void UpdateDrawOrderCount(int drawOrderCount) { attachmentsFlipState.GrowIfNeeded(drawOrderCount); attachmentsFlipState.Count = drawOrderCount; - attachmentsTriangleCount.GrowIfNeeded(drawOrderCount); - attachmentsTriangleCount.Count = drawOrderCount; + attachments.GrowIfNeeded(drawOrderCount); + attachments.Count = drawOrderCount; } } From e4f9c464129c8dc6000e8473967eb333bc52aaf2 Mon Sep 17 00:00:00 2001 From: John Date: Tue, 15 Dec 2015 17:19:18 +0800 Subject: [PATCH 7/7] [Unity] Fix GroundConstraint -y pose values Fix for this issue: https://github.com/EsotericSoftware/spine-runtimes/issues/484 http://esotericsoftware.com/forum/Unity-IK-SkeletonUtilityGroundConstraint-problem-5464 --- .../SkeletonUtility/SkeletonUtilityGroundConstraint.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityGroundConstraint.cs b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityGroundConstraint.cs index 371b5f170..2b8837eac 100644 --- a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityGroundConstraint.cs +++ b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityGroundConstraint.cs @@ -71,6 +71,7 @@ public class SkeletonUtilityGroundConstraint : SkeletonUtilityConstraint { protected override void OnEnable () { base.OnEnable(); + lastHitY = transform.position.y; } protected override void OnDisable () {