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

CollisionObject2D _input_event ignores pause mode #3703

Closed
Tracked by #45334
Gastronok opened this issue Feb 13, 2016 · 20 comments · Fixed by #45775
Closed
Tracked by #45334

CollisionObject2D _input_event ignores pause mode #3703

Gastronok opened this issue Feb 13, 2016 · 20 comments · Fixed by #45775

Comments

@Gastronok
Copy link
Contributor

According to the tutorial on pausing, whenever the game is paused, _process(delta), _fixed_process(delta), _input(event), and _input_event(viewport, event, shape_idx) will not be called.

Supposedly, for any nodes who have PAUSE_MODE_PROCESS set, those functions will still be called. And indeed, _process(delta), _fixed_process(delta), and _input(event) all appear to be called for any nodes who have PAUSE_MODE_PROCESS set even while the game is paused. But such nodes will not call _input_event(viewport, event, shape_idx) while paused, regardless of what the pause mode is set to. Instead they will just queue up all the events, and report them simultaneously when the game is unpaused.

Attached is an Example. It has two RigidBody2Ds which both inherit the same script. One is set to Pause Mode Stop, the other is set to Pause Mode Process.

While the game is unpaused, both nodes report clicks in general and clicks on themselves specifically. When the game is paused, the one with Process Mode Process will still report on any general clicks, but it will not report that it has been clicked. This seems against the spirit of PAUSE_MODE_PROCESS, and makes it impossible to tell when a node was clicked on while the game was paused.

When the game is unpaused, both nodes will report any clicks made on them as though they had just then happened, regardless of the pause setting.

This behavior occurs in both 1.1 Stable and 2.0 RC1 2016-02-09.

@Listwon
Copy link
Contributor

Listwon commented Sep 29, 2016

Still not fixed in 2.1 stable

@RandomShaper
Copy link
Member

RandomShaper commented Feb 6, 2017

I've been able to reproduce your issue with your test project.

The thing is that CollisionObject2D._input_event is a different animal from Control._input_event. I think the docs refer to the latter.

Apart from _input, all the input callbacks a CollisionObject2D can receive (including _input_event, _mouse_enter, etc.) are sent from the physics picking system, which is handled differently from Node._input and Control._input_event.

This opens two ways of handling this:

  1. Consider this difference in behavior is effectively an inconsistency in how input is handled during pause, modify the physics picking code to block all events during pause and to drop them instead of queueing them. Then the docs should be updated to reflect that pausing also affects _mouse_enter and any other CollisionObject2D's callbacks.
  2. Accept that picking is another subsystem which for efficiency works the way it does (my hypothesis) and update the docs to reflect the fact that when they say _input_event they mean Control's.

I'm not biased here nor can come with a solid opinion on which one is better. I hope my research helps with the discussion. I wonder what @reduz has to say about this.

EDIT: Due to the compatibility breakage that will happen with 3.0 this is a good time to re-examine this.

@bojidar-bg
Copy link
Contributor

Note that in 3.0 it became _gui_event, so additional clarification might be not so necessary.

@Gastronok
Copy link
Contributor Author

@RandomShaper The solution I would like to see implemented is that RigidBody2Ds with PAUSE_MODE_PROCESS report that they're clicked on while the game is paused.

Dropping the queued up input events from PAUSE_MODE_PROCESS objects would be even further from the expected behavior.

@akien-mga
Copy link
Member

What's the status on this issue in 3.0?

@Gastronok
Copy link
Contributor Author

Still happens in 3.0.2 Stable (win64). Below is essentially the same example project recreated in Godot 3:
Example3.zip

@akien-mga akien-mga changed the title Input Events ignore Pause Mode CollisionObject2D _input_event ignores pause mode May 29, 2018
@akien-mga
Copy link
Member

Thanks for checking and updating the example project.

@jahd2602
Copy link
Contributor

jahd2602 commented Apr 2, 2019

Still happens on 3.1 stable.

@akien-mga akien-mga added this to the 3.2 milestone Apr 9, 2019
@noname1477
Copy link
Contributor

Still happens on 3.2alpha3.

