- Home /
ConfigurableJoint Target Position/Rotation Issues?
Hi all,
I'm working on a VR game using tracked motion controllers. I'd like to have a baton object be aligned to my controller using Rigidbody forces so that you can wave the baton around as if you're holding it, but have it interact with other physics objects and not just pass right through them.
Reading about ConfigurableJoint, I saw that using target position/rotation parameters, I should be able to align the object (or the joint?) to my controller using forces, which sounds perfect! For the life of me, I can't figure out how to do it though. If I set the target position/rotation to the world space values for my controller, the baton just flies around almost at random. I've tried fiddling with the anchor values, as well as toggling between "Configured in world space" on and off, no luck.
Can anybody please explain how I can use a ConfigurableJoint to apply forces to an object so that it remains oriented with another object?
how about assigning it a kinematic rigidbody and keep up with position of the controller with $$anonymous$$ovePosition and $$anonymous$$oveRotation in FixedUpdate? This way it can still hit flying objects of that's what you intend to do.
Answer by DrunkenMaster0 · Dec 31, 2016 at 03:29 PM
I spent some time fiddling with configurable joints as I found documentation to be only marginally useful in fully understanding how they are designed to work. I still have some doubts, but I wrote down all I know about setting up configurable joint. Hope it helps!
Start with a simple setup and do some experiments until you are comfortable with it. Here is how to get started.
Create an empty gameobject, name it "controller", and add rigidbody component to it. This represents the controller's center of mass as a point mass in world space. Assign it mass. You can set "use gravity" and "is kinematic" as needed. Add the mesh(es), collider(s) to child object(s), rotated and positioned as needed. To make it easier, adjust your mesh(es) to make sure the center (of mass) for controller is at local origin (pivot).
Create another empty gameobject, name it "baton" and add rigidbody component to it. Assign it mass. You can enable "use gravity" if you wish. Obviously, "is kinematic" is unset. This represents the baton's center of mass as a point mass in world space. Assume transform.forward represents the orientation of baton. Add mesh(es), collider(s) to child object(s), rotated and positioned as needed. To make it easier, adjust your mesh(es) to make sure the center (of mass) for baton is at local origin (pivot). NOTE: Baton should not be parented to controller.
Position and orient the baton in world space as you want it near the controller to represent initial/rest/neutral state. Add a Configurable Joint to it and assign controller as connected rigidbody. NOTE: If baton has 'use gravity' set and controller is not kinematic then make sure the controller mass is at least 3 times the baton's mass. The forces applied by joint are affected by this ratio. To verify this, set joint anchor to (0,0,0) and all constraints to locked, enter play-mode and verify baton stays at its initial position. If not, adjust controller's mass higher until this is satisfied.
The joint's connected anchor represents the joint's hinge/pivot/origin in connected body's local space. Primary Axis is it's X axis; Secondary Axis is it's Y axis and Z axis is auto computed orthogonal to X,Y. The target position, velocity, rotation and angular velocity are all relative to initial state and interpreted according to joint's origin, axes. Based on how you want the baton to move and rotate, you should configure the constraints and assign values to limits, drive forces etc. Documentation explains this part well. NOTE: (a) If connected body moves then the connected anchor in world space will change accordingly. (b) Unity uses left hand rule for rotations. (c) Target Rotation is interpreted as rotation towards, so apply Quaternion.Inverse() to the rotation expected. Ex. to rotate joint by Euler angles (x,y,z) then: joint.targetRotation = Quaternion.Inverse(Quaternion.Euler(new Vector3(x,y,z))); (d) For Target Position, Velocity and Rotation, the selected drive's Position Spring and Damper must have values. Adjust Damper to be slightly lower value than Spring, as needed. (e) For Target Angular Velocity, the selected drive's Position Spring must be 0. Damper and Maximum Force must have same values. For unknown reason, when slerp drive is chosen, the angular velocity is inversely interpreted relative to axes.
Your answer
Follow this Question
Related Questions
Violent shaking when using position drive in Configurable Joints 1 Answer
Configure configurableJoint to act as the disctontinued driveJoint 0 Answers
Object movement choppy when picked up in VR 1 Answer
How to have a character hold teddy bear in hand, using ragdoll and joints? 1 Answer
Throwing object with force 1 Answer