diff --git a/CHANGELOG.md b/CHANGELOG.md index ec625f51e1..f269566d93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -103,6 +103,7 @@ * Timeline extension package: An additional Spine preferences parameter `Timeline` - `Default Mix Duration` has been added, setting newly added `SpineAnimationStateClip` clips accordingly, defaults to false. This Spine preferences parameter can be enabled to default to the previous behaviour before this update. * Tint Black: Added support for [Tint Black](http://en.esotericsoftware.com/spine-slots#Tint-black) functionality at all Spine URP shaders (2D and 3D shaders) and at all standard pipeline `Spine/Sprite` shaders. This feature can be enabled via the `Tint Black` material parameter in the Inspector. Note: The URP Sprite shaders provided in the Spine URP Shaders extension UPM package require the latest version of the spine-unity runtime (package version 4.1.12, 2023-05-31 or newer) to display the added material parameters in the Inspector GUI. * Added `SkeletonGraphic.MeshScale` property to allow access to calculated mesh scale. `MeshScale` is based on (1) Canvas pixels per unit, and (2) `RectTransform` bounds when using `Layout Scale Mode` other than `None` at `SkeletonGraphic` which scales the skeleton mesh to fit the parent `RectTransform` bounds accordingly. + * Added `updateSeparatorPartScale` property to `SkeletonGraphic` to let render separator parts follow the scale (lossy scale) of the `SkeletonGraphic` GameObject. Defaults to `false` to maintain existing behaviour. * **Breaking changes** * Made `SkeletonGraphic.unscaledTime` parameter protected, use the new property `UnscaledTime` instead. diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonGraphicInspector.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonGraphicInspector.cs index 85a8f1af51..7e7e82ef5a 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonGraphicInspector.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonGraphicInspector.cs @@ -64,7 +64,8 @@ public class SkeletonGraphicInspector : UnityEditor.Editor { updateTiming, updateWhenInvisible, unscaledTime, tintBlack, layoutScaleMode, editReferenceRect; SerializedProperty initialFlipX, initialFlipY; SerializedProperty meshGeneratorSettings; - SerializedProperty allowMultipleCanvasRenderers, separatorSlotNames, enableSeparatorSlots, updateSeparatorPartLocation; + SerializedProperty allowMultipleCanvasRenderers, separatorSlotNames, enableSeparatorSlots, + updateSeparatorPartLocation, updateSeparatorPartScale; SerializedProperty raycastTarget, maskable; readonly GUIContent UnscaledTimeLabel = new GUIContent("Unscaled Time", @@ -141,6 +142,7 @@ public class SkeletonGraphicInspector : UnityEditor.Editor { allowMultipleCanvasRenderers = so.FindProperty("allowMultipleCanvasRenderers"); updateSeparatorPartLocation = so.FindProperty("updateSeparatorPartLocation"); + updateSeparatorPartScale = so.FindProperty("updateSeparatorPartScale"); enableSeparatorSlots = so.FindProperty("enableSeparatorSlots"); separatorSlotNames = so.FindProperty("separatorSlotNames"); @@ -304,7 +306,7 @@ public class SkeletonGraphicInspector : UnityEditor.Editor { } EditorGUILayout.Space(); - SeparatorsField(separatorSlotNames, enableSeparatorSlots, updateSeparatorPartLocation); + SeparatorsField(separatorSlotNames, enableSeparatorSlots, updateSeparatorPartLocation, updateSeparatorPartScale); } } @@ -428,7 +430,7 @@ public class SkeletonGraphicInspector : UnityEditor.Editor { } public static void SeparatorsField (SerializedProperty separatorSlotNames, SerializedProperty enableSeparatorSlots, - SerializedProperty updateSeparatorPartLocation) { + SerializedProperty updateSeparatorPartLocation, SerializedProperty updateSeparatorPartScale) { bool multi = separatorSlotNames.serializedObject.isEditingMultipleObjects; bool hasTerminalSlot = false; @@ -466,6 +468,7 @@ public class SkeletonGraphicInspector : UnityEditor.Editor { EditorGUILayout.PropertyField(enableSeparatorSlots, SpineInspectorUtility.TempContent("Enable Separation", tooltip: "Whether to enable separation at the above separator slots.")); EditorGUILayout.PropertyField(updateSeparatorPartLocation, SpineInspectorUtility.TempContent("Update Part Location", tooltip: "Update separator part GameObject location to match the position of the SkeletonGraphic. This can be helpful when re-parenting parts to a different GameObject.")); + EditorGUILayout.PropertyField(updateSeparatorPartScale, SpineInspectorUtility.TempContent("Update Part Scale", tooltip: "Update separator part GameObject scale to match the scale (lossyScale) of the SkeletonGraphic. This can be helpful when re-parenting parts to a different GameObject.")); } } diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs index 8dc0da467b..7e060a6747 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs @@ -116,6 +116,7 @@ public enum LayoutMode { [SerializeField] protected List separatorParts = new List(); public List SeparatorParts { get { return separatorParts; } } public bool updateSeparatorPartLocation = true; + public bool updateSeparatorPartScale = false; private bool wasUpdatedAfterInit = true; private bool requiresInstructionUpate = true; @@ -952,6 +953,17 @@ public enum LayoutMode { separatorParts[p].rotation = this.transform.rotation; } } + if (updateSeparatorPartScale) { + Vector3 targetScale = this.transform.lossyScale; + for (int p = 0; p < this.separatorParts.Count; ++p) { + Transform partParent = separatorParts[p].transform.parent; + Vector3 parentScale = partParent == null ? Vector3.one : partParent.lossyScale; + separatorParts[p].localScale = new Vector3( + parentScale.x == 0f ? 1f : targetScale.x / parentScale.x, + parentScale.y == 0f ? 1f : targetScale.y / parentScale.y, + parentScale.z == 0f ? 1f : targetScale.z / parentScale.z); + } + } for (int i = 0; i < submeshCount; i++) { CanvasRenderer canvasRenderer = canvasRenderers[i];