This commit is contained in:
badlogic 2021-09-07 15:38:31 +02:00
commit 486699162f
12 changed files with 51 additions and 28 deletions

View File

@ -157,6 +157,7 @@
* Timeline clips now also offer `Don't End with Clip` and `Clip End Mix Out Duration` parameters. By default when empty space follows the clip on the timeline, the empty animation is set on the track with a MixDuration of `Clip End Mix Out Duration`. Set `Don't End with Clip` to `true` to continue playing the clip's animation instead and mimic the old 3.8 behaviour. If you prefer pausing the animation instead of mixing out to the empty animation, set `Clip End Mix Out Duration` to a value less than 0, then the animation is paused instead. * Timeline clips now also offer `Don't End with Clip` and `Clip End Mix Out Duration` parameters. By default when empty space follows the clip on the timeline, the empty animation is set on the track with a MixDuration of `Clip End Mix Out Duration`. Set `Don't End with Clip` to `true` to continue playing the clip's animation instead and mimic the old 3.8 behaviour. If you prefer pausing the animation instead of mixing out to the empty animation, set `Clip End Mix Out Duration` to a value less than 0, then the animation is paused instead.
* Prefabs containing `SkeletonRenderer`, `SkeletonAnimation` and `SkeletonMecanim` now provide a proper Editor preview, including the preview thumbnail. * Prefabs containing `SkeletonRenderer`, `SkeletonAnimation` and `SkeletonMecanim` now provide a proper Editor preview, including the preview thumbnail.
* `SkeletonRenderer` (and subclasses`SkeletonAnimation` and `SkeletonMecanim`) now provide a property `Advanced - Fix Prefab Override MeshFilter`, which when enabled fixes the prefab always being marked as changed. It sets the MeshFilter's hide flags to `DontSaveInEditor`. Unfortunately this comes at the cost of references to the `MeshFilter` by other components being lost, therefore this parameter defaults to `false` to keep the safe existing behaviour. * `SkeletonRenderer` (and subclasses`SkeletonAnimation` and `SkeletonMecanim`) now provide a property `Advanced - Fix Prefab Override MeshFilter`, which when enabled fixes the prefab always being marked as changed. It sets the MeshFilter's hide flags to `DontSaveInEditor`. Unfortunately this comes at the cost of references to the `MeshFilter` by other components being lost, therefore this parameter defaults to `false` to keep the safe existing behaviour.
* `BoundingBoxFollower` and `BoundingBoxFollowerGraphic` now provide previously missing `usedByEffector` and `usedByComposite` parameters to be set at all generated colliders.
* **Changes of default values** * **Changes of default values**

View File

@ -263,8 +263,8 @@ package spine {
var rotation : Number = bone.arotation + (target.arotation + _data.offsetRotation) * mixRotate; var rotation : Number = bone.arotation + (target.arotation + _data.offsetRotation) * mixRotate;
var x : Number = bone.ax + (target.ax + _data.offsetX) * mixX; var x : Number = bone.ax + (target.ax + _data.offsetX) * mixX;
var y : Number = bone.ay + (target.ay + _data.offsetY) * mixY; var y : Number = bone.ay + (target.ay + _data.offsetY) * mixY;
var scaleX : Number = (bone.ascaleX * ((target.ascaleX - 1 + _data.offsetScaleX) * mixScaleX) + 1); var scaleX : Number = bone.ascaleX * (((target.ascaleX - 1 + _data.offsetScaleX) * mixScaleX) + 1);
var scaleY : Number = (bone.ascaleY * ((target.ascaleY - 1 + _data.offsetScaleY) * mixScaleY) + 1); var scaleY : Number = bone.ascaleY * (((target.ascaleY - 1 + _data.offsetScaleY) * mixScaleY) + 1);
var shearY : Number = bone.ashearY + (target.ashearY + _data.offsetShearY) * mixShearY; var shearY : Number = bone.ashearY + (target.ashearY + _data.offsetShearY) * mixShearY;
bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY); bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY);

