godot: Pause mode enabled stops body/area signals being raised on a scene that has pause mode set as Process

Godot version: 3.2.3

OS/device including version: Linux mint

Issue description: I have the following global code to toggle pausing so my main game pauses but a node (a mini-game popup in a gui) runs:

func _input(event: InputEvent) -> void:
	if Input.is_action_just_pressed(INTERFACE_OPENCLOSE_ACTION):
		visible=!visible
		if visible:
			get_tree().paused=true
		else:
			get_tree().paused=false

I have set pause mode as PROCESS for this ‘popup’ node. When the game runs, the scene is shown, the mini-game plays ok, i.e. pause mode is being ignored for this whole scene correctly. However none of the body or area entered signals within the scene are raised and no collisions occur, they are completely ignored, but the rest of the scene runs fine.

Please see below the little character going straight through the blocks. I have enabled collision visibility to show these are being generated ok

https://user-images.githubusercontent.com/12863685/112331419-cd370580-8cb0-11eb-88bd-6159b9c208d7.mp4

Now, if I change the autoload to not pause the game, then everything works fine. So game_pause is stopping signals from being raised.

    func _input(event: InputEvent) -> void:
	if Input.is_action_just_pressed(INTERFACE_OPENCLOSE_ACTION):
		visible=!visible
		#if visible:
		#	get_tree().paused=true
		#else:
		#	get_tree().paused=false

https://user-images.githubusercontent.com/12863685/112331444-d1fbb980-8cb0-11eb-9b88-6f484cc15165.mp4

Minimal reproduction project: See below comments

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 15 (8 by maintainers)

Commits related to this issue

Most upvoted comments

@pouleyKetchoupp It works great, thanks. One thing I’ve just noticed and oddly I raised an issue about this ages ago but never saw the link, is when you have animated resources (e.g. animated tres for a tile) they continue to animate with game_pause on. These changes regarding how physics engine works that you mention is coming to 4, would they fix this issue?

At the minute I go through every animated tile and set it’s speed to 0 which is quite painful and obviously easy to break when adding new animated resources.

@Calinou Find attached a simple as possible case as I could do

  1. Run the program use the cursors and watch it either collide with the tilemap or the kinematic (kinematic to show it’s not tilemap at fault)
  2. Press the ui_accept key to pause the game and hide display, then press immediately again to unpause the game
  3. Repeat 1 and watch it not collide with anything

collision_test.zip

Any short term fix suggestion would be appreciated as my game relies on this ability…

The reason behind this limitation is that the physics world can only be processed or paused as a whole, which includes checking for collision and sending signals.

In Godot 4.0, the plan is to allow physics objects to be removed from the simulation or set to static when the game is paused, which will help with this limitation.

But yeah, I agree the documentation in 3.2 could be clearer on this aspect. It only mentions that physics 2D/3D will be stopped when you pause the tree, without giving details about what it means. https://docs.godotengine.org/en/stable/classes/class_scenetree.html#class-scenetree-property-paused

And the pause modes could have more details about this too: https://docs.godotengine.org/en/stable/classes/class_node.html#enum-node-pausemode

Right now, in your test project, pressing the key twice doesn’t revert the state to normal, it’s setting pause to true, that’s why the signals keep not being received.

But beside that, I understand better what you’re trying to do.

By default, yes I can confirm the whole physics is paused when the tree is paused. It causes rigid bodies to stop colliding and getting forces applied, and no collision signal is sent. On the other hand, _process and _physics_process are still called on objects with pause mode set to “process”, that’s why you can still move the character.

You can work around that by forcing physics to still be processed while paused, using Physics2DServer.set_active(true) just after pausing the game. In this case, the physics world will be still processed while paused, which means rigid bodies will be still moving and signals will be sent on all objects. Objects with pause mode set to “stop” won’t receive calls to _process or _physics_process but they will receive signals.