Dragging a 3d Object in 2D space

I have a cube in my camera’s field of view and I want to be able to drag around on the screen in 2D. So how do I move a 3D object along a 2D plane and have the movement match the position of my Mouse? There is a DraggableGUIElement in the Wiki that moves GUI Elements around the screen, but GUI elements are 2D to start with which makes it pretty straight forward.

My thought process was to create a vector from the camera to the cube, then create a plane that was perpendicular to this vector, then constrain the movement of the cube within that plane. That makes sense to me logically, but creating the code for it is a different story.

Anybody try to do this already? Is there an easier way than what I described?

Thanks

Flash

This was discussed here. Only thing is, things have changed a bit in Unity 2. Namely, ScreenToWorldPoint used to use 0 in the z direction to mean the camera’s near clip plane, but now 0 just means, well, 0. So this bit:

p = mainCamera.ScreenToWorldPoint(Vector3(Input.mousePosition.x, Input.mousePosition.y, 0));

I believe needs to be

p = mainCamera.ScreenToWorldPoint(Vector3(Input.mousePosition.x, Input.mousePosition.y, mainCamera.nearClipPlane));

–Eric

but as a newbie, still wondering why the camera is involved at all. my goal is to use a simple plane, rendered using an image of a floor plan, with a few moveable things just sitting on the plane. use would grab them and slide them around. that’s it

so, if i may ask, what is the absolute barebones scripting approach to making anything draggable?

-thanks

You need some point of reference. Otherwise there is no way to tell what your 2D mouse movements are intended to do in 3D space.

The script in the linked thread would work perfectly for that. Just attach it to your draggable objects.

–Eric

thanks for responding. I thought, though, that the starting position of object to be moved is the refernce point of the motion?

Most click-and-dragging (all, as far as I know) uses raycasting. The camera is necessary because it provides a starting point for the ray. Keep in mind: if you didn’t have a camera, no 2D image would be displayed at all.

I’m using Bliprob’s wiimote plugin to create some controls using the wiimotes. btw if you haven’t tried it, the wiimote’s are an awesome tool.

Here’s what I ended up using as a solution. This is Carsten’s code that can be found if you follow the links on these threads. I converted it from JS to C# and it works exactly like I want it to. (this is code is heavily truncated)

public class wiiActions {

        private float currentZDistanceFromCamera;
	private Vector3 p;
	private Camera mainCamera;
		
	public void moveObject(Vector3 wiimotePos, GameObject moveOb, float distanceFromCamera) {
   		mainCamera = Camera.main;
                // Position on the near clipping plane of the camera in world space
   		p = mainCamera.ScreenToWorldPoint(new Vector3(wiimotePos.x, wiimotePos.y, mainCamera.nearClipPlane)); 
   		// Position relative to the eye-point of the camera 
   		p -= mainCamera.transform.position; 
   		// A relative position at the wanted z distance from the camera 
   		currentZDistanceFromCamera = Vector3.Dot(mainCamera.transform.forward, p ); 
   		p *= distanceFromCamera / currentZDistanceFromCamera; 
   		// The position in world space 
   		p += mainCamera.transform.position; 
    
   		moveOb.transform.position = p;    
	}

This is called as a function from a different class.

One of the other questions I had was how to make that work, how do you set up the structure (in C#) to call a function in another class.

Here’s the code in the “manager” class to call the function moveObject. (again, heavily truncated)

public class wiiMote: MonoBehaviour {        
        private wiiActions wii = null;

	// Initialization
	void Start () {
                cubeObject = GameObject.Find("Cube");
		wii = new wiiActions();
	}

	void FixedUpdate () {
		//Move object
		float objectToCamera = 80;
		if (wiimote_getButtonB(0)) {wii.moveObject(wiimotePos_1,cubeObject,objectToCamera);}
		
	}
}

where objectToCamera is an arbitary distance and cubeObject is simply a cube in the scene.

There’s a lot of code missing there for this but it shows how to call a function in another class. Makes for some nice structure in your code.

Hope this helps somebody out in the future

Flash