Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Undefined propagation order for clicks on overlapped CollisionShape2D #23051

Closed
Tracked by #45334
DancingOx opened this issue Oct 16, 2018 · 4 comments · Fixed by #68492
Closed
Tracked by #45334

Undefined propagation order for clicks on overlapped CollisionShape2D #23051

DancingOx opened this issue Oct 16, 2018 · 4 comments · Fixed by #68492

Comments

@DancingOx
Copy link

DancingOx commented Oct 16, 2018

Godot version:
v3.1.alpha.official

OS/device including version:

  1. macOS Sierra Version 10.12.6, MacBook Pro 2015
  2. Linux Mint 17 Cinnamon 64-bit, AMD A10-6800K APU with Radeon HD Graphins + Advanced Micro Devices [AMD/ATI] Turks PRO [Radeon HD 6570/7570/8550] X.Org: 1.15.1 drivers: ati,fglrx (unloaded: fbdev,vesa,radeon) Resolution: 1920x1080@60.0hz GLX Renderer: AMD Radeon HD 6570 GLX Version: 4.5.13399 - CPC 15.201.1151

Issue description:
Propagation order of mouse click event can be different on sequenced launches without any changes in project using CollisionShape2D for input handling.

Steps to reproduce:
(You can use attached project instead of doing 1 - 9 below)

  1. Create new empty project
  2. Create Area2D with Sprite and CollisionShape2D as its children
  3. Create another Area2D with Sprite and CollisionShape2D as its children
  4. Move one area to be a child of another or make two areas siblings (my case is first, but it doesn't matter)
  5. Set textures for both Sprite objects
  6. Configure Shape attribute for both CollisionSape2D objects
  7. Make Sprites and CollisionShapes overlapped
  8. Add scripts to both Area2D objects
  9. Implement event handling function for mouse clicks in both scripts:
func _input_event(viewport, event, shape_idx):
	if event is InputEventMouseButton and event.is_pressed():
		print('Back sprite clicked', viewport, event, shape_idx)
func _input_event(viewport, event, shape_idx):
	if event is InputEventMouseButton and event.is_pressed():
		print('Front sprite clicked', viewport, event, shape_idx)
  1. Run the game
  2. Click overlapped area of sprites
  3. Notice an order of handling clicks, for example:
Front sprite clicked ...
Back sprite clicked ...
  1. Close the game app
  2. Repeat 10 - 13 up to 10 times to see that sometimes the front sprite is clicked first but sometimes the back one.

Minimal reproduction project:

TestOverlapCollisionShape2D.zip

@KoBeWi
Copy link
Member

KoBeWi commented Aug 7, 2020

Still valid in 6831da6

@laander
Copy link

laander commented Apr 20, 2021

Yup, I'm experiencing this problem too, and it makes it almost impossible to work with clicking on collision shapes in Godot since the event propagation order is erratic and seemingly random.

My use-case:

I'm building a little RTS and want to be able to 1) select units by clicking on them and 2) make them move to a target point if you click the ground. Since _unhandled_input doesn't play ball with the _input_event on collision shapes (the unhandled input is triggered before checking the collision shapes), I'm instead creating a Area2D "ground" shape that covers the entire map to register clicks that falls through. But yeah, this doesn't work either because I can't assure that the units will always get the click event before the ground.

I'm getting desperate at this point, especially since behavior like this is presumably really common and should be very straightforward to achieve (at least in theory)

@jeremyz
Copy link
Contributor

jeremyz commented May 25, 2021

I've found a workaround using a simple "state machine", prioritizing unit's Area2D over map Area2D
boardgame-map

@dploeger
Copy link

This is still an issue in stable Godot 3.3

See the attached testgame:
testgame.zip

It has two Area2Ds with overlapping shapes:

image

It would've been expected (based on the documentation), that abb's input_event would be called first and then aba.

Instead it is the other way around. Running the test game and clicking on the top left corner of the screen yields:

aba was clicked
abb was clicked

This is the result on my machine. Reading the OP's description it may be the other way around as well as they've written, that there's no defined order.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants