Drag & Drop
Overview
The drag & drop feature makes it very easy to add drag/drop support to your game. It even supports multi-touch, meaning on a touchpad device, you can drag/drop multiple objects with multiple fingers at once, and completely independently of each other. The quick-start steps are:
That's all there is to it! Now on to a more thorough explanation: |
In-depth
First, you will notice a few drag/drop-specific inspector settings which have been added for drag & drop support, and easing its use:
UIManager * Default Drag Offset - This is the default distance an object being dragged will be offset toward the camera so as to ensure that it "hovers" above other objects in the scene. This can be overridden in individual objects, if desired. If you find your controls are winding up "behind" other objects in the scene when you drag it, increase this value. * Cancel Drag Easing - The easing to use when a drag operation is canceled. If you drop an object without a suitable drop target, it will using this easing method to move back to the place from where you dragged it. * Cancel Drag Duration - This is the number of seconds the aforementioned animation should take.
Note that all the above settings in UIManager are just defaults. All of these settings can be overridden in individual controls, if desired. But if you leave the individual controls at their defaults, the values in UIManager will be used.
All controls * Is Draggable - When this box is checked, the control will be dragged if you drag it, and will generate drag & drop notifications for your delegates and other scripts. * Drag Offset - Same as in UIManager. If left at the default of NaN, the value in UIManager will be used. * Cancel Drag Easing - Same as in UIManager. If left at "Default", the value in UIManager will be used. * Cancel Drag Duration - Same as in UIManager. If left at the default of -1, the value in UIManager will be used.
How to use it Once you've checked the "Is Draggable" box, the control will drag around when you drag it with your pointer. It's that easy. To react to the dragging and dropping, you can do one, or both, of two things:
1) Simply write an OnEZDragDrop() method in your own script, attached to the object you wish to receive dropped objects (see below for more details). or 2) Register a delegate to be called by either the object being dragged, the object being dropped on, or both. This is done by calling any EZ GUI control's .AddDragDropDelegate() and passing it your delegate. The advantage to using delegates is you will be informed when the object being dragged begins its drag operation. This gives you the opportunity to respond to the initiation of the drag.
Below is a code example of a suitable method to respond to drag/drop messages, and this is also what a delegate should look like for use with AddDragDropDelegate(). This is a very simple example:
void OnEZDragDrop(EZDragDropParams parms)
function OnEZDragDrop(parms : EZDragDropParams)
First, you'll note that OnEZDragDrop() receives an EZDragDropParams structure. This contains three pieces of information:
* evt - the drag/drop event that has occurred. * dragObj - A reference to the object being dragged. * ptr - A POINTER_INFO structure that can contain information about the pointer dragging the object. Note, however, that some types of drag/drop events will not populate this structure with relevant information as no pointer is involved in these types of events.
Next, note that we check for the "Dropped" event. This is sent when an object is being dropped onto a "drop target". This message is sent both to the control being dropped, to any registered delegate thereof, and to the drop target object itself. This lets you place the logic of validating a drop action in a place that makes sense for your game. If it makes more sense to let the drop target object decide for itself, you can do that. If however, the item being dropped should be the one to decide, you can do that as well. Finally, you'll note that we set the dropObj's .DropHandled property to true. This tells EZ GUI that the drop was a success and therefore not to cancel the drag by returning the object to its original position. At this point, it is up to your code to do whatever you want with the dropped object. That's all there is to basic dragging and dropping. Of course, there's more you can do. Below you'll find a basic skeleton method that handles all the supported drag/drop events, and describes each in the comments: void OnEZDragDrop(EZDragDropParams parms)
function OnEZDragDrop(parms : EZDragDropParams)
|
You can define an OnEZDragDrop() method in any script, in either C# or JS. As long as the object you attach it to has a collider and is in a layer where EZ GUI will "see" it, it can be a drop target and its OnEZDragDrop() method will be called automatically whenever an EZ GUI control is dragged over it. That means ANY object can be a drop-target, not just EZ GUI controls. So you can use this to drop EZ GUI controls onto 3D in-world objects, if you want, for example. As shown in the example above, store the data you want communicated in the drag/drop operation in the control's .Data property. .Data is of type System.Object, meaning it can point to anything. In the example above, we've used it to point to "MyPickupInfo" which would be a class containing all the information I need for the item being dropped. There are also some drag & drop-specific properties and methods to EZ GUI controls you may find useful when working with drag-and-drop:
* IsDragging - This indicates whether the object is currently in the midst of being dragged/dropped. * DropTarget - When this is non-null, it points to the first GameObject detected "behind" the object being dragged. This object will have its OnEZDragDrop() called, if any, while the dragged object is over it. * CancelDrag() - Lets you cancel a drag operation mid-stream. This will do the same thing as if the item was dropped over an invalid drop target. |
Additional Considerations
Drag alignment The point that is checked against drop targets, etc, is the point where the touch/click is. So if you grab your draggable object at its edge, then drag it over your drop area, it won't "hit" the drop area unless your pointer itself is over the drop area, even though the majority of the visible portion of the object being dragged may be over the drop area. So be sure to keep this in mind. If you would prefer the dragged object always remain centered around the pointer so as to help avoid confusion, comment out this line at the top of EZDragDropHelper.cs:
#define DONT_CENTER_OBJECT
Drag threshold Note that the drag threshold setting is the distance a pointer is allowed to drift from the point where it was first "pressed" (or went "active") before being considered a DRAG event. This means if you have a drag threshold set very high, then this threshold must be exceeded before the control begins to be dragged. Keep this in mind if it seems you have to drag a long distance before the control starts to follow, or if it doesn't follow at all.
Destroying objects being dragged/dropped If you plan on destroying an object when it is dropped, do one or more of the following: * Mark the drop as handled as described in the instructions above. * Set the control's .UseDefaultcancelDragAnim to false. * Don't destroy the control until the CancelDone event is received. |