Reparent node at runtime

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By two_headed_goblin
:warning: Old Version Published before Godot 3 was released.

Hi, i’m using VideoPlayer to make a looping bg based on a video. Natively the video player does not have to option to loop, the answer in this forum is to track progress and just send “play()” again, but that makes a flicker in black while the stream is reloaded and i wouldn’t want that on my bg.

I tried to come up with a node of my own to handle this issue, what i need to do is to create a new instance of video player underneath the one currently playing and then after a second, swap the nodes, the player that finished moved to the back to reload the video and the one on the back to the front.

I’ve had lots of issues trying to remove a node from a parent and adding it to another one, mora when the node is a stream player actively playing. Also there is no callback for “playing_finished” which could be very useful.

Anyways, what i need is a way of instantiating a node in a container, and then swapping it with another node in another container every certain amount of seconds (already got the timer structure, just having issues with the reparenting at runtime part).

Thanks in advance! =).

:bust_in_silhouette: Reply From: avencherus

It should look something like this.

var target = get_node("../..")
var source = get_node("child")
self.remove_child(source)
target.add_child(source)
source.set_owner(target)

The paths will depend on where the code resides.

Awesome, i’ll give it a try now i was sleeping hehe. stayed to 2:33 AM to try to make it work, now i’m so sleepy at my job but i don’t care.

two_headed_goblin | 2016-11-09 12:42

It should be fine. When you do remove_child, the node will stay in memory.

So you just grab it’s reference, remove it, then add it to the other node. It does have to be removed first, because Godot doesn’t appreciate nodes having two parent nodes.

avencherus | 2016-11-09 13:10

Hey again, yeah it’s working, only thing i had to change was that i needed to change ownership on the parent with “parent.add_child(ch1)”. The set_owner from the child threw error “invalid_parent”

two_headed_goblin | 2016-11-09 13:15

Oh, I see, sorry about the bug, I normally would’ve tested the code, but I wasn’t at my computer. I’m glad you got it adjusted and solved though. :slight_smile:

avencherus | 2016-11-09 13:23

:bust_in_silhouette: Reply From: luislodosm

Here’s a solution encapsulated in a function:

func reparent(child: Node, new_parent: Node):
    var old_parent = child.get_parent()
	old_parent.remove_child(child)
	new_parent.add_child(child)
:bust_in_silhouette: Reply From: thiagola92

Nodes have a reparent method now:

node.reparent(new_parent)