1
\$\begingroup\$

I am able to make my UI panel draggable. Here is the script, it will be helpful:

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;
    }
}

It is working fine but with one issue. Each time I click to drag the panel, my UI panel drag from the center (i have custom panel anchor). Is there any way available to move it with the clicked position of UI? I mean it should be draggable from where i have clicked. Certainly, problem lies in this line

transform.position = new Vector2(Input.mousePosition.x, Input.mousePosition.y);

transform.position need to change to clicked position of object?

https://www.youtube.com/watch?v=gayEHaol4Lc

\$\endgroup\$
1
  • \$\begingroup\$ Did you try storing the offset of the click in OnPointerDown, and using it to shift the position you assign in Update? \$\endgroup\$
    – DMGregory
    Sep 25, 2020 at 13:14

2 Answers 2

1
\$\begingroup\$

This is pretty trivial:

private bool dragging;
public Vector2 dragOffset;// = new Vector2(5,5); // Store the offset of the center/pivot from the clicked position.

public void Update()
{
    if (dragging)
    {
        transform.position = (Vector2)Input.mousePosition
                           + dragOffset; // Add the offset when dragging to get the center point.
    }
}

public override void OnPointerDown(PointerEventData eventData)
{

    dragging = true;

    // Compute the offset from the cursor position to the object's center/pivot.
    dragOffset = (Vector2)transform.position - (Vector2)Input.mousePosition;    
}


public override void OnPointerUp(PointerEventData eventData)
{
    dragging = false;
}
\$\endgroup\$
0
\$\begingroup\$

Here is another version of dragging and keeping click position offset.

This one uses delta value of eventData, so you'll have to also take Canvas scaleFactor into calculation.

Note, this one works with both:

  • Screen Space - Overlay Canvas
  • Screen Space - Camera Canvas

This solution doesn't work with World Space Canvas (for VR/AR?), for such solution you'll have to use (maybe) local coordinates of Canvas RectTransform and RectTransformUtility.ScreenPointToLocalPointInRectangle to get your Canvas positions.

public class DragItem : MonoBehaviour, IDragHandler
{
    Canvas canvas;

    private void Awake()
    {
        canvas = GetComponentInParent<Canvas>();
    }

    public void OnDrag(PointerEventData eventData)
    {
        transform.localPosition += (Vector3)eventData.delta / canvas.scaleFactor;
    }
}
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .