- Home /
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
I'm using this code now,
function On$$anonymous$$ouseDown() { scanPos= gameObject.transform.position; screenPoint = Camera.main.WorldToScreenPoint(scanPos); offset = scanPos - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z)); }
function On$$anonymous$$ouseDrag() { curScreenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z); curPosition = Camera.main.ScreenToWorldPoint(curScreenPoint) + offset; transform.position = curPosition; }
But when I'm dropping the button, is very far away from the mouse and is very dificult to control. Please help!!!
Answer by WillTAtl · Nov 20, 2011 at 01:41 AM
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;
}
Answer by AnaF · Nov 28, 2011 at 09:36 PM
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.
Answer by AnaF · Nov 28, 2011 at 09:36 PM
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?
If this is the only script on the dropped copies, I'm not sure why any of them would be copyable. This script never even calls Instantiate, so I find it very strange!
What modifications have you made in the drag source's script? And if you're using a ghost object while dragging from source, are there any scripts attached to it?
Answer by AnaF · Nov 28, 2011 at 11:53 PM
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
}
Hmm. All I can think to say is doublecheck your prefabs for the dropped versions, and make sure you've not linked any of the dropObject fields to the dragSource prefabs by mistake.
Also, you should really post this sort of thing in comments, or edit them into the original question, rather than posting them all as new answers! Just a unityAnswers best practices tip!
Your answer
![](https://koobas.hobune.stream/wayback/20220613050221im_/https://answers.unity.com/themes/thub/images/avi.jpg)