Get and set Character Joint initial/base rotation?

I am using a choppable limb and I’m copying details of the original character joint. There is a range of rotation based on the original joint’s rotation. I want that range of movement to stay the same when creating new joints for the chopped versions. But what is happening is that base/initial rotation is being based on the modified rotation rather than the original one. You can see that here where the limb is hanging more and more each time it is chopped. I want the limit to how much it can hang to stay the same.

The limbs originally: (the base rotation is vertical, the legs moved due to gravity)

cow-legs1

A chopped limb causes it to hang more:

cow-legs2

When chopped again the limit to the rotation allows it to hang even more:

cow-legs3

When chopped again it hangs all of the way down:

cow-legs4b

When chopped I want the initial/base rotation to be set to what it was originally but then rotate the joint to its current rotation. That way it won’t hang any more than it was originally.

To get the initial rotation I could save it originally but how do I apply this to a joint that has a rotation that has changed to something else? (temporarily change the rotation to the initial one, apply some character joint function, then change the rotation to the new rotation?)

Joints take the “zero rotation” state from the poses of the connected parts when the joint is created.

  • Before creating the joint, you must ensure that both parts are in their “zero rotation” pose.
  • After creating the joint, you can modify the rotations by modifying Transform.rotation to set the initial poses.

Using Transform.rotation to rotate rigidbodies is correct here. We want to “teleport” those parts to their initial poses without affecting physics. Then, physics will take them from there.

If Project Settings > Physics > autoSyncTransforms is not enabled, then you should call Physics.SyncTransforms() after finishing modifying the transforms.

Thanks. Well AutoSyncTransforms is disabled.

I made all of the body parts direct children of the parent object. When chopping, the original body part is disabled/hidden. I use fixed and character joints between the objects/sliced objects. (U is upper hull and L is lower hull from slicing)

Here is what it looks like:

cow-prefab2

The choppable body parts each contain SliceableObject. In Start:

if (!hasBeenSliced)
{
    initialRotation = transform.localRotation;
}

I made it local rotation since the parent can move and rotate while it is alive… but body parts can be relative to each other (e.g. the tail parts) and not necessarily just the parent.

Here joints are added to the new objects created from the hulls:

    public void HandleJoint(GameObject originalObj, GameObject hull, Rigidbody connectedRB)
    {
        CharacterJoint origCharacterJoint = originalObj.GetComponent<CharacterJoint>();
        if (origCharacterJoint != null)
        {
            CharacterJoint hullCharacterJoint = hull.AddComponent<CharacterJoint>();
            hullCharacterJoint.connectedBody = connectedRB;
            hullCharacterJoint.anchor = Vector3.zero;
            hullCharacterJoint.highTwistLimit = origCharacterJoint.highTwistLimit;
            hullCharacterJoint.swing1Limit = origCharacterJoint.swing1Limit;
            hullCharacterJoint.swing2Limit = origCharacterJoint.swing2Limit;
        }
        else if (originalObj.TryGetComponent<FixedJoint>(out _))
        {
            FixedJoint hullFixedJoint = hull.AddComponent<FixedJoint>();
            hullFixedJoint.connectedBody = connectedRB;
        }
    }
  Joint foundJoint = objectToSlice.GetComponent<Joint>();
  if (foundJoint != null)
  {
      Rigidbody connectedRB = foundJoint.connectedBody;
      if (connectedRB != null && connectedRB.gameObject.activeInHierarchy)
      {
          if (lowerSlice.isConnectedToPivot) // and is closest?
          {
              lowerHull.transform.localRotation = sliceObj.initialRotation;
              HandleJoint(objectToSlice, lowerHull, connectedRB);
              lowerHull.transform.localRotation = sliceObj.transform.localRotation;
              lowerSlice.initialRotation = sliceObj.initialRotation;

Originally just the HandleJoint call was there. The additions don’t give the desired results. I was wondering if you had any more advice ?

I’d suggest you to set up the simplest case possible (2 rigidbodies, 1 joint) with a new script for start testing from scratch. Then test every possible case you will need in your project, so you could figure out how to resolve each situation. Otherwise, it might be significantly difficult to find solutions.