Godot version:
Godot 3 RC 2
OS/device including version:
Windows 10
Issue description:
Setting pause mode on editor or by script does nothing. Using get_tree().paused = true
works, though.
I think this is by design. For now, you can't pause individual node. You may pause the whole tree and whitelist some node branch using PAUSE_MODE_PROCESS.
...like it always has? This is a regression. If you can't do it, why would you even have the PAUSE_MODE_STOP then?
Not a regression.
http://docs.godotengine.org/en/stable/learning/features/misc/pausing_games.html
http://docs.godotengine.org/en/latest/classes/class_node.html?#enums
PAUSE_MODE_INHERIT = 0 — Inherits pause mode from parent. For root node, it is equivalent to PAUSE_MODE_STOP.
PAUSE_MODE_STOP = 1 — Stop processing when SceneTree is paused.
PAUSE_MODE_PROCESS = 2 — Continue to process regardless of SceneTree pause state.
So you're saying that the sole purpose of STOP is to stop a node if the tree is paused and its parent is in PROCESS, but it doesn't have any effect on anything if the tree is not paused.
https://youtu.be/PEZWYXPvmS8?t=1s
It's surprising because one would think it's more work to implement it like this. Enhancement it is then.
You can call set_process(false)
and set_process_internal(false)
(and all the other processing functions if needed which makes this a bit cumbersome). I think this doesn't affect the node's children though.
Maybe we can have PAUSE_MODE_FORCE or something to pause node regardless of the SceneTree pausing status.
A Godot user was experimenting with "pause masks" and seems to work, would be cool to have that in the engine, is better, more useful and organized than the single full tree pause.
I just wanted to stop by and say that I also think that the _ability to pause any branch_ of nodes would be a great improvement over Godot's current system (pausing the SceneTree globally with the option of exempting certain nodes).
I'm still pretty new to Godot's codebase, so maybe there are some roadblocks that I'm underestimating here, but from a distance it seems like if each node had something like a _run_state
that could be set to RUNNING
, PAUSED
, or INHERIT
we could set the run state of any node in the tree, which would (by default) be inherited by its children.
This would be pretty similar to what we have right now, and setting the root node to PAUSED
while some other branch of nodes is set to RUNNING
would be effectively the same as telling the SceneTree to pause while setting a branch to PAUSE_MODE_PROCESS
. _However, this would also allow you to do the opposite - allowing users to pause any branch of nodes even when the rest of the SceneTree (including the root node) is RUNNING
- something that I don't think is very easy to do right now._
edit: Adding a PAUSE_MODE_FORCE, as suggested above, seems like it would also do the trick. But, I think the naming would be slightly less clear.
Generally, while I think Godot's current system is a good start and with some work-arounds you can probably get the results that you want, I think a slightly more flexible pausing system would just give people more control over their games.
+1 on pausing node branches.
It'd be nice, in order to reduce processing power, to pause individual node branches instead of the entire scene tree (which is how I thought it worked originally, and thought this was a bug like OP).
There are times, like in fighting games, where you might want to pause a fighter for like .1 seconds whenever they get hit for the sake of "impact". It'd be nice to just access the animation player node or character node and just .pause()
or .unpause()
.
In my scenario, I have a node (an enemy) that I do not want to process at all but I want to still be seen in the game. It's an enemy that dies, but stays in the Scene instead of being removed. Enemies in my project have a lot of children nodes working "concurrent".
I either have to:
PROCESS
and the enemy nodes' pause mode as STOP
or(1) is inconvenient because putting it means I can't pause the entire game without messing with pause modes and (2) doesn't scale well (and could potentially get expensive).
The only workaround I can muster is doing something like this:
func my_pause(node : Node) -> void:
node.set_physics_process(false)
node.set_process(false)
# disable input processes
# disable physics somehow
for c in get_children():
my_pause(c)
Anyways, those are my 2 cents.
It's quite confusing to have a pause state that's separate from the pause mode enum. What I would expect is that I could pause any node, not just the root of the tree. As the system currently stands PAUSE_MODE_STOP
does not work as I would expect it to. Godot has a great node and scene system, and it's weird that the root node breaks the simplicity here.
My proposal:
Get rid of the paused
boolean entirely.
Make the paused state entirely determined by the enum, such that Process is always running, Stop is always not running, and Inherit inherits.
Either don't allow the root node to be Inherit, or make Inherit behave like Process.
That is a simpler system that allows pausing any node and behaves as I'd expect.
We can mostly preserve compatibility by making paused
a boolean property that sets the pause mode to Stop for true and Process (or Inherit?) for false. Also, while I don't see why you would want it, the old behavior of a Stop child on a Process parent can be emulated in this system by manually setting that child node's pause mode when you pause.
I hope this gets looked at some more. It's very common to do something like a "hitpause" or "healpause" in games and still be able to pause the game during those pauses. Lucrecious's workaround is the only viable solution currently.
func freeze_node(node, freeze):
node.set_process(!freeze)
node.set_physics_process(!freeze)
node.set_process_input(!freeze)
node.set_process_internal(!freeze)
node.set_process_unhandled_input(!freeze)
node.set_process_unhandled_key_input(!freeze)
func freeze_scene(node, freeze):
freeze_node(node, freeze)
for c in node.get_children():
freeze_scene(c, freeze)
I use something like this to freeze my main game world node while also allowing for a pause game. However if I have nodes set to false, this will blanket set them to true when the freeze finishes. So I have to do some extra checks in those instances. Also this doesn't affect particles.
It would be great if Godot had a better built in hierarchical pause system.
Feature and improvement proposals for the Godot Engine are now being discussed and reviewed in a dedicated Godot Improvement Proposals (GIP) (godotengine/godot-proposals) issue tracker. The GIP tracker has a detailed issue template designed so that proposals include all the relevant information to start a productive discussion and help the community assess the validity of the proposal for the engine.
The main (godotengine/godot) tracker is now solely dedicated to bug reports and Pull Requests, enabling contributors to have a better focus on bug fixing work. Therefore, we are now closing all older feature proposals on the main issue tracker.
If you are interested in this feature proposal, please open a new proposal on the GIP tracker following the given issue template (after checking that it doesn't exist already). Be sure to reference this closed issue if it includes any relevant discussion (which you are also encouraged to summarize in the new proposal). Thanks in advance!
Most helpful comment
I just wanted to stop by and say that I also think that the _ability to pause any branch_ of nodes would be a great improvement over Godot's current system (pausing the SceneTree globally with the option of exempting certain nodes).
I'm still pretty new to Godot's codebase, so maybe there are some roadblocks that I'm underestimating here, but from a distance it seems like if each node had something like a
_run_state
that could be set toRUNNING
,PAUSED
, orINHERIT
we could set the run state of any node in the tree, which would (by default) be inherited by its children.This would be pretty similar to what we have right now, and setting the root node to
PAUSED
while some other branch of nodes is set toRUNNING
would be effectively the same as telling the SceneTree to pause while setting a branch toPAUSE_MODE_PROCESS
. _However, this would also allow you to do the opposite - allowing users to pause any branch of nodes even when the rest of the SceneTree (including the root node) isRUNNING
- something that I don't think is very easy to do right now._edit: Adding a PAUSE_MODE_FORCE, as suggested above, seems like it would also do the trick. But, I think the naming would be slightly less clear.
Generally, while I think Godot's current system is a good start and with some work-arounds you can probably get the results that you want, I think a slightly more flexible pausing system would just give people more control over their games.