Hold object at mouse position

I have some objects that I can pick up with the mouse or by touch, but the picking position is always at the center of the picked object.
How could I pick up an object at the position where I clicked with the mouse and still let the physics do it’s job, because if I edit the pivot of the object, it seems to pick up the object from a corner, but box or whatever I pick up still sits in the air in the same position as before picking it up.

Here is a snippet of my code:

Vector3 worldPoint = Camera.main.ScreenToWorldPoint(Input.mousePosition);
hit = Physics2D.Raycast(worldPoint, Vector2.zero, 50.0f);

if (holdingObject)
{
    pickedObject.rigidbody2D.velocity = (worldPoint - pickedObject.transform.position).normalized * 200.0f; ;
}

You might want to use hinges! a slightly more complicated script would be required as you need to update some properties of the hinge, but I think that’s what you want.

I managed to get it work with Spring Joint :slight_smile:
thanks for the idea :wink:

No problem :slight_smile:

Here is my C# version of the DragRigidBody:

using UnityEngine;
using System.Collections;

public class DragBox : MonoBehaviour
{
    public float spring = 50.0f;
    public float damper = 5.0f;
    public float drag = 10.0f;
    public float angularDrag = 5.0f;
    public float distance = 0.2f;
    public bool attachToCenterOfMass;
    public Camera mainCamera;

    private SpringJoint springJoint;

    void Update()
    {
        // Make sure the user pressed the mouse down
        if (!Input.GetMouseButtonDown(0))
            return;

        mainCamera = FindCamera();

        // We need to actually hit an object
	    RaycastHit hit;
        if (!Physics.Raycast(mainCamera.ScreenPointToRay(Input.mousePosition), out hit, 100))
        {
            return;
        }
	    // We need to hit a rigidbody that is not kinematic
        if (!hit.rigidbody || hit.rigidbody.isKinematic)
        {
            return;
        }

        if (!springJoint)
	    {
		    GameObject go = new GameObject("Rigidbody dragger");
		    Rigidbody body = go.AddComponent ("Rigidbody") as Rigidbody;
		    springJoint = go.AddComponent ("SpringJoint") as SpringJoint;
		    body.isKinematic = true;
	    }

        springJoint.transform.position = hit.point;
        if (attachToCenterOfMass)
        {
            Vector3 anchor = transform.TransformDirection(hit.rigidbody.centerOfMass) + hit.rigidbody.transform.position;
            anchor = springJoint.transform.InverseTransformPoint(anchor);
            springJoint.anchor = anchor;
        }
        else
        {
            springJoint.anchor = Vector3.zero;
        }

        springJoint.spring = spring;
        springJoint.damper = damper;
        springJoint.maxDistance = distance;
        springJoint.connectedBody = hit.rigidbody;

        StartCoroutine("DragTheBox", hit.distance);
    }

    IEnumerator DragTheBox(float distance)
    {
	    float oldDrag = springJoint.connectedBody.drag;
	    float oldAngularDrag = springJoint.connectedBody.angularDrag;
	    springJoint.connectedBody.drag = drag;
	    springJoint.connectedBody.angularDrag = angularDrag;
	    mainCamera = FindCamera();

	    while (Input.GetMouseButton (0))
	    {
		    Ray ray = mainCamera.ScreenPointToRay (Input.mousePosition);
		    springJoint.transform.position = ray.GetPoint(distance);
            yield return distance;
	    }

	    if (springJoint.connectedBody)
	    {
		    springJoint.connectedBody.drag = oldDrag;
		    springJoint.connectedBody.angularDrag = oldAngularDrag;
		    springJoint.connectedBody = null;
	    }
    }

    public Camera FindCamera()
    {
        if (camera)
            return camera;
        else
            return Camera.main;
    }
}
1 Like