- Home /
How to set Character Joint "Twist Limit" to current transform rotation?
I used the Ragdoll Wizard to create a ragdoll. What I want to do is rotate the joints how I like during runtime and then enable the ragdoll so I can have a ragdoll that's stiff in the pose it was just set to.
So in every Character Joint on the ragdoll I've set Low Twist Limit > Limit and High Twist Limit > Limit to values which only have a difference of 1, this made the ragdoll stiff since it can only bend each joint by 1 degree.
The problem is, this ignores the pose I put the character in before enabling the ragdoll. For example, if I set every joint's Low Twist Limit to 0 and High Twist Limit to 1 it'll T-pose.
What I need is to adjust the Low and High Twist Limit values when I'm enabling the ragdoll but I don't understand how to know what the values should be to get the character to be a ragoll in the pose it was in just before I enabled the ragdoll.
Answer by MaceB · Apr 02, 2021 at 11:50 AM
I noticed that the Character Joint's Low and High Twist Limit value is relative to its transform's rotation at the start of the scene (or whenever a Character Joint is added to the scene).
So all you have to do is add the Character Joint components at the time that you want to make the character a ragdoll. I didn't want to have to manually input the Character Joint values for each joint, so I kept all the Character Joints and instead stored their values like Connected Body, Axis, Swing Axis, etc. and destroyed the joints on Start(). Then I add new Character Joints and apply all the values back to each one accordingly at the time that I need the Character to be a ragdoll.
This way I can edit all the Character Joint values in the Editor like usual and then when I need the character to become a ragdoll, the new Character Joints will have the same values.
So all you have to do is store whatever information you need from all of the Character Joints at Start(), Destroy all the Character Joints, and then whenever you want to make the character a ragdoll you add all the Character Joints back like they were before. Boom, it works!
Here's a script that does just that!
//This script is to be applied to the root GameObject
using System.Collections.Generic;
using UnityEngine;
public class StiffRagdoll : MonoBehaviour
{
//Create a class to store whatever information you need from all the Character Joints
public class CharacterJointInfo
{
//The GameObject this Character Joint will become a component of
public GameObject gameObject;
public Rigidbody connectedBody;
public Vector3 axis, swingAxis;
public SoftJointLimit lowTwistLimit, highTwistLimit, swing1Limit, swing2Limit;
}
//The list of all the Character Joint info which will be collected at Start()
List<CharacterJointInfo> jointInfos = new List<CharacterJointInfo>();
void Start()
{
SaveJointInfo();
}
//This stores the joint values from every joint and adds it to the jointInfos list
void SaveJointInfo()
{
CharacterJoint[] characterJoints = GetComponentsInChildren<CharacterJoint>();
//Store the information of each Character Joint
foreach (var characterJoint in characterJoints)
{
CharacterJointInfo jointInfo = new CharacterJointInfo();
jointInfo.gameObject = characterJoint.gameObject;
jointInfo.connectedBody = characterJoint.connectedBody;
jointInfo.axis = characterJoint.axis;
jointInfo.swingAxis = characterJoint.swingAxis;
jointInfo.lowTwistLimit = characterJoint.lowTwistLimit;
jointInfo.highTwistLimit = characterJoint.highTwistLimit;
jointInfo.swing1Limit = characterJoint.swing1Limit;
jointInfo.swing2Limit = characterJoint.swing2Limit;
//Add to jointInfos list
jointInfos.Add(jointInfo);
//Destroy character joint after storing
Destroy(characterJoint);
}
}
//Call this whenever you want it to become a ragdoll
public void ActivateRagdoll()
{
//Do Ragdoll stuff like:
//Disable animator
//Enable each limb's Rigidbody
//etc.
//Add the joints back with the saved info you stored
AddCharacterJoints();
}
//This adds the Character Joint component to each body part that had it before
//and assigns the values stored from the initial Character Joints
void AddCharacterJoints()
{
//Create a new Character Joint for every stored joint
//and assign the stored information for that specific joint.
foreach (var jointInfo in jointInfos)
{
CharacterJoint newCharacterJoint = jointInfo.gameObject.AddComponent<CharacterJoint>();
newCharacterJoint.connectedBody = jointInfo.connectedBody;
newCharacterJoint.axis = jointInfo.axis;
newCharacterJoint.swingAxis = jointInfo.swingAxis;
newCharacterJoint.lowTwistLimit = jointInfo.lowTwistLimit;
newCharacterJoint.highTwistLimit = jointInfo.highTwistLimit;
newCharacterJoint.swing1Limit = jointInfo.swing1Limit;
newCharacterJoint.swing2Limit = jointInfo.swing2Limit;
}
}
}
Your answer
Follow this Question
Related Questions
How to make Character Joint rotate towards a rest position? 0 Answers
How should I make a animate fully physics based Active Ragdoll? 0 Answers
How to have a character hold teddy bear in hand, using ragdoll and joints? 1 Answer
How do I change the position spring value in the angular X drive of a configurable joint 1 Answer
2d ragdoll joint connection. 0 Answers