Replies: 5 comments 2 replies
-
You can get the root of the edited scene from By the way, I think it is good to also let the developer see those properties when Editable Children tuned on (it used to be the case that you needed to get the value from the And yes, I agree that requiring |
Beta Was this translation helpful? Give feedback.
-
By the way, I do have a use case for this. Since I have been trying to make my scripts more reusable, I have moved away from using |
Beta Was this translation helpful? Give feedback.
-
I've tried to put together a little test project with this capability: test-exportinternal v1.zip Video demo: Godot.Export.Internal.Editor.Script.Demo.mp4Overall it seems to be working pretty well. I'm a bit disappointed that the inspector doesn't update automatically when Editable Children is toggled (you have to click off of and then back onto the node for the properties to appear or disappear), but looking at the code for The GDScript code is, of course, in the test project, but here it is for ease of readability: @tool
extends Node2D
## Should only appear when this is the root node or is editable
@export var sprite: Sprite2D
@export var sound_player: AudioStreamPlayer2D
## Should always appear
@export var health: int = 10
func _process(_delta):
if Engine.is_editor_hint():
return
print("Sprite = %s, sound player = %s, health = %s" % [sprite, sound_player, health])
func _validate_property(property):
var scene_root = EditorInterface.get_edited_scene_root()
var this_is_root = scene_root == self
var show_exported_properties = true
# If this node is the edited scene root, then we're editing its internals,
# so we don't need to any special behavior (it should definitely show up
# in the editor).
if not this_is_root:
# Required to prevent an error:
# Condition "!is_ancestor_of(p_node)" is true. Returning: false
if not scene_root.is_ancestor_of(self):
show_exported_properties = true
else:
show_exported_properties = scene_root.is_editable_instance(self)
if property.name in ["sprite", "sound_player"] and not show_exported_properties:
property.usage = PROPERTY_USAGE_NO_EDITOR Ideally, the GDScript-side code for this kind of behavior could be something like extends Node2D
@export_internal var sprite: Sprite2D
@export_internal var sound_player: AudioStreamPlayer2D
@export var health: int = 10
func _process(_delta):
print("Sprite = %s, sound player = %s, health = %s" % [sprite, sound_player, health]) I'm not sure if |
Beta Was this translation helpful? Give feedback.
-
Great news! I decided to take the leap and implement this into GDScript itself. My branch https://github.com/Meorge/godot/tree/export_if_root includes the annotation extends Node2D
@export @export_if_root var sprite: Sprite2D
@export @export_if_root var sound_player: AudioStreamPlayer2D
@export var health: int = 10
func _process(_delta):
print("Sprite = %s, sound player = %s, health = %s, healh" % [sprite, sound_player, health]) I think that |
Beta Was this translation helpful? Give feedback.
-
There's a pull request at godotengine/godot#93528 now open. Since I feel like the exact syntax might still need some workshopping, I set it to be a draft. There's also a proposal at #10024 for discussing it further, if necessary. |
Beta Was this translation helpful? Give feedback.
-
I think it would be useful to have a version of the
@export
annotation that only displays the variable when viewed from inside a scene.To demonstrate, take this basic Player scene I put together:
The script on the Player scene itself is very simple:
By doing this instead of using node paths like
$Sprite2D
or unique names like%AudioStreamPlayer2D
, I can ensure that even if I change the name or location of these child nodes, my parent node is still able to access them. Great!However, this is how it looks when the Player scene is placed in another scene:
Even though I can't see the nodes in the Scene tab (without enabling "Editable Children"), the Inspector tab still shows the slots with those nodes. There isn't any reason I can think of to make these slots visible from this level, since the Player scene should be handling its children, and nodes outside of it should be interacting with the Player root node instead of trying to directly access its children. Likewise, when we're making modifications to this outer scene, we should never have a need to mess with the internals of the Player scene (we'd just open the Player scene, if we wanted to do that).
While looking into this issue, I did happen upon #1056 which sounds closely related. The agreed-upon solution seemed to be to use
_validate_property()
, but there are a few issues I see with this approach here:@tool
annotation feels clunky. It means that the user will have to include extra lines of code in functions like_ready()
and_process()
to ensure that the node isn't running when it's not supposed to.@tool
annotation, running its_process()
function inside the editor, but with this current solution it would have to anyways (and I'd have to add extra code to_process()
to tell it to not do anything while in the editor).If an elegant solution to this problem already exists, that would be great! But the solutions I'm currently aware of - node paths like
$Sprite2D
, unique names like%AudioStreamPlayer2D
, and the use of@tool
and_validate_property()
- all fall flat in one way or another for me.Beta Was this translation helpful? Give feedback.
All reactions