How to drag UI element immediately after instantiating/spawning it on tap/click.

The problem right now is that after i spawn/instantiate the dragable UI element by tapping(OnPointerDown) the spawn UI element, i have to lift my finger and tap the dragable UI again (which spawns on top of the spawn point).

I want this to be 1 smooth motion. 1 Tap(and hold) - instantiate - somehow force the drag event on the dragable UI element - drag the UI to new position - profit.

I am struggling to find information how to use/manipulate these events. the docs tell me what they do but i am thinking more like a guide on how to use them. example like how to force an event or what event fires before the other etc. any info on this is very much appreciated.

1 Like

I tried recreating this and I think I have a solution.

In my case, as soon as I start dragging the UI element, I instantiate the new element. In the script where you are instantiating your new UI element, you’re going to want to assign the element to eventData.pointerDrag.

public class DragSpawnTest : MonoBehaviour, IDragHandler, IBeginDragHandler
{
    public GameObject testUI;
    public GameObject parentCanvas;

    public void OnBeginDrag(PointerEventData eventData)
    {
        GameObject go = Instantiate(testUI, eventData.position, Quaternion.identity);
        go.transform.SetParent(parentCanvas.transform, false);
        eventData.pointerDrag = go; // assign instantiated element
    }

    public void OnDrag(PointerEventData eventData)
    {
    }
}

Then in a script attached to your instantiated UI element, you can have your OnDrag event. The element will continue to follow your mouse.

public void OnDrag(PointerEventData eventData)
    {
        _rectTransform.position = eventData.position;
        Debug.Log("Dragging");
    }

Thanks to @valdeezzee's answer, I was able to figure out how to create and drag the created object, but exactly after pressing on the first object, as the author of the question @RustyCrow and I wanted. Thus, regardless of whether you started dragging or not, a new object will still be created.

Here is code on base of valdeezzee's example. We need IInitializePotentialDragHandler and IDragHandler in our first object, which is the button in this case. OnInitializePotentialDrag is called when the button is clicked, so that's the point. But without having IDragHandler this will not work.

public class FirstObject : MonoBehaviour, IInitializePotentialDragHandler, IDragHandler {
    public GameObject testUI;
    public GameObject parentCanvas;

    public void OnInitializePotentialDrag(PointerEventData eventData) {

        // Here we instantiate the second object, that we want to drag. 
        GameObject go = Instantiate(testUI, eventData.position, Quaternion.identity);
        go.transform.SetParent(parentCanvas.transform, false);
        //

        eventData.pointerDrag = go; // assign instantiated object
    }
    public void OnDrag(PointerEventData eventData) {
    }
}

The rest is the same. This is the scipt attached to the dragable, fresh created object.

public class DragableObject : MonoBehaviour, IDragHandler {
    public void OnDrag(PointerEventData eventData) {
        _rectTransform.position = eventData.position;
        Debug.Log("Dragging");
    }
}

You can shoot a ray at the canvas, get the position of where the ray hit and set the object’s transform to that position. So it will drag along with your mouse.

So a friend of mine sent me a “reasonable answer” to my question (Original Post).

The TLDR → You can piggyback off the OnDrag event activation from the Spawner, since you already need to press it once to spawn the UI element. So
Spawner.OnDrag { instantiatedObj.draglogic }. The important point is that the OnDrag() calls are now done in the Spawner not on the Draggable UI.

I dont really like this solution as its not the spawners “Job” to have the OnDrag() calls and not to mention the confused PointerEventData as you are now technically dragging the Spawner, but here it is and it works.

I would also like to add and alternative approach, just spawn in the amount of draggable object at the start of the level and just drag them from there.