Drag GameObject with mouse

I have maybe a dumb question, but how do I drag a GameObject when I click the mouse?

I'd like to use OnMouseDrag. When the user clicks on my GameObject it first does some animation (moves forward a bit). When the user still holds down the mouse button and moves the mouse, I'd like to have the GameObject move with it (with dampening).

Tried some stuff out but I can't get it to work.

Does anyone know how to do this? It would be of great help!

Thanks.

No problem It's often the simpler mistakes that we overlook the longest. Best of luck with your project.

–

11 Answers

11

Drop this onto a gameobject, use the collider that matches your type of gameobject

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(MeshCollider))]

public class GizmosController : MonoBehaviour 
{

private Vector3 screenPoint;
private Vector3 offset;

void OnMouseDown()
{
    screenPoint = Camera.main.WorldToScreenPoint(gameObject.transform.position);

    offset = gameObject.transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z));

}

void OnMouseDrag()
{
    Vector3 curScreenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z);

Vector3 curPosition = Camera.main.ScreenToWorldPoint(curScreenPoint) + offset;
transform.position = curPosition;

}

}

There is a script which comes with Standard Assets of Unity called `DragRigidbody.js`. You can play with it by following these steps:

  • Create an empty `Scene` with a `Terrain`
  • Add some `GameObject` like `Cube` and `Sphere`
  • Assign `Rigidbody` to the ones that you want to be able to Drag (`Component` > `Physics` > `Rigidbody`)
  • Add a `First Person Controller` from the Prefabs of Standard Assets
  • Finally drag the `DragRigidbody.js` on the `First Person Controller` object in your scene.
  • Press the `Play` button and you are good to go

I don't know in how much into details you want to go, but in general the `DragRigidbody.js` script is using a combination of `Raycast`, `Rigidbody` and `SpringJoint` to achieve the Drag and Drop.

You can also check the Room of Shadows example which is a little bit more complicated but this is because they also highlighting the objects and playing with lights/shadows.

Have fun and good luck.

A little simpler

3D Drag:

void OnMouseDrag()
	{
		float distance_to_screen = Camera.main.WorldToScreenPoint(gameObject.transform.position).z;
		transform.position = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, distance_to_screen ));
	 
	}

Plane Drag:

   void OnMouseDrag()
    	{
    		float distance_to_screen = Camera.main.WorldToScreenPoint(gameObject.transform.position).z;
    		Vector3 pos_move = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, distance_to_screen ));
            transform.position = new Vector3( pos_move.x, transform.position.y, pos_move.z );
    	 
    	}

Thanks for your reactions. This is what I did to make it work:

void OnMouseDown()
{
    screenPoint = Camera.main.WorldToScreenPoint(scanPos);

    offset = scanPos - Camera.main.ScreenToWorldPoint(
        new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z));
}

void OnMouseDrag()
{
    Vector3 curScreenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z);

    Vector3 curPosition = Camera.main.ScreenToWorldPoint(curScreenPoint) + offset;
    transform.position = curPosition;
}

It's not moving really natural I would say.. and I've notice that a lot of people here.. answering their own questions here.. It's not a forum like site.. check the stackoverflow.com :) Usually you are commenting on someones question.. (to get more details on a specific matter) or just updating the main question.. don't forget that there is an edit here.. Regards

–

@Lipis There is nothing wrong with that, and since you're familiar with StackOverflow, you should know there are plenty of examples of people answering their own questions. In fact, it's even encouraged to provide both a question and answer to subjects that a user knows well. Just because he answered his own question doesn't mean nobody else should answer. Especially if they have a better solution. That's what makes communities like this so useful.

–

Your code block is broken, you should fix it to benefit future readers.

–

Yes you are right, it's indeed faster, thanks for the reminds! But it's still laggy for capturing image sequences during the game play x_x

–

Check out the script "DragRigidbodyShadow.js" from the Unity Shadow Demo Project: http://unity3d.com/support/resources/example-projects/shadowdemo

Sorry....what's "scanPos" of the code?

there is another script in unity's procedural example project.

"Sorry....what's "scanPos" of the code?"

scanPos is a the position (Vector3) of the gameobject you want to drag. In my case it is a scanner so scanPos stands for scanner position :-)

This is the simpliest way i can think of:

public class DragMove : MonoBehaviour
{
	void OnMouseDrag()
	{
		Vector3 point = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x,Input.mousePosition.y,(transform.position.z-Camera.main.transform.position.z)));
		point.z = transform.position.z;
		transform.position = point;
	}
}

the code on the previous page, it is moving the object from the angle of camera, I need the version which moves the object in respect to planes, from cameras angle [ for example from the cameras angle if i move the object it moves on the direction of y, but i want it to move on the direction of x , or z because its my plane, alltough the object moves on x, and partial y and partial z because of my camera angle how can i block it from moving on y direction and make it move on z only?

Err, what @Scoutas said was exactly what you wanted. float yPos = target.position.y; if (yPos > highestPos) { highestPos = yPos; //Move Camera } else { //Don't move Camera }

–

Simpler with Unity’s new UI:

    public void OnDrag (PointerEventData eventData)
    {
        Vector3 delta = eventData.pointerPressRaycast.worldPosition - eventData.pointerCurrentRaycast.worldPosition;
        delta.z = 0; // this is to keep the camera's Z fixed, change at will
        m_camera.transform.position += delta;
        CheckLimits();
    }

Make sure you add the IBeginDragHandler, IDragHandler, IEndDragHandler interfaces to your MonoBehaviour.

Im not using a UI canvas to do this but is there a way to drag and drop an object in the 3d world space? I keep getting the error with not set to an instance of an object on these lines : Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); one under get mouse button one under get mouse button

–

Actually i do but the mouse thing im trying to go for is on a secondary camera thats set over a specific part of the scene thats activated like a mini game and its in that small area i want the mouse movement

–

I didnt even think about that Thank you so much Hellium much appreciated

–

Ok so now the issue I am having is its grabbing all the items and not just one at a time.

–