#1 Draggable Behavior Pointer Events
Friday, May 17, 2019
In this article we will do a little setup and then spend the majority of time focusing on dealing with user input, in our case both pointer up and pointer down, as it relates to our draggable behavior. We will first see how we wire up our event handlers using the Unity editor and once we have a better understanding of that process we will proceed to wire them up programatically so that we do not have to do the manual steps everytime we add our draggable behavior to an object.
Parts
- Part 4: Confine Using View Box
- Part 3: UI Camera
- Part 2: Follow Pointer Coroutine
- Part 1: Draggable Pointer Events
Project Start
- Assets
- UserInterface
- Scenes
- DraggableScene.unity
- DraggableBehavior.cs
- Scenes
- UserInterface
We will start by creating the UserInterface
folder within our Unity project.
Once that is done we will create an additional Scenes
folder that will contain our
scenes and we will create a new scene within it. Last up is to create our first script which we will name
DraggableBehavior.cs
and is shown in (a).
DraggableBehavior.cs
using UnityEngine;
namespace UserInterface
{
public sealed class DraggableBehavior : MonoBehaviour
{
}
}
Now that our script is created we will return to Unity and create a DraggableScene
and
within that scene we will add UI Panel. Once tha panel is added will need to set the anchors and the pivot to (0.5, 0.5),
the position to (0, 0) and height and width to 150 each. Next up we can add our DraggableBehavior
script
to our panel either by dragging the the script into the inspector on the right or by using the add component button. Once that
is done we should have everything set up as shown in (b).
How about a pretty green color?
- Assets
- UserInterface
- DraggableBehavior.cs
- UserInterface
My intention is to have the ability to drag a ui component around whenever our draggable behavior is active. To indicate to the user that
they can in fact drag something our first job is to define a color that will be shown when our component is active and to have that
color applied automatically for us (c). The property that we are calling
Handle
represents the game object that will be able to click and drag on to move the object. In
the end we will end up with the ability to drag around an ancestor container by clicking and dragging on a child. But for now
we will focus on just dragging our single panel around.
DraggableBehavior.cs
...
using UnityEngine.UI;
namespace UserInterface
{
public sealed class DraggableBehavior : MonoBehaviour
{
public Color activeColor = new Color(0.1f, 1f, 0.18f, 0.65f);
public Transform handle;
private Color ActiveColor => activeColor;
private Transform Handle
{
get
{
if (handle == null)
{
handle = transform;
}
return handle;
}
}
private void Awake()
{
Init();
}
private void Init()
{
var image = Handle.GetComponent<Image>();
if (image != null)
{
image.color = ActiveColor;
}
}
}
}
Once that is done and we return to Unity if we play our scene we should see that our panel is colored with the appropriate color as shown in (d).
Manual Event Handling
- Assets
- UserInterface
- DraggableBehavior.cs
- UserInterface
Next up we will add some event handling to our script. First up is just to add a couple of methods that we can use to wire up the event handling within the Unity editor (e).
DraggableBehavior.cs
...
using UnityEngine.EventSystems;
...
namespace UserInterface
{
public sealed class DraggableBehavior : MonoBehaviour
{
...
public void OnPointerDown(BaseEventData data)
{
Debug.Log($"pointer down: {data}");
}
public void OnPointerUp(BaseEventData data)
{
Debug.Log($"pointer up: {data}");
}
}
}
Now that we have the methods defined we can turn back to the Unity editor and add an
Event Trigger
component and within it add our
two entries, one each for pointer up and pointer down, and point them to the methods
we just created (f). With that done if he play
our scene we should see information printed to the console if we click on the panel.
Doing things manually is for the birds
- Assets
- UserInterface
- DraggableBehavior.cs
- UserInterface
I am a big believer in having things work with as close to zero configuration as possible and to that
end we will add our event handling within our script instead of having to wire things up manually
inside of the Unity editor any time we want to add our dragging behavior. First thing to do is to
remove the Event Trigger
component from our panel. Next up is
to modify our script to add the Event Trigger
component
and to wire up our entries (g).
DraggableBehavior.cs
...
namespace UserInterface
{
public sealed class DraggableBehavior : MonoBehaviour
{
...
private void ConfigureEventHandling()
{
var trigger = Handle.GetComponent<EventTrigger>();
if (trigger == null)
{
trigger = gameObject.AddComponent<EventTrigger>();
}
var pointerDownTrigger = new EventTrigger.Entry {eventID = EventTriggerType.PointerDown};
pointerDownTrigger.callback.AddListener(OnPointerDown);
trigger.triggers.Add(pointerDownTrigger);
var pointerUpTrigger = new EventTrigger.Entry{eventID = EventTriggerType.PointerUp};
pointerUpTrigger.callback.AddListener(OnPointerUp);
trigger.triggers.Add(pointerUpTrigger);
}
private void Awake()
{
...
ConfigureEventHandling();
}
...
private void OnPointerDown(BaseEventData data)
{
Debug.Log($"pointer down: {data}");
}
private void OnPointerUp(BaseEventData data)
{
Debug.Log($"pointer up: {data}");
}
}
}
If we check again by playing our scene and click on our panel we should see once again that we have the information being displayed in the debug console.
Enter the extension method
- Assets
- Utilities
- UiUtilities.cs
- Utilities
Adding the event handlers to our panel is a bit on the verbose side for me. And since this is an operation that we will do multiple times we might as well make it a bit easier on us to do. To do this we will create our first extension method (h).
UiUtilities.cs
using UnityEngine.Events;
using UnityEngine.EventSystems;
namespace Utilities
{
public static class UiUtilities
{
public static EventTrigger AddTrigger(this EventTrigger trigger,
EventTriggerType triggerType, UnityAction<BaseEventData> callback)
{
var entry = new EventTrigger.Entry { eventID = triggerType };
entry.callback.AddListener(callback);
trigger.triggers.Add(entry);
return trigger;
}
}
}
Updating our behavior
- Assets
- UserInterface
- DraggableBehavior.cs
- UserInterface
With our extension method in place we can update our draggable behavior to use it as shown in (i).
DraggableBehavior.cs
...
namespace UserInterface
{
public sealed class DraggableBehavior : MonoBehaviour
{
...
private void ConfigureEventHandling()
{
var trigger = Handle.GetComponent<EventTrigger>();
if (trigger == null)
{
trigger = gameObject.AddComponent<EventTrigger>();
}
trigger
.AddTrigger(EventTriggerType.PointerDown, OnPointerDown)
.AddTrigger(EventTriggerType.PointerUp, OnPointerUp);
}
...
}
}