Chains and Unity Character Joints Pt. 1

Welcome to my second tutorial. Today i will be covering how to create chains in Unity which will be powered by the built in character joint. Unfortunately there is more information on this topic than i first thought so ill have to split it up into two parts. The project files for this tutorial can be found here: https://spennerino.itch.io/unitychaintutorial

To start off, i will explain some of the properties of the joint so that you can better understand how to configure it for your own purposes in the future.

Character Joint

The character joint is the perfect joint type for ropes, rag-dolls and chains which is what i will be covering today as it basically functions as a ball joint connection. The joint physics in Unity are pretty amazing but using them for the first time can be very confusing, and unfortunately the documentation is a bit too short and sweet to be able to grasp all of the concepts without playing around.

https://docs.unity3d.com/Manual/class-CharacterJoint.html

Connected Body: The parent object for the joint. For a chain, the parent object is always the previous link in the chain.

Anchor: The pivot point for the joint. All rotation will occur with this spot at its center. The pivot point of a chain is where one link touches the next.

Axis: This one isn’t as obvious what it does. A ball joint can swivel on its connection and swing on two axis. This setting specifies which axis in 3D local space is used for the swivel rotations, and if it is set incorrectly you will get really strange results. Luckily there is a orange arrow on the joint gizmo to visualize which direction it is facing. This should be set to follow the axis that the chain extends down. You can think of the chain as a bunch of orange arrows pointing in a straight line.

(Twist Axis)

Swing Axis: This setting works similar to the Axis, but for swing motion instead of twisting motion. This axis is labeled on the gizmo with a green arrow and effects which axis is swing 1 and which is swing 2. If a chain is dangling from a ceiling, the twist axis would be Y and the swing axis would be X and Z.

(Swing Axis)

Low and High Twist Limit: This setting specifies how far the twist axis is allowed to rotate before hitting a threshold in the simulation. For a chain you can imagine twisting 2 links from the anchor point between them. The twist limits are how far you can twist the two links before the they edges touch each other and physically stop and further movement.

Swing 1 and Swing 2 Limit: The maximum angle that one link is allowed to swing relative to the next.

Enable Preprocessing: This setting toggles on and off what will happen if the chain is pulled too further than each chain link is able to reach. If the setting is on, it will still try and simulate the chain movement even if the links are unable to reach each other anymore.

Chain Creation

The first step is to create a single chain link and attach rigidbody and character joint components to it. The rigidbody is a required component of any Unity physics simulations. The character joint was already described above.

To create a chain we need to duplicate the link we already added until the chain is the length that you want it. The CTRL + D shortcut makes this really fast. Once we have the amount we want we can add each link as a child to the previously created one to make positioning and rotating all the links much easier.

The second step is to separate the link positions and rotations so that they aren’t all occupying the same space and so that each link is rotated 90 degrees relatively.

Finally be are able to begin the configuration of the character joint. The connected body property is currently blank so if you ran the project  all of the links would be connected to the world at their anchor position instead of the previous link in the chain. We can either manually drag each link in to the property field of the next…or we can make a simple script to do this for us. Add this script to all but the top level chain link:

public class AutoConnectJoint : MonoBehaviour
{
    void Awake()
    {
        GetComponent(CharacterJoint).connectedBody = transform.parent.GetComponent(Rigidbody);
    }
}

To configure the Anchor position we need to pay attention to the gizmo that appears when a object with a joint is selected. Make sure that all of the links are selected in the hierarchy when configuring these properties. The anchor needs to be moved to the center of the parent links edge for the rotations to look correct.

The gizmo is currently showing green (swing) for X and Z and orange (twist) for Y which is incorrect for the orientation of our chain. This needs to be flipped so that the orange arrow is pointing parallel to the chain.

Feel free to play around with these values. For my chain i am going to set the low twist limit to -45 degrees, high twist limit to 45 degrees, and both swing 1 and 2 limits to 140 degrees. At this point the simulation works and looks pretty good.

Unfortunately there are still a few problems, if the chain starts moving too fast there is nothing in place to stop is from going crazy and breaking all realism in the simulation.

To fix this we can set a spring and damper value of 1 for both the twist and the swing limit springs. The spring properties help the simulation return to a resting position by slowly pulling the twist and swing of each link back to its natural state.

