[unity] PhysicsConstraints: Changed boolean ApplyTranslation/RotationToPhysics properties to float and Vector2 scale properties for more flexibility. See commit 9602a71.

This commit is contained in:
Harald Csaszar 2024-02-14 17:23:27 +01:00
parent c64096ccad
commit 506c2dd33a
5 changed files with 117 additions and 65 deletions

View File

@ -53,14 +53,15 @@
* Added `Animation Update` mode (called `UpdateTiming` in code) `In Late Update` for `SkeletonAnimation`, `SkeletonMecanim` and `SkeletonGraphic`. This allows you to update the `SkeletonMecanim` skeleton in the same frame that the Mecanim Animator updated its state, which happens between `Update` and `LateUpdate`.
* URP Shaders: Added URP "Blend Mode" shader variants for both URP 3D and URP 2D renderers. They are listed under shader name "Universal Render Pipeline/Spine/Blend Modes/" and "Universal Render Pipeline/2D/Spine/Blend Modes/" respectively.
* URP Shaders: Added support for [Tint Black](http://en.esotericsoftware.com/spine-slots#Tint-black) functionality at "Blend Modes" Spine URP shaders (2D and 3D shaders).
* PhysicsConstraints: Skeleton GameObjects now automatically apply Transform translation and rotation to the skeleton's `PhysicsConstraints`. You can disable applying translation or rotation at the Skeleton component Inspector under `Advanced - Physics Constraints` `Transform Translation` and `Transform Rotation`, or by setting the properties `applyTranslationToPhysics` and `applyRotationToPhysics` at the skeleton component via code.
* PhysicsConstraints: Skeleton GameObjects now automatically apply Transform translation and rotation to the skeleton's `PhysicsConstraints`. You can disable applying translation or rotation at the Skeleton component Inspector under `Advanced - Physics Inheritance` by setting `Position` to (0,0)and `Rotation` to 0, or by setting the properties `physicsPositionInheritanceFactor` to `Vector2.zero` and `physicsRotationInheritanceFactor` to `0` at the skeleton component via code.
* Added `Physics Constraints` example scene (located in `Spine Examples/Other Examples`) together with `celestial-circus` example skeleton assets. This scene demonstrates Transform movement automatically affecting physics constraints of a skeleton.
* PhysicsConstraints: Skeleton components now allow you to use relative instead of world-space Transform movement (with `applyTranslationToPhysics` and `applyRotationToPhysics`) by assigning a Transform (typically the parent) to the new `Movement relative to` property. Leave this property at `null` (the default) to use world-space Transform movement for physics.
* PhysicsConstraints: Skeleton components now allow you to use relative instead of world-space Transform movement by assigning a Transform (typically the parent) to the new `Movement relative to` property. Leave this property at `null` (the default) to use world-space Transform movement for physics.
* **Breaking changes**
* Changed `SpineShaderWithOutlineGUI` outline related methods from `private` to `protected virtual` to allow for custom shader GUI subclasses to switch to different outline shaders.
* Changed `BoneFollower` and `BoneFollowerGraphic` methods `LateUpdate` and `Initialize` to `virtual` to allow easier overriding for e.g. positional offset in custom subclasses.
* `MeshGenerator` received a new optimization option to avoid rendering fully transparent attachments at slot alpha 0 by default. Comment out `#define SLOT_ALPHA_DISABLES_ATTACHMENT` in `MeshGenerator.cs` to revert to previous behaviour. You may only need this option disabled when utilizing a custom shader which uses vertex color alpha for purposes other than transparency.
* PhysicsConstraints: bool properties `ApplyTranslationToPhysics` and `ApplyRotationToPhysics` were changed to `Vector2 PhysicsPositionInheritanceFactor` and `float PhysicsRotationInheritanceFactor` to allow the Transform movement the be scaled by a factor before being applied to the skeleton. You can set the properties to `Vector2.zero` and `0` respectively to disable applying any Transform movement at all. The `Advanced` Inspector section `Physics Constraints` was renamed to `Physics Inheritance`, the properties in the section are now called `Position` and `Rotation`.
* **Changes of default values**

View File

@ -62,7 +62,7 @@ namespace Spine.Unity.Editor {
SerializedProperty skeletonDataAsset, initialSkinName;
SerializedProperty startingAnimation, startingLoop, timeScale, freeze,
updateTiming, updateWhenInvisible, unscaledTime, tintBlack, layoutScaleMode, editReferenceRect;
SerializedProperty applyTranslationToPhysics, applyRotationToPhysics, physicsMovementRelativeTo;
SerializedProperty physicsPositionInheritanceFactor, physicsRotationInheritanceFactor, physicsMovementRelativeTo;
SerializedProperty initialFlipX, initialFlipY;
SerializedProperty meshGeneratorSettings;
SerializedProperty allowMultipleCanvasRenderers, separatorSlotNames, enableSeparatorSlots,
@ -73,10 +73,20 @@ namespace Spine.Unity.Editor {
"If enabled, AnimationState uses unscaled game time (Time.unscaledDeltaTime), " +
"running animations independent of e.g. game pause (Time.timeScale). " +
"Instance SkeletonAnimation.timeScale will still be applied.");
readonly GUIContent ApplyTranslationToPhysicsLabel = new GUIContent("Transform Translation",
"When enabled, the GameObject Transform translation movement is applied to PhysicsConstraints of the skeleton.");
readonly GUIContent ApplyRotationToPhysicsLabel = new GUIContent("Transform Rotation",
"When enabled, the GameObject Transform rotation movement is applied to PhysicsConstraints of the skeleton.");
readonly GUIContent PhysicsPositionInheritanceFactorLabel = new GUIContent("Position",
"When set to non-zero, Transform position movement in X and Y direction is applied to skeleton " +
"PhysicsConstraints, multiplied by these " +
"\nX and Y scale factors to the right. Typical values are " +
"\n(1,1) to apply XY movement normally, " +
"\n(2,2) to apply movement with double intensity, " +
"\n(1,0) to apply only horizontal movement, or" +
"\n(0,0) to not apply any Transform position movement at all.");
readonly GUIContent PhysicsRotationInheritanceFactorLabel = new GUIContent("Rotation",
"When set to non-zero, Transform rotation movement is applied to skeleton PhysicsConstraints, " +
"multiplied by this scale factor to the right. Typical values are " +
"\n1 to apply movement normally, " +
"\n2 to apply movement with double intensity, or " +
"\n0 to not apply any Transform rotation movement at all.");
readonly GUIContent PhysicsMovementRelativeToLabel = new GUIContent("Movement relative to",
"Reference transform relative to which physics movement will be calculated, or null to use world location.");
@ -143,8 +153,8 @@ namespace Spine.Unity.Editor {
updateWhenInvisible = so.FindProperty("updateWhenInvisible");
layoutScaleMode = so.FindProperty("layoutScaleMode");
editReferenceRect = so.FindProperty("editReferenceRect");
applyTranslationToPhysics = so.FindProperty("applyTranslationToPhysics");
applyRotationToPhysics = so.FindProperty("applyRotationToPhysics");
physicsPositionInheritanceFactor = so.FindProperty("physicsPositionInheritanceFactor");
physicsRotationInheritanceFactor = so.FindProperty("physicsRotationInheritanceFactor");
physicsMovementRelativeTo = so.FindProperty("physicsMovementRelativeTo");
meshGeneratorSettings = so.FindProperty("meshGenerator").FindPropertyRelative("settings");
@ -320,9 +330,16 @@ namespace Spine.Unity.Editor {
EditorGUILayout.Space();
using (new SpineInspectorUtility.LabelWidthScope()) {
EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Physics Constraints", SpineEditorUtilities.Icons.constraintPhysics), EditorStyles.boldLabel);
EditorGUILayout.PropertyField(applyTranslationToPhysics, ApplyTranslationToPhysicsLabel);
EditorGUILayout.PropertyField(applyRotationToPhysics, ApplyRotationToPhysicsLabel);
EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Physics Inheritance", SpineEditorUtilities.Icons.constraintPhysics), EditorStyles.boldLabel);
using (new GUILayout.HorizontalScope()) {
EditorGUILayout.LabelField(PhysicsPositionInheritanceFactorLabel, GUILayout.Width(EditorGUIUtility.labelWidth));
int savedIndentLevel = EditorGUI.indentLevel;
EditorGUI.indentLevel = 0;
EditorGUILayout.PropertyField(physicsPositionInheritanceFactor, GUIContent.none, GUILayout.MinWidth(60));
EditorGUI.indentLevel = savedIndentLevel;
}
EditorGUILayout.PropertyField(physicsRotationInheritanceFactor, PhysicsRotationInheritanceFactorLabel);
EditorGUILayout.PropertyField(physicsMovementRelativeTo, PhysicsMovementRelativeToLabel);
}
}

View File

@ -68,7 +68,7 @@ namespace Spine.Unity.Editor {
protected SerializedProperty normals, tangents, zSpacing, pmaVertexColors, tintBlack; // MeshGenerator settings
protected SerializedProperty maskInteraction;
protected SerializedProperty maskMaterialsNone, maskMaterialsInside, maskMaterialsOutside;
protected SerializedProperty applyTranslationToPhysics, applyRotationToPhysics, physicsMovementRelativeTo;
protected SerializedProperty physicsPositionInheritanceFactor, physicsRotationInheritanceFactor, physicsMovementRelativeTo;
protected SpineInspectorUtility.SerializedSortingProperties sortingProperties;
protected bool wasInitParameterChanged = false;
protected bool requireRepaint = false;
@ -88,10 +88,20 @@ namespace Spine.Unity.Editor {
protected GUIContent MaskMaterialsHeadingLabel, MaskMaterialsNoneLabel, MaskMaterialsInsideLabel, MaskMaterialsOutsideLabel;
protected GUIContent SetMaterialButtonLabel, ClearMaterialButtonLabel, DeleteMaterialButtonLabel;
readonly GUIContent ApplyTranslationToPhysicsLabel = new GUIContent("Transform Translation",
"When enabled, the GameObject Transform translation movement is applied to PhysicsConstraints of the skeleton.");
readonly GUIContent ApplyRotationToPhysicsLabel = new GUIContent("Transform Rotation",
"When enabled, the GameObject Transform rotation movement is applied to PhysicsConstraints of the skeleton.");
readonly GUIContent PhysicsPositionInheritanceFactorLabel = new GUIContent("Position",
"When set to non-zero, Transform position movement in X and Y direction is applied to skeleton " +
"PhysicsConstraints, multiplied by these " +
"\nX and Y scale factors to the right. Typical values are " +
"\n(1,1) to apply XY movement normally, " +
"\n(2,2) to apply movement with double intensity, " +
"\n(1,0) to apply only horizontal movement, or" +
"\n(0,0) to not apply any Transform position movement at all.");
readonly GUIContent PhysicsRotationInheritanceFactorLabel = new GUIContent("Rotation",
"When set to non-zero, Transform rotation movement is applied to skeleton PhysicsConstraints, " +
"multiplied by this scale factor to the right. Typical values are " +
"\n1 to apply movement normally, " +
"\n2 to apply movement with double intensity, or " +
"\n0 to not apply any Transform rotation movement at all.");
readonly GUIContent PhysicsMovementRelativeToLabel = new GUIContent("Movement relative to",
"Reference transform relative to which physics movement will be calculated, or null to use world location.");
@ -169,8 +179,8 @@ namespace Spine.Unity.Editor {
maskMaterialsNone = so.FindProperty("maskMaterials.materialsMaskDisabled");
maskMaterialsInside = so.FindProperty("maskMaterials.materialsInsideMask");
maskMaterialsOutside = so.FindProperty("maskMaterials.materialsOutsideMask");
applyTranslationToPhysics = so.FindProperty("applyTranslationToPhysics");
applyRotationToPhysics = so.FindProperty("applyRotationToPhysics");
physicsPositionInheritanceFactor = so.FindProperty("physicsPositionInheritanceFactor");
physicsRotationInheritanceFactor = so.FindProperty("physicsRotationInheritanceFactor");
physicsMovementRelativeTo = so.FindProperty("physicsMovementRelativeTo");
separatorSlotNames = so.FindProperty("separatorSlotNames");
@ -418,9 +428,16 @@ namespace Spine.Unity.Editor {
}
#endif
using (new SpineInspectorUtility.LabelWidthScope()) {
EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Physics Constraints", SpineEditorUtilities.Icons.constraintPhysics), EditorStyles.boldLabel);
EditorGUILayout.PropertyField(applyTranslationToPhysics, ApplyTranslationToPhysicsLabel);
EditorGUILayout.PropertyField(applyRotationToPhysics, ApplyRotationToPhysicsLabel);
EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Physics Inheritance", SpineEditorUtilities.Icons.constraintPhysics), EditorStyles.boldLabel);
using (new GUILayout.HorizontalScope()) {
EditorGUILayout.LabelField(PhysicsPositionInheritanceFactorLabel, GUILayout.Width(EditorGUIUtility.labelWidth));
int savedIndentLevel = EditorGUI.indentLevel;
EditorGUI.indentLevel = 0;
EditorGUILayout.PropertyField(physicsPositionInheritanceFactor, GUIContent.none, GUILayout.MinWidth(60));
EditorGUI.indentLevel = savedIndentLevel;
}
EditorGUILayout.PropertyField(physicsRotationInheritanceFactor, PhysicsRotationInheritanceFactorLabel);
EditorGUILayout.PropertyField(physicsMovementRelativeTo, PhysicsMovementRelativeToLabel);
}

View File

@ -391,21 +391,22 @@ namespace Spine.Unity {
public virtual void ApplyTransformMovementToPhysics () {
if (Application.isPlaying) {
if (applyTranslationToPhysics) {
if (physicsPositionInheritanceFactor != Vector2.zero) {
Vector2 position = GetPhysicsTransformPosition();
Vector2 positionDelta = (position - lastPosition) / meshScale;
if (physicsMovementRelativeTo != null) {
positionDelta.x *= physicsMovementRelativeTo.lossyScale.x;
positionDelta.y *= physicsMovementRelativeTo.lossyScale.y;
}
positionDelta.x /= transform.lossyScale.x;
positionDelta.y /= transform.lossyScale.y;
positionDelta.x *= physicsPositionInheritanceFactor.x / transform.lossyScale.x;
positionDelta.y *= physicsPositionInheritanceFactor.y / transform.lossyScale.y;
skeleton.PhysicsTranslate(positionDelta.x, positionDelta.y);
lastPosition = position;
}
if (applyRotationToPhysics) {
if (physicsRotationInheritanceFactor != 0f) {
float rotation = GetPhysicsTransformRotation();
skeleton.PhysicsRotate(0, 0, rotation - lastRotation);
skeleton.PhysicsRotate(0, 0, physicsRotationInheritanceFactor * (rotation - lastRotation));
lastRotation = rotation;
}
}
@ -567,10 +568,10 @@ namespace Spine.Unity {
}
}
/// <summary>When enabled, Transform translation is applied to skeleton PhysicsConstraints.</summary>
[SerializeField] protected bool applyTranslationToPhysics = true;
/// <summary>When enabled, Transform rotation is applied to skeleton PhysicsConstraints.</summary>
[SerializeField] protected bool applyRotationToPhysics = true;
/// <seealso cref="PhysicsPositionInheritanceFactor"/>
[SerializeField] protected Vector2 physicsPositionInheritanceFactor = Vector2.one;
/// <seealso cref="PhysicsRotationInheritanceFactor"/>
[SerializeField] protected float physicsRotationInheritanceFactor = 1.0f;
/// <summary>Reference transform relative to which physics movement will be calculated, or null to use world location.</summary>
[SerializeField] protected Transform physicsMovementRelativeTo = null;
@ -579,25 +580,33 @@ namespace Spine.Unity {
/// <summary>Used for applying Transform rotation to skeleton PhysicsConstraints.</summary>
protected float lastRotation;
/// <summary>When enabled, Transform translation is applied to skeleton PhysicsConstraints.</summary>
public bool ApplyTranslationToPhysics {
/// <summary>When set to non-zero, Transform position movement in X and Y direction
/// is applied to skeleton PhysicsConstraints, multiplied by this scale factor.
/// Typical values are <c>Vector2.one</c> to apply XY movement 1:1,
/// <c>Vector2(2f, 2f)</c> to apply movement with double intensity,
/// <c>Vector2(1f, 0f)</c> to apply only horizontal movement, or
/// <c>Vector2.zero</c> to not apply any Transform position movement at all.</summary>
public Vector2 PhysicsPositionInheritanceFactor {
get {
return applyTranslationToPhysics;
return physicsPositionInheritanceFactor;
}
set {
if (value && !applyTranslationToPhysics) ResetLastPosition();
applyTranslationToPhysics = value;
if (physicsPositionInheritanceFactor == Vector2.zero && value != Vector2.zero) ResetLastPosition();
physicsPositionInheritanceFactor = value;
}
}
/// <summary>When enabled, Transform rotation is applied to skeleton PhysicsConstraints.</summary>
public bool ApplyRotationToPhysics {
/// <summary>When set to non-zero, Transform rotation movement is applied to skeleton PhysicsConstraints,
/// multiplied by this scale factor. Typical values are <c>1</c> to apply movement 1:1,
/// <c>2</c> to apply movement with double intensity, or
/// <c>0</c> to not apply any Transform rotation movement at all.</summary>
public float PhysicsRotationInheritanceFactor {
get {
return applyRotationToPhysics;
return physicsRotationInheritanceFactor;
}
set {
if (value && !applyRotationToPhysics) ResetLastRotation();
applyRotationToPhysics = value;
if (physicsRotationInheritanceFactor == 0f && value != 0f) ResetLastRotation();
physicsRotationInheritanceFactor = value;
}
}
@ -608,8 +617,8 @@ namespace Spine.Unity {
}
set {
physicsMovementRelativeTo = value;
if (applyTranslationToPhysics) ResetLastPosition();
if (applyRotationToPhysics) ResetLastRotation();
if (physicsPositionInheritanceFactor != Vector2.zero) ResetLastPosition();
if (physicsRotationInheritanceFactor != 0f) ResetLastRotation();
}
}

View File

@ -289,10 +289,10 @@ namespace Spine.Unity {
#endregion
#region Physics
/// <summary>When enabled, Transform translation is applied to skeleton PhysicsConstraints.</summary>
[SerializeField] protected bool applyTranslationToPhysics = true;
/// <summary>When enabled, Transform rotation is applied to skeleton PhysicsConstraints.</summary>
[SerializeField] protected bool applyRotationToPhysics = true;
/// <seealso cref="PhysicsPositionInheritanceFactor"/>
[SerializeField] protected Vector2 physicsPositionInheritanceFactor = Vector2.one;
/// <seealso cref="PhysicsRotationInheritanceFactor"/>
[SerializeField] protected float physicsRotationInheritanceFactor = 1.0f;
/// <summary>Reference transform relative to which physics movement will be calculated, or null to use world location.</summary>
[SerializeField] protected Transform physicsMovementRelativeTo = null;
@ -301,25 +301,33 @@ namespace Spine.Unity {
/// <summary>Used for applying Transform rotation to skeleton PhysicsConstraints.</summary>
protected float lastRotation;
/// <summary>When enabled, Transform translation is applied to skeleton PhysicsConstraints.</summary>
public bool ApplyTranslationToPhysics {
/// <summary>When set to non-zero, Transform position movement in X and Y direction
/// is applied to skeleton PhysicsConstraints, multiplied by this scale factor.
/// Typical values are <c>Vector2.one</c> to apply XY movement 1:1,
/// <c>Vector2(2f, 2f)</c> to apply movement with double intensity,
/// <c>Vector2(1f, 0f)</c> to apply only horizontal movement, or
/// <c>Vector2.zero</c> to not apply any Transform position movement at all.</summary>
public Vector2 PhysicsPositionInheritanceFactor {
get {
return applyTranslationToPhysics;
return physicsPositionInheritanceFactor;
}
set {
if (value && !applyTranslationToPhysics) ResetLastPosition();
applyTranslationToPhysics = value;
if (physicsPositionInheritanceFactor == Vector2.zero && value != Vector2.zero) ResetLastPosition();
physicsPositionInheritanceFactor = value;
}
}
/// <summary>When enabled, Transform rotation is applied to skeleton PhysicsConstraints.</summary>
public bool ApplyRotationToPhysics {
/// <summary>When set to non-zero, Transform rotation movement is applied to skeleton PhysicsConstraints,
/// multiplied by this scale factor. Typical values are <c>1</c> to apply movement 1:1,
/// <c>2</c> to apply movement with double intensity, or
/// <c>0</c> to not apply any Transform rotation movement at all.</summary>
public float PhysicsRotationInheritanceFactor {
get {
return applyRotationToPhysics;
return physicsRotationInheritanceFactor;
}
set {
if (value && !applyRotationToPhysics) ResetLastRotation();
applyRotationToPhysics = value;
if (physicsRotationInheritanceFactor == 0f && value != 0f) ResetLastRotation();
physicsRotationInheritanceFactor = value;
}
}
@ -330,8 +338,8 @@ namespace Spine.Unity {
}
set {
physicsMovementRelativeTo = value;
if (applyTranslationToPhysics) ResetLastPosition();
if (applyRotationToPhysics) ResetLastRotation();
if (physicsPositionInheritanceFactor != Vector2.zero) ResetLastPosition();
if (physicsRotationInheritanceFactor != 0f) ResetLastRotation();
}
}
@ -504,21 +512,21 @@ namespace Spine.Unity {
public virtual void ApplyTransformMovementToPhysics () {
if (Application.isPlaying) {
if (applyTranslationToPhysics) {
if (physicsPositionInheritanceFactor != Vector2.zero) {
Vector2 position = GetPhysicsTransformPosition();
Vector2 positionDelta = position - lastPosition;
if (physicsMovementRelativeTo != null) {
positionDelta.x *= physicsMovementRelativeTo.lossyScale.x;
positionDelta.y *= physicsMovementRelativeTo.lossyScale.y;
}
positionDelta.x /= transform.lossyScale.x;
positionDelta.y /= transform.lossyScale.y;
positionDelta.x *= physicsPositionInheritanceFactor.x / transform.lossyScale.x;
positionDelta.y *= physicsPositionInheritanceFactor.y / transform.lossyScale.y;
skeleton.PhysicsTranslate(positionDelta.x, positionDelta.y);
lastPosition = position;
}
if (applyRotationToPhysics) {
if (physicsRotationInheritanceFactor != 0f) {
float rotation = GetPhysicsTransformRotation();
skeleton.PhysicsRotate(0, 0, rotation - lastRotation);
skeleton.PhysicsRotate(0, 0, physicsRotationInheritanceFactor * (rotation - lastRotation));
lastRotation = rotation;
}
}