View File

@ -231,8 +231,8 @@ void _spTransformConstraint_applyRelativeLocal(spTransformConstraint *self) {
rotation = bone->arotation + (target->arotation + self->data->offsetRotation) * mixRotate; rotation = bone->arotation + (target->arotation + self->data->offsetRotation) * mixRotate;
x = bone->ax + (target->ax + self->data->offsetX) * mixX; x = bone->ax + (target->ax + self->data->offsetX) * mixX;
y = bone->ay + (target->ay + self->data->offsetY) * mixY; y = bone->ay + (target->ay + self->data->offsetY) * mixY;
scaleX = (bone->ascaleX * ((target->ascaleX - 1 + self->data->offsetScaleX) * mixScaleX) + 1); scaleX = bone->ascaleX * (((target->ascaleX - 1 + self->data->offsetScaleX) * mixScaleX) + 1);
scaleY = (bone->ascaleY * ((target->ascaleY - 1 + self->data->offsetScaleY) * mixScaleY) + 1); scaleY = bone->ascaleY * (((target->ascaleY - 1 + self->data->offsetScaleY) * mixScaleY) + 1);
shearY = bone->ashearY + (target->ashearY + self->data->offsetShearY) * mixShearY; shearY = bone->ashearY + (target->ashearY + self->data->offsetShearY) * mixShearY;
spBone_updateWorldTransformWith(bone, x, y, rotation, scaleX, scaleY, bone->ashearX, shearY); spBone_updateWorldTransformWith(bone, x, y, rotation, scaleX, scaleY, bone->ashearX, shearY);

View File

@ -327,8 +327,8 @@ void TransformConstraint::applyRelativeLocal() {
float rotation = bone._arotation + (target._arotation + _data._offsetRotation) * mixRotate; float rotation = bone._arotation + (target._arotation + _data._offsetRotation) * mixRotate;
float x = bone._ax + (target._ax + _data._offsetX) * mixX; float x = bone._ax + (target._ax + _data._offsetX) * mixX;
float y = bone._ay + (target._ay + _data._offsetY) * mixY; float y = bone._ay + (target._ay + _data._offsetY) * mixY;
float scaleX = (bone._ascaleX * ((target._ascaleX - 1 + _data._offsetScaleX) * mixScaleX) + 1); float scaleX = bone._ascaleX * (((target._ascaleX - 1 + _data._offsetScaleX) * mixScaleX) + 1);
float scaleY = (bone._ascaleY * ((target._ascaleY - 1 + _data._offsetScaleY) * mixScaleY) + 1); float scaleY = bone._ascaleY * (((target._ascaleY - 1 + _data._offsetScaleY) * mixScaleY) + 1);
float shearY = bone._ashearY + (target._ashearY + _data._offsetShearY) * mixShearY; float shearY = bone._ashearY + (target._ashearY + _data._offsetShearY) * mixShearY;
bone.updateWorldTransform(x, y, rotation, scaleX, scaleY, bone._ashearX, shearY); bone.updateWorldTransform(x, y, rotation, scaleX, scaleY, bone._ashearX, shearY);

View File

@ -276,8 +276,8 @@ namespace Spine {
float rotation = bone.arotation + (target.arotation + data.offsetRotation) * mixRotate; float rotation = bone.arotation + (target.arotation + data.offsetRotation) * mixRotate;
float x = bone.ax + (target.ax + data.offsetX) * mixX; float x = bone.ax + (target.ax + data.offsetX) * mixX;
float y = bone.ay + (target.ay + data.offsetY) * mixY; float y = bone.ay + (target.ay + data.offsetY) * mixY;
float scaleX = (bone.ascaleX * ((target.ascaleX - 1 + data.offsetScaleX) * mixScaleX) + 1); float scaleX = bone.ascaleX * (((target.ascaleX - 1 + data.offsetScaleX) * mixScaleX) + 1);
float scaleY = (bone.ascaleY * ((target.ascaleY - 1 + data.offsetScaleY) * mixScaleY) + 1); float scaleY = bone.ascaleY * (((target.ascaleY - 1 + data.offsetScaleY) * mixScaleY) + 1);
float shearY = bone.ashearY + (target.ashearY + data.offsetShearY) * mixShearY; float shearY = bone.ashearY + (target.ashearY + data.offsetShearY) * mixShearY;
bone.UpdateWorldTransform(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY); bone.UpdateWorldTransform(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY);

View File

@ -278,8 +278,8 @@ public class TransformConstraint implements Updatable {
float rotation = bone.arotation + (target.arotation + data.offsetRotation) * mixRotate; float rotation = bone.arotation + (target.arotation + data.offsetRotation) * mixRotate;
float x = bone.ax + (target.ax + data.offsetX) * mixX; float x = bone.ax + (target.ax + data.offsetX) * mixX;
float y = bone.ay + (target.ay + data.offsetY) * mixY; float y = bone.ay + (target.ay + data.offsetY) * mixY;
float scaleX = (bone.ascaleX * ((target.ascaleX - 1 + data.offsetScaleX) * mixScaleX) + 1); float scaleX = bone.ascaleX * (((target.ascaleX - 1 + data.offsetScaleX) * mixScaleX) + 1);
float scaleY = (bone.ascaleY * ((target.ascaleY - 1 + data.offsetScaleY) * mixScaleY) + 1); float scaleY = bone.ascaleY * (((target.ascaleY - 1 + data.offsetScaleY) * mixScaleY) + 1);
float shearY = bone.ashearY + (target.ashearY + data.offsetShearY) * mixShearY; float shearY = bone.ashearY + (target.ashearY + data.offsetShearY) * mixShearY;
bone.updateWorldTransform(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY); bone.updateWorldTransform(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY);

View File

@ -309,8 +309,8 @@ function TransformConstraint:applyRelativeLocal ()
local rotation = bone.arotation + (target.arotation + self.data.offsetRotation) * mixRotate local rotation = bone.arotation + (target.arotation + self.data.offsetRotation) * mixRotate
local x = bone.ax + (target.ax + self.data.offsetX) * mixX local x = bone.ax + (target.ax + self.data.offsetX) * mixX
local y = bone.ay + (target.ay + self.data.offsetY) * mixY local y = bone.ay + (target.ay + self.data.offsetY) * mixY
local scaleX = (bone.ascaleX * ((target.ascaleX - 1 + self.data.offsetScaleX) * mixScaleX) + 1) local scaleX = bone.ascaleX * (((target.ascaleX - 1 + self.data.offsetScaleX) * mixScaleX) + 1)
local scaleY = (bone.ascaleY * ((target.ascaleY - 1 + self.data.offsetScaleY) * mixScaleY) + 1) local scaleY = bone.ascaleY * (((target.ascaleY - 1 + self.data.offsetScaleY) * mixScaleY) + 1)
local shearY = bone.ashearY + (target.ashearY + self.data.offsetShearY) * mixShearY local shearY = bone.ashearY + (target.ashearY + self.data.offsetShearY) * mixShearY
bone:updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY) bone:updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY)
end end

View File

@ -273,8 +273,8 @@ export class TransformConstraint implements Updatable {
let rotation = bone.arotation + (target.arotation + this.data.offsetRotation) * mixRotate; let rotation = bone.arotation + (target.arotation + this.data.offsetRotation) * mixRotate;
let x = bone.ax + (target.ax + this.data.offsetX) * mixX; let x = bone.ax + (target.ax + this.data.offsetX) * mixX;
let y = bone.ay + (target.ay + this.data.offsetY) * mixY; let y = bone.ay + (target.ay + this.data.offsetY) * mixY;
let scaleX = (bone.ascaleX * ((target.ascaleX - 1 + this.data.offsetScaleX) * mixScaleX) + 1); let scaleX = bone.ascaleX * (((target.ascaleX - 1 + this.data.offsetScaleX) * mixScaleX) + 1);
let scaleY = (bone.ascaleY * ((target.ascaleY - 1 + this.data.offsetScaleY) * mixScaleY) + 1); let scaleY = bone.ascaleY * (((target.ascaleY - 1 + this.data.offsetScaleY) * mixScaleY) + 1);
let shearY = bone.ashearY + (target.ashearY + this.data.offsetShearY) * mixShearY; let shearY = bone.ashearY + (target.ashearY + this.data.offsetShearY) * mixShearY;
bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY); bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY);

View File

@ -41,7 +41,8 @@ namespace Spine.Unity.Editor {
[CustomEditor(typeof(BoundingBoxFollowerGraphic))] [CustomEditor(typeof(BoundingBoxFollowerGraphic))]
public class BoundingBoxFollowerGraphicInspector : UnityEditor.Editor { public class BoundingBoxFollowerGraphicInspector : UnityEditor.Editor {
SerializedProperty skeletonGraphic, slotName, isTrigger, clearStateOnDisable; SerializedProperty skeletonGraphic, slotName,
isTrigger, usedByEffector, usedByComposite, clearStateOnDisable;
BoundingBoxFollowerGraphic follower; BoundingBoxFollowerGraphic follower;
bool rebuildRequired = false; bool rebuildRequired = false;
bool addBoneFollower = false; bool addBoneFollower = false;
@ -60,6 +61,8 @@ namespace Spine.Unity.Editor {
skeletonGraphic = serializedObject.FindProperty("skeletonGraphic"); skeletonGraphic = serializedObject.FindProperty("skeletonGraphic");
slotName = serializedObject.FindProperty("slotName"); slotName = serializedObject.FindProperty("slotName");
isTrigger = serializedObject.FindProperty("isTrigger"); isTrigger = serializedObject.FindProperty("isTrigger");
usedByEffector = serializedObject.FindProperty("usedByEffector");
usedByComposite = serializedObject.FindProperty("usedByComposite");
clearStateOnDisable = serializedObject.FindProperty("clearStateOnDisable"); clearStateOnDisable = serializedObject.FindProperty("clearStateOnDisable");
follower = (BoundingBoxFollowerGraphic)target; follower = (BoundingBoxFollowerGraphic)target;
} }
@ -118,18 +121,23 @@ namespace Spine.Unity.Editor {
using (new SpineInspectorUtility.LabelWidthScope(150f)) { using (new SpineInspectorUtility.LabelWidthScope(150f)) {
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(isTrigger); EditorGUILayout.PropertyField(isTrigger);
bool triggerChanged = EditorGUI.EndChangeCheck(); EditorGUILayout.PropertyField(usedByEffector);
EditorGUILayout.PropertyField(usedByComposite);
bool colliderParamChanged = EditorGUI.EndChangeCheck();
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(clearStateOnDisable, new GUIContent(clearStateOnDisable.displayName, "Enable this if you are pooling your Spine GameObject")); EditorGUILayout.PropertyField(clearStateOnDisable, new GUIContent(clearStateOnDisable.displayName, "Enable this if you are pooling your Spine GameObject"));
bool clearStateChanged = EditorGUI.EndChangeCheck(); bool clearStateChanged = EditorGUI.EndChangeCheck();
if (clearStateChanged || triggerChanged) { if (clearStateChanged || colliderParamChanged) {
serializedObject.ApplyModifiedProperties(); serializedObject.ApplyModifiedProperties();
InitializeEditor(); InitializeEditor();
if (triggerChanged) if (colliderParamChanged)
foreach (var col in follower.colliderTable.Values) foreach (var col in follower.colliderTable.Values) {
col.isTrigger = isTrigger.boolValue; col.isTrigger = isTrigger.boolValue;
col.usedByEffector = usedByEffector.boolValue;
col.usedByComposite = usedByComposite.boolValue;
}
} }
} }
@ -220,6 +228,8 @@ namespace Spine.Unity.Editor {
if (original != null) { if (original != null) {
newFollower.slotName = original.slotName; newFollower.slotName = original.slotName;
newFollower.isTrigger = original.isTrigger; newFollower.isTrigger = original.isTrigger;
newFollower.usedByEffector = original.usedByEffector;
newFollower.usedByComposite = original.usedByComposite;
newFollower.clearStateOnDisable = original.clearStateOnDisable; newFollower.clearStateOnDisable = original.clearStateOnDisable;
} }
if (slotName != null) if (slotName != null)

View File

@ -41,7 +41,8 @@ namespace Spine.Unity.Editor {
[CustomEditor(typeof(BoundingBoxFollower))] [CustomEditor(typeof(BoundingBoxFollower))]
public class BoundingBoxFollowerInspector : UnityEditor.Editor { public class BoundingBoxFollowerInspector : UnityEditor.Editor {
SerializedProperty skeletonRenderer, slotName, isTrigger, clearStateOnDisable; SerializedProperty skeletonRenderer, slotName,
isTrigger, usedByEffector, usedByComposite, clearStateOnDisable;
BoundingBoxFollower follower; BoundingBoxFollower follower;
bool rebuildRequired = false; bool rebuildRequired = false;
bool addBoneFollower = false; bool addBoneFollower = false;
@ -60,6 +61,8 @@ namespace Spine.Unity.Editor {
skeletonRenderer = serializedObject.FindProperty("skeletonRenderer"); skeletonRenderer = serializedObject.FindProperty("skeletonRenderer");
slotName = serializedObject.FindProperty("slotName"); slotName = serializedObject.FindProperty("slotName");
isTrigger = serializedObject.FindProperty("isTrigger"); isTrigger = serializedObject.FindProperty("isTrigger");
usedByEffector = serializedObject.FindProperty("usedByEffector");
usedByComposite = serializedObject.FindProperty("usedByComposite");
clearStateOnDisable = serializedObject.FindProperty("clearStateOnDisable"); clearStateOnDisable = serializedObject.FindProperty("clearStateOnDisable");
follower = (BoundingBoxFollower)target; follower = (BoundingBoxFollower)target;
} }
@ -118,18 +121,23 @@ namespace Spine.Unity.Editor {
using (new SpineInspectorUtility.LabelWidthScope(150f)) { using (new SpineInspectorUtility.LabelWidthScope(150f)) {
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(isTrigger); EditorGUILayout.PropertyField(isTrigger);
bool triggerChanged = EditorGUI.EndChangeCheck(); EditorGUILayout.PropertyField(usedByEffector);
EditorGUILayout.PropertyField(usedByComposite);
bool colliderParamChanged = EditorGUI.EndChangeCheck();
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(clearStateOnDisable, new GUIContent(clearStateOnDisable.displayName, "Enable this if you are pooling your Spine GameObject")); EditorGUILayout.PropertyField(clearStateOnDisable, new GUIContent(clearStateOnDisable.displayName, "Enable this if you are pooling your Spine GameObject"));
bool clearStateChanged = EditorGUI.EndChangeCheck(); bool clearStateChanged = EditorGUI.EndChangeCheck();
if (clearStateChanged || triggerChanged) { if (clearStateChanged || colliderParamChanged) {
serializedObject.ApplyModifiedProperties(); serializedObject.ApplyModifiedProperties();
InitializeEditor(); InitializeEditor();
if (triggerChanged) if (colliderParamChanged)
foreach (var col in follower.colliderTable.Values) foreach (var col in follower.colliderTable.Values) {
col.isTrigger = isTrigger.boolValue; col.isTrigger = isTrigger.boolValue;
col.usedByEffector = usedByEffector.boolValue;
col.usedByComposite = usedByComposite.boolValue;
}
} }
} }
@ -219,6 +227,8 @@ namespace Spine.Unity.Editor {
if (original != null) { if (original != null) {
newFollower.slotName = original.slotName; newFollower.slotName = original.slotName;
newFollower.isTrigger = original.isTrigger; newFollower.isTrigger = original.isTrigger;
newFollower.usedByEffector = original.usedByEffector;
newFollower.usedByComposite = original.usedByComposite;
newFollower.clearStateOnDisable = original.clearStateOnDisable; newFollower.clearStateOnDisable = original.clearStateOnDisable;
} }
if (slotName != null) if (slotName != null)

View File

@ -49,7 +49,7 @@ namespace Spine.Unity {
public SkeletonRenderer skeletonRenderer; public SkeletonRenderer skeletonRenderer;
[SpineSlot(dataField: "skeletonRenderer", containsBoundingBoxes: true)] [SpineSlot(dataField: "skeletonRenderer", containsBoundingBoxes: true)]
public string slotName; public string slotName;
public bool isTrigger; public bool isTrigger, usedByEffector, usedByComposite;
public bool clearStateOnDisable = true; public bool clearStateOnDisable = true;
#endregion #endregion
@ -167,9 +167,10 @@ namespace Spine.Unity {
++collidersCount; ++collidersCount;
SkeletonUtility.SetColliderPointsLocal(bbCollider, slot, boundingBoxAttachment); SkeletonUtility.SetColliderPointsLocal(bbCollider, slot, boundingBoxAttachment);
bbCollider.isTrigger = isTrigger; bbCollider.isTrigger = isTrigger;
bbCollider.usedByEffector = usedByEffector;
bbCollider.usedByComposite = usedByComposite;
bbCollider.enabled = false; bbCollider.enabled = false;
bbCollider.hideFlags = HideFlags.NotEditable; bbCollider.hideFlags = HideFlags.NotEditable;
bbCollider.isTrigger = IsTrigger;
colliderTable.Add(boundingBoxAttachment, bbCollider); colliderTable.Add(boundingBoxAttachment, bbCollider);
nameTable.Add(boundingBoxAttachment, entry.Name); nameTable.Add(boundingBoxAttachment, entry.Name);
} }

View File

@ -49,7 +49,7 @@ namespace Spine.Unity {
public SkeletonGraphic skeletonGraphic; public SkeletonGraphic skeletonGraphic;
[SpineSlot(dataField: "skeletonGraphic", containsBoundingBoxes: true)] [SpineSlot(dataField: "skeletonGraphic", containsBoundingBoxes: true)]
public string slotName; public string slotName;
public bool isTrigger; public bool isTrigger, usedByEffector, usedByComposite;
public bool clearStateOnDisable = true; public bool clearStateOnDisable = true;
#endregion #endregion
@ -171,9 +171,10 @@ namespace Spine.Unity {
++collidersCount; ++collidersCount;
SkeletonUtility.SetColliderPointsLocal(bbCollider, slot, boundingBoxAttachment, scale); SkeletonUtility.SetColliderPointsLocal(bbCollider, slot, boundingBoxAttachment, scale);
bbCollider.isTrigger = isTrigger; bbCollider.isTrigger = isTrigger;
bbCollider.usedByEffector = usedByEffector;
bbCollider.usedByComposite = usedByComposite;
bbCollider.enabled = false; bbCollider.enabled = false;
bbCollider.hideFlags = HideFlags.NotEditable; bbCollider.hideFlags = HideFlags.NotEditable;
bbCollider.isTrigger = IsTrigger;
colliderTable.Add(boundingBoxAttachment, bbCollider); colliderTable.Add(boundingBoxAttachment, bbCollider);
nameTable.Add(boundingBoxAttachment, entry.Name); nameTable.Add(boundingBoxAttachment, entry.Name);
} }