Mouse Click and Drag

I attempted to figure this out on my own, but fell short of accomplishing that feat.

Basically, I attached an OnMouseDown and OnMouseOver to register a ‘drag mode’ boolean and was then attempting to move a cube around constrained to the X/Y (using the Force2D script from Wiki).

I can’t seem to figure out though, how to translate Input.mousePosition to a valid world coordinate … I tried Camera.ScreenToViewportPoint and Camera.ScreenToWorldPoint … but both seemed to give me incorrect values …

Vector3 mp = Input.mousePosition;
Vector3 wp = camera.ScreenToWorldPoint(mp);
wp.z = depth; // depth is the value from Force2D
transform.position = wp;

That’s more or less what I had … and debug print outs gave me outrageous results …

I think I’m doing something completely backwards, but I’m not 100% sure … so I thought I’d pose the question to the community.

Thanks,

This is trickier than it seems (which is unusual for Unity). It’s also come up several times…maybe it should be in a FAQ. :wink: Fortunately Carsten graced us with a nifty script which you can see in this topic, which I suspect is what you’re after. There was also another topic recently where he did a variation on it for a similar purpose, but I can’t remember which topic that was exactly.

–Eric

I tried the suggestion in that thread, and my cube still jumps to the center of the screen and has very little adjustment in movement when I move the mouse around … the object is originally placed somewhere near the bottom of the screen …

any ideas?

Carsten put a revised version of the mouse drag script up on this post to help me. It might do what you want…
http://forum.unity3d.com/viewtopic.php?t=5946

I played with the script and had the same problem. It seems upping the ZDistance var higher than 5 (10 or so depending) and disregarding the z component when you transfer that position to your object helps.

I don’t know why yet, as I just threw it in some code for prototyping last night.

HTH,
-Jeremy

This will make your mouse drag any rigidBody you click and hold on:

var spring = 50.0;
var damper = 5.0;
var drag = 10.0;
var angularDrag = 5.0;
var distance = 0.2;
var attachToCenterOfMass = false;

private var springJoint : SpringJoint;

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

	var mainCamera = FindCamera();
		
	// We need to actually hit an object
	var hit : RaycastHit;
	if (!Physics.Raycast(mainCamera.ScreenPointToRay(Input.mousePosition),  hit, 100))
		return;
	// We need to hit a rigidbody that is not kinematic
	if (!hit.rigidbody || hit.rigidbody.isKinematic)
		return;
	
	if (!springJoint)
	{
		var go = new GameObject("Rigidbody dragger");
		body = go.AddComponent ("Rigidbody");
		springJoint = go.AddComponent ("SpringJoint");
		body.isKinematic = true;
	}
	
	springJoint.transform.position = hit.point;
	if (attachToCenterOfMass)
	{
		var 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 ("DragObject", hit.distance);
}

function DragObject (distance : float)
{
	var oldDrag = springJoint.connectedBody.drag;
	var oldAngularDrag = springJoint.connectedBody.angularDrag;
	springJoint.connectedBody.drag = drag;
	springJoint.connectedBody.angularDrag = angularDrag;
	var mainCamera = FindCamera();
	while (Input.GetMouseButton (0))
	{
		var ray = mainCamera.ScreenPointToRay (Input.mousePosition);
		springJoint.transform.position = ray.GetPoint(distance);
		yield;
	}
	if (springJoint.connectedBody)
	{
		springJoint.connectedBody.drag = oldDrag;
		springJoint.connectedBody.angularDrag = oldAngularDrag;
		springJoint.connectedBody = null;
	}
}

function FindCamera ()
{
	if (camera)
		return camera;
	else
		return Camera.main;
}

if this doesn’t work… :stuck_out_tongue:

Just got to trying this out, I’ve not yet tried the latest post for moving the rigidbodie’s … which, I was in fact trying to move a rigidbody … however …

I’m curious … why does my object get placed in the center of the screen when I click on it using the previous code?

ok – i just checked some stuff, basically, here’s what happens:

p = (-1503,521.8,3426.5)
m = (412, 284, 0)
w = (-1503.8, 521.8, 3430.5)

Where p is the final position calculated, m is Input.mousePosition and w is camera.ScreenToWorldPoint(m)

This is using the following code:

	var mainCamera = FindCamera();   
	// Position on the near clipping plane of the camera in world space
	var p = mainCamera.ScreenToWorldPoint(Vector3(Input.mousePosition.x, Input.mousePosition.y, 0));
	// Position relative to the eye-point of the camera
 	p -= mainCamera.transform.position;
	// A relative position at the wanted z distance from the camera
	var currentZDistanceFromCamera : float = Vector3.Dot(mainCamera.transform.forward, p );
	p *= wantedZDistanceFromCamera / currentZDistanceFromCamera;
	// The position in world space
	p += mainCamera.transform.position;
   
	Debug.Log(p + " / " + Input.mousePosition + " / " + mainCamera.ScreenToWorldPoint(Input.mousePosition));
	transform.position = p;

I’m not all that great at math, so I don’t quite get whats really going on … but this is a copy/paste from another thread that was mentioned above …

The only variable data is ‘wantedZDistanceFromCamera’ , which is set to 5.0 – I also tried 100.0 and 100000.0 … didn’t seem to make much of a difference to the result.

The box’s original position, before being translated is something like (-1452.143, -43.74426, -240.1693)

The scale is (0.64, 0.64, 0.64) and it’s a model from maya which is basically just a cube … no rotation or anything …

Gah, now I feel dumb … just checked the post again to see if i missed anything … and, I can’t believe I did this … I must have been tired or something, I copied the code from the first post and not the second post … and the second post works PERFECTLY …

lines up for a stoning

:slight_smile:

Another "Higgins" on the forum? :shock: How have I managed to miss that so far...

Now, let us commence with the stoning…

Dad??? :shock:

rofl!

ROTFLOL :smile:

HiggyB, I was wondering when someone was going to say something about that … haha

No chance there’s a relation, eh?

Doubt it … haha, I used to think the name was unique, then I found this thing called the internet :wink:

ducks from the stoning

Oddly enough, my dad’s name is David so…

Dad, is that you?

:stuck_out_tongue:

</thread hijack>

ok – did someone seriously create a new forum account just for that joke? Oiy!

HiggyB, haha …

:lol: This is just to funny. Two Higgens. Take a look at http://unity3d.com/company/people.html.

ifrog, yeah, I know he works for OTEE –

I tried the ‘family discount’ line when I ordered my license, didn’t work :stuck_out_tongue: