From 9cd40dd3c18d5809f05d1e6811e584c4dc505dbf Mon Sep 17 00:00:00 2001 From: Fenrisul Date: Sat, 4 Oct 2014 19:35:46 -0700 Subject: [PATCH] [Unity] Added Bone FlipX support to Skeleton Utility. --- .../Editor/SkeletonUtilityBoneInspector.cs | 26 +++- .../SkeletonUtility/SkeletonUtilityBone.cs | 116 ++++++++++++++++-- 2 files changed, 130 insertions(+), 12 deletions(-) diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs b/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs index 1a6b80054..c0eb706d5 100644 --- a/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs +++ b/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs @@ -41,7 +41,7 @@ using Spine; [CustomEditor(typeof(SkeletonUtilityBone)), CanEditMultipleObjects] public class SkeletonUtilityBoneInspector : Editor { - SerializedProperty mode, boneName, zPosition, position, rotation, scale, overrideAlpha, parentReference; + SerializedProperty mode, boneName, zPosition, position, rotation, scale, overrideAlpha, parentReference, flip, flipX; //multi selected flags bool containsFollows, containsOverrides, multiObject; @@ -60,6 +60,8 @@ public class SkeletonUtilityBoneInspector : Editor { scale = this.serializedObject.FindProperty("scale"); overrideAlpha = this.serializedObject.FindProperty("overrideAlpha"); parentReference = this.serializedObject.FindProperty("parentReference"); + flip = this.serializedObject.FindProperty("flip"); + flipX = this.serializedObject.FindProperty("flipX"); EvaluateFlags(); @@ -134,11 +136,24 @@ public class SkeletonUtilityBoneInspector : Editor { EditorGUILayout.PropertyField(position); EditorGUILayout.PropertyField(rotation); EditorGUILayout.PropertyField(scale); + EditorGUILayout.PropertyField(flip); EditorGUI.BeginDisabledGroup( containsFollows ); { EditorGUILayout.PropertyField(overrideAlpha); EditorGUILayout.PropertyField(parentReference); + + EditorGUI.BeginDisabledGroup(multiObject || !flip.boolValue); + { + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(flipX); + if (EditorGUI.EndChangeCheck()) + { + FlipX(flipX.boolValue); + } + } + EditorGUI.EndDisabledGroup(); + } EditorGUI.EndDisabledGroup(); @@ -173,6 +188,15 @@ public class SkeletonUtilityBoneInspector : Editor { serializedObject.ApplyModifiedProperties(); } + void FlipX(bool state) + { + utilityBone.FlipX(state); + if (Application.isPlaying == false) + { + skeletonUtility.skeletonAnimation.LateUpdate(); + } + } + void BoneSelectorContextMenu(string current, List bones, string topValue, GenericMenu.MenuFunction2 callback){ GenericMenu menu = new GenericMenu(); diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs index a8e03e0e5..ca0b56bde 100644 --- a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs +++ b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs @@ -61,6 +61,8 @@ public class SkeletonUtilityBone : MonoBehaviour { public bool position; public bool rotation; public bool scale; + public bool flip; + public bool flipX; [Range(0f,1f)] public float overrideAlpha = 1; @@ -138,23 +140,41 @@ public class SkeletonUtilityBone : MonoBehaviour { } } + - float flipRotation = (skeleton.flipX ^ skeleton.flipY) ? -1f : 1f; - + float skeletonFlipRotation = (skeleton.flipX ^ skeleton.flipY) ? -1f : 1f; + + float flipCompensation = 0; + if (flip && (flipX || ( flipX != bone.flipX)) && bone.parent != null) + { + flipCompensation = bone.parent.WorldRotation * -2; + } if(mode == Mode.Follow){ + if (flip) + { + flipX = bone.flipX; + } + + if(position){ cachedTransform.localPosition = new Vector3(bone.x, bone.y, 0); } - + if(rotation){ if(bone.Data.InheritRotation){ - cachedTransform.localRotation = Quaternion.Euler(0,0,bone.rotationIK); + if (bone.FlipX) + { + cachedTransform.localRotation = Quaternion.Euler(0, 180, bone.rotationIK - flipCompensation); + } + else { + cachedTransform.localRotation = Quaternion.Euler(0,0,bone.rotationIK); + } } else{ Vector3 euler = skeletonTransform.rotation.eulerAngles; - cachedTransform.rotation = Quaternion.Euler(euler.x, euler.y, skeletonTransform.rotation.eulerAngles.z + (bone.worldRotation * flipRotation) ); + cachedTransform.rotation = Quaternion.Euler(euler.x, euler.y, skeletonTransform.rotation.eulerAngles.z + (bone.worldRotation * skeletonFlipRotation) ); } } @@ -167,8 +187,11 @@ public class SkeletonUtilityBone : MonoBehaviour { } else if(mode == Mode.Override){ + + + if(transformLerpComplete) - return; + return; if(parentReference == null){ if(position){ @@ -177,8 +200,23 @@ public class SkeletonUtilityBone : MonoBehaviour { } if(rotation){ - bone.rotation = Mathf.LerpAngle(bone.Rotation, cachedTransform.localRotation.eulerAngles.z, overrideAlpha); - } + float angle = Mathf.LerpAngle(bone.Rotation, cachedTransform.localRotation.eulerAngles.z, overrideAlpha) + flipCompensation; + + if (flip) { + if ((!flipX && bone.flipX)) + { + angle -= flipCompensation; + } + + //TODO fix this... + if (angle >= 360) + angle -= 360; + else if (angle <= -360) + angle += 360; + } + + bone.Rotation = angle; + } if(scale){ bone.scaleX = Mathf.Lerp(bone.scaleX, cachedTransform.localScale.x, overrideAlpha); @@ -186,8 +224,17 @@ public class SkeletonUtilityBone : MonoBehaviour { nonUniformScaleWarning = (bone.scaleX != bone.scaleY); } + + if (flip) + { + bone.flipX = flipX; + } } else{ + + if (transformLerpComplete) + return; + if(position){ Vector3 pos = parentReference.InverseTransformPoint(cachedTransform.position); bone.x = Mathf.Lerp(bone.x, pos.x, overrideAlpha); @@ -195,22 +242,69 @@ public class SkeletonUtilityBone : MonoBehaviour { } if(rotation){ - bone.rotation = Mathf.LerpAngle(bone.Rotation, Quaternion.LookRotation( Vector3.forward, parentReference.InverseTransformDirection( cachedTransform.up ) ).eulerAngles.z, overrideAlpha); + float angle = Mathf.LerpAngle(bone.Rotation, Quaternion.LookRotation(flipX ? Vector3.forward * -1 : Vector3.forward, parentReference.InverseTransformDirection(cachedTransform.up)).eulerAngles.z, overrideAlpha) + flipCompensation; + + if (flip) + { + if ((!flipX && bone.flipX)) + { + angle -= flipCompensation; + } + + //TODO fix this... + if (angle >= 360) + angle -= 360; + else if (angle <= -360) + angle += 360; + } + + bone.Rotation = angle; } //TODO: Something about this if(scale){ - bone.scaleX = Mathf.Lerp(bone.scaleX, cachedTransform.localScale.x, overrideAlpha); - bone.scaleY = Mathf.Lerp(bone.scaleY, cachedTransform.localScale.y, overrideAlpha); + bone.scaleX = Mathf.Lerp(bone.scaleX, cachedTransform.localScale.x, overrideAlpha); + bone.scaleY = Mathf.Lerp(bone.scaleY, cachedTransform.localScale.y, overrideAlpha); nonUniformScaleWarning = (bone.scaleX != bone.scaleY); } + + if (flip) + { + bone.flipX = flipX; + } + } transformLerpComplete = true; } } + public void FlipX(bool state) + { + if (state != flipX) + { + flipX = state; + if (flipX && Mathf.Abs(transform.localRotation.eulerAngles.y) > 90) + { + skeletonUtility.skeletonAnimation.LateUpdate(); + return; + } + else if (!flipX && Mathf.Abs(transform.localRotation.eulerAngles.y) < 90) + { + skeletonUtility.skeletonAnimation.LateUpdate(); + return; + } + } + + bone.FlipX = state; + transform.RotateAround(transform.position, skeletonUtility.transform.up, 180); + Vector3 euler = transform.localRotation.eulerAngles; + euler.x = 0; + euler.y = bone.FlipX ? 180 : 0; + transform.localRotation = Quaternion.Euler(euler); + } + void OnDrawGizmos(){ if(NonUniformScaleWarning){ Gizmos.DrawIcon(transform.position + new Vector3(0,0.128f,0), "icon-warning");