The only thing that remains to me is recreate a drag and drop because the previous one would’t work as you said
I need to understand how to move element UI on the screen to trigger Up/Down and move
I mean if you had a working third-party drag and drop solution then keep using that. You only need to figure out why the drop event wasn’t working, and where it isn’t working.
It actually require another visual element container maybe I should change DropEvent from VisualElement to GameObject as a prefab somehow
I think this is where it gets triggered
private void DragEnd(IPointerEvent ev)
{
if (!isDragging)
return;
VisualElement droppable;
bool canDrop = CanDrop(ev.position, out droppable);
Debug.Log($"droppable {droppable}");
if (canDrop)
droppable.RemoveFromClassList("droppable--can-drop");
target.RemoveFromClassList("draggable--dragging");
target.RemoveFromClassList("draggable--can-drop");
lastDroppable?.RemoveFromClassList("droppable--can-drop");
lastDroppable = null;
target.ReleasePointer(ev.pointerId);
target.pickingMode = lastPickingMode;
isDragging = false;
if (canDrop)
Drop(droppable);
else
ResetPosition();
if (removeClassOnDrag != null && removedClass)
target.AddToClassList(removeClassOnDrag);
}
protected virtual void Drop(VisualElement droppable)
{
var e = DropEvent.GetPooled(this, droppable);
e.target = this.target;
// We send the event one tick later so that our changes to the class list
// will take effect.
this.target.schedule.Execute(() => e.target.SendEvent(e));
}
and then on drop checking raycast maybe I’m not sure for now
So I spent an hour tonight working on this and it honestly wasn’t that difficult. Here’s a package with a working example of dragging visual elements over the scene and spawning objects at that position:
DragAndDropExample.unitypackage (24.3 KB)
The package in action: https://i.gyazo.com/593affae727fe9a72b90280c2adbb577.mp4
Overall didn’t find it too difficult. Just follow a bit of the tutorial I linked to see how to get the faux dragging element to work, the rest was straight forward.
Thank you very much. This is exactly what I was trying to achieve. Huge huge thanks
But Is there anyway of not using or covering the entire screen with Visual Element? Why I can’t just use drag and drop without it? In the ugui it doesn’t require you to create transparent image to cover entire screen. So this is the only way of doing it?
Did you ever find a solution for that? Because it always return true since we covering the whole area with UI Element
No unfortunately I gave up. I turned back to uGUI. I mean it is only about 2 lines of code in order to have a drag and drop in the game. Even tho after I get a solution from Spiney I couldn’t make it work properly and there was a bunch of the scripts that I honestly don’t know how they work… Too much complicated for me. I tried to search for tutorials but I found nothing. So I definitely switched back to uGUI because I have no idea how to continue.
And yes if you cover the whole screen with ui element it will always return true…
I’m genuinely concerned about the lack of creativity and lateral thinking here. My code also was not that complicated.
In my example there was a different element for dragging, and a different element for dropping.
The drop zone doesn’t cover the whole screen. It only covers the area to the right of the side bar. You can make it whatever size you want. You can also impose any conditions on whether a drop is successful or not. That is entirely up to your specific implementation details.
The drag zone covers the whole screen in order to be able to read the pointer move events wherever the pointer is on the screen, alongside positioning the faux element you’re dragging anywhere on the screen as well.
You can’t rely on tutorials for everything. At some point you need to solve your own problems, though this isn’t really a difficult problem.
I mean I’m not complaining about the solution but for me I still found it very complicated. I tried to think about it but still I couldn’t manage it.
I got the part where I drag and drop my cards into the field but I still don’t know how to replace drop zone in order to get rid of the whole coverage screen. I do understand that it needs to be there so it can read the pointer move event but what If I don’t want to cover the whole screen with ui element?
Why don’t you? What’s you reason for not wanting to?
Once again, the full screen visual element is only for dragging. It doesn’t handle the dropping. Another visual element is the drop zone. You can size it however you want.
Edit: You can also still predicate a successful drop by some condition in the scene itself. In my example we simply check if our camera raycast hits a game object with a specific component. It will make more sense for the drop to not be predicated on the UI itself.
I have a lot of game logic that depends on detecting whether the mouse or a finger is over UI elements. The problem is that it triggers as ‘over UI elements’ almost every time because the pointer is constantly over a UI element, which stops or prevents many things from working.
For example in uGUI I still can drag elements without setting or displaying anything on the entire screen and it’s not triggered as over ui element.
In our case using drop zone always cover it.
Then just hide and display the drag zone as needed. Namely you’ll want to set the elements style.display
to DisplayStyle.None
when not in use so it isn’t occupying any space in the screen.
This will require a restructure of the layout I had in my sample project, as I believe I had the sidebar and dropzone as children of the drag zone, but this could easily be adjusted so they’re siblings instead.
I think you miss the point. So here’s what happens when I start to drag cards.
Typically when I start to drag the card I need immediately disable drop zone before and after but doing this will prevent drag to stop from working right?
And after I release the mouse or a finger the drop zone still need to be disabled in order to not triggering any elements over ui so then this logic will work fine with my game normally so I’m not sure how could I solve it
I mean, again, the drop zone is a different visual element.
But… why do you disable the drop zones? That completely undermines the entire system.
You seem very set in your current logic. Obviously if you’re using a different system you may need to rethink your approach.
In any case, if you’re using UGUI now I’m not going to bother to keep trying to provide simple solutions.
Because it will breaks all the rules that I setuped in my scripts. If it triggers over ui it will prevent me from placing cards on the field and It will prevent me from moving it on the field in 3D.
And this is why I switched back. For a moment I thought it will be possible… It would definitely take a huge time on refactoring every code from scratch and this is a time consuming for me. And honestly I don’t want to change my code for such a simple thing when everything is working fine and without any issue. I didn’t know that UI Toolkit need to cover entire screen in order to drag elements it wasn’t mentioned anywhere.
I mean… my example is probably only one out of many possible solutions.
No doubt there are ways to do it without the full screen element. That would probably involve inducing some proper state (maybe a state machine) that determines when a drag starts, and positions a faux element using coordinates from the Input System, rather than a PointerMoveEvent
. Just spit balling ideas.
If you have specific requirements you may have to come up with a creative solution.
I think that your solution will help the other more like in 2D game. Cause it’s really that simple you can set entire screen as a game field with an image then yes it will work fine because the element will be the part of the game itself. But in my case the screen should remain completely empty except some UI on top or on the bottom.
I just don’t get it why such a simple thing like drag and drop is not there by default. I mean it is really necessary in most of the game for any specific case today.
I mean I’m sure there’s ways to test of your pointer is over a specific element, specific panel, or to filter out specific elements from your result.
Each Visual Element belongs to a panel and each panel has two methods to test what elements are under a position: Unity - Scripting API: IPanel
But then you need to assign everything manually everysingle element.