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

Allow scripts to override default property values #7593

Open
Malcolmnixon opened this issue Sep 1, 2023 · 8 comments · May be fixed by godotengine/godot#81217
Open

Allow scripts to override default property values #7593

Malcolmnixon opened this issue Sep 1, 2023 · 8 comments · May be fixed by godotengine/godot#81217

Comments

@Malcolmnixon
Copy link

Malcolmnixon commented Sep 1, 2023

Describe the project you are working on

Maintaining the Godot XR Tools library

Describe the problem or limitation you are having in your project

Godot XR Tools provides many types of nodes for users to create XR experiences:
image

Godot XR Tools has many scenes which exist purely to provide working default values for properties provided by the C++ scene objects such as collision layers and masks. Our users are continuously trying to use the Add Child Node dialog in the scene-tree editor which results in broken objects due to these properties not being configured correctly.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

We would like a way for the scripts to override the creation values for properties in the base C++ nodes.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

A script can already change the default revert value for C++ implemented properties by implementing the _property_can_revert() and _property_get_revert() methods.

Changing the initial value after "Add New Node" could be achieved via a new notification (NOTIFICATION_CREATED) which is invoked only when a new node is created (either via Add New Node, or dynamically in code) - not when it is instantiated from a PackedScene or duplicated.

The script would then be able to contain the following code:

const DEFAULT_COLLISION_LAYER = 0x0103

# Override base properties when the node is constructed in the editor
func _notification(what : int):
    if what == NOTIFICATION_EDITOR_CREATED:
        collision_layer = DEFAULT_COLLISION_LAYER

# Report revert support for base properties
func _property_can_revert(property : String) -> bool:
    return property == "collision_layer"

# Provide report values for base properties
func _property_get_revert(property : String):
    if property == "collision_layer":
        return DEFAULT_COLLISION_LAYER

If this enhancement will not be used often, can it be worked around with a few lines of script?

The current approach of providing pre-configured scenes and extensive user documentation appears to be the only workaround at this time; however it creates significant user issues.

Is there a reason why this should be core and not an add-on in the asset library?

No means of implementing it outside of the core has been found.

@BastiaanOlij
Copy link

BastiaanOlij commented Sep 1, 2023

Something I'd like to add in here is that historically we would use scenes here, when you create a scene with a certain Godot type as the root node, you can set the default values in the properties in that scene, and they would become the overriding defaults when that scene was added as a child scene. Perfect.

But ever since we've added class_name and allowed for people to add nodes based purely on the script, we've ran into the problem that it confuses users of our plugin. It's easier to press + and add a node, than to press the link button and add a child scene, but the result is a broken system. We need to define a class_name on these scripts for them to work properly with other parts of the plugin, but we're missing out of functionality when just the script is used.

Ergo, we've started to rebuild the plugin to not rely on the scenes, but have the scripts handle all logic including creating further child nodes.
This is the one missing feature to make that approach complete.

edit Note that my solution to this problem would be to simply allow defining the default by either redefining the variable like so:

@export var collision_layer = 0x0103

and Godot seeing this is an existing property and simply overriding whatever is changed and leaving the rest of the property in tact,
Or add a new keyword for this:

@override var collision_layer = 0x0103

@dalexeev
Copy link
Member

dalexeev commented Sep 1, 2023

@ultrasuperpingu
Copy link

As a complement, it would be nice also to be able to send this notification again on demand, because this notification could be also use to create new nodes for example.

@AThousandShips
Copy link
Member

AThousandShips commented Apr 5, 2024

How would creating another node mean you should receive this notification? A nice is only created once

@ultrasuperpingu
Copy link

How would creating another node mean you should receive this notification? A nice is only created once

Not sure to understand. Sorry, my english level is probably the cause :(

My purpose is:

  • The setup of a new object can be pretty complex (creating new (child) nodes, changing properties values, etc
  • It could be useful to be able to run this setup again.

As an example, here is what I'd like to be able to do on a new node creation:

  • Add a script on this object (ok, it's handle by creating a new node type by implementing a plugin (AddCustomType) but it would be nice to have a callback when you add the script to an object too)
  • add a StaticBody3D
  • Compute a child CollisionShape3D and add it as a child of the StaticBody3D
  • Add a child which reacts when the mouse is hover/click/exit the StaticBody3D
  • Compute a point of view position for this object and store it as a child Node3D
  • etc...

I hope with clarify my purpose (and I hope my purpose is not stupid :))

@AThousandShips
Copy link
Member

here is what I'd like to be able to do on a new node creation

A node is only created once, you can't "recreate" it, this will be called when a node is created, once

@ultrasuperpingu
Copy link

A node is only created once, you can't "recreate" it, this will be called when a node is created, once

You're right, so my needs are: I'd like a setup notification that would be automaticly called on node and to be called on demand.

But clearly, the main need for me is a notification when the node is created. For the possibility to run the setup again, I can do it with other mecanism, you're right. My "As a complement" in my precedent post should be ignore in this topics.

@ultrasuperpingu
Copy link

ultrasuperpingu commented Apr 5, 2024

Trying to be clear on this:

  • My needs were to get a setup command on a node that would be called automaticly on node creation and to have the ability to call it again on demand (exactly like the Reset function in Unity).
  • The main lack in Godot is that there is no notification when the node is created in the editor.
  • If this notification is added in godot, it is possible to get the same functionality. The ability to call the setup again can be done with few lines of code so it's ok and my comment on this was useless, sorry (:/) (I still think the functionality would be a nice to have, but as @AThousandShips noticed it, it would be a non sense to be able to send a "node created" event on demand)

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.

6 participants