diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ca2ad615..55ba29640 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -232,6 +232,7 @@ * Added support for **Render Separator Slots** at `SkeletonGraphic`. Render separation can be enabled directly in the `Advanced` section of the `SkeletonGraphic` Inspector, it does not require any additional components (like `SkeletonRenderSeparator` or `SkeletonPartsRenderer` for `SkeletonRenderer` components). When enabled, additional separator GameObjects will be created automatically for each separation part, and `CanvasRenderer` GameObjects re-parented to them accordingly. The separator GameObjects can be moved around and re-parented in the hierarchy according to your requirements to achieve the desired draw order within your `Canvas`. A usage example can be found in the updated `Spine Examples/Other Examples/SkeletonRenderSeparator` scene. * Added `SkeletonGraphicCustomMaterials` component, providing functionality to override materials and textures of a `SkeletonGraphic`, similar to `SkeletonRendererCustomMaterials`. Note: overriding materials or textures per slot is not provided due to structural limitations. * Added **Root Motion support** for `SkeletonAnimation`, `SkeletonMecanim` and `SkeletonGraphic` via new components `SkeletonRootMotion` and `SkeletonMecanimRootMotion`. The `SkeletonAnimation` and `SkeletonGraphic` component Inspector now provides a line `Root Motion` with `Add Component` and `Remove Component` buttons to add/remove the new `SkeletonRootMotion` component to your GameObject. The `SkeletonMecanim` Inspector detects whether root motion is enabled at the `Animator` component and adds a `SkeletonMecanimRootMotion` component automatically. + * `SkeletonMecanim` now provides an additional `Custom MixMode` parameter under `Mecanim Translator`. It is enabled by default in version 3.8 to maintain current behaviour, using the set `Mix Mode` for each Mecanim layer. When disabled, `SkeletonMecanim` will use the recommended `MixMode` according to the layer blend mode. Additional information can be found in the [Mecanim Translator section](http://esotericsoftware.com/spine-unity#Parameters-for-animation-blending-control) on the spine-unity documentation pages. * **Changes of default values** * `SkeletonMecanim`'s `Layer Mix Mode` now defaults to `MixMode.MixNext` instead of `MixMode.MixAlways`. diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonMecanimInspector.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonMecanimInspector.cs index 9f75dee10..65929f084 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonMecanimInspector.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonMecanimInspector.cs @@ -39,6 +39,7 @@ namespace Spine.Unity.Editor { public static bool mecanimSettingsFoldout; protected SerializedProperty autoReset; + protected SerializedProperty useCustomMixMode; protected SerializedProperty layerMixModes; protected SerializedProperty layerBlendModes; @@ -46,6 +47,7 @@ namespace Spine.Unity.Editor { base.OnEnable(); SerializedProperty mecanimTranslator = serializedObject.FindProperty("translator"); autoReset = mecanimTranslator.FindPropertyRelative("autoReset"); + useCustomMixMode = mecanimTranslator.FindPropertyRelative("useCustomMixMode"); layerMixModes = mecanimTranslator.FindPropertyRelative("layerMixModes"); layerBlendModes = mecanimTranslator.FindPropertyRelative("layerBlendModes"); } @@ -64,9 +66,13 @@ namespace Spine.Unity.Editor { "pose when an animation finishes, according to the " + "animation's keyed items.")); - EditorGUILayout.Space(); - DrawLayerSettings(); - EditorGUILayout.Space(); + EditorGUILayout.PropertyField(useCustomMixMode, new GUIContent("Custom MixMode", + "When disabled, the recommended MixMode is used according to the layer blend mode. Enable to specify a custom MixMode for each Mecanim layer.")); + + if (useCustomMixMode.hasMultipleDifferentValues || useCustomMixMode.boolValue == true) { + DrawLayerSettings(); + EditorGUILayout.Space(); + } } } } diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonRendererInspector.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonRendererInspector.cs index 8942660dd..62f50ed22 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonRendererInspector.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonRendererInspector.cs @@ -172,11 +172,8 @@ namespace Spine.Unity.Editor { if (serializedObject.ApplyModifiedProperties() || SpineInspectorUtility.UndoRedoPerformed(Event.current) || AreAnyMaskMaterialsMissing()) { if (!Application.isPlaying) { - if (multi) { - foreach (var o in targets) SpineEditorUtilities.ReinitializeComponent((SkeletonRenderer)o); - } else { - SpineEditorUtilities.ReinitializeComponent((SkeletonRenderer)target); - } + foreach (var o in targets) + SpineEditorUtilities.ReinitializeComponent((SkeletonRenderer)o); SceneView.RepaintAll(); } } diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonMecanim.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonMecanim.cs index a15d93e30..d85390b18 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonMecanim.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonMecanim.cs @@ -125,6 +125,7 @@ namespace Spine.Unity { public class MecanimTranslator { #region Inspector public bool autoReset = true; + public bool useCustomMixMode = true; public MixMode[] layerMixModes = new MixMode[0]; public MixBlend[] layerBlendModes = new MixBlend[0]; #endregion @@ -351,14 +352,7 @@ namespace Spine.Unity { out clipInfo, out nextClipInfo, out interruptingClipInfo, out interpolateWeightTo1); MixBlend layerBlendMode = (layer < layerBlendModes.Length) ? layerBlendModes[layer] : MixBlend.Replace; - MixMode mode = layerMixModes[layer]; - // Note: at additive blending it makes no sense to use constant weight 1 at a fadeout anim add1 as - // with override layers, so we use AlwaysMix instead to use the proper weights. - // AlwaysMix leads to the expected result = lower_layer + lerp(add1, add2, transition_weight). - if (layerBlendMode == MixBlend.Add && mode == MixMode.MixNext) { - mode = MixMode.AlwaysMix; - layerMixModes[layer] = mode; - } + MixMode mode = GetMixMode(layer, layerBlendMode); if (mode == MixMode.AlwaysMix) { // Always use Mix instead of Applying the first non-zero weighted clip. for (int c = 0; c < clipInfoCount; c++) { @@ -469,7 +463,24 @@ namespace Spine.Unity { } } - #if UNITY_EDITOR + private MixMode GetMixMode (int layer, MixBlend layerBlendMode) { + if (useCustomMixMode) { + MixMode mode = layerMixModes[layer]; + // Note: at additive blending it makes no sense to use constant weight 1 at a fadeout anim add1 as + // with override layers, so we use AlwaysMix instead to use the proper weights. + // AlwaysMix leads to the expected result = lower_layer + lerp(add1, add2, transition_weight). + if (layerBlendMode == MixBlend.Add && mode == MixMode.MixNext) { + mode = MixMode.AlwaysMix; + layerMixModes[layer] = mode; + } + return mode; + } + else { + return layerBlendMode == MixBlend.Add ? MixMode.AlwaysMix : MixMode.MixNext; + } + } + +#if UNITY_EDITOR void GetLayerBlendModes() { if (layerBlendModes.Length < animator.layerCount) { System.Array.Resize(ref layerBlendModes, animator.layerCount);