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;
}
}
}