How to disable/enable a node?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By paolobb4

I’m trying to implement a respawning static object in 3D (it’s an energy wall). For convenience I’d prefere to disable it on “death” and reinable it on respawn, rather than freeing it and reinstancing it later. I’m not sure how to go about this. I’m pretty certain that node.hide() only disables visibility and disabling process won’t disable signals.

I can’t find anything that might have the effect I’m looking for. Any suggestions?

For Godot 4, see How to "disable" nodes? - Archive - Godot Forum

Hyper Sonic | 2023-02-18 14:44

:bust_in_silhouette: Reply From: johnygames

Apart from just hiding the object, you can also disable it by calling the set_process(false)function. Just bear in mind that if you disable a process of a node from within the node itself, you will have to reenable the process by calling set_process(true)from another script, should you decide to do that later. Generally speaking, it is good practice to enable and disable nodes from a master node. So dedicate a spawner object whose role is to activate and deactivate other nodes.

Another way would be to delete a node from the tree with remove_child() and reenter it when necessary, after you have kept its position in a variable

I find that add_child is very expensive

Tux | 2020-05-22 10:30

Is this still true? It seems setting process_mode to Node.PROCESS_MODE_DISABLED or 4 does the trick too (if children have process_mode inherit).

st_phan | 2023-03-28 15:36

2 Likes
:bust_in_silhouette: Reply From: Zylann

The most generic way to disable a node entirely is to remove it from the tree temporarily, and store it somewhere so that you can put it back later. I’m just not sure if signals will turn off, maybe they remain.

Another way is to delete it entirely, and re-instance later.

Other more efficient solutions will switch only the relevant states, so it depends on the node and scripts it might have. You could want to:

  • Hide it
  • Turn off its physics shapes and layers so it no longer collides
  • Stop any sound it might play
  • Disconnect its signals, or add checks in its script
  • set_process(false)
  • set_physics_process(false)
  • set_process_input(false) etc

That means the concept of “disabled” is highly specialized to what you actually want, so quite often you need to write that yourself.

Is this still true? It seems setting process_mode to Node.PROCESS_MODE_DISABLED or 4 does the trick too (if children have process_mode inherit).

st_phan | 2023-03-28 15:35

:bust_in_silhouette: Reply From: Mateusz Kolpa

You can just set the pause property to true → pause = true and visible = false. That makes it ‘disabled’.

There is no pause-property, only a pause_mode-property: You don’t pause individual nodes, you pause the whole tree (using get_tree().paused = true). While it’s true that you can define exceptions by setting the pause_mode to PAUSE_MODE_PROCESS, that’s certainly not something you should use to disable just one node.

njamster | 2020-05-11 23:51

not actually becouse its collision shape is still there

God Mod | 2021-03-22 19:31

:bust_in_silhouette: Reply From: qaptoR

If you right-click on a node to open the context menu, then choose “save branch as scene”, once it has been converted you can now open the context menu again and turn on the option “load as placeholder”. This will keep the scene in the tree, but won’t perform any loading actions.

I use it to turn of big ticket items like landscapes (using zylann HeightMap) when I’m testing things I don’t need the landscape for.

I haven’t tried this yet, but I think once you’re done testing you can open the context menu one last time after turning off ‘load as placeholder’, and choose “merge from scene”, which theoretically converts it back into a basic node-subtree

:bust_in_silhouette: Reply From: st_phan

I use process_mode in tandem with showing/hiding nodes:
(Important is that child nodes’ process_mode is set to inherit)

func disable_and_hide_node(node:Node) -> void:
	node.process_mode = 4 # = Mode: Disabled
	node.hide()

func enable_and_show_node(node:Node) -> void:
	node.process_mode = 0 # = Mode: Inherit
	node.show()
6 Likes

This worked! Thanks

Just a consideration: instead of relying on magic numbers, use the built-in constants as suggested above, example:

node.set_process_mode(Node.PROCESS_MODE_DISABLED)
1 Like