@systemsoverload
Copy link

Still happens in released 3.2

@Zireael07
Copy link
Contributor

Confirming, still happens in 3.2.

@davidkbd
Copy link

Still happens on Godot_v3.2.1-stable_x11.64

@Lattay
Copy link

Lattay commented Jun 6, 2020

Is there any reason for this to still happen ? I think it is a pretty unexpected behavior even after reading the documentation. There is no mention of exceptions in the white listing.
If there is a will to keep this behavior for some reason, shouldn't it be documented ?
If there is only a lack of man-force I can write a note myself in the documentation, unless this is actually seen as a bug.

@Gastronok
Copy link
Contributor Author

I'd still strongly argue that it's a bug which should be corrected -- it prevents a whole lot of reasonable behavior, requiring one to either create their own pause implementation (because the existing one doesn't allow for exceptions with these types of nodes) or create a bunch of redundant Control objects just so some parts of the game can function while the rest is paused.

@RandomShaper
Copy link
Member

I'll check this again today and will try to fix it.

@RandomShaper
Copy link
Member

RandomShaper commented Jun 8, 2020

I've been checking this and thinking how to address it.

First of all, the main reason why the unwanted behavior happens is that Viewports only process picking events if not paused. Therefore, an easy workaround for projects is doing this:
get_node("/").pause_mode = PAUSE_MODE_PROCESS

That way, the internal physics processing of the root viewport keeps running so it process the picking input events, which is needed for 2D/3D physics nodes to get _input_event, _mouse_enter, etc.

These are our options:

  1. Document this and keep the current behavior.
  2. Do 1) for 3.2 to avoid the risk of breaking compat and do some changes for 4.0 (the one explained in 3) is an option).
  3. Try to write a non-breaking patch for 3.2 (which can also be the same for 4.0); something like this: all the logic that Viewport runs in its internal physics processing is changed in a way it runs unconditionally (regardless pause) and it doesn't call the callbacks on physics nodes that are paused. This would be a chamge in behavior and whether it's a compat breakage or not should be studied.
  4. Doing the change for 3.2 and 4.0 and also add a project setting for the former to enable the new behavior (enabled by default for new projects). I don't like this option. Just adding that for the sake of completeness.

@Gastronok
Copy link
Contributor Author

Wouldn't setting the root node (which I had to access via get_node("/root") instead of get_node("/"))'s pause mode to PAUSE_MODE_PROCESS change the default behavior of all PAUSE_MODE_INHERIT nodes?

Right now all nodes default to PAUSE_MODE_INHERIT and, unless somewhere up on the scene tree something was set to PAUSE_MODE_PROCESS, they'll all pause when the game is paused.

By setting the root node to PAUSE_MODE_PROCESS now all nodes by default don't pause, unless one wants to manually set all various nodes to PAUSE_MODE_STOP.

Also, at least on the sample project, setting the root node to PAUSE_MODE_PROCESS and clicking on the PAUSE_MODE_STOP RigidBody2D (named "Pauses") causes that node to report that it was clicked. Even while the game is paused.

That would seem to be the same problem happening in reverse -- input_event is ignoring a specific node's pause mode, this time causing a PAUSE_MODE_STOP node to process events while the game is paused, even though _input will in that case skip events.

@RandomShaper
Copy link
Member

Yes, I mistyped the root viewport path.

You're right in that the workaround is not good enough. I'll try something and make a tentative PR.

@RandomShaper
Copy link
Member

Please have a look at #39421. Or, even better, try it. Just don't forget to enable the new setting in the test or real project.

@Gastronok
Copy link
Contributor Author

That patch makes the example project behave as expected, both as written and with a few extra minor tests that came to mind.

I don't have any real-world projects that have pause-problems right now but I do recall having seen similar complaints about pause functionality somewhere on the internet. If I can find them again I'll redirect them here; it'd be nice to know if this helps out the other complaints and I don't know enough about the core code to evaluate the overall wisdom and impact of the changes you implemented.

Thanks for getting some traction on this problem. It's always demoralizing when you have to fight against the engine instead of work within it.

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.