Hit result under cursor while dragging widgets

Hello,
I’ve created a simple draggable widget that creates a drag operation. The class of the DragVisual is different from the actual draggable widget. It consists only of an image. Both the DragVisual widget and its image are set to HitTestInvisible.

Inside the PlayerController I perform a GetHitResultUnderCursorByChannel operation with a custom trace channel (LandscapeTrace). As soon as I start the drag operation I stop receiving information about objects under the cursor - the operation always returns false.

Is there any way to fix this? Any help will be highly appreciated.

2 Likes

It’s complicated, sort of.

As soon as I start the drag operation
I stop receiving information about
objects under the cursor - the
operation always returns false.

That’s pretty normal, the Player Controller does not receive mouse input during drag operation. The widgets take over.


The goal:

Have the widget send the screen location to the player controller which can then line trace for objects in world space. Essentially, you want to drag a widget and have the cursor react to world space, too.


The method:

  • in the Player Controller (PC) create a custom event with a 2d vector input - this is how the PC is going to receive the data
  • in the content browser create a custom Drag & Drop Operation
  • in that operation override onDragged - it reports the mouse screen location during drag
  • you can’t cast to the player controller from here, though (!) so you’ll need onDragged to call an event dispatcher, broadcasting a 2d vector with the mouse coords
  • when you detect dragging, in onDraggedDetected, rather than creating a standard operation, create a custom one mentioned in the beginning, and dynamically bind its dispatcher to the event in the PC (step 1)
  • at this point the PC will be receiving screen coords, convert Absolute to Viewport to get window’s local space
  • now Convert Screen Location To World Space - this will give you world location and direction which you can use to trace for objects

I double checked the names of the nodes but I really do hope I did not skip any of the steps. Do tell how it goes.

4 Likes

Wow!
Thank you very much for the detailed explanation. It worked like a charm for me :wink:

Thanks a lot, your method also solved my problem with Touch drag and drop.

For anyone who needs Pointer’s position for tracing on Drag & Drop with Touch:

Create a custom Drag & Drop Operation → Override function → Dragged
DragDrop 1

Create Event Dispatcher, return type vector 2D then connect Event Dragged with that Event Dispatcher

Go back to your widget that has drag & drop function → Create new event has return type 2D Vector → Create a new variable to store this pointer position

Lastly, “On Drag Detected” create your custom Drag & Drop Operator, then bind its Event Dispatcher to the Event created in the previous step.

Hope this help!

3 Likes

This solution came up as a hit on Google and I understand the purpose of it however I found a simpler solution.

In the widget you are drag/dropping, use the Event on Drag Cancelled override.

Then, use a 0.05s or some value like this as a delay with a boolean to determine if your drag was holding onto a widget.

What happens is that the action is cancelled and the delay given allows the system to recover the position of the cursor, and then it can determine what is under it. In my use-case I used a trace since I needed something else.

If a value in the delay is of 0.01s, depending on FPS, the event may misfire, so use a value where people cannot see the difference, under 0.1s.

In practical terms, this is easier to implement with less overhead and less places to debug.
It’s not an exact method, but if your usecase is to drag and drop from a widget to world space, this works fine.