diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonUtilityBoneInspector.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonUtilityBoneInspector.cs index 0aafcef6b..0ed6e2af5 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonUtilityBoneInspector.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonUtilityBoneInspector.cs @@ -310,7 +310,6 @@ namespace Spine.Unity.Editor { UnityEditor.EditorUtility.DisplayDialog("No parent SkeletonUtilityBone found!", "Please select the first physically moving chain node, having a parent GameObject with a SkeletonUtilityBone component attached.", "OK"); return; } - float mass = 10; const float rotationLimit = 20.0f; @@ -334,40 +333,55 @@ namespace Spine.Unity.Editor { //followRotationComponent.reference = skeletonUtility.boneRoot; // Follower Kinematic Rigidbody - GameObject followerKinematicObject = new GameObject(kinematicParentUtilityBone.name + " Follower"); - followerKinematicObject.transform.parent = normalChainParentObject.transform; - Rigidbody2D followerRigidbody = followerKinematicObject.AddComponent(); + GameObject rootFollowerKinematic = new GameObject(kinematicParentUtilityBone.name + " Follower"); + rootFollowerKinematic.transform.parent = normalChainParentObject.transform; + Rigidbody2D followerRigidbody = rootFollowerKinematic.AddComponent(); followerRigidbody.mass = mass; followerRigidbody.isKinematic = true; - followerKinematicObject.AddComponent().reference = kinematicParentUtilityBone.transform; - followerKinematicObject.transform.position = kinematicParentUtilityBone.transform.position; - followerKinematicObject.transform.rotation = kinematicParentUtilityBone.transform.rotation; + rootFollowerKinematic.AddComponent().reference = kinematicParentUtilityBone.transform; + rootFollowerKinematic.transform.position = kinematicParentUtilityBone.transform.position; + rootFollowerKinematic.transform.rotation = kinematicParentUtilityBone.transform.rotation; - // Child Bones - SkeletonUtilityBone[] utilityBones = utilityBone.GetComponentsInChildren(); - Transform childBoneParentReference = followerKinematicObject.transform; - for (int i = 0; i < utilityBones.Length; ++i) { - SkeletonUtilityBone childBone = utilityBones[i]; - mass *= 0.75f; - childBone.parentReference = (i == 0) ? kinematicParentUtilityBone.transform : childBoneParentReference; - childBone.transform.SetParent(normalChainParentObject.transform, true); // we need a flat hierarchy of all Joint objects in Unity. - AttachRigidbodyAndCollider2D(childBone); - childBone.mode = SkeletonUtilityBone.Mode.Override; - childBone.scale = childBone.position = childBone.zPosition = false; - - HingeJoint2D joint = childBone.gameObject.AddComponent(); - joint.connectedBody = childBoneParentReference.GetComponent(); - joint.useLimits = true; - ApplyJoint2DAngleLimits(joint, rotationLimit, childBoneParentReference, childBone.transform); - - childBone.GetComponent().mass = mass; - childBoneParentReference = childBone.transform; - } + CreateHingeChain2D(utilityBone, mass, rotationLimit, normalChainParentObject.transform, + rootFollowerKinematic.transform, kinematicParentUtilityBone.transform); Duplicate2DHierarchyForFlippedChains(normalChainParentObject, commonParentActivateOnFlip, skeletonUtility.transform, rotationLimit); UnityEditor.Selection.activeGameObject = commonParentObject; } + void CreateHingeChain2D (SkeletonUtilityBone bone, float mass, float rotationLimit, Transform groupObject, + Transform jointParent, Transform utilityParent) { + + mass *= 0.75f; + bone.parentReference = utilityParent; + bone.transform.SetParent(groupObject, true); // we need a flat hierarchy of all Joint objects in Unity. + AttachRigidbodyAndCollider2D(bone); + bone.mode = SkeletonUtilityBone.Mode.Override; + bone.scale = bone.position = bone.zPosition = false; + + HingeJoint2D joint = bone.gameObject.AddComponent(); + joint.connectedBody = jointParent.GetComponent(); + joint.useLimits = true; + ApplyJoint2DAngleLimits(joint, rotationLimit, jointParent, bone.transform); + bone.GetComponent().mass = mass; + + Transform parent = bone.transform; + List children = new List(); + int utilityChildCount = 0; + for (int i = 0; i < parent.childCount; ++i) { + var childUtilityBone = parent.GetChild(i).GetComponent(); + if (childUtilityBone != null) + children.Add(childUtilityBone); + } + mass /= Mathf.Max(1.0f, utilityChildCount); + + for (int i = 0; i < children.Count; ++i) { + SkeletonUtilityBone childBone = children[i]; + if (childBone == null) continue; + CreateHingeChain2D(childBone, mass, rotationLimit, groupObject, parent, parent); + } + } + void ApplyJoint2DAngleLimits (HingeJoint2D joint, float rotationLimit, Transform parentBone, Transform bone) { #if HINGE_JOINT_NEW_BEHAVIOUR float referenceAngle = (parentBone.eulerAngles.z - bone.eulerAngles.z + 360f) % 360f; @@ -452,6 +466,8 @@ namespace Spine.Unity.Editor { UnityEditor.EditorUtility.DisplayDialog("No parent SkeletonUtilityBone found!", "Please select the first physically moving chain node, having a parent GameObject with a SkeletonUtilityBone component attached.", "OK"); return; } + float mass = 10; + const float rotationLimit = 20.0f; SetSkeletonUtilityToFlipByRotation(); @@ -465,39 +481,57 @@ namespace Spine.Unity.Editor { followRotationComponent.reference = skeletonUtility.boneRoot; // Follower Kinematic Rigidbody - GameObject followerKinematicObject = new GameObject(kinematicParentUtilityBone.name + " Follower"); - followerKinematicObject.transform.parent = chainParentObject.transform; - Rigidbody followerRigidbody = followerKinematicObject.AddComponent(); - followerRigidbody.mass = 10; + GameObject rootFollowerKinematic = new GameObject(kinematicParentUtilityBone.name + " Follower"); + rootFollowerKinematic.transform.parent = chainParentObject.transform; + Rigidbody followerRigidbody = rootFollowerKinematic.AddComponent(); + followerRigidbody.mass = mass; followerRigidbody.isKinematic = true; - followerKinematicObject.AddComponent().reference = kinematicParentUtilityBone.transform; - followerKinematicObject.transform.position = kinematicParentUtilityBone.transform.position; - followerKinematicObject.transform.rotation = kinematicParentUtilityBone.transform.rotation; + rootFollowerKinematic.AddComponent().reference = kinematicParentUtilityBone.transform; + rootFollowerKinematic.transform.position = kinematicParentUtilityBone.transform.position; + rootFollowerKinematic.transform.rotation = kinematicParentUtilityBone.transform.rotation; - // Child Bones - SkeletonUtilityBone[] utilityBones = utilityBone.GetComponentsInChildren(); - Transform childBoneParentReference = followerKinematicObject.transform; - foreach (SkeletonUtilityBone childBone in utilityBones) { - childBone.parentReference = childBoneParentReference; - childBone.transform.SetParent(chainParentObject.transform, true); // we need a flat hierarchy of all Joint objects in Unity. - AttachRigidbodyAndCollider(childBone); - childBone.mode = SkeletonUtilityBone.Mode.Override; + CreateHingeChain(utilityBone, mass, rotationLimit, chainParentObject.transform, rootFollowerKinematic.transform); - HingeJoint joint = childBone.gameObject.AddComponent(); - joint.axis = Vector3.forward; - joint.connectedBody = childBoneParentReference.GetComponent(); - joint.useLimits = true; - joint.limits = new JointLimits { - min = -20, - max = 20 - }; - childBone.GetComponent().mass = childBoneParentReference.transform.GetComponent().mass * 0.75f; - - childBoneParentReference = childBone.transform; - } UnityEditor.Selection.activeGameObject = chainParentObject; } + void CreateHingeChain (SkeletonUtilityBone bone, float mass, float rotationLimit, Transform groupObject, + Transform jointParent) { + + mass *= 0.75f; + + bone.parentReference = jointParent; + bone.transform.SetParent(groupObject.transform, true); // we need a flat hierarchy of all Joint objects in Unity. + AttachRigidbodyAndCollider(bone); + bone.mode = SkeletonUtilityBone.Mode.Override; + + HingeJoint joint = bone.gameObject.AddComponent(); + joint.axis = Vector3.forward; + joint.connectedBody = jointParent.GetComponent(); + joint.useLimits = true; + joint.limits = new JointLimits { + min = -rotationLimit, + max = rotationLimit + }; + bone.GetComponent().mass = mass; + + Transform parent = bone.transform; + List children = new List(); + int utilityChildCount = 0; + for (int i = 0; i < parent.childCount; ++i) { + var childUtilityBone = parent.GetChild(i).GetComponent(); + if (childUtilityBone != null) + children.Add(childUtilityBone); + } + mass /= Mathf.Max(1.0f, utilityChildCount); + + for (int i = 0; i < children.Count; ++i) { + SkeletonUtilityBone childBone = children[i]; + if (childBone == null) continue; + CreateHingeChain(childBone, mass, rotationLimit, groupObject, parent); + } + } + void SetSkeletonUtilityToFlipByRotation () { if (!skeletonUtility.flipBy180DegreeRotation) { skeletonUtility.flipBy180DegreeRotation = true; diff --git a/spine-unity/Assets/Spine/package.json b/spine-unity/Assets/Spine/package.json index 44a11044c..025414711 100644 --- a/spine-unity/Assets/Spine/package.json +++ b/spine-unity/Assets/Spine/package.json @@ -2,7 +2,7 @@ "name": "com.esotericsoftware.spine.spine-unity", "displayName": "spine-unity Runtime", "description": "This plugin provides the spine-unity runtime core.", - "version": "4.2.100", + "version": "4.2.101", "unity": "2018.3", "author": { "name": "Esoteric Software",