Drag and Drop Javascript

Hi all,

I have a blocking issue with this, an since I’m new in Unity, I need somebody that could give me a hand.

I create a buttom with a GUI.Texture and I need to move this button with the mouse, but with a small detail: this button should not disapear from the original position. I don’t know how to do a drag and drop script for the button, and I don’t image how to do to move a copy and not the original, because I need to be able to take a lot of this button and move it around the screen.

Thanks in advance!

Ana

Your main problem, I think, is using ScreenToWorldPoint. GUITexture transforms are not in world space, but in viewport space, you want to convert between screen coordinates (pixel, mouse) and viewport coordinates (GUITextures transforms)

I happen to have a demo of this behavior handy which covers the whole deal, dragging a “ghost” proxy object, so the drag source button stays where it is, then dropping a new instance. Put it together for a friend, so it’s fairly well commented

whole scene uses three prefabs:

DragSource - one instance placed in scene, with the following script attached to it

DragGhost - separate object with same GUITexture settings but color’s alpha reduced to ~64 so you can see through to where you’re dropping. No scripts or other components besides the GUITexture. Placed in scene along with DragSource, should have it’s GUITexture component disabled initially in the inspector.

DropObject - whatever object you want to place; a clone of DragSource works, though you’ll want to remove the script unless you want every dropped copy to become a new drag source.

and here’s the script…

//DragDemo.js

//simple demo of drag and drop with "ghost" copy in unityscript
//written by Will Thomas, nov. 2011, 
//no rights reserved, do whatever the hell you want with it

//position of our drag source button in screen space
var screenPos:Vector3;

//offset from where they begin the drag to the center of the button/object
var offset:Vector3;

//holds current position during drag
var currentPos:Vector3;

//reference to the prefab we instantiate on drop
var dropObject:Transform;

//some cached variables
//my GUITexture
private var texture:GUITexture;
//the ghost button object
private var ghostButtonObj:GameObject;
//the ghost button's GUITexture component
private var ghostButtonTex:GUITexture;

function Start()
{
	//cache some things..
	//our (the drag source's) GUITexture
	texture=GetComponent(GUITexture);
	//the GameObject and GUITexture of the GhostButton object
	ghostButtonObj=GameObject.Find("GhostButton");
	ghostButtonTex=ghostButtonObj.GetComponent(GUITexture);
	//and calculate the screen position of our guitexture
	screenPos=Camera.main.ViewportToScreenPoint(transform.position);
}

function OnMouseDown() 
{
	//enable the ghost's texture
	ghostButtonTex.enabled=true;
	
	//calc the offset of the drag point to the object
	//screen position (precalc'd above) minus mouse pos
	offset = Input.mousePosition - screenPos; 
}
 
function OnMouseDrag() 
{ 
	//adjust mouse pos by offset...
	currentPos = Input.mousePosition-offset;
	//and move the ghost object to that position translated into viewport space
	ghostButtonObj.transform.position=Camera.main.ScreenToViewportPoint(currentPos);
}

function OnMouseUp()
{
	//dropping, convert the position to viewport space
	var viewportPos=Camera.main.ScreenToViewportPoint(Vector3(currentPos.x,currentPos.y,10));

	//instantiate at viewportPos, just use our rotation
	var newButton = Instantiate(dropObject,viewportPos,transform.rotation);

	//move the ghost back to the original position
    ghostButtonObj.transform.position=transform.position;
    //deactivate the ghost so it won't draw until we drag again
	ghostButtonTex.enabled=false;
}

Thanks for your answer! The code is very clear and useful!!! Now I can make multiple copies of a button. Now I have the problem that each of these children also generate many copies, how I can do to make the script only affects the original button and not your childrens?

Thanks in advance!!

Ana.

I used a DropObject with a script that only have this:

function Start(){

screenPos=Camera.main.ViewportToScreenPoint(transform.position);

}

function OnMouseDown()
{

screenPos=Camera.main.ViewportToScreenPoint(transform.position);
offset = Input.mousePosition - screenPos; 
print("BUUU");

}

function OnMouseDrag()
{

currentPos = Input.mousePosition-offset;
gameObject.transform.position=Camera.main.ScreenToViewportPoint(currentPos);

}

function OnMouseUp()
{

var viewportPos=Camera.main.ScreenToViewportPoint(Vector3(currentPos.x,currentPos.y,10));
gameObject.transform.position=transform.position;

}

But I have a random behavior, some of the childrends from the original button generate copies and some not… can somebody explain me why is happening this?

I’m using a ghost object with no script attach, as you suggested in the first response. I attach the first script to the DragSource, no script on DragGhost and the script that I put before on the DropObject.
The script that you give me looks like this on my DragSource Object: I reduce the code a little bit because I have 7 buttons…

private var screenPosDerecho:Vector3;
var offset:Vector3;
var currentPos:Vector3;
var dropObject:Transform;
private var ghostButtonObjDerecho:GameObject;
private var ghostButtonTexDerecho:GUITexture;
// I delete the rest of the variables for the other buttons to simplify the code

function Start()
{
ghostButtonObjDerecho=GameObject.Find(“derechoghost”);
ghostButtonTexDerecho=ghostButtonObjDerecho.GetComponent(GUITexture);
screenPosDerecho=Camera.main.ViewportToScreenPoint(transform.position);

    //repeat the same code for the other 6 buttons

}

function OnMouseDown()
{

    if(ghostButtonObjDerecho){
	ghostButtonTexDerecho.enabled=true;
	offset = Input.mousePosition - screenPosDerecho; 
}
//repeat the same code for the other 6 buttons

}
function OnMouseDrag()
{

    if(ghostButtonObjDerecho){
	currentPos = Input.mousePosition-offset;
	ghostButtonObjDerecho.transform.position=Camera.main.ScreenToViewportPoint(currentPos);
}
 //repeat the same code for the other 6 buttons

}
function OnMouseUp()
{

   if(ghostButtonObjDerecho){
	var viewportPos1=Camera.main.ScreenToViewportPoint(Vector3(currentPos.x,currentPos.y,10));
	var newButton1 =Instantiate(dropObject,viewportPos1,transform.rotation);
	ghostButtonObjDerecho.transform.position=transform.position;
	ghostButtonTexDerecho.enabled=false;
}
//repeat the same code for the other 6 buttons	

}