using UnityEngine; using System.Collections; namespace RootMotion.Dynamics { /// /// Contains tools for converting 3D Joints. /// public static class JointConverter { #region Public /// /// Converts any 3D joints on the root GameObject and its children to ConfigurableJoints /// /// Root. public static void ToConfigurable(GameObject root) { int count = 0; CharacterJoint[] characterJoints = root.GetComponentsInChildren(); for (int i = 0; i < characterJoints.Length; i++) { CharacterToConfigurable(characterJoints[i]); count ++; } HingeJoint[] hingeJoints = root.GetComponentsInChildren(); for (int i = 0; i < hingeJoints.Length; i++) { HingeToConfigurable(hingeJoints[i]); count ++; } FixedJoint[] fixedJoints = root.GetComponentsInChildren(); for (int i = 0; i < fixedJoints.Length; i++) { FixedToConfigurable(fixedJoints[i]); count ++; } SpringJoint[] springJoints = root.GetComponentsInChildren(); for (int i = 0; i < springJoints.Length; i++) { SpringToConfigurable(springJoints[i]); count ++; } if (count > 0) { Debug.Log(count.ToString() + " joints were successfully converted to ConfigurableJoints."); } else { Debug.Log("No joints found in the children of " + root.name + " to convert to ConfigurableJoints."); } } /// /// Replaces a HingeJoint with a ConfigurableJoint. /// public static void HingeToConfigurable(HingeJoint src) { #if UNITY_EDITOR ConfigurableJoint conf = UnityEditor.Undo.AddComponent(src.gameObject, typeof(ConfigurableJoint)) as ConfigurableJoint; #else ConfigurableJoint conf = src.gameObject.AddComponent(); #endif ConvertJoint(ref conf, src as Joint); conf.secondaryAxis = Vector3.zero; conf.xMotion = ConfigurableJointMotion.Locked; conf.yMotion = ConfigurableJointMotion.Locked; conf.zMotion = ConfigurableJointMotion.Locked; conf.angularXMotion = src.useLimits? ConfigurableJointMotion.Limited: ConfigurableJointMotion.Free; conf.angularYMotion = ConfigurableJointMotion.Locked; conf.angularZMotion = ConfigurableJointMotion.Locked; conf.highAngularXLimit = ConvertToHighSoftJointLimit(src.limits, src.spring, src.useSpring); conf.angularXLimitSpring = ConvertToSoftJointLimitSpring(src.limits, src.spring, src.useSpring); conf.lowAngularXLimit = ConvertToLowSoftJointLimit(src.limits, src.spring, src.useSpring); if (src.useMotor) { Debug.LogWarning("Can not convert HingeJoint Motor to ConfigurableJoint."); } #if UNITY_EDITOR UnityEditor.Undo.DestroyObjectImmediate(src); #else GameObject.DestroyImmediate(src); #endif } /// /// Replaces a FixedJoint with a ConfigurableJoint. /// public static void FixedToConfigurable(FixedJoint src) { #if UNITY_EDITOR ConfigurableJoint conf = UnityEditor.Undo.AddComponent(src.gameObject, typeof(ConfigurableJoint)) as ConfigurableJoint; #else ConfigurableJoint conf = src.gameObject.AddComponent(); #endif ConvertJoint(ref conf, src as Joint); conf.secondaryAxis = Vector3.zero; conf.xMotion = ConfigurableJointMotion.Locked; conf.yMotion = ConfigurableJointMotion.Locked; conf.zMotion = ConfigurableJointMotion.Locked; conf.angularXMotion = ConfigurableJointMotion.Locked; conf.angularYMotion = ConfigurableJointMotion.Locked; conf.angularZMotion = ConfigurableJointMotion.Locked; #if UNITY_EDITOR UnityEditor.Undo.DestroyObjectImmediate(src); #else GameObject.DestroyImmediate(src); #endif } /// /// Replaces a SpringJoint with a ConfigurableJoint. /// public static void SpringToConfigurable(SpringJoint src) { #if UNITY_EDITOR ConfigurableJoint conf = UnityEditor.Undo.AddComponent(src.gameObject, typeof(ConfigurableJoint)) as ConfigurableJoint; #else ConfigurableJoint conf = src.gameObject.AddComponent(); #endif ConvertJoint(ref conf, src as Joint); conf.xMotion = ConfigurableJointMotion.Limited; conf.yMotion = ConfigurableJointMotion.Limited; conf.zMotion = ConfigurableJointMotion.Limited; conf.angularXMotion = ConfigurableJointMotion.Free; conf.angularYMotion = ConfigurableJointMotion.Free; conf.angularZMotion = ConfigurableJointMotion.Free; SoftJointLimit linearLimit = new SoftJointLimit(); linearLimit.bounciness = 0f; linearLimit.limit = src.maxDistance; conf.linearLimit = linearLimit; SoftJointLimitSpring linearLimitSpring = new SoftJointLimitSpring(); linearLimitSpring.damper = src.damper; linearLimitSpring.spring = src.spring; conf.linearLimitSpring = linearLimitSpring; #if UNITY_EDITOR UnityEditor.Undo.DestroyObjectImmediate(src); #else GameObject.DestroyImmediate(src); #endif } /// /// Replaces a CharacterJoint with a ConfigurableJoint. /// public static void CharacterToConfigurable(CharacterJoint src) { #if UNITY_EDITOR ConfigurableJoint conf = UnityEditor.Undo.AddComponent(src.gameObject, typeof(ConfigurableJoint)) as ConfigurableJoint; #else ConfigurableJoint conf = src.gameObject.AddComponent(); #endif ConvertJoint(ref conf, src as Joint); conf.secondaryAxis = src.swingAxis; conf.xMotion = ConfigurableJointMotion.Locked; conf.yMotion = ConfigurableJointMotion.Locked; conf.zMotion = ConfigurableJointMotion.Locked; conf.angularXMotion = ConfigurableJointMotion.Limited; conf.angularYMotion = ConfigurableJointMotion.Limited; conf.angularZMotion = ConfigurableJointMotion.Limited; conf.highAngularXLimit = CopyLimit(src.highTwistLimit); conf.lowAngularXLimit = CopyLimit(src.lowTwistLimit); conf.angularYLimit = CopyLimit(src.swing1Limit); conf.angularZLimit = CopyLimit(src.swing2Limit); conf.angularXLimitSpring = CopyLimitSpring(src.twistLimitSpring); conf.angularYZLimitSpring = CopyLimitSpring(src.swingLimitSpring); conf.enableCollision = src.enableCollision; conf.projectionMode = src.enableProjection? JointProjectionMode.PositionAndRotation: JointProjectionMode.None; conf.projectionAngle = src.projectionAngle; conf.projectionDistance = src.projectionDistance; #if UNITY_EDITOR UnityEditor.Undo.DestroyObjectImmediate(src); #else GameObject.DestroyImmediate(src); #endif } #endregion Public // Common to all joints private static void ConvertJoint(ref ConfigurableJoint conf, Joint src) { conf.anchor = src.anchor; conf.autoConfigureConnectedAnchor = src.autoConfigureConnectedAnchor; conf.axis = src.axis; conf.breakForce = src.breakForce; conf.breakTorque = src.breakTorque; conf.connectedAnchor = src.connectedAnchor; conf.connectedBody = src.connectedBody; conf.enableCollision = src.enableCollision; } // Conversion from JointLimit and JointSpring to high SoftJointLimit private static SoftJointLimit ConvertToHighSoftJointLimit(JointLimits src, JointSpring spring, bool useSpring) { SoftJointLimit limit = new SoftJointLimit(); limit.limit = -src.max; limit.bounciness = src.bounciness; return limit; } // Conversion from JointLimit and JointSpring to low SoftJointLimit private static SoftJointLimit ConvertToLowSoftJointLimit(JointLimits src, JointSpring spring, bool useSpring) { SoftJointLimit limit = new SoftJointLimit(); limit.limit = -src.min; limit.bounciness = src.bounciness; return limit; } // Conversion from JointLimit and JointSpring to SoftJointLimitSpring private static SoftJointLimitSpring ConvertToSoftJointLimitSpring(JointLimits src, JointSpring spring, bool useSpring) { SoftJointLimitSpring limitSpring = new SoftJointLimitSpring(); limitSpring.damper = useSpring? spring.damper: 0f; limitSpring.spring = useSpring? spring.spring: 0f; return limitSpring; } // Returns a copy of the specified SoftJointLimit private static SoftJointLimit CopyLimit(SoftJointLimit src) { SoftJointLimit limit = new SoftJointLimit(); limit.limit = src.limit; limit.bounciness = src.bounciness; return limit; } // Returns a copy of the specified SoftJointLimitSpring private static SoftJointLimitSpring CopyLimitSpring(SoftJointLimitSpring src) { SoftJointLimitSpring limitSpring = new SoftJointLimitSpring(); limitSpring.damper = src.damper; limitSpring.spring = src.spring; return limitSpring; } } }