Skip to content

Instantly share code, notes, and snippets.

@mstevenson
Created October 24, 2014 07:14
Show Gist options
  • Select an option

  • Save mstevenson/7b85893e8caf5ca034e6 to your computer and use it in GitHub Desktop.

Select an option

Save mstevenson/7b85893e8caf5ca034e6 to your computer and use it in GitHub Desktop.
Extension methods for working with Configurable Joints for Unity
using UnityEngine;
public static class ConfigurableJointExtensions
{
/// <summary>
/// Sets a joint's targetRotation to match a given local rotation.
/// The joint transform's local rotation must be cached on Start and passed into this method.
/// </summary>
public static void SetTargetRotationLocal (this ConfigurableJoint joint, Quaternion targetLocalRotation, Quaternion startLocalRotation)
{
if (joint.configuredInWorldSpace) {
Debug.LogError ("SetTargetRotationLocal should not be used with joints that are configured in world space. For world space joints, use SetTargetRotation.", joint);
}
SetTargetRotationInternal (joint, targetLocalRotation, startLocalRotation, Space.Self);
}
/// <summary>
/// Sets a joint's targetRotation to match a given world rotation.
/// The joint transform's world rotation must be cached on Start and passed into this method.
/// </summary>
public static void SetTargetRotation (this ConfigurableJoint joint, Quaternion targetWorldRotation, Quaternion startWorldRotation)
{
if (!joint.configuredInWorldSpace) {
Debug.LogError ("SetTargetRotation must be used with joints that are configured in world space. For local space joints, use SetTargetRotationLocal.", joint);
}
SetTargetRotationInternal (joint, targetWorldRotation, startWorldRotation, Space.World);
}
static void SetTargetRotationInternal (ConfigurableJoint joint, Quaternion targetRotation, Quaternion startRotation, Space space)
{
// Calculate the rotation expressed by the joint's axis and secondary axis
var right = joint.axis;
var forward = Vector3.Cross (joint.axis, joint.secondaryAxis).normalized;
var up = Vector3.Cross (forward, right).normalized;
Quaternion worldToJointSpace = Quaternion.LookRotation (forward, up);
// Transform into world space
Quaternion resultRotation = Quaternion.Inverse (worldToJointSpace);
// Counter-rotate and apply the new local rotation.
// Joint space is the inverse of world space, so we need to invert our value
if (space == Space.World) {
resultRotation *= startRotation * Quaternion.Inverse (targetRotation);
} else {
resultRotation *= Quaternion.Inverse (targetRotation) * startRotation;
}
// Transform back into joint space
resultRotation *= worldToJointSpace;
// Set target rotation to our newly calculated rotation
joint.targetRotation = resultRotation;
}
/// <summary>
/// Adjust ConfigurableJoint settings to closely match CharacterJoint behaviour
/// </summary>
public static void SetupAsCharacterJoint (this ConfigurableJoint joint)
{
joint.xMotion = ConfigurableJointMotion.Locked;
joint.yMotion = ConfigurableJointMotion.Locked;
joint.zMotion = ConfigurableJointMotion.Locked;
joint.angularXMotion = ConfigurableJointMotion.Limited;
joint.angularYMotion = ConfigurableJointMotion.Limited;
joint.angularZMotion = ConfigurableJointMotion.Limited;
joint.breakForce = Mathf.Infinity;
joint.breakTorque = Mathf.Infinity;
joint.rotationDriveMode = RotationDriveMode.Slerp;
var slerpDrive = joint.slerpDrive;
slerpDrive.mode = JointDriveMode.Position;
slerpDrive.maximumForce = Mathf.Infinity;
joint.slerpDrive = slerpDrive;
}
}
@sergioabreu-g
Copy link

Thanks! It was very useful :D

@PixHammer
Copy link

Thank you for this, I use it a lot. Absolute nightmare using target rotation usually.

@R3X-G1L6AME5H
Copy link

Used this a long while ago to set up 6DOF Joints in Godot. It worked there as well. Cheers, mate!

@SuJiaTao
Copy link

SuJiaTao commented Feb 1, 2023

Thank you!

@JamDoggie
Copy link

Used this a long while ago to set up 6DOF Joints in Godot. It worked there as well. Cheers, mate!

How exactly did you apply this to godot, if you remember? I'm trying to match spring equilibrium with a world space rotation using jolt in 4.4 and I just can't seem to figure out how it works.

@EugenSav
Copy link

Thank you!! I hate configurable joints so much, they are very confusing, but your extension works like a charm!!

@EugenSav
Copy link

Thanks! It was very useful :D

Thank you for your video about active ragdolls :D

@JohannHotzel
Copy link

That’s fantastic... bless you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment