DEV Community

Matthew Odle
Matthew Odle

Posted on

Simple UI Element Dragging Script in Unity C#

Attach this script to your gameobject/prefab to enable a simple drag mechanism for your UI elements. You'll also need to add the EventSystem object to your scene.

It's fairly straightforward. The overridden UnityEngine.EventSystems.OnPointerDown and OnPointerUp methods simply toggle the dragging bool. Then the Update method will modify the position of the object this script is attached to.

With this solution, the UI element's center will snap to the cursor, but to make this cleaner, an offset can be added based on the position within the UI element when the OnPointerDown is triggered.

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class UIElementDragger : EventTrigger {

    private bool dragging;

    public void Update() {
        if (dragging) {
            transform.position = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
        }
    }

    public override void OnPointerDown(PointerEventData eventData) {
        dragging = true;
    }

    public override void OnPointerUp(PointerEventData eventData) {
        dragging = false;
    }
}

Discussion (2)

Collapse
chrisbarrow89 profile image
Chris Barrow

Hey thank you for the script it's exactly what i was after, only thing i'm struggling to get it so it doesn't centre on mouse click. I would like the component to move from where the mouse is clicked. any ideas how i could do this please?

Collapse
handelo profile image
Handelo

As Matthew mentioned in the original post, all you need to do is capture an offset value on click and add that offset to the position change in the Update() method.
You can also circumvent using an Event System by inheriting from MonoBehavior and the pointer up/down handler interfaces instead of an EventTrigger.

So:

public class Draggable : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
    private bool dragging;
    private Vector2 offset;

    public void Update()
    {
        if (dragging)
        {
            transform.position = new Vector2(Input.mousePosition.x, Input.mousePosition.y) - offset;
        }
    }

    public void OnPointerDown(PointerEventData eventData)
    {
        dragging = true;
        offset = eventData.position - new Vector2(transform.position.x, transform.position.y);
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        dragging = false;
    }
}
Enter fullscreen mode Exit fullscreen mode