[unity] Fix unconstrained SkeletonUtility following one frame behind.

This commit is contained in:
pharan 2018-01-31 19:27:07 +08:00
parent c584de7c26
commit b7b839063b
2 changed files with 61 additions and 30 deletions

View File

@ -267,27 +267,27 @@ namespace Spine.Unity {
for (int i = 0, n = utilityBones.Count; i < n; i++) for (int i = 0, n = utilityBones.Count; i < n; i++)
utilityBones[i].transformLerpComplete = false; utilityBones[i].transformLerpComplete = false;
UpdateAllBones(); UpdateAllBones(SkeletonUtilityBone.UpdatePhase.Local);
} }
void UpdateWorld (ISkeletonAnimation anim) { void UpdateWorld (ISkeletonAnimation anim) {
UpdateAllBones(); UpdateAllBones(SkeletonUtilityBone.UpdatePhase.World);
for (int i = 0, n = utilityConstraints.Count; i < n; i++) for (int i = 0, n = utilityConstraints.Count; i < n; i++)
utilityConstraints[i].DoUpdate(); utilityConstraints[i].DoUpdate();
} }
void UpdateComplete (ISkeletonAnimation anim) { void UpdateComplete (ISkeletonAnimation anim) {
UpdateAllBones(); UpdateAllBones(SkeletonUtilityBone.UpdatePhase.Complete);
} }
void UpdateAllBones () { void UpdateAllBones (SkeletonUtilityBone.UpdatePhase phase) {
if (boneRoot == null) if (boneRoot == null)
CollectBones(); CollectBones();
var utilityBones = this.utilityBones; var utilityBones = this.utilityBones;
if (utilityBones == null) return; if (utilityBones == null) return;
for (int i = 0, n = utilityBones.Count; i < n; i++) for (int i = 0, n = utilityBones.Count; i < n; i++)
utilityBones[i].DoUpdate(); utilityBones[i].DoUpdate(phase);
} }
public Transform GetBoneRoot () { public Transform GetBoneRoot () {

View File

@ -43,6 +43,12 @@ namespace Spine.Unity {
Override Override
} }
public enum UpdatePhase {
Local,
World,
Complete
}
#region Inspector #region Inspector
/// <summary>If a bone isn't set, boneName is used to find the bone.</summary> /// <summary>If a bone isn't set, boneName is used to find the bone.</summary>
public string boneName; public string boneName;
@ -71,7 +77,7 @@ namespace Spine.Unity {
skeletonTransform = skeletonUtility.transform; skeletonTransform = skeletonUtility.transform;
skeletonUtility.OnReset -= HandleOnReset; skeletonUtility.OnReset -= HandleOnReset;
skeletonUtility.OnReset += HandleOnReset; skeletonUtility.OnReset += HandleOnReset;
DoUpdate(); DoUpdate(UpdatePhase.Local);
} }
void OnEnable () { void OnEnable () {
@ -95,7 +101,7 @@ namespace Spine.Unity {
} }
} }
public void DoUpdate () { public void DoUpdate (UpdatePhase phase) {
if (!valid) { if (!valid) {
Reset(); Reset();
return; return;
@ -112,46 +118,71 @@ namespace Spine.Unity {
} }
} }
var thisTransform = cachedTransform;
float skeletonFlipRotation = (skeleton.flipX ^ skeleton.flipY) ? -1f : 1f; float skeletonFlipRotation = (skeleton.flipX ^ skeleton.flipY) ? -1f : 1f;
if (mode == Mode.Follow) { if (mode == Mode.Follow) {
if (!bone.appliedValid) switch (phase) {
bone.UpdateAppliedTransform(); case UpdatePhase.Local:
if (position)
thisTransform.localPosition = new Vector3(bone.x, bone.y, 0);
if (position) if (rotation) {
cachedTransform.localPosition = new Vector3(bone.ax, bone.ay, 0); if (bone.data.transformMode.InheritsRotation()) {
thisTransform.localRotation = Quaternion.Euler(0, 0, bone.rotation);
} else {
Vector3 euler = skeletonTransform.rotation.eulerAngles;
thisTransform.rotation = Quaternion.Euler(euler.x, euler.y, euler.z + (bone.WorldRotationX * skeletonFlipRotation));
}
}
if (rotation) { if (scale) {
if (bone.data.transformMode.InheritsRotation()) { thisTransform.localScale = new Vector3(bone.scaleX, bone.scaleY, 1f);
cachedTransform.localRotation = Quaternion.Euler(0, 0, bone.AppliedRotation); incompatibleTransformMode = BoneTransformModeIncompatible(bone);
} else { }
Vector3 euler = skeletonTransform.rotation.eulerAngles; break;
cachedTransform.rotation = Quaternion.Euler(euler.x, euler.y, euler.z + (bone.WorldRotationX * skeletonFlipRotation)); case UpdatePhase.World:
} case UpdatePhase.Complete:
// Use Applied transform values (ax, ay, AppliedRotation, ascale) because world values may be modified by constraints.
bone.UpdateAppliedTransform();
if (position)
thisTransform.localPosition = new Vector3(bone.ax, bone.ay, 0);
if (rotation) {
if (bone.data.transformMode.InheritsRotation()) {
thisTransform.localRotation = Quaternion.Euler(0, 0, bone.AppliedRotation);
} else {
Vector3 euler = skeletonTransform.rotation.eulerAngles;
thisTransform.rotation = Quaternion.Euler(euler.x, euler.y, euler.z + (bone.WorldRotationX * skeletonFlipRotation));
}
}
if (scale) {
thisTransform.localScale = new Vector3(bone.ascaleX, bone.ascaleY, 1f);
incompatibleTransformMode = BoneTransformModeIncompatible(bone);
}
break;
} }
if (scale) {
cachedTransform.localScale = new Vector3(bone.ascaleX, bone.ascaleY, 1f);
incompatibleTransformMode = BoneTransformModeIncompatible(bone);
}
} else if (mode == Mode.Override) { } else if (mode == Mode.Override) {
if (transformLerpComplete) if (transformLerpComplete)
return; return;
if (parentReference == null) { if (parentReference == null) {
if (position) { if (position) {
Vector3 clp = cachedTransform.localPosition; Vector3 clp = thisTransform.localPosition;
bone.x = Mathf.Lerp(bone.x, clp.x, overrideAlpha); bone.x = Mathf.Lerp(bone.x, clp.x, overrideAlpha);
bone.y = Mathf.Lerp(bone.y, clp.y, overrideAlpha); bone.y = Mathf.Lerp(bone.y, clp.y, overrideAlpha);
} }
if (rotation) { if (rotation) {
float angle = Mathf.LerpAngle(bone.Rotation, cachedTransform.localRotation.eulerAngles.z, overrideAlpha); float angle = Mathf.LerpAngle(bone.Rotation, thisTransform.localRotation.eulerAngles.z, overrideAlpha);
bone.Rotation = angle; bone.Rotation = angle;
bone.AppliedRotation = angle; bone.AppliedRotation = angle;
} }
if (scale) { if (scale) {
Vector3 cls = cachedTransform.localScale; Vector3 cls = thisTransform.localScale;
bone.scaleX = Mathf.Lerp(bone.scaleX, cls.x, overrideAlpha); bone.scaleX = Mathf.Lerp(bone.scaleX, cls.x, overrideAlpha);
bone.scaleY = Mathf.Lerp(bone.scaleY, cls.y, overrideAlpha); bone.scaleY = Mathf.Lerp(bone.scaleY, cls.y, overrideAlpha);
} }
@ -161,19 +192,19 @@ namespace Spine.Unity {
return; return;
if (position) { if (position) {
Vector3 pos = parentReference.InverseTransformPoint(cachedTransform.position); Vector3 pos = parentReference.InverseTransformPoint(thisTransform.position);
bone.x = Mathf.Lerp(bone.x, pos.x, overrideAlpha); bone.x = Mathf.Lerp(bone.x, pos.x, overrideAlpha);
bone.y = Mathf.Lerp(bone.y, pos.y, overrideAlpha); bone.y = Mathf.Lerp(bone.y, pos.y, overrideAlpha);
} }
if (rotation) { if (rotation) {
float angle = Mathf.LerpAngle(bone.Rotation, Quaternion.LookRotation(Vector3.forward, parentReference.InverseTransformDirection(cachedTransform.up)).eulerAngles.z, overrideAlpha); float angle = Mathf.LerpAngle(bone.Rotation, Quaternion.LookRotation(Vector3.forward, parentReference.InverseTransformDirection(thisTransform.up)).eulerAngles.z, overrideAlpha);
bone.Rotation = angle; bone.Rotation = angle;
bone.AppliedRotation = angle; bone.AppliedRotation = angle;
} }
if (scale) { if (scale) {
Vector3 cls = cachedTransform.localScale; Vector3 cls = thisTransform.localScale;
bone.scaleX = Mathf.Lerp(bone.scaleX, cls.x, overrideAlpha); bone.scaleX = Mathf.Lerp(bone.scaleX, cls.x, overrideAlpha);
bone.scaleY = Mathf.Lerp(bone.scaleY, cls.y, overrideAlpha); bone.scaleY = Mathf.Lerp(bone.scaleY, cls.y, overrideAlpha);
} }