I’m making a card game where i can drag cards. There is a hand which is a HBoxContainer where i can rearrange my card order. I use Button as the basic type of my card and use _on_gui_input to detect mouse click. One click to pick up (start dragging) and another click to drop.
Here is the problem:
I click on one card (Card A) and start to drag it. When i try to put it on an empty place it works fine. However, when i try to drop it onto onther card (Card B) the click event is not detected by Card A, but detected by Card B. I tried to set mouse_filter of Card B to IGNORE / PASS when i pick up Card A. Though Card B no longer detect the click event, Card A still cannot detect the event.
I’m not sure what the issue here is exactly since the video seems to show the card being placed down just fine. What do you expect to happen?
But the way gui input works is that mouse events are propagated in a specific order, and it only ever goes up the scenetree, not down. So setting the mouse filter to pass wouldn’t have an effect unless the cards are parents of each other.
Thanks for your reply! In fact, in the video, after i picked up Spade 2, I first move it over Diamond 6 and clicked twice, Spade 2 did not drop. Then I move it to the right of Dimaond 6 ( an empty space) and click, and it drops successfully.
I got you that the input event goes up the scenetree. Which i don’t understand is that I actually clicked on both Spade 2 and Diamond 6 (since they are overlapping), why only Diamond 6 received the click event?
Setting mouse_filter to MOUSE_FILTER_IGNORE on Card B is the correct action to take if you don’t want Card B to receive any _gui_input events.
I’m not certain why Card A doesn’t receive the second click though. I suspect there is some layering with another Contol node you’re not accounting for based on being able to drop the card in an empty spot.
What does your Card scene look like?.. is it a single TextureButton or are other Control nodes involved?
What Control nodes in your scene are using MOUSE_FILTER_STOP? Are these overlapping with Card A?
When you select Card A, what is happening to it? I can see that the card is moving visually, but how is that accomplished? If you are re-parenting it temporarily or re-ordering it within the same parent it may mess with the input flow and another overlapping control may be consuming the event.
Essentially, if you have confirmed the Card A is not using MOUSE_FILTER_IGNORE while it’s “picked up”, then Card A should get the event as long as the mouse is still within the bounding box of Card A and no other Control node is consuming the event.
These all inherit from Control. If all of these Control’s are using MOUSE_FILTER_STOP and overlapping, the order in which they will receive _gui_input events is as follows: SomeOtherControlB > CardB > SomeOtherControlA > CardA > HBoxContainer. Only SomeOtherControlB would ever see the event because MOUSE_FILTER_STOP is making that Control consume the event, subsequent Control nodes will never see it.
The CardContainer in the Hand node uses MOUSE_FILTER_STOP, but i don’t think its the reason because dropping at an empty place works, maybe?
When selecting Card A, it begins to follow my mouse. I kept its mouse_filter to STOP (otherwise I will not be able to drop it anywhere i guess?) I just makes it follow the mouse position in _process(). In fact, if the card is dragged out side the Area2D of Hand Node, it will get reparented. And if the Card is dragged to the left or right of another card, i will reorder them (see in the next image). However, even if i did not change the order of cars ( just slightly move it above the card to its right), I cannot drop it.
I figured it out. It seems i did not understand the difference between MOUSE_FILTER_PASS and MOUSE_FILTER_IGNORE. I set the mouse filter to PASS in children nodes of Card, and it seems the event is propagated up to its parent and never goes to its brother node. By setting the filter to IGNORE it works.