[unity] Optimized RootMotion components behaviour when using FixedUpdate timing at SkeletonAnimation, avoiding unnecessary calls. See #2046.

This commit is contained in:
Harald Csaszar 2022-03-18 11:35:19 +01:00
parent 322d042309
commit f7aaa25ee1

View File

@ -90,6 +90,16 @@ namespace Spine.Unity {
} }
#endregion #endregion
protected bool SkeletonAnimationUsesFixedUpdate {
get {
var skeletonAnimation = skeletonComponent as ISkeletonAnimation;
if (skeletonAnimation != null) {
return skeletonAnimation.UpdateTiming == UpdateTiming.InFixedUpdate;
}
return false;
}
}
protected ISkeletonComponent skeletonComponent; protected ISkeletonComponent skeletonComponent;
protected Bone rootMotionBone; protected Bone rootMotionBone;
protected int rootMotionBoneIndex; protected int rootMotionBoneIndex;
@ -129,9 +139,16 @@ namespace Spine.Unity {
} }
protected virtual void FixedUpdate () { protected virtual void FixedUpdate () {
// Root motion is only applied when component is enabled.
if (!this.isActiveAndEnabled) if (!this.isActiveAndEnabled)
return; // Root motion is only applied when component is enabled. return;
// When SkeletonAnimation component uses UpdateTiming.InFixedUpdate,
// we directly call PhysicsUpdate in HandleUpdateLocal instead of here.
if (!SkeletonAnimationUsesFixedUpdate)
PhysicsUpdate(false);
}
protected virtual void PhysicsUpdate (bool skeletonAnimationUsesFixedUpdate) {
if (rigidBody2D != null) { if (rigidBody2D != null) {
Vector2 gravityAndVelocityMovement = Vector2.zero; Vector2 gravityAndVelocityMovement = Vector2.zero;
if (applyRigidbody2DGravity) { if (applyRigidbody2DGravity) {
@ -153,15 +170,14 @@ namespace Spine.Unity {
rigidBody.MoveRotation(rigidBody.rotation * rigidbodyRotation); rigidBody.MoveRotation(rigidBody.rotation * rigidbodyRotation);
} else return; } else return;
if (UsesRigidbody) { Vector2 parentBoneScale;
Vector2 parentBoneScale; GetScaleAffectingRootMotion(out parentBoneScale);
GetScaleAffectingRootMotion(out parentBoneScale); if (!skeletonAnimationUsesFixedUpdate) {
ClearEffectiveBoneOffsets(parentBoneScale); ClearEffectiveBoneOffsets(parentBoneScale);
skeletonComponent.Skeleton.UpdateWorldTransform(); skeletonComponent.Skeleton.UpdateWorldTransform();
previousRigidbodyRootMotion = rigidbodyDisplacement;
ClearRigidbodyTempMovement();
} }
previousRigidbodyRootMotion = rigidbodyDisplacement;
ClearRigidbodyTempMovement();
} }
protected virtual void OnDisable () { protected virtual void OnDisable () {
@ -480,10 +496,15 @@ namespace Spine.Unity {
skeletonRotationDelta = GetSkeletonSpaceRotationDelta(boneLocalDeltaRotation, totalScale); skeletonRotationDelta = GetSkeletonSpaceRotationDelta(boneLocalDeltaRotation, totalScale);
} }
ApplyRootMotion(skeletonTranslationDelta, skeletonRotationDelta, parentBoneScale); bool usesFixedUpdate = SkeletonAnimationUsesFixedUpdate;
ApplyRootMotion(skeletonTranslationDelta, skeletonRotationDelta, parentBoneScale, usesFixedUpdate);
if (usesFixedUpdate)
PhysicsUpdate(usesFixedUpdate);
} }
void ApplyRootMotion (Vector2 skeletonTranslationDelta, float skeletonRotationDelta, Vector2 parentBoneScale) { void ApplyRootMotion (Vector2 skeletonTranslationDelta, float skeletonRotationDelta, Vector2 parentBoneScale,
bool skeletonAnimationUsesFixedUpdate) {
// Apply root motion to Transform or RigidBody; // Apply root motion to Transform or RigidBody;
if (UsesRigidbody) { if (UsesRigidbody) {
rigidbodyDisplacement += transform.TransformVector(skeletonTranslationDelta); rigidbodyDisplacement += transform.TransformVector(skeletonTranslationDelta);
@ -491,7 +512,8 @@ namespace Spine.Unity {
// Accumulated displacement is applied on the next Physics update in FixedUpdate. // Accumulated displacement is applied on the next Physics update in FixedUpdate.
// Until the next Physics update, tempBoneDisplacement is offsetting bone locations // Until the next Physics update, tempBoneDisplacement is offsetting bone locations
// to prevent stutter which would otherwise occur if we don't move every Update. // to prevent stutter which would otherwise occur if we don't move every Update.
tempSkeletonDisplacement += skeletonTranslationDelta; if (!skeletonAnimationUsesFixedUpdate)
tempSkeletonDisplacement += skeletonTranslationDelta;
if (skeletonRotationDelta != 0.0f) { if (skeletonRotationDelta != 0.0f) {
if (rigidBody != null) { if (rigidBody != null) {
@ -502,10 +524,14 @@ namespace Spine.Unity {
float rotationSign = lossyScale.x * lossyScale.y > 0 ? 1 : -1; float rotationSign = lossyScale.x * lossyScale.y > 0 ? 1 : -1;
rigidbody2DRotation += rotationSign * skeletonRotationDelta; rigidbody2DRotation += rotationSign * skeletonRotationDelta;
} }
tempSkeletonRotation += skeletonRotationDelta; if (!skeletonAnimationUsesFixedUpdate)
tempSkeletonRotation += skeletonRotationDelta;
} }
SetEffectiveBoneOffsetsTo(tempSkeletonDisplacement, tempSkeletonRotation, parentBoneScale); if (skeletonAnimationUsesFixedUpdate)
ClearEffectiveBoneOffsets(parentBoneScale);
else
SetEffectiveBoneOffsetsTo(tempSkeletonDisplacement, tempSkeletonRotation, parentBoneScale);
} else { } else {
transform.position += transform.TransformVector(skeletonTranslationDelta); transform.position += transform.TransformVector(skeletonTranslationDelta);
if (skeletonRotationDelta != 0.0f) { if (skeletonRotationDelta != 0.0f) {