mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-04 14:24:53 +08:00
[unity] SkeletonRootMotion components now support arbitrary bones in the hierarchy as Root Motion Bone. Now supporting arbitrary Skeleton.ScaleX/Y and parent bone scale. Closes #1876.
This commit is contained in:
parent
6c40624d5e
commit
758a83ac96
@ -163,6 +163,7 @@
|
||||
b) to an arbitrary directory outside the Assets directory and then open Package Manager in Unity, select the `+` icon, choose `Add package from disk..` and point it to the package.json file.
|
||||
The Project panel should now show an entry `Spine Timeline Extensions` under `Packages`. If the directory is not yet listed, you will need to close and re-open Unity to have it display the directory and its contents.
|
||||
* `SkeletonMecanim`'s `Layer Mix Mode` enum name `MixMode.SpineStyle` has been renamed to `MixMode.Hard`. This is most likely not set via code and thus unlikely to be a problem. Serialized scenes and prefabs are unaffected.
|
||||
* `SkeletonRootMotion` and `SkeletonMecanimRootMotion` components now support arbitrary bones in the hierarchy as `Root Motion Bone`. Previously there were problems when selecting a non-root bone as `Root Motion Bone`. `Skeleton.ScaleX` and `.ScaleY` and parent bone scale is now respected as well.
|
||||
|
||||
* **Additions**
|
||||
* **Spine Preferences stored in Assets/Editor/SpineSettings.asset** Now Spine uses the new `SettingsProvider` API, storing settings in a SpineSettings.asset file which can be shared with team members. Your old preferences are automatically migrated to the new system.
|
||||
|
||||
@ -61,6 +61,7 @@ namespace Spine.Unity {
|
||||
protected Bone rootMotionBone;
|
||||
protected int rootMotionBoneIndex;
|
||||
protected List<Bone> topLevelBones = new List<Bone>();
|
||||
protected Vector2 initialOffset = Vector2.zero;
|
||||
protected Vector2 rigidbodyDisplacement;
|
||||
|
||||
protected virtual void Reset () {
|
||||
@ -71,10 +72,14 @@ namespace Spine.Unity {
|
||||
skeletonComponent = GetComponent<ISkeletonComponent>();
|
||||
GatherTopLevelBones();
|
||||
SetRootMotionBone(rootMotionBoneName);
|
||||
if (rootMotionBone != null)
|
||||
initialOffset = new Vector2(rootMotionBone.x, rootMotionBone.y);
|
||||
|
||||
var skeletonAnimation = skeletonComponent as ISkeletonAnimation;
|
||||
if (skeletonAnimation != null)
|
||||
if (skeletonAnimation != null) {
|
||||
skeletonAnimation.UpdateLocal -= HandleUpdateLocal;
|
||||
skeletonAnimation.UpdateLocal += HandleUpdateLocal;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void FixedUpdate () {
|
||||
@ -178,36 +183,51 @@ namespace Spine.Unity {
|
||||
return; // Root motion is only applied when component is enabled.
|
||||
|
||||
var movementDelta = CalculateAnimationsMovementDelta();
|
||||
AdjustMovementDeltaToConfiguration(ref movementDelta, animatedSkeletonComponent.Skeleton);
|
||||
ApplyRootMotion(movementDelta);
|
||||
Vector2 parentBoneScale;
|
||||
AdjustMovementDeltaToConfiguration(ref movementDelta, out parentBoneScale, animatedSkeletonComponent.Skeleton);
|
||||
ApplyRootMotion(movementDelta, parentBoneScale);
|
||||
}
|
||||
|
||||
void AdjustMovementDeltaToConfiguration (ref Vector2 localDelta, Skeleton skeleton) {
|
||||
if (skeleton.ScaleX < 0) localDelta.x = -localDelta.x;
|
||||
if (skeleton.ScaleY < 0) localDelta.y = -localDelta.y;
|
||||
if (!transformPositionX) localDelta.x = 0f;
|
||||
if (!transformPositionY) localDelta.y = 0f;
|
||||
}
|
||||
void AdjustMovementDeltaToConfiguration (ref Vector2 localDelta, out Vector2 parentBoneScale, Skeleton skeleton) {
|
||||
localDelta.x *= skeleton.ScaleX;
|
||||
localDelta.y *= skeleton.ScaleY;
|
||||
|
||||
parentBoneScale = Vector2.one;
|
||||
Bone scaleBone = rootMotionBone;
|
||||
while ((scaleBone = scaleBone.parent) != null) {
|
||||
parentBoneScale.x *= scaleBone.ScaleX;
|
||||
parentBoneScale.y *= scaleBone.ScaleY;
|
||||
}
|
||||
localDelta *= parentBoneScale;
|
||||
|
||||
void ApplyRootMotion (Vector2 localDelta) {
|
||||
localDelta *= AdditionalScale;
|
||||
localDelta.x *= rootMotionScaleX;
|
||||
localDelta.y *= rootMotionScaleY;
|
||||
|
||||
if (!transformPositionX) localDelta.x = 0f;
|
||||
if (!transformPositionY) localDelta.y = 0f;
|
||||
}
|
||||
|
||||
void ApplyRootMotion (Vector2 localDelta, Vector2 parentBoneScale) {
|
||||
// Apply root motion to Transform or RigidBody;
|
||||
if (UsesRigidbody) {
|
||||
rigidbodyDisplacement += (Vector2)transform.TransformVector(localDelta);
|
||||
// Accumulated displacement is applied on the next Physics update (FixedUpdate)
|
||||
}
|
||||
else {
|
||||
|
||||
transform.position += transform.TransformVector(localDelta);
|
||||
}
|
||||
|
||||
// Move top level bones in opposite direction of the root motion bone
|
||||
foreach (var topLevelBone in topLevelBones) {
|
||||
if (transformPositionX) topLevelBone.x -= rootMotionBone.x;
|
||||
if (transformPositionY) topLevelBone.y -= rootMotionBone.y;
|
||||
if (topLevelBone == rootMotionBone) {
|
||||
if (transformPositionX) topLevelBone.x = 0;
|
||||
if (transformPositionY) topLevelBone.y = 0;
|
||||
}
|
||||
else {
|
||||
if (transformPositionX) topLevelBone.x = -(rootMotionBone.x - initialOffset.x) * parentBoneScale.x;
|
||||
if (transformPositionY) topLevelBone.y = -(rootMotionBone.y - initialOffset.y) * parentBoneScale.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user