The contact distance properties in low twist limit, high twist limit, swing 1 limit and swing 2 limit can also be used to improve the simulation by reducing jitter when reaching the limit of the swing, or twist motions. Contact distance is represented by degrees from the contact point of the configured limit…and for my purposes I’ve set these four values to 5 degrees.

To end the first part of the chain tutorial we will make one final adjustment. By default the rigidbody has a drag value of 0. Due to there being no drag, there is essentially no friction in the world to slow down the chain and it makes it seem like the chain has no weight behind it. Setting the drag to a small number like 0.1 will allow the chain to find a resting position after it hasn’t been interacted with for a while.

In Part 2 i will cover attaching chains to objects in the world, interacting with them, and applying wind to them. Part 2!

Follow me on Twitter to get updates on my development projects and new tutorials.

Thanks for reading!

 

-Spencer

Advertisements
Chains and Unity Character Joints Pt. 1

21 thoughts on “Chains and Unity Character Joints Pt. 1

  1. Anonymous says:

    Hey Spencer!

    Thanks for this write-up. I’m currently trying to work my way through creating a rope swing/hookshot type effect, and having some trouble getting my joints to spawn and attach through script. Would jump for joy if you put together part 2, and showed how to attach the end point to the world.

    Thanks for all your work.

    – A

    Liked by 1 person

    1. Hey! Take a look at the project files on itch.io, hopefully they can help you through the difficulties you are having. If not feel free to ask me questions. Hopefully ill get around to writing Part 2 at some point, the response to Part 1 was worse than expected so i didn’t make it a priority. Thank you for the comment!

      Like

  2. Anonymous says:

    Hi! Enjoyed your tutorial, helped me set up my own chain.
    I have an issue I do not know how to fix though (might be part of the next part of your tutorial, but idk).

    My chain is attached to a door equipped with a hinge joint. When I pull the chain, I would like the door to rotate regarding its hinge component depending on the force I apply to pull the chain. Do you have any idea how I can do that? So far, what I have tried have not been successful.

    Thank you and have a good day!

    Like

    1. I am glad part one was able to help. I think the only way i could for sure get you through your issue is by writing part 2 of the tutorial. I will hopefully get around to it as some point but i am extremely busy for the next 2 months. Sorry about that.

      I have never tried to do what you are attempting but the first thing i would try is adding the door as a link in the chain but not as a child to the previous chain link. If that doesn’t work because of the door hinge then you could make the chain a child of the door. Make sure the door has a rigidbody on it as well.

      Good luck!

      Like

  3. Thank you Spencer! This is exactly what I was looking for.
    Most of the resources which I’ve found were showing only that someone built a chain already, but none of them was explaining how to exactly do it ,
    and what the problems can possibly appear. I like the structure of your article. It’s written in a very clear way, step by step.
    It would be great as a video tutorial too thought.
    When can I expect part2?
    Thanks again! Great work!

    Like

    1. Thank you very much Sebastian. If it wasn’t for these kind words i probably wouldn’t bother taking the time to make this content.

      I definitely cant justify the time of producing a video tutorial and i personally prefer this format over video when i consume other peoples content.

      I would really like to make Part 2 but i just probably wont have the time until October. Really sorry that they are so far apart like that.

      Like

  4. Anonymous says:

    Please use a common format like OBJ or FBX for meshes. I don’t use blender but it’s required for unity to import your mesh.

    Like

  5. Carlos says:

    Oh my goodness, thanks so much for this post! I really needed an intuitive understanding of CharacterJoints, and this helped me a ton 🙂

    Like

  6. This is great, great insight into character joints, I can not find the part 2, if someone can help me with that, that’d be great. Also, can I use character joints with billboards for particle emitters?

    Like

  7. Phew, this was a life-saver! I spent the entire morning trying to set up chain physics for a pair of handcuffs. After reading your tutorial, I got it all set up in less than 10 minutes. Cheers!

    Like

  8. Anonymous says:

    If you are having issues with the AutoConnectJoint script here’s the fixed version.

    public class AutoConnectJoint : MonoBehaviour
    {
    void Awake()
    {
    GetComponent().connectedBody = transform.parent.GetComponent();
    }
    }

    Like

    1. Anonymous says:

      public class AutoConnectJoint : MonoBehaviour
      {
      void Awake()
      {
      GetComponent().connectedBody = transform.parent.GetComponent();
      }
      }

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s