How do i save a Node and Its children

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

I’m trying to save a node and its children, but only the Parent is saved:

func save():
	var save = PackedScene.new()
	save.pack(self);
		
	ResourceSaver.save(save, "res://lista de clientes/JDC.tscn");
:bust_in_silhouette: Reply From: GlitchedCode

There is one step you are missing here to include a nodes children, that would be to set the owner. So using your example code here:

func save():
    var save = PackedScene.new()
    for c in self.get_children():
        c.set_owner(self)
    save.pack(self);

    ResourceSaver.save(save, "res://lista de clientes/JDC.tscn");

Remember to set the owner before you pack it, this will now save itself and it’s immediate children. As a side note, if c in this case has children, you will also need to loop through these and set owner to self so the for loop would then become

for c in self.get_children():
            c.set_owner(self)
            for a in c.get_children():
                a.set_owner(self)

Okay, it kinda worked, but when it loads, all the variables were reset to the default

K3n1 | 2023-03-24 00:10

if your variable is exported, it will have the appropriate flags set to be saved

GlitchedCode | 2023-03-24 21:43

Okay, i used the @export thingy on the variables i wanted and it kinda works

But everytime i use it in a array that stores the Nodes inside the parent variable it crashes

It might me because i’m declaring the array wrong

@export var clientes:=[];

K3n1 | 2023-03-27 12:30

Nope, you are declaring it correctly. When I export and use an array, the same one you posted, it seems to save just fine with its children and a random value appended to it just fine. I tried with the node paths and it was fine, as well as getting a node with $ and storing it. Getting the node of course caused an empty entry, but it did not crash.

Could I see the code as you are writing it, so I can try to replicate this crash and if so, help try to find the reason why.

GlitchedCode | 2023-03-27 23:51

I noticed i was doing an infinite loop inside the object, sorry XD.

But thanks, you were of immense help!!

K3n1 | 2023-03-28 14:36

1 Like

I was having a similar problem. Just as an additional solution here is what I did:

func set_ownership(p_owner, node):    # p_owner, because it might shadow owner in self,
	for c in node.get_children():     # although this wouldn't matter here
		c.owner = p_owner
		set_ownership(p_owner, c)

It’s basically a recursive function that goes through all the children and sets the owner. I don’t know how Godot handles recursion, but intuitively I would say, unless you are working on a AAA title, this function is safe. At least I did not work with Trees in Godot that were 1000 levels deep.

func save(filename, node):                         
    set_ownership(node, node)  
    var scene = PackedScene.new()    
    scene.pack(node)

    ResourceSaver.save(scene, filename);                 

All you have to do is call the function with the root node that you want to save before you pack it and it will go through all the children. Maybe this can be of help to somebody.

Cheers,

1 Like