- Home /
How to Write a Drag and Drop script for Unity 5.3.3?
I am working on a Drag-and-Drop game for 2nd graders, which was assigned to me from school. I have almost no knowledge of coding, but i have set up a field to which i will drag an object into a "drop" object. I have an old script I have been trying to fix for Unity 5.3.3, but it doesn't work. I need a script I can attach to the "drag" object and the "drop object".
Here is the Drag script: (I use Visual Studio)
using System;
using System.Collections;
using UnityEngine;
class DragandDrop : MonoBehaviour {
private Color mouseOverColor = Color.blue;
private Color originalColor = Color.yellow;
private bool dragging = false;
private float distance;
void OnMouseEnter()
{
GetComponet<Renderer> ().material.color = mouseOverColor;
}
private object GetComponet<T>()
{
throw new NotImplementedException();
}
void OnMouseExit()
{
GetComponet<Renderer> ().material.color = originalColor;
}
void OnMouseDown()
{
distance = Vector3.Distance(transform.position, Camera.main.transform.position);
dragging = true;
}
void OnMouseUp()
{
dragging = false;
}
void Update()
{
if (dragging)
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
Vector3 rayPoint = ray.GetPoint(distance);
transform.position = rayPoint;
}
}
}
I have no current script for the object the item is dragged onto.
I'm not quite sure what you're trying to accomplish here, can you explain in detail what you're trying to do?
@Paricus I am trying to make a drag and drop game for my school project. The script above was placed on the object that would be dragged, but it is outdated. I am trying to code the drag object and the object that the drag is dropped onto, aka, say, a block is dropped onto a target area, then you gain points from that. The only bad thing is, I have to make the game 2d.
Answer by Koen-Matthijs · Jan 16, 2017 at 11:54 PM
You can use the event systems. Below is an example. Use it on a test scene as follows:
Create a new scene
Add an EventSystem to the scene
Add a Physics Raycaster to the Main Camera
Add a primitive (eg cube) to the scene
Attach the script below to the cube
Fill OnDrag() with whatever functionality you like (eg repositioning the cube based on mouse position which is in the PointerEventData parameter).
All available interfaces are explained in the online documentation under UnityEgine.EventSystems/Interfaces. It takes a while to figure out but is easy to implement once you understand.
using System;
using UnityEngine;
using UnityEngine.EventSystems;
public class DragNDropExample : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
int initialPointerId;
void Start()
{
initialPointerId = int.MaxValue;
}
void OnBeginDrag(PointerEventData eventData)
{
if (initialPointerId == int.MaxValue)
{
initialPointerId = eventData.pointerId;
}
}
public void OnEndDrag(PointerEventData eventData)
{
if (initialPointerId == eventData.pointerId)
{
initialPointerId = int.MaxValue;
}
}
public void OnDrag(PointerEventData eventData)
{
if (initialPointerId == eventData.pointerId)
{
// DO WHATEVER YOU WANNA DO DURING DRAGGING HERE
}
}
}
@$$anonymous$$oen-$$anonymous$$atthijs
Works, except I get problems at IBeginDragHandler It says:
interface UnityEngine.EventSystems.IBeginDragHandler
'DragNDropExample' does not implement interface member 'IBeginDragHandler.OnBeginDrag(PointerEventData)'.'DragNDropExample.OnBeginDrag(PointerEventData) cannot implement an interface member because it is not public.
and when I try to implement an interface it doesn't work.
You're right. The OnBeginDrag method in my example needs to be public. Change it to :
public void OnBeginDrag(PointerEventData eventData)
@$$anonymous$$oen-$$anonymous$$atthijs
So am I supposed to put it where the void OnBeginDrag(PointerEventData eventData)
, replacing the code? Also, do I put an On$$anonymous$$ouseDown portion of code where it says DO WHATEVER YOU WANNA DO DURING DRAGGNG HERE?
Sorry about my confusion, I noticed the public void mistake when you posted the answer. I should have seen it earlier.
@$$anonymous$$oen-$$anonymous$$attHijs Hi All thanks for this work 100% one question? If I use a terrain or block as ground how can I prevent the mouse to drop or move the object that it don't fell thru the floor
@geniraal What do you mean by the object is falling through the floor? if you are using 2d objects in 3d mode, like the Robot Boy asset, he will fall through the floor unless you put a platform there to stop him. Have you added mesh colliders? If you are using a complicated object like, say, a sword, then if I were you I would use the mesh collider, box (has to be resized) or the cylinder collider (also has to be resized)
Answer by RadioR4Y · Jan 27, 2017 at 12:56 AM
Thanks for the help, I was confused on the scripting problem until I searched some stuff and found it out. I used your script and this new one i found, which works just as well.
using UnityEngine;
using System.Collections;
public class DragAndDrop : MonoBehaviour
{
private bool _mouseState;
private GameObject target;
public Vector3 screenSpace;
public Vector3 offset;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
// Debug.Log(_mouseState);
if (Input.GetMouseButtonDown(0))
{
RaycastHit hitInfo;
target = GetClickedObject(out hitInfo);
if (target != null)
{
_mouseState = true;
screenSpace = Camera.main.WorldToScreenPoint(target.transform.position);
offset = target.transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenSpace.z));
}
}
if (Input.GetMouseButtonUp(0))
{
_mouseState = false;
}
if (_mouseState)
{
//keep track of the mouse position
var curScreenSpace = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenSpace.z);
//convert the screen mouse position to world point and adjust with offset
var curPosition = Camera.main.ScreenToWorldPoint(curScreenSpace) + offset;
//update the position of the object in the world
target.transform.position = curPosition;
}
}
GameObject GetClickedObject(out RaycastHit hit)
{
GameObject target = null;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray.origin, ray.direction * 10, out hit))
{
target = hit.collider.gameObject;
}
return target;
}
}
Works perfectly now, all I have to do is figure out how to add an element that allows players to write what they want in the "Text boxes" (aka, cubes) and drag them to arrange a word.
@$$anonymous$$oen-$$anonymous$$attHijs
Sorry for posting the other script above, I used that one ins$$anonymous$$d of yours. I updated Unity and found that the other one doesn't work, but yours does. Thanks for the scripts, and is there any way I can use the script to drag text?
Answer by nightdr3am · Oct 12, 2017 at 12:15 PM
hi i was wondering if you can help me scripting the drag and drop system.
my aim is to create a CTG of an existing physical version of the game in a digital world. i saw a script that was written by @Rustelk2930. i would like to know if this scripting is best suited for CTG. my aim is to have a hand of card and placing the card on 3D surface in a certain place can you help.
Since these scripts worked in 5.3.3, it may not work in the beta or newer versions.
I don't know what CTG means, but these scripts were written mainly for 2d mode, be careful if that's what you want
Both scripts should work
sorry about the confusion CTG stands for Card Trading Game. because i was following a tutorial that uses screen space overlay for drag and drop via using a canvas in a 3D project. however it was quite limited in depth. So i chose world space rendering mode. to add depth however by doing that existing code it misplace the sprite in the z axis ins$$anonymous$$d of x or y. thats why i request some help. i could give you my email so we can talk if you like. its halcyonspree@gmail.com