I used A simple solution for grabbing and dragging physics objects in Unity. Attach a DragRigidbody component to an object that has a both collider and a rigidbody. Add the object to a layer named "Interactive". · GitHub as the basis to build a really simple rigidbody drag & drop implementation, and 99% of the time it works great. However, if I carefully perch the object on its corner and drag the mouse far outside of its range of motion (so the joint is trying to pull it under/through the collider it’s sitting on), the rigidbody will start vibrating aggressively and eventually slip through the collider or fly off into space. Massively increasing the damping value of the joint spring helps somewhat, but it’s still a noticeable and jarring behavior that most people find within 30 seconds of playing around with it. Is there any obvious modification I can make to the joint to prevent this?
public float force = 600;
public float damping = 6;
Transform jointTrans;
float dragDepth;
public void OnBeginDrag(PointerEventData eventData)
{
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
dragDepth = CameraPlane.CameraToPointDepth(Camera.main, hit.point);
jointTrans = AttachJoint(hit.rigidbody, hit.point);
}
}
public void OnDrag(PointerEventData eventData)
{
if (jointTrans == null)
return;
Vector3 worldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
jointTrans.position = CameraPlane.ScreenToWorldPlanePoint(Camera.main, dragDepth, Input.mousePosition);
}
public void OnEndDrag(PointerEventData eventData)
{
Destroy(jointTrans.gameObject);
jointTrans = null;
}
Transform AttachJoint(Rigidbody rb, Vector3 attachmentPosition)
{
GameObject go = new GameObject("Attachment Point");
go.hideFlags = HideFlags.HideInHierarchy;
go.transform.position = attachmentPosition;
var newRb = go.AddComponent<Rigidbody>();
newRb.isKinematic = true;
var joint = go.AddComponent<ConfigurableJoint>();
joint.connectedBody = rb;
joint.configuredInWorldSpace = true;
joint.xDrive = NewJointDrive(force, damping);
joint.yDrive = NewJointDrive(force, damping);
joint.zDrive = NewJointDrive(force, damping);
joint.slerpDrive = NewJointDrive(force, damping);
joint.rotationDriveMode = RotationDriveMode.Slerp;
return go.transform;
}
private JointDrive NewJointDrive(float force, float damping)
{
JointDrive drive = new JointDrive();
// drive.mode = JointDriveMode.Position;
drive.positionSpring = force;
drive.positionDamper = damping;
drive.maximumForce = 600;
return drive;
}