- Home /
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.
Answer by valdeezzee · Feb 10, 2020 at 08:18 PM
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");
}
thank you so much, thats a really neat way of handling things!
Answer by Niserent · Apr 12 at 10:21 AM
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");
}
}
Answer by SunnyPalmSprings · May 21, 2019 at 02:55 PM
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.
I am using OnDrag right now to make my UI element draggable. The issue is the Activation of OnDrag function not actually moving the UI. I could Spawn a X amount if Elements at the start of the level, but if i need an infinite amount its going to get cumbersome to tap 1 to spawn tap again to drag.
How about shooting a ray ins$$anonymous$$d of using OnDrag() ?
Graphic Raycaster what you do when using OnDrag . But you are thinking about using actual raycast and Update () to move the UI? hmm i feel like it is a step back unless i am misunderstanding what you are saying. unity has made the current setup to allow for simple manipulation of the UI. If i use the ScreenPoint stuff i would have to make a completely new setup. I might give this a try if i cant find a alternative.
Answer by RustyCrow · May 23, 2019 at 05:09 PM
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.