From 5b98c80d326ea6d13250dcb4cc2980db690fbb4e Mon Sep 17 00:00:00 2001 From: Harald Csaszar Date: Fri, 18 Oct 2019 12:38:48 +0200 Subject: [PATCH 1/7] [unity] Fixed Unity editor bone scale resetting to 1.0 after play mode change. Closes #1526. --- .../spine-unity/Editor/Utility/Preferences.cs | 16 +++++++++------- .../Editor/Utility/SpineHandles.cs | 19 +++++++++---------- .../Editor/Windows/SpinePreferences.cs | 9 ++++----- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/Preferences.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/Preferences.cs index 16d6257ba..d8f90e195 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/Preferences.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/Preferences.cs @@ -129,8 +129,8 @@ namespace Spine.Unity.Editor { public const float DEFAULT_MIPMAPBIAS = SpinePreferences.DEFAULT_MIPMAPBIAS; - public const float DEFAULT_SCENE_ICONS_SCALE = SpinePreferences.DEFAULT_SCENE_ICONS_SCALE; - public const string SCENE_ICONS_SCALE_KEY = SpinePreferences.SCENE_ICONS_SCALE_KEY; + public const string SCENE_ICONS_SCALE_KEY = "SPINE_SCENE_ICONS_SCALE"; + public static float handleScale = SpinePreferences.DEFAULT_SCENE_ICONS_SCALE; const string AUTO_RELOAD_SCENESKELETONS_KEY = "SPINE_AUTO_RELOAD_SCENESKELETONS"; public static bool autoReloadSceneSkeletons = SpinePreferences.DEFAULT_AUTO_RELOAD_SCENESKELETONS; @@ -141,6 +141,7 @@ namespace Spine.Unity.Editor { const string TIMELINE_USE_BLEND_DURATION_KEY = "SPINE_TIMELINE_USE_BLEND_DURATION_KEY"; public static bool timelineUseBlendDuration = SpinePreferences.DEFAULT_TIMELINE_USE_BLEND_DURATION; + static bool preferencesLoaded = false; public static void Load () { @@ -158,8 +159,7 @@ namespace Spine.Unity.Editor { atlasTxtImportWarning = EditorPrefs.GetBool(ATLASTXT_WARNING_KEY, SpinePreferences.DEFAULT_ATLASTXT_WARNING); textureImporterWarning = EditorPrefs.GetBool(TEXTUREIMPORTER_WARNING_KEY, SpinePreferences.DEFAULT_TEXTUREIMPORTER_WARNING); timelineUseBlendDuration = EditorPrefs.GetBool(TIMELINE_USE_BLEND_DURATION_KEY, SpinePreferences.DEFAULT_TIMELINE_USE_BLEND_DURATION); - - SpineHandles.handleScale = EditorPrefs.GetFloat(SCENE_ICONS_SCALE_KEY, DEFAULT_SCENE_ICONS_SCALE); + handleScale = EditorPrefs.GetFloat(SCENE_ICONS_SCALE_KEY, SpinePreferences.DEFAULT_SCENE_ICONS_SCALE); preferencesLoaded = true; } @@ -176,6 +176,7 @@ namespace Spine.Unity.Editor { newPreferences.atlasTxtImportWarning = EditorPrefs.GetBool(ATLASTXT_WARNING_KEY, SpinePreferences.DEFAULT_ATLASTXT_WARNING); newPreferences.textureImporterWarning = EditorPrefs.GetBool(TEXTUREIMPORTER_WARNING_KEY, SpinePreferences.DEFAULT_TEXTUREIMPORTER_WARNING); newPreferences.timelineUseBlendDuration = EditorPrefs.GetBool(TIMELINE_USE_BLEND_DURATION_KEY, SpinePreferences.DEFAULT_TIMELINE_USE_BLEND_DURATION); + newPreferences.handleScale = EditorPrefs.GetBool(SCENE_ICONS_SCALE_KEY, SpinePreferences.DEFAULT_SCENE_ICONS_SCALE); } public static void SaveToEditorPrefs(SpinePreferences preferences) { @@ -190,6 +191,7 @@ namespace Spine.Unity.Editor { EditorPrefs.SetBool(ATLASTXT_WARNING_KEY, preferences.atlasTxtImportWarning); EditorPrefs.SetBool(TEXTUREIMPORTER_WARNING_KEY, preferences.textureImporterWarning); EditorPrefs.SetBool(TIMELINE_USE_BLEND_DURATION_KEY, preferences.timelineUseBlendDuration); + EditorPrefs.SetBool(SCENE_ICONS_SCALE_KEY, preferences.handleScale); } #endif @@ -254,10 +256,10 @@ namespace Spine.Unity.Editor { EditorGUILayout.LabelField("Handles and Gizmos", EditorStyles.boldLabel); { EditorGUI.BeginChangeCheck(); - SpineHandles.handleScale = EditorGUILayout.Slider("Editor Bone Scale", SpineHandles.handleScale, 0.01f, 2f); - SpineHandles.handleScale = Mathf.Max(0.01f, SpineHandles.handleScale); + handleScale = EditorGUILayout.Slider("Editor Bone Scale", handleScale, 0.01f, 2f); + handleScale = Mathf.Max(0.01f, handleScale); if (EditorGUI.EndChangeCheck()) { - EditorPrefs.SetFloat(SCENE_ICONS_SCALE_KEY, SpineHandles.handleScale); + EditorPrefs.SetFloat(SCENE_ICONS_SCALE_KEY, handleScale); SceneView.RepaintAll(); } } diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineHandles.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineHandles.cs index 3fffd53a3..afa5a91ba 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineHandles.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineHandles.cs @@ -44,7 +44,6 @@ namespace Spine.Unity.Editor { using EventType = UnityEngine.EventType; public static class SpineHandles { - internal static float handleScale = 1f; public static Color BoneColor { get { return new Color(0.8f, 0.8f, 0.8f, 0.4f); } } public static Color PathColor { get { return new Color(254/255f, 127/255f, 0); } } public static Color TransformContraintColor { get { return new Color(170/255f, 226/255f, 35/255f); } } @@ -200,7 +199,7 @@ namespace Spine.Unity.Editor { Quaternion rot = Quaternion.Euler(0, 0, b.WorldRotationX); Vector3 scale = Vector3.one * length * b.WorldScaleX * skeletonRenderScale; const float my = 1.5f; - scale.y *= (SpineHandles.handleScale + 1) * 0.5f; + scale.y *= (SpineEditorUtilities.Preferences.handleScale + 1) * 0.5f; scale.y = Mathf.Clamp(scale.x, -my * skeletonRenderScale, my * skeletonRenderScale); Handles.DrawPolyLine(GetBoneWireBuffer(transform.localToWorldMatrix * Matrix4x4.TRS(pos, rot, scale))); var wp = transform.TransformPoint(pos); @@ -218,7 +217,7 @@ namespace Spine.Unity.Editor { Quaternion rot = Quaternion.Euler(0, 0, b.WorldRotationX); Vector3 scale = Vector3.one * length * b.WorldScaleX * skeletonRenderScale; const float my = 1.5f; - scale.y *= (SpineHandles.handleScale + 1f) * 0.5f; + scale.y *= (SpineEditorUtilities.Preferences.handleScale + 1f) * 0.5f; scale.y = Mathf.Clamp(scale.x, -my * skeletonRenderScale, my * skeletonRenderScale); SpineHandles.GetBoneMaterial().SetPass(0); Graphics.DrawMeshNow(SpineHandles.BoneMesh, transform.localToWorldMatrix * Matrix4x4.TRS(pos, rot, scale)); @@ -235,7 +234,7 @@ namespace Spine.Unity.Editor { Quaternion rot = Quaternion.Euler(0, 0, b.WorldRotationX); Vector3 scale = Vector3.one * length * b.WorldScaleX; const float my = 1.5f; - scale.y *= (SpineHandles.handleScale + 1f) * 0.5f; + scale.y *= (SpineEditorUtilities.Preferences.handleScale + 1f) * 0.5f; scale.y = Mathf.Clamp(scale.x, -my, my); SpineHandles.GetBoneMaterial(color).SetPass(0); Graphics.DrawMeshNow(SpineHandles.BoneMesh, transform.localToWorldMatrix * Matrix4x4.TRS(pos, rot, scale)); @@ -425,13 +424,13 @@ namespace Spine.Unity.Editor { } static void DrawCrosshairs2D (Vector3 position, float scale, float skeletonRenderScale = 1f) { - scale *= SpineHandles.handleScale * skeletonRenderScale; + scale *= SpineEditorUtilities.Preferences.handleScale * skeletonRenderScale; Handles.DrawLine(position + new Vector3(-scale, 0), position + new Vector3(scale, 0)); Handles.DrawLine(position + new Vector3(0, -scale), position + new Vector3(0, scale)); } static void DrawCrosshairs (Vector3 position, float scale, float a, float b, float c, float d, Transform transform, float skeletonRenderScale = 1f) { - scale *= SpineHandles.handleScale * skeletonRenderScale; + scale *= SpineEditorUtilities.Preferences.handleScale * skeletonRenderScale; var xOffset = (Vector3)(new Vector2(a, c).normalized * scale); var yOffset = (Vector3)(new Vector2(b, d).normalized * scale); @@ -443,7 +442,7 @@ namespace Spine.Unity.Editor { } static void DrawArrowhead2D (Vector3 pos, float localRotation, float scale = 1f) { - scale *= SpineHandles.handleScale; + scale *= SpineEditorUtilities.Preferences.handleScale; SpineHandles.IKMaterial.SetPass(0); Graphics.DrawMeshNow(SpineHandles.ArrowheadMesh, Matrix4x4.TRS(pos, Quaternion.Euler(0, 0, localRotation), new Vector3(scale, scale, scale))); @@ -454,7 +453,7 @@ namespace Spine.Unity.Editor { } static void DrawArrowhead (Matrix4x4 m) { - float s = SpineHandles.handleScale; + float s = SpineEditorUtilities.Preferences.handleScale; m.m00 *= s; m.m01 *= s; m.m02 *= s; @@ -470,14 +469,14 @@ namespace Spine.Unity.Editor { } static void DrawBoneCircle (Vector3 pos, Color outlineColor, Vector3 normal, float scale = 1f) { - scale *= SpineHandles.handleScale; + scale *= SpineEditorUtilities.Preferences.handleScale; Color o = Handles.color; Handles.color = outlineColor; float firstScale = 0.08f * scale; Handles.DrawSolidDisc(pos, normal, firstScale); const float Thickness = 0.03f; - float secondScale = firstScale - (Thickness * SpineHandles.handleScale * scale); + float secondScale = firstScale - (Thickness * SpineEditorUtilities.Preferences.handleScale * scale); if (secondScale > 0f) { Handles.color = new Color(0.3f, 0.3f, 0.3f, 0.5f); diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Windows/SpinePreferences.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Windows/SpinePreferences.cs index 4343311b9..32acff2a5 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Windows/SpinePreferences.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Windows/SpinePreferences.cs @@ -87,7 +87,7 @@ namespace Spine.Unity.Editor { public bool autoReloadSceneSkeletons = DEFAULT_AUTO_RELOAD_SCENESKELETONS; internal const float DEFAULT_SCENE_ICONS_SCALE = 1f; - public const string SCENE_ICONS_SCALE_KEY = "SPINE_SCENE_ICONS_SCALE"; + public static float handleScale = DEFAULT_SCENE_ICONS_SCALE; public const bool DEFAULT_MECANIM_EVENT_INCLUDE_FOLDERNAME = true; public bool mecanimEventIncludeFolderName = DEFAULT_MECANIM_EVENT_INCLUDE_FOLDERNAME; @@ -98,7 +98,6 @@ namespace Spine.Unity.Editor { #if NEW_PREFERENCES_SETTINGS_PROVIDER public static void Load () { - SpineHandles.handleScale = EditorPrefs.GetFloat(SCENE_ICONS_SCALE_KEY, DEFAULT_SCENE_ICONS_SCALE); GetOrCreateSettings(); } @@ -172,10 +171,10 @@ namespace Spine.Unity.Editor { EditorGUILayout.LabelField("Handles and Gizmos", EditorStyles.boldLabel); { EditorGUI.BeginChangeCheck(); - SpineHandles.handleScale = EditorGUILayout.Slider("Editor Bone Scale", SpineHandles.handleScale, 0.01f, 2f); - SpineHandles.handleScale = Mathf.Max(0.01f, SpineHandles.handleScale); + handleScale = EditorGUILayout.Slider("Editor Bone Scale", handleScale, 0.01f, 2f); + handleScale = Mathf.Max(0.01f, handleScale); if (EditorGUI.EndChangeCheck()) { - EditorPrefs.SetFloat(SpinePreferences.SCENE_ICONS_SCALE_KEY, SpineHandles.handleScale); + EditorPrefs.SetFloat(SpinePreferences.SCENE_ICONS_SCALE_KEY, handleScale); SceneView.RepaintAll(); } } From 8b9c9314f2a65244ac80d6ff5afb06a6e0879f34 Mon Sep 17 00:00:00 2001 From: Harald Csaszar Date: Fri, 18 Oct 2019 15:17:24 +0200 Subject: [PATCH 2/7] [unity] Fixed transition blending of Deform timeline. Led to difference of vertex location to reference implementation after animation transition. Closes #1525. --- spine-csharp/src/Animation.cs | 2 +- spine-csharp/src/AnimationState.cs | 25 ++++++++++++------------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/spine-csharp/src/Animation.cs b/spine-csharp/src/Animation.cs index ce30bd8d3..dd420b5ba 100644 --- a/spine-csharp/src/Animation.cs +++ b/spine-csharp/src/Animation.cs @@ -1064,7 +1064,7 @@ namespace Spine { case MixBlend.Setup: deformArray.Clear(); return; - case MixBlend.Replace: + case MixBlend.First: if (alpha == 1) { deformArray.Clear(); return; diff --git a/spine-csharp/src/AnimationState.cs b/spine-csharp/src/AnimationState.cs index 3dfed92ae..4752aaa5b 100644 --- a/spine-csharp/src/AnimationState.cs +++ b/spine-csharp/src/AnimationState.cs @@ -76,8 +76,7 @@ namespace Spine { protected AnimationStateData data; private readonly ExposedList tracks = new ExposedList(); private readonly ExposedList events = new ExposedList(); - - // difference to libgdx reference: delegates are used for event callbacks instead of 'Array listeners'. + // difference to libgdx reference: delegates are used for event callbacks instead of 'final SnapshotArray listeners'. internal void OnStart (TrackEntry entry) { if (Start != null) Start(entry); } internal void OnInterrupt (TrackEntry entry) { if (Interrupt != null) Interrupt(entry); } internal void OnEnd (TrackEntry entry) { if (End != null) End(entry); } @@ -85,12 +84,12 @@ namespace Spine { internal void OnComplete (TrackEntry entry) { if (Complete != null) Complete(entry); } internal void OnEvent (TrackEntry entry, Event e) { if (Event != null) Event(entry, e); } - public delegate void TrackEntryDelegate(TrackEntry trackEntry); + public delegate void TrackEntryDelegate (TrackEntry trackEntry); public event TrackEntryDelegate Start, Interrupt, End, Dispose, Complete; - public delegate void TrackEntryEventDelegate(TrackEntry trackEntry, Event e); + public delegate void TrackEntryEventDelegate (TrackEntry trackEntry, Event e); public event TrackEntryEventDelegate Event; - + // end of difference private readonly EventQueue queue; // Initialized by constructor. private readonly HashSet propertyIDs = new HashSet(); private bool animationsChanged; @@ -98,7 +97,7 @@ namespace Spine { private readonly Pool trackEntryPool = new Pool(); - public AnimationState(AnimationStateData data) { + public AnimationState (AnimationStateData data) { if (data == null) throw new ArgumentNullException("data", "data cannot be null."); this.data = data; this.queue = new EventQueue( @@ -233,8 +232,8 @@ namespace Spine { } else { var timelineMode = current.timelineMode.Items; - bool firstFrame = current.timelinesRotation.Count == 0; - if (firstFrame) current.timelinesRotation.EnsureCapacity(timelines.Count << 1); + bool firstFrame = current.timelinesRotation.Count != timelineCount << 1; + if (firstFrame) current.timelinesRotation.Resize(timelines.Count << 1); var timelinesRotation = current.timelinesRotation.Items; for (int ii = 0; ii < timelineCount; ii++) { @@ -242,8 +241,8 @@ namespace Spine { MixBlend timelineBlend = (timelineMode[ii] & AnimationState.NotLast - 1) == AnimationState.Subsequent ? blend : MixBlend.Setup; var rotateTimeline = timeline as RotateTimeline; if (rotateTimeline != null) - ApplyRotateTimeline(rotateTimeline, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii << 1, - firstFrame); + ApplyRotateTimeline(rotateTimeline, skeleton, animationTime, mix, timelineBlend, timelinesRotation, + ii << 1, firstFrame); else timeline.Apply(skeleton, animationLast, animationTime, events, mix, timelineBlend, MixDirection.In); } @@ -287,7 +286,7 @@ namespace Spine { var timelineMode = from.timelineMode.Items; var timelineHoldMix = from.timelineHoldMix.Items; - bool firstFrame = from.timelinesRotation.Count == 0; + bool firstFrame = from.timelinesRotation.Count != timelineCount << 1; if (firstFrame) from.timelinesRotation.Resize(timelines.Count << 1); // from.timelinesRotation.setSize var timelinesRotation = from.timelinesRotation.Items; @@ -325,8 +324,8 @@ namespace Spine { var rotateTimeline = timeline as RotateTimeline; if (rotateTimeline != null) { - ApplyRotateTimeline(rotateTimeline, skeleton, animationTime, alpha, timelineBlend, timelinesRotation, i << 1, - firstFrame); + ApplyRotateTimeline(rotateTimeline, skeleton, animationTime, alpha, timelineBlend, timelinesRotation, + i << 1, firstFrame); } else { if (timelineBlend == MixBlend.Setup) { if (timeline is AttachmentTimeline) { From f5956594235ad96f8a64ad41285e3bbaf5113159 Mon Sep 17 00:00:00 2001 From: Harald Csaszar Date: Sun, 20 Oct 2019 18:43:15 +0200 Subject: [PATCH 3/7] [unity] Fixed compile error on Unity 2018.3+. --- .../Editor/spine-unity/Editor/Utility/Preferences.cs | 4 ++-- .../spine-unity/Editor/Windows/SpinePreferences.cs | 12 +++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/Preferences.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/Preferences.cs index d8f90e195..ef8db192e 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/Preferences.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/Preferences.cs @@ -176,7 +176,7 @@ namespace Spine.Unity.Editor { newPreferences.atlasTxtImportWarning = EditorPrefs.GetBool(ATLASTXT_WARNING_KEY, SpinePreferences.DEFAULT_ATLASTXT_WARNING); newPreferences.textureImporterWarning = EditorPrefs.GetBool(TEXTUREIMPORTER_WARNING_KEY, SpinePreferences.DEFAULT_TEXTUREIMPORTER_WARNING); newPreferences.timelineUseBlendDuration = EditorPrefs.GetBool(TIMELINE_USE_BLEND_DURATION_KEY, SpinePreferences.DEFAULT_TIMELINE_USE_BLEND_DURATION); - newPreferences.handleScale = EditorPrefs.GetBool(SCENE_ICONS_SCALE_KEY, SpinePreferences.DEFAULT_SCENE_ICONS_SCALE); + newPreferences.handleScale = EditorPrefs.GetFloat(SCENE_ICONS_SCALE_KEY, SpinePreferences.DEFAULT_SCENE_ICONS_SCALE); } public static void SaveToEditorPrefs(SpinePreferences preferences) { @@ -191,7 +191,7 @@ namespace Spine.Unity.Editor { EditorPrefs.SetBool(ATLASTXT_WARNING_KEY, preferences.atlasTxtImportWarning); EditorPrefs.SetBool(TEXTUREIMPORTER_WARNING_KEY, preferences.textureImporterWarning); EditorPrefs.SetBool(TIMELINE_USE_BLEND_DURATION_KEY, preferences.timelineUseBlendDuration); - EditorPrefs.SetBool(SCENE_ICONS_SCALE_KEY, preferences.handleScale); + EditorPrefs.SetFloat(SCENE_ICONS_SCALE_KEY, preferences.handleScale); } #endif diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Windows/SpinePreferences.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Windows/SpinePreferences.cs index 32acff2a5..477b5195b 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Windows/SpinePreferences.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Windows/SpinePreferences.cs @@ -86,8 +86,10 @@ namespace Spine.Unity.Editor { public const bool DEFAULT_AUTO_RELOAD_SCENESKELETONS = true; public bool autoReloadSceneSkeletons = DEFAULT_AUTO_RELOAD_SCENESKELETONS; + public const string SCENE_ICONS_SCALE_KEY = "SPINE_SCENE_ICONS_SCALE"; internal const float DEFAULT_SCENE_ICONS_SCALE = 1f; - public static float handleScale = DEFAULT_SCENE_ICONS_SCALE; + [Range(0.01f, 2f)] + public float handleScale = DEFAULT_SCENE_ICONS_SCALE; public const bool DEFAULT_MECANIM_EVENT_INCLUDE_FOLDERNAME = true; public bool mecanimEventIncludeFolderName = DEFAULT_MECANIM_EVENT_INCLUDE_FOLDERNAME; @@ -95,7 +97,7 @@ namespace Spine.Unity.Editor { // Timeline extension module public const bool DEFAULT_TIMELINE_USE_BLEND_DURATION = true; public bool timelineUseBlendDuration = DEFAULT_TIMELINE_USE_BLEND_DURATION; - + #if NEW_PREFERENCES_SETTINGS_PROVIDER public static void Load () { GetOrCreateSettings(); @@ -171,10 +173,10 @@ namespace Spine.Unity.Editor { EditorGUILayout.LabelField("Handles and Gizmos", EditorStyles.boldLabel); { EditorGUI.BeginChangeCheck(); - handleScale = EditorGUILayout.Slider("Editor Bone Scale", handleScale, 0.01f, 2f); - handleScale = Mathf.Max(0.01f, handleScale); + var scaleProperty = settings.FindProperty("handleScale"); + EditorGUILayout.PropertyField(scaleProperty, new GUIContent("Editor Bone Scale")); if (EditorGUI.EndChangeCheck()) { - EditorPrefs.SetFloat(SpinePreferences.SCENE_ICONS_SCALE_KEY, handleScale); + EditorPrefs.SetFloat(SpinePreferences.SCENE_ICONS_SCALE_KEY, scaleProperty.floatValue); SceneView.RepaintAll(); } } From ae2d40fd849705e7efabf2748e4e4f699e6df142 Mon Sep 17 00:00:00 2001 From: Harald Csaszar Date: Mon, 21 Oct 2019 13:35:46 +0200 Subject: [PATCH 4/7] [unity] SetDefaultTextureSettings was not called properly on import. Now fixed with working proper meta-file based solution. Closes #1514. --- .../Asset Types/SkeletonDataAssetInspector.cs | 2 +- .../Editor/Utility/AssetUtility.cs | 33 +++++++------------ .../Editor/Utility/SpineEditorUtilities.cs | 18 ++++++++-- 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Asset Types/SkeletonDataAssetInspector.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Asset Types/SkeletonDataAssetInspector.cs index 21aaace86..a74b2b359 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Asset Types/SkeletonDataAssetInspector.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Asset Types/SkeletonDataAssetInspector.cs @@ -659,7 +659,7 @@ namespace Spine.Unity.Editor { } void DoReimport () { - AssetUtility.ImportSpineContent(new [] { AssetDatabase.GetAssetPath(skeletonJSON.objectReferenceValue) }, true); + AssetUtility.ImportSpineContent(new [] { AssetDatabase.GetAssetPath(skeletonJSON.objectReferenceValue) }, null, true); preview.Clear(); InitializeEditor(); EditorUtility.SetDirty(targetSkeletonDataAsset); diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/AssetUtility.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/AssetUtility.cs index 1dab19b49..939a93ed2 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/AssetUtility.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/AssetUtility.cs @@ -65,7 +65,7 @@ namespace Spine.Unity.Editor { public static readonly List protectFromStackGarbageCollection = new List(); public static HashSet assetsImportedInWrongState = new HashSet(); - public static void HandleOnPostprocessAllAssets (string[] imported) { + public static void HandleOnPostprocessAllAssets (string[] imported, List texturesWithoutMetaFile) { // 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) @@ -87,7 +87,7 @@ namespace Spine.Unity.Editor { if (AssetDatabaseAvailabilityDetector.IsAssetDatabaseAvailable()) { string[] combinedAssets = AssetUtility.assetsImportedInWrongState.ToArray(); AssetUtility.assetsImportedInWrongState.Clear(); - AssetUtility.ImportSpineContent(combinedAssets); + AssetUtility.ImportSpineContent(combinedAssets, texturesWithoutMetaFile); } } @@ -243,7 +243,9 @@ namespace Spine.Unity.Editor { } #endregion - public static void ImportSpineContent (string[] imported, bool reimport = false) { + public static void ImportSpineContent (string[] imported, List texturesWithoutMetaFile, + bool reimport = false) { + var atlasPaths = new List(); var imagePaths = new List(); var skeletonPaths = new List(); @@ -285,7 +287,7 @@ namespace Spine.Unity.Editor { if (ap.StartsWith("Packages")) continue; TextAsset atlasText = AssetDatabase.LoadAssetAtPath(ap); - AtlasAssetBase atlas = IngestSpineAtlas(atlasText); + AtlasAssetBase atlas = IngestSpineAtlas(atlasText, texturesWithoutMetaFile); atlases.Add(atlas); } @@ -428,7 +430,7 @@ namespace Spine.Unity.Editor { return arr; } - static AtlasAssetBase IngestSpineAtlas (TextAsset atlasText) { + static AtlasAssetBase IngestSpineAtlas (TextAsset atlasText, List texturesWithoutMetaFile) { if (atlasText == null) { Debug.LogWarning("Atlas source cannot be null!"); return null; @@ -469,8 +471,9 @@ namespace Spine.Unity.Editor { for (int i = 0; i < pageFiles.Count; i++) { string texturePath = assetPath + "/" + pageFiles[i]; Texture2D texture = (Texture2D)AssetDatabase.LoadAssetAtPath(texturePath, typeof(Texture2D)); - if (SpineEditorUtilities.Preferences.setTextureImporterSettings) { - SetDefaultTextureSettingsIfNew(texturePath, atlasAsset); + bool textureIsUninitialized = texturesWithoutMetaFile != null && texturesWithoutMetaFile.Contains(texturePath); + if (SpineEditorUtilities.Preferences.setTextureImporterSettings && textureIsUninitialized) { + SetDefaultTextureSettings(texturePath, atlasAsset); } string pageName = Path.GetFileNameWithoutExtension(pageFiles[i]); @@ -546,27 +549,13 @@ namespace Spine.Unity.Editor { return (AtlasAssetBase)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(AtlasAssetBase)); } - static bool SetDefaultTextureSettingsIfNew (string texturePath, SpineAtlasAsset atlasAsset) { + static bool SetDefaultTextureSettings (string texturePath, SpineAtlasAsset atlasAsset) { TextureImporter texImporter = (TextureImporter)TextureImporter.GetAtPath(texturePath); if (texImporter == null) { Debug.LogWarning(string.Format("{0}: Texture asset \"{1}\" not found. Skipping. Please check your atlas file for renamed files.", atlasAsset.name, texturePath)); return false; } - #if UNITY_2018_1_OR_NEWER - bool customTextureSettingsExist = !texImporter.importSettingsMissing; - #else - // unfortunately, importSettingsMissing is not available in Unity 2017, - // so we check if any settings deviate from Unity's default texture settings. - bool customTextureSettingsExist = texImporter.mipmapEnabled != true || - texImporter.maxTextureSize != 2048 || - texImporter.alphaIsTransparency != true || - texImporter.wrapMode != TextureWrapMode.Repeat || - texImporter.filterMode != FilterMode.Bilinear; - #endif - if (customTextureSettingsExist) - return false; - texImporter.textureCompression = TextureImporterCompression.Uncompressed; texImporter.alphaSource = TextureImporterAlphaSource.FromInput; texImporter.mipmapEnabled = false; diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineEditorUtilities.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineEditorUtilities.cs index 3e89893cf..5f7cac9e4 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineEditorUtilities.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineEditorUtilities.cs @@ -65,13 +65,27 @@ namespace Spine.Unity.Editor { public static string editorPath = ""; public static string editorGUIPath = ""; public static bool initialized; + private static List texturesWithoutMetaFile = new List(); - // Auto-import entry point + // Auto-import entry point for textures + void OnPreprocessTexture () { + #if UNITY_2018_1_OR_NEWER + bool customTextureSettingsExist = !assetImporter.importSettingsMissing; + #else + bool customTextureSettingsExist = System.IO.File.Exists(assetImporter.assetPath + ".meta"); + #endif + if (!customTextureSettingsExist) { + texturesWithoutMetaFile.Add(assetImporter.assetPath); + } + } + + // Auto-import post process entry point for all assets static void OnPostprocessAllAssets (string[] imported, string[] deleted, string[] moved, string[] movedFromAssetPaths) { if (imported.Length == 0) return; - AssetUtility.HandleOnPostprocessAllAssets(imported); + AssetUtility.HandleOnPostprocessAllAssets(imported, texturesWithoutMetaFile); + texturesWithoutMetaFile.Clear(); } #region Initialization From 86b979e812e1d223b607571cc0fcb806d8bcd637 Mon Sep 17 00:00:00 2001 From: Harald Csaszar Date: Tue, 22 Oct 2019 17:12:39 +0200 Subject: [PATCH 5/7] [unity] Fixed editor bone scale reset to 1.0 after play mode changes. Closes #1526. --- .../spine-unity/Editor/Utility/SpineEditorUtilities.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineEditorUtilities.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineEditorUtilities.cs index 5f7cac9e4..de571cb48 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineEditorUtilities.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineEditorUtilities.cs @@ -94,14 +94,16 @@ namespace Spine.Unity.Editor { } static void Initialize () { - if (EditorApplication.isPlayingOrWillChangePlaymode) return; - + // Note: Preferences need to be loaded when changing play mode + // to initialize handle scale correctly. #if !NEW_PREFERENCES_SETTINGS_PROVIDER Preferences.Load(); #else SpinePreferences.Load(); #endif + if (EditorApplication.isPlayingOrWillChangePlaymode) return; + string[] assets = AssetDatabase.FindAssets("t:script SpineEditorUtilities"); string assetPath = AssetDatabase.GUIDToAssetPath(assets[0]); editorPath = Path.GetDirectoryName(assetPath).Replace("\\", "/"); From 366178e7305270c8167768792af02f3027eeb1b9 Mon Sep 17 00:00:00 2001 From: badlogic Date: Wed, 23 Oct 2019 16:12:15 +0200 Subject: [PATCH 6/7] [ue4] Update example project to UE 4.23, update README.md. --- spine-ue4/README.md | 4 ++-- spine-ue4/SpineUE4.uproject | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spine-ue4/README.md b/spine-ue4/README.md index f7f782a12..4ecb1a302 100644 --- a/spine-ue4/README.md +++ b/spine-ue4/README.md @@ -1,5 +1,5 @@ # spine-ue4 -The spine-ue4 runtime provides functionality to load, manipulate and render [Spine](http://esotericsoftware.com) skeletal animation data using [Unreal Engine 4.18+](https://www.unrealengine.com/). spine-ue4 is based on [spine-cpp](../spine-cpp). +The spine-ue4 runtime provides functionality to load, manipulate and render [Spine](http://esotericsoftware.com) skeletal animation data using [Unreal Engine 4.21+](https://www.unrealengine.com/). spine-ue4 is based on [spine-cpp](../spine-cpp). ## Licensing @@ -33,7 +33,7 @@ See the [Spine Runtimes documentation](http://esotericsoftware.com/spine-documen ## Example ### [Please see the spine-ue4 guide for full documentation](http://esotericsoftware.com/spine-ue4) -The Spine UE4 example works on all platforms supported by Unreal Engine. The samples require Unreal Engine 4.18. +The Spine UE4 example works on all platforms supported by Unreal Engine. The samples require Unreal Engine 4.23+. 1. Copy the `spine-cpp` folder from this repositories root directory to your `Plugins/SpinePlugin/Sources/SpinePlugin/Public/` directory. 2. Open the SpineUE4.uproject file with Unreal Editor diff --git a/spine-ue4/SpineUE4.uproject b/spine-ue4/SpineUE4.uproject index 8830daf34..1fd20a5a7 100644 --- a/spine-ue4/SpineUE4.uproject +++ b/spine-ue4/SpineUE4.uproject @@ -1,6 +1,6 @@ { "FileVersion": 3, - "EngineAssociation": "4.22", + "EngineAssociation": "4.23", "Category": "", "Description": "", "Modules": [ From b9f8fb3b9ebf77dce3bd320af5f97405d938585c Mon Sep 17 00:00:00 2001 From: badlogic Date: Thu, 24 Oct 2019 16:49:53 +0200 Subject: [PATCH 7/7] [libgdx] Added mouse following IK example. See #1532. --- .../com/esotericsoftware/spine/IKTest.java | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/IKTest.java diff --git a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/IKTest.java b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/IKTest.java new file mode 100644 index 000000000..6f3dbedaa --- /dev/null +++ b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/IKTest.java @@ -0,0 +1,128 @@ +package com.esotericsoftware.spine; + +import com.badlogic.gdx.ApplicationAdapter; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.backends.lwjgl.LwjglApplication; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.math.Vector3; +import com.esotericsoftware.spine.utils.TwoColorPolygonBatch; + +/** Demonstrates how to let the target bone of an IK constraint + * follow the mouse or touch position, which in turn repositions + * part of the skeleton, in this case Spineboy's back arm including + * his gun. + */ +public class IKTest extends ApplicationAdapter { + OrthographicCamera camera; + TwoColorPolygonBatch batch; + SkeletonRenderer renderer; + + TextureAtlas atlas; + Skeleton skeleton; + AnimationState state; + + Vector3 cameraCoords = new Vector3(); + Vector2 boneCoords = new Vector2(); + + public void create () { + // Create objects needed for rendering + camera = new OrthographicCamera(); + batch = new TwoColorPolygonBatch(); + renderer = new SkeletonRenderer(); + renderer.setPremultipliedAlpha(true); + + // Load the texture atlas and skeleton data + atlas = new TextureAtlas(Gdx.files.internal("spineboy/spineboy-pma.atlas")); + SkeletonBinary json = new SkeletonBinary(atlas); + json.setScale(0.6f); + SkeletonData skeletonData = json.readSkeletonData(Gdx.files.internal("spineboy/spineboy-pro.skel")); + + // Create a skeleton from the skeleton data + skeleton = new Skeleton(skeletonData); + skeleton.setPosition(250, 20); + + // Create an animation satte + AnimationStateData stateData = new AnimationStateData(skeletonData); + state = new AnimationState(stateData); + + // Queue the "walk" animation on the first track. + state.setAnimation(0, "walk", true); + + // Queue the "aim" animation on a higher track. + // It consists of a single frame that positions + // the back arm and gun such that they point at + // the "crosshair" bone. By setting this + // animation on a higher track, it overrides + // any changes to the back arm and gun made + // by the walk animation, allowing us to + // mix the two. The mouse position following + // is performed in the render() method below. + state.setAnimation(1, "aim", true); + + // apply the state once, so we have world + // bone positions that we can use. + skeleton.setToSetupPose(); + } + + public void render () { + // Update and apply the animations to the skeleton, + // then calculate the world transforms of every bone. + // This is needed so we can call Bone#worldToLocal() + // later. + state.update(Gdx.graphics.getDeltaTime()); + state.apply(skeleton); + skeleton.updateWorldTransform(); + + // Position the "crosshair" bone at the mouse + // location. We do this before calling + // skeleton.updateWorldTransform() below, so + // our change is incorporated before the IK + // constraint is applied. + // + // When setting the crosshair bone position + // to the mouse position, we need to translate + // from "mouse space" to "camera space" + // and then to "local bone space". Note that the local + // bone space is calculated using the bone's parent + // worldToLocal() function! + cameraCoords.set(Gdx.input.getX(), Gdx.input.getY(), 0); + camera.unproject(cameraCoords); // mouse space to camera space + + Bone crosshair = skeleton.findBone("crosshair"); // Should be cached. + boneCoords.set(cameraCoords.x, cameraCoords.y); + crosshair.getParent().worldToLocal(boneCoords); // camera space to local bone space + crosshair.setPosition(boneCoords.x, boneCoords.y); // override the crosshair position + crosshair.setAppliedValid(false); + + // Calculate final world transform with the + // crosshair bone set to the mouse cursor + // position. + skeleton.updateWorldTransform(); + + // Clear the screen, update the camera and + // render the skeleton. + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + camera.update(); + + batch.getProjectionMatrix().set(camera.combined); + batch.begin(); + renderer.draw(batch, skeleton); + batch.end(); + + } + + public void resize (int width, int height) { + camera.setToOrtho(false); // Update camera with new size. + } + + public void dispose () { + atlas.dispose(); + } + + public static void main (String[] args) throws Exception { + new LwjglApplication(new IKTest()); + } +}