I’m using Unity4.6 with C#. I’m working on a VESPR simulator for atoms.
- There’s three components…two atoms and a “bond”.
- The bond is a simple, base cylinder object; the atoms are simple, base sphere objects.
- The atoms are attached to the bond by two configurable joints, one at each end. The joints are components of the bond, not the atoms.
- Each end of the bond sits at the 0,0,0 (centerpoint) of the spheres that make up each of the atoms.
- There’s no flex in the joints. The X, Y, and Z-motion are locked, but the X, Y, and Z ANGULAR motion are free to rotate around the spheres.
- The bond is the child of one of the atoms, with that bond-atom unit being the child of the other atom.
The problem is this:
When I resize the bond (make it shorter along the X-axis) the atoms to which it is attached stay in their worldwide position and the lengths of the joints “stretch” (see images). I’d like the position relationships between the atoms and the bond to stay the same (with the ends of the bond continuing to be anchored – and positioned – at the centerpoint of the sphere.)
Is there a way to do this without just breaking the joints, repositioning all three objects, and re-creating the joints?
Thanks!
OK. I found the answer. It involved using x/y/z-drives for position in conjunction with the object size change.
I.e. when I create the configurable joint, I not only set the connected anchor to Vector3(0,0,0) [the center of the sphere] but I also set the “Target Position” to 0,0,0 as well.
I then lock the x-motion and z-motion, but set the y-motion (‘y’ corresponds to the ‘long’ axis of the rod) to limited.
I turn on the y-drive, set it to “position” and turn the y-drive spring to 1.
This causes the rod to be constantly trying to return to position 0,0,0 of the connected anchor. So when the rod gets resized, the end is no longer at 0,0,0 and the y-drive pushes it back into place.
public void SetChemicalBondLength() {
// activeEndJoint = the configurable joint in question at the -1 end of the rod
activeEndJoint.yMotion = ConfigurableJointMotion.Limited;
SoftJointLimit softLimit = new SoftJointLimit();
softLimit.limit = CHEMICAL_BOND_LENGTH; // this just sets the limit to 1 in this example
activeEndJoint.linearLimit = softLimit;
activeEndJoint.targetPosition = new Vector3(0, 0, 0);
JointDrive yDrive = new JointDrive();
yDrive.mode = JointDriveMode.Position;
yDrive.positionSpring = 1;
yDrive.maximumForce = 1;
activeEndJoint.yDrive = yDrive;