-
-
Notifications
You must be signed in to change notification settings - Fork 21.3k
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
node.duplicate() does not resolve exported node properties #78060
Comments
Note that exported This could be added as a new feature, but I'd say it'd be best to have it controlled by a flag to |
This is a pretty serious issue that still persist in v4.1.1. It happens not just at runtime but in editor too. If you simply duplicate a node (Ctrl+D) that uses exported variables, then the value of exported variable will refer to the originaI node's value we duplicated, causing all sorts of unpredictable behaviours. I faced the same issue in my project, and took me a good enough time to figure out the cause. I believe fixing this issue should be prioritized. Otherwise, making duplicates by Ctrl+D will be a useless feature if a node uses exported variables. |
This makes inventory systems that move items in and out of the scene really messy to build. |
As a workaround -- and I am noticing this feels like a necessary feature to have -- there's an alternative to duplication. var packed_scene = PackedScene.new()
packed_scene.pack(self)
var duplicated_node = packed_scene.instantiate()
add_sibling(duplicated_node) It's totally possible this doesn't always work (and I may have written it wrong), but it may suffice in most cases. There's also... the DUPLICATE_USE_INSTANTIATION flag of |
I made a test PR for the aforementioned suggestion of having it as a separate flag. #81866 |
It's worth nothing this workaround only works if the whole subtree being packed only contains references to nodes in that same subtree. If a Node has a reference to a Node elsewhere outside of the subtree, I guess it makes sense that isn't allowed, because normally, regular scenes only get to reference external nodes via exported variables. Therefore, trying to pack Nodes with external references wouldn't work, unless all references were in the root node, and/or the engine made some magic. |
As we are reaching the 4.2 version soon and this problem is still existent 2 ideas: and just for addition the NodePath As the source code works in GDScript but not it C#, its either due to the script bridge breaking there or something internal. But just out of the box - what if one would test the following idea: 2) As Workaround: How about a feature called "Mass Instantiate"? As commented above, the PackedScene.Instantiate() is the current workaround for that problem. What about this: PackedScene.Instantiate() // -> returning a Node
PackedScene.Instantiate<T>() // -> returning a <T> with new "MassInstantiate" methods PackedScene.MassInstantiate(int count, Node parent) // -> returning a Node[] or Array<Node>
PackedScene.MassInstantiate<T>(int count, Node parent) // -> returning a T[] or Array<T> basically performing the following logic (written in C#) public static Node[] MassInstantiate(PackedScene targetPackedScene, int count, Node parent)
{
if(targetPackedScene == null || count < 0 || parent == null)
throw new IllegalArgumentException("One of the parameters is invald!");
Node[] instances = new Node[count];
for(int i = 0; i < count; i++)
{
instances[i] = targetPackedScene.Instantiate();
parent.AddChild(instances[i]);
}
return instances;
} which will also get a new menu entry only available on PackedScenes (edited image) with eventually a hotkey/shortcut. |
Thanks for reporting! Had same issue when moving from 4.1.1 to 4.2 beta 😅 |
This problem still occurs in godot 4.2.1. After creating a Node created as a Scene in the editor as an object in another Scene, the new object created by duplicating the object refers to the Export of the existing object. I'm having a hard time identifying the problem because I can't tell which node is referenced in the Export field. |
Got exactly that issue today, I was duplicating a UI widget (a segment of my health bar as many times as character had HP) for convenience (quick testing, "I can make it a scene to instantiate later"), and then I noticed that the last widgets were referring to and affecting the original segment, causing an invalid appearance. I think we should at least, at an emergency measure, document this behavior (along with the fact that Then we can work on adding an option to deep duplicate references to child nodes (if we want to keep retrocompatibility - if we add some By the way, #84146 which is about Editor duplicate was closed in favor of this (and also @Skyvastern stated it clearly), so could we change the title to include "duplicating node in editor scene tree"? |
In the case of PackedScenes and child nodes this behavior is so confusing it should be treated as bug. Why would a PackedScene in the editor be able to point to a child node in another PackedScene that I only see as a single node. I've run into this a bunch of times and probably lost a few hours all in all. I imagine it to be super frustrating for newbies. |
Because it fixed node duplication godotengine/godot#78060
Godot version
v4.0.3.stable.mono.official [5222a99]
System information
Windows 10, Godot 4.0.3.stable, Vulken (Forward+)
Issue description
If a script has an exported node property, eg
@export var node : Node
pointing to a child node, when duplicated, the duplicate of said script will still point to the original node.The ideal or expected behaviour would be:
If the exported node points to a child of the object, its duplicate should point the equivalent child of the duplicated object (the underlying NodePath does not change)
If the exported node does not point to a child of the object, its duplicate should target the same node as the original (the underlying NodePath will be different)
Currently, the behaviour is always the latter. This causes particular problems if you're assembling game elements procedurally; to give an example, a procedurally generated mob character might be assembled once and then duplicated as needed, an approach that will currently fall apart in very unpredictable ways if any part of said mob uses exported Node properties.
Steps to reproduce
Have a script with an exported node property
Call duplicate() on an instance of said script
Check the node path
Minimal reproduction project
DuplicateExportedNodeBug.zip
Open in the editor and run the scene; check the paths printed in the Output window.
The text was updated successfully, but these errors were encountered: