Skip to content

Add new notification when a new Node is created in editor - #81217

Closed
Malcolmnixon wants to merge 1 commit into
godotengine:masterfrom
Malcolmnixon:notification-editor-created
Closed

Add new notification when a new Node is created in editor#81217
Malcolmnixon wants to merge 1 commit into
godotengine:masterfrom
Malcolmnixon:notification-editor-created

Conversation

@Malcolmnixon

@Malcolmnixon Malcolmnixon commented Sep 1, 2023

Copy link
Copy Markdown
Contributor

This pull request implements godotengine/godot-proposals#7593 by:

  • Adding a NOTIFICATION_EDITOR_CREATED notification.
  • Emitting NOTIFICATION_EDITOR_CREATED when the scene_tree_dock creates new node.

The following script demonstrates how these changes can create a new node script capable of being instantiated via the "Add New Node" scene-tree command and having the node pre-populated with the overridden default values specified by the script.

@tool
class_name CustomRigidBody3D
extends RigidBody3D


# Specify custom default collision layers used in the editor
const DEFAULT_COLLISION_LAYER := 3
const DEFAULT_COLLISION_MASK := 3


# Apply new default values when created in the editor
func _notification(what : int):
	if what == NOTIFICATION_EDITOR_CREATED:
		collision_layer = DEFAULT_COLLISION_LAYER
		collision_mask = DEFAULT_COLLISION_MASK


# Indicate revert supported in the editor inspector
func _property_can_revert(property : StringName) -> bool:
	return property == "collision_layer" or property == "collision_mask"


# Provide revert values to the editor inspector
func _property_get_revert(property : StringName):
	match property:
		"collision_layer":
			return DEFAULT_COLLISION_LAYER

		"collision_mask":
			return DEFAULT_COLLISION_MASK

Bugsquad edit: Closes godotengine/godot-proposals#7593

@Malcolmnixon
Malcolmnixon requested a review from a team as a code owner September 1, 2023 03:13
@Malcolmnixon
Malcolmnixon requested a review from a team September 1, 2023 03:13
@Malcolmnixon
Malcolmnixon requested a review from a team as a code owner September 1, 2023 03:13
@Calinou Calinou added this to the 4.x milestone Sep 1, 2023
@MewPurPur

Copy link
Copy Markdown
Contributor

Seems like I have been doing this in my game like

func _enter_tree() -> void:
	if SceneUtils.is_tool():
		z_index = 6
		z_as_relative = false

I suppose this made it so these defaults are enforced every single time the scene is opened, while your PR adds a way to enforce a default only when the node is added?

@YuriSizov

Copy link
Copy Markdown
Contributor

I'm concerned about adding an editor-specific notification to Node, but this is likely useful and we do seem to have a couple other editor notifications in there.

You probably need to add this same notification to SceneCreateDialog::create_scene_root() and SceneTreeDock::_tool_selected() (for TOOL_CREATE_* options).

@Malcolmnixon
Malcolmnixon force-pushed the notification-editor-created branch from cc9a6e9 to f925245 Compare September 1, 2023 13:04
@AThousandShips

Copy link
Copy Markdown
Member

Think the documentation should clarify that it happens when created through the UI, and not through for example a script

@Malcolmnixon
Malcolmnixon force-pushed the notification-editor-created branch from f925245 to f0e007f Compare September 1, 2023 13:12
@Malcolmnixon

Copy link
Copy Markdown
Contributor Author

Good catch @YuriSizov - I hadn't considered the other methods of creating node instances via favorites or the file-system dock.

@AThousandShips - I updated the node documentation to clarify the notification is only invoked when creating nodes through the Godot editor UI.

@Malcolmnixon

Copy link
Copy Markdown
Contributor Author

I had considered other methods for allowing scripts to override default values; however one of my primary goals was to limit the performance impact on shipping games. The three approaches I considered were:

  • Forcing the editor to "revert" all properties on new nodes:
    • Allows changing default values using only _property_can_revert() and _property_get_revert()
    • May interfere with values set during _init()
  • Adding new @override attribute:
    • Significant changes to scripting
    • Might introduce ambiguities with _property_can_revert() and _property_get_revert()
    • May incur runtime cost of processing override list in object construction
  • Adding the NOTIFICATION_EDITOR_CREATED signal:
    • Virtually no performance impact on shipping games
    • May be useful for other use cases
    • Does not support nodes created in scripts, however:
      • The script creating the node can set properties
      • The script creating the node could choose to send the notification

@BastiaanOlij

Copy link
Copy Markdown
Contributor

cc @vnen

What is your view on this George? Is this the proper way with this, it's something we need to continue some of the development on XR Tools for.

@KoBeWi

KoBeWi commented Sep 25, 2023

Copy link
Copy Markdown
Member

If it does solve the problem, I think this implementation is fine.
There is one more way of creating nodes that I think might need to receive the notification - when you drop a script to scene tree while holding Ctrl. It creates a new instance of the type and it's a UI action, so I think it should be handled too.

Added NOTIFICATION_EDITOR_CREATED notification.
Added emitting NOTIFICATION_EDITOR_CREATED when editor creates new nodes
@Malcolmnixon
Malcolmnixon force-pushed the notification-editor-created branch from f0e007f to 1365ede Compare September 28, 2023 22:28
@Malcolmnixon

Copy link
Copy Markdown
Contributor Author

If it does solve the problem, I think this implementation is fine. There is one more way of creating nodes that I think might need to receive the notification - when you drop a script to scene tree while holding Ctrl. It creates a new instance of the type and it's a UI action, so I think it should be handled too.

I added firing NOTIFICATION_EDITOR_CREATED for the Ctrl script-drag into the scene tree.

KoBeWi
KoBeWi previously approved these changes Sep 28, 2023
@akien-mga

Copy link
Copy Markdown
Member

Asked reduz to review, but in typical reduz fashion he replied to me instead of commenting here ;)

<reduz> I dont understand, they want a new notification `NOTIFICATION_CREATED` basically? you can do this already `if (Engine.is_editor_hint() and get_tree().get_edited_scene_root().is_ancestor_of(this)`)
<Akien> Sounds like it yeah.
<Akien> But I guess they didn't know they could do it like this.
<YuriSizov> They seem to need it outside of tree.

@KoBeWi

KoBeWi commented Sep 30, 2023

Copy link
Copy Markdown
Member

There isn't any NOTIFICATION_CREATED and even if it was, it's not the same as the new one here. It needs to be received only when the node is created for the first time.

@akien-mga

Copy link
Copy Markdown
Member

There isn't any NOTIFICATION_CREATED and even if it was, it's not the same as the new one here. It needs to be received only when the node is created for the first time.

I guess @reduz was referring to Object.NOTIFICATION_POSTINITIALIZE. Wouldn't that be suitable?

@KoBeWi

KoBeWi commented Oct 3, 2023

Copy link
Copy Markdown
Member

Notification received when the object is initialized, before its script is attached. Used internally.

Not really. And as I said, this notification is received when node is duplicated, instantiated etc. It's not suitable for initializing a default value, because it would be overwriting the property every time. It's basically early _init().

@BastiaanOlij

Copy link
Copy Markdown
Contributor

Just to bring this back to attention. Discussing this during the XR meeting where we are waiting for this functionality.

Let's focus back on the original problem we are trying to solve here. Right now it is not possible to extend a class and provide alternative default values for properties from the class we are extending.

So RigidBody3D has a default collision layer of 1, in our extended class we want that default layer to be 3.

We can do this when we also defined a custom_rigid_body_3d.tscn along side the new class and specify the overriding default there, however when using "add new node" instead of "add child scene", this accompanying scene file is not used.

The bottom line here is solving that issue, this PR solves that by introducing a notification after our node is created, but before our properties are processed, so that the default value can be overridden. The other suggestions made here as alternatives do not fit that purpose, they either happen to early, too late, or too often in order to solve the underlying issue.

@reduz

reduz commented Jan 4, 2024

Copy link
Copy Markdown
Member

I would prefer we find another way to do this than hacking a notification inside Node. As I mentioned above, there are other ways to work around this issue.

I would appreciate more detail into this scenario, I still don´t quite understand why it can´t be done via the usual channels.

@Calinou

Calinou commented Feb 21, 2024

Copy link
Copy Markdown
Member

Regarding use cases, check the bottom of the description of #88647. I tried to implement a virtual method for this, but the method is never being called: https://github.com/Calinou/godot/tree/editor-add-on-instantiated-call

@KoBeWi

KoBeWi commented Jul 28, 2026

Copy link
Copy Markdown
Member

I'm getting reminded about this PR once every few months, because new scenarios keep popping up where such notification would be useful.

I would prefer we find another way to do this than hacking a notification inside Node.

This change does not modify node in any way, other than registering a new constant. The notification could be registered elsewhere, but being next to other editor-specific notifications is more intuitive I think.

As I mentioned above, there are other ways to work around this issue.

None of the existing methods/notifications allow to achieve the same thing (unless I'm missing something), so what are these other ways?

Again, the goal is to notify the node when it's just created in the editor, once. It's similar to PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT, but for nodes.

@KoBeWi KoBeWi Jul 28, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it might be appropriate to move all calls to instantiate_object_properties() instead, it's called in the same scenarios.

@KoBeWi

KoBeWi commented Aug 11, 2026

Copy link
Copy Markdown
Member

Superseded by #122058
Thanks for the contribution.

@KoBeWi KoBeWi closed this Aug 11, 2026
@KoBeWi KoBeWi removed this from the 4.x milestone Aug 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow scripts to override default property values

9 participants