The Complete Guide To Unity’s Configurable Joints

As you may know I write most of my tutorials on how to create physics based VR interaction systems, and to do that I almost exclusively use the configurable joint. For the most part I had to learn all of this on my own through trial and error and searching through forum posts, as tutorials and documentation on unity’s joints seems pretty scarce. I think it’s time to fix that.

This thing has so many options that I had to close most of them to get it to even fit on my screen

So what I am going to do is go through each option one by one and tell you what I have learned about each one of them. This is going to take a while


Connected Body

This one is pretty simple, it’s the rigidbody that the joint connects this object to, if you leave it blank it pretendends that it’s connected to a kinematic rigidbody and the center of the world. This is something to look for if your joint is flying toward the world center for no reason.

for consistency's sake here is the code to change it:
joint.connectedBody = rigidbodyToConnectTo;

Anchor and Connected Anchor

These anchors are how you set an offset on the position of your joint. By default, autoConfigureConnectedAnchor is on and that will automatically set the Connected anchor as the name suggests. The reason that there are two is so that you can set the offset of the point of rotation, or center of the joint. So if you were to map it out it would go:

Object with joint >> anchor >> where the joint rotatates >> connected anchor >> connected body.

I don’t know how much that helped you but I hope it did.

joint.anchor = new Vector3(x,y,z);
joint.connectedAnchor = new Vector3(x,y,z);

Axis and Secondary Axis

These are a little harder to explain and I still haven’t completely figured them out yet. They set the local coordinate space of the joint relative to the rotation that it was first connected to an object at. Good luck. I was able to use them to offset the x rotation of the joint by setting the Axis but I haven’t had that much luck setting an offset to multiple rotations yet. It seems like you can’t directly affect the rotation of the joint through them but you have to change the rotation yourself and then set the axis.

If you know how these work please comment below.

joint.axis = new Vecor3(x, y, z);
joint.secondaryAxis = new Vector3(x, y, z);

Axis Motion and Angular Axis Motion

These set the range of motion of the three-axis of movement and rotation. Locked means that it supposedly can’t move, though if you apply two much force it looks like a spring. Limited means that you can set the range of motion with the limits and limit springs. Free means that the movement in this direction will not be directly opposed, though we can still limit it using drives.

joint.xMotion = ConfigurableJointMotion.Locked;
joint.angularXMotion = ConfigurableJointMotion.Locked;

Limits and Limit Springs

These are how you limit the positions and rotations that your joint will allow. You can set individual limits for the angular rotations but you can only set one limit for linear motion that will affect all axis of movement. Setting these through code is a little harder since the variables are not directly exposed but we can still get to them:

SoftJointLimit limit = joint.linearLimit; //First we get a copy of the limit we want to change
limit.limit = 0.5f; //set the value that we want to change
joint.linearLimit = limit; //set the joint's limit to our edited version.

Target Position and Velocity

These are the values that the linear drives try to reach in local space. If both of them are zeroed out then what you have is a spring joint, with the target position being the offset. You will have to be creative to find a use for the target velocity as just applying a force in a direction would probably be better but in some specific scenarios, I’m sure it’s useful.

joint.targetPosition = new Vector3(x, y, z);
joint.targetVelocity = new Vector3(x, y, z);

Linear Drives

These will apply forces to try to reach the target position and velocity. The spring will set how much force it will use to try to reach the position. Damping smooths out the motion but also slows it down. If you want something to be snappy don’t use damping (or just dynamically set it). Max force is the max force that this drive can apply, by default, it’s set to infinity. Just like for limits we can’t directly set their values but that doesn’t mean it’s impossible.

JointDrive drive = joint.xDrive; // get a copy of the drive 
drive.maximumForce = maxLinearForce; // set the value that you want to change
joint.xDrive = drive; // Set the joint's drive to our edited drive

Target Rotation and angular velocity

This is basically the same as the linear targets but for rotation, in this case the target velocity is useful if you want something like a fan or windmill to spin at a constant rate. Now setting target rotation is really confusing as it doesn’t use global or local coordinates even if your joint is set to use world space so you have to calculate yourself and store the original rotation of the joint. I have to give credit for the code to Github user mstevenson for creating the extension class that I use to set target rotation so go check it out here: https://gist.github.com/mstevenson/4958837

Rotation Drives

The rotation drive is just like the linear drives except that you have two options, X and YZ, and Slerp. X and YZ allows you to choose different forces for different axis, the reason there are only two axis is that most models are rigged with the x axis as forward so the x drive is for rotation about the limb and YZ is the force of keeping the limb straight (I have no idea why they would set it up like that though). The second one, the Slerp drive, is my preferred one. It simply tries to rotate towards the target rotation in a straight line. We set them just like the linear drives, it doesn’t even use a different class:

JointDrive drive = joint.slerpDrive; // get a copy of the drive 
drive.maximumForce = maxLinearForce; // set the value that you want to change
joint.xDrive = drive; // Set the joint's drive to our edited drive

Projection

Projection is to account for when the joint breaks. if the joint stretches or breaks or otherwise exceeds the tolerances that you set it will snap/teleport to the position that it should be

Configured in world space

This toggles between local and world coordinates.

Swap Bodies

This swaps how the linked rigidbodies are treated

Break forces

If the joint experiences forces above these values it will break.

Enable Collision

Allow connected bodies to collide

Enable Preprocessing

As far as I can tell this makes joints look better, disabling it allegedly makes ragdolls more stable.

Mass scales

This makes the joint treat the connected rigidbodies as if they have different scales by multiplying their masses by these values.


Well, this took forever, I hope that something in here helped you out. If you have anything to add to this list don’t hesitate to comment below. Hopefully this blog will still apply to the new ECS physics system when it gets released soon.

Liked it? Take a second to support WireWhiz on Patreon!
Become a patron at Patreon!

2 comments

Comments are closed.