ConfigurableJoint Object snaps back to old position when AngularMotion locked

I’m working in Unity3D version 4.

— In a Nutshell—

  1. Two objects.
  2. A ConfigurableJoint is created between them with Motionx/y/z and angularMotionx/y/z locked so their relative positions to each other doesn’t change.
  3. OnMouseDrag changes angularMotionx/y/z to “Free”
  4. User drags one object around the other.
  5. When user releases mouse, I simply set the ConfigurableJoint’s angularMotionx/y/z BACK to locked.

DESIRED OUTCOME: The objects stay in their new positions, and the configged joint is again locked so the two objects won’t move in relation to each other (staying where the user put them).

ACTUAL OUTCOME: The objects snap back to the original relative position they were in when the joint was made.

— DETAILS —
I have two objects attached by a configurable joint. When the objects are NOT interacting with the user, I want the joint to constrain their relative postition to each other. I accomplish this by setting the ConfigurableJoint’s motionX/Y/Z and angularMotionX/Y/Z to “Locked”.

However, I also want the user to be able to drag the objects around RELATIVE to each other.

I tried to accomplish this by setting the ConfigurableJoint’s angular-motion to “Free” when one of the objects is being dragged around, and then setting it BACK to Locked when the user stops dragging on object.

But when I release the object, and re-lock the angular motion - the object snaps back to its original position.

private ConfigurableJoint MakeConfigurableJoint(Collider other, int end)
{
    Vector3 myAnchor;
    ConfigurableJoint tempJoint = this.gameObject.AddComponent("ConfigurableJoint") as ConfigurableJoint; // Neg
    tempJoint.autoConfigureConnectedAnchor = false; // Prevent joint from finding it's own position

        myAnchor = new Vector3(1f, 0, 0);
        connectedBody1 = other.gameObject;
        connectedBody1Script = connectedBody1.GetComponent<AtomScript>() as AtomScript;
    
    tempJoint.anchor = myAnchor; 
    tempJoint.connectedBody = other.transform.rigidbody;
    tempJoint.connectedAnchor = new Vector3(0, 0, 0);

    // PARAMETERS //
    // Motion
    tempJoint.xMotion = ConfigurableJointMotion.Locked;
    tempJoint.yMotion = ConfigurableJointMotion.Locked;
    tempJoint.zMotion = ConfigurableJointMotion.Locked;
    tempJoint.angularXMotion = ConfigurableJointMotion.Locked;
    tempJoint.angularYMotion = ConfigurableJointMotion.Locked;
    tempJoint.angularZMotion = ConfigurableJointMotion.Locked;

    tempJoint.axis          = new Vector3(0, 0, 0);
    tempJoint.secondaryAxis = new Vector3(0,0,0);

    return tempJoint;
}//MakeConfigurableJoint

// This DOES successfully allow me to move the object around the other
public void loosenBonds()
{
    tempJoint.angularXMotion = ConfigurableJointMotion.Free;
    tempJoint.angularYMotion = ConfigurableJointMotion.Free;
    tempJoint.angularZMotion = ConfigurableJointMotion.Free;
}// loosenBonds

// This DOES lock the movement again, but first it snaps the object back to the original location (doesn't leave it where I dragged it)
public void tightenBonds()
{
    tempJoint.angularXMotion = ConfigurableJointMotion.Locked;
    tempJoint.angularYMotion = ConfigurableJointMotion.Locked;
    tempJoint.angularZMotion = ConfigurableJointMotion.Locked;
}// tightenBonds

void OnMouseDown(){ loosenBonds() };
void OnMouseUp()  { tightenBonds(); }

The proper way to do this is to actually change from using desired velocity to desired rotation in order to lock the joint.

So when you start driving the joint with a force, you unlock the joint:

JointDrive drive = joint.angularXDrive;
drive.positionSpring = 0.0f;
drive.positionDamper = 50000.0f;
drive.targetAngularVelocity = new Vector3(1.0f, 0.0f, 0.0f);
joint.angularXDrive = drive;

Once you stop wanting to move the joint you then lock the joint:

joint.targetRotation = GetCurrentRotation(joint);
joint.targetAngularVelocity = new Vector3(0.0f, 0.0f, 0.0f);
JointDrive drive = joint.angularXDrive;
drive.positionSpring = 50000.0f;
drive.positionDamper = 0.0f;
joint.angularXDrive = drive;

The good thing about this is it gives your joint a realistic strength to its locking mechanism, depending on what you set your spring values to upon locking it can still react to forces and weights being applied.

Hi @dwaldrum,
How can you get the current rotation of the joint please ?