- Home /
Can I make a non UI gameObject draggable by implementing the IDragHandler interface?
I've been following an online tutorial where Ui Components are dragged by implementing the IDragHandler interface but when I tried to apply it to a non UI gameObject it's not working, is there a way to make it work and any helpful tutorials on the subject?
Answer by troien · Mar 27, 2016 at 09:16 AM
You can.
You need to set up your eventsystem accordingly however.
To do this you need 2 things.
An EventSystem
A raycaster (A canvas uses a GraphicRaycaster, but you can also use Physics2DRaycaster or PhysicsRaycaster).
To make your object respond to events, simply add a PhysicsRaycaster to your camera, make sure you have an eventsystem somewhere in the scene, and that your MonoBehaviour implements IDragHandler (and make sure it has a collider obviously).
As for how to implement dragging, this is a simplified piece of code that allows you to drag in world x/z.
using UnityEngine;
using UnityEngine.EventSystems;
public class DragExample : MonoBehaviour, IDragHandler
{
public void OnDrag(PointerEventData eventData)
{
// Vector3.up makes it move in the world x/z plane.
Plane plane = new Plane(Vector3.up, transform.position);
Ray ray = eventData.pressEventCamera.ScreenPointToRay(eventData.position);
float distamce;
if (plane.Raycast(ray, out distamce))
{
transform.position = ray.origin + ray.direction * distamce;
}
}
}
I know this is a bit old, but can you explain what's happening here, particularly with the plane and why it's necessary?
I'll try to explain this using words. Sinse my drawing skills are terrible... But I hope I'm clear enough so you can visualize it in your head yourself :)
First thing, to be sure you don't misunderstand. This Plane is not an actual GameObject that exists in the world, It is just a bit of data (position and normal) that represents a 2D plane on which we are dragging the object in a 3D world.
When dragging a 2d object in a 2d world, dragging is straightforward, as you can move the mouse over a 2d plane (in screen space) and the object moves along over the same 2d plane.
In 3d this can be more complicated, as you still move your mouse over a 2d plane (screen space). But the object you want to move has this extra dimension it might want to move in. If you would drag using the same plane as the camera, you can't move your object in this extra third dimension, and rotating the camera would mean you are suddenly moving the object on a different plane. This type of dragging could be what you want, but in most cases it is just very frustrating for the user, as having to perfectly rotate the camera in order to move an object in the direction you want is just really annoying.
Therefore we limit dragging to a fixed 2d plane, but unlike in a 2d world, this 2d plane doesn't have to align with the camera. $$anonymous$$eaning that if we rotate our camera, the plane on which we move our object doesn't change, making dragging much more intuitive. To do this we create an (imaginary/invisible) plane on the position of the object we are dragging with a 'normal' indicating which direction the plane is facing in world space. (Vector3.up is the most common one as it means you can drag the object along x/z (i.e. ground), but if you want to drag it along a different plane you can change this for your needs)
We then cast a ray from the camera, through the mousePosition and look at which point it intersects our imaginary plane, we then place our 3d object at the position where the ray intersects the plane.
There are other options ofcourse, but that all depends on how you want to drag the object. You could for instance raycast your terrain ins$$anonymous$$d, and move it along the point where you intersect your terrain. But I opted to give a example that works in practically all setups, as the OP didn't specify a setup nor how the objects should be dragged.
Answer by Geometrical · Mar 26, 2016 at 07:57 PM
No, you'll have to write up your own code structure.
Your answer
Follow this Question
Related Questions
How can I drag just one object, but not all the objects ? (Android) 1 Answer
Terminate drag while mouse is still down 0 Answers
How to reset clear UI events after game is paused? 0 Answers
Drag and drop picks an object too far away from mouse position 2 Answers
Cancel a drag and drop movement 1 Answer