I want an object to destroy the previous node as soon as it is created.

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

I want an object to destroy the previous node as soon as it is created.

I’m building a spawner system for my highway racing game, but when a node is created in my game, I want it to destroy the previous node.
But I couldn’t find anything. Please help me.
The code I use for this is:

:bust_in_silhouette: Reply From: BigTuna675

Hey! I think your image link isn’t working properly.

But if you want to achieve this effect, you could do the following:

  1. Create an empty Node2D or Node3D and call it “ObjectHolder” or similar. This will hold the new nodes of interest you are trying to create and destroy.
  2. When it is time to create a new node, first queue free all of the children nodes of “ObjectHolder” and then add the new node as a child of the object holder node.

So this will ensure that “ObjectHolder” only has one child node at a time and deletes the old nodes before adding the new one

I’m sure there’s another/better way to do this but without any additional information this is what I came up with. Good luck!

Can you show with a code example?

Gangster53 YT | 2022-10-07 12:25

By the way how can I get the name of the previous node instead of deleting the previous node.

Gangster53 YT | 2022-10-07 12:35

The code I used was:

func _on_new_road_spawner_body_entered(body):
  if body.name == "car":
	 var road = load("res://scenes/maps/test_road_load.tscn").instance()
	 road.translation.z = new_road_pos_z
	 new_road_spawner_pos_z += -226.051
	 add_child(road)

	 $new_road_spawner.translation.z += -43.189 + -226.049

Gangster53 YT | 2022-10-07 12:44

So one issue I see with the above code is that the node name might not be exactly “car”. It might be “car1” or “car2” which is what the engine does if you have multiple nodes with the same name appearing in the same level/spot on the tree.

In Godot, it can be tricky to work with the absolute name of a node. Because if the name changes or moves around in the scene tree then your reference will break and you’ll get some errors. It’s best to avoid this.

The first thing you should do is to add your car to a group, called “PlayerCar” or something.

If your scene tree looks like this:
World (Spatial)
—Other nodes…car, map, terrain, etc
—ObjectHolder (Spatial)

In the ObjectHolder node, add it to a group, called “ObjectHolder”

Then in your function

func _on_new_road_spawner_body_entered(body):
    if body.is_in_group("PlayerCar"):
         if get_tree().get_nodes_in_group("ObjectHolder")[0].get_child_count() > 0:
             var delThese = get_tree().get_nodes_in_group("ObjectHolder")[0].get_children()
             for tempNode in delThese:
                   tempNode.queue_free()

         var road = load("res://scenes/maps/test_road_load.tscn").instance()
         get_tree().get_nodes_in_group("ObjectHolder")[0].add_child(road)
         road.translation.z = new_road_pos_z
         new_road_spawner_pos_z += -226.051
        $new_road_spawner.translation.z += -43.189 + -226.049
         

This is still kind of a hacky way to do it, and Signals are the best way to do this for sure, but that opens up a larger discussion. This way “should” still work at least. Happy to show you the signal route if this doesn’t work out

BigTuna675 | 2022-10-07 13:50

Very thanks. I will try this code and get back to you.

Gangster53 YT | 2022-10-07 14:54

I did as you said but no result. It does not create the new path.
İndir test map1 tscn Power The Cars Godot Engine 2022
I thought maybe it was because of the if body.is_in_group("car"): code at the beginning, so I replaced it with if body.name == "car":
But this time, the game gives an error when the car enters the area.
İndir error

Gangster53 YT | 2022-10-07 15:15

Ahh sorry that link doesn’t work for me, can you copy and paste the text of your error?

BigTuna675 | 2022-10-07 17:50

Invalid get index ‘0’ (on base: ‘Array’).

Gangster53 YT | 2022-10-07 18:21

That relates to this piece of code

get_tree().get_nodes_in_group("ObjectHolder")[0]

Means that the game tried to find a node in the group “ObjectHolder” but there was none found.

get_tree().get_nodes_in_group("ObjectHolder")[0]

Returns an array, and gets the zero’th element of it (the [0] part) but if the array is empty, then there is no zero’th element

BigTuna675 | 2022-10-07 18:29

https://www.mediafire.com/view/7o4jk880xop2hfg/test_map1.tscn_-_Power_Of_The_Cars_-_Godot_Engine_7.10.2022_21_36_17.png/file
I renamed it new_road_holder instead of ObjectHolder.
I added the path node below, but it still gives the same error. I hope the link above works. You can see the picture there.

Gangster53 YT | 2022-10-07 18:40

gotchya, so I am assuming that the child of newroadholder, mainroad, is the thing you want to delete and recreate right?

It doesn’t look like newroadholder is in any groups. check this doc page for help on how to add a node to a group in the inspector Groups — Godot Engine (stable) documentation in English

Groups are something different than names- it’s like a special tag you can assign to things for quick identifying or locating purposes

BigTuna675 | 2022-10-07 18:48

I didn’t know about these groups. Am I doing it right? I clicked on the “new_road_holder” node you see in the picture, I clicked the node above, and then I clicked on the groups from there.
After that, I created a group called “new_road_holder”. Do I now have to add the “main_road” node below the node to the group as well?

Gangster53 YT | 2022-10-07 18:59

Not quite! That sounds like you added new road spawner to the group

You want to only add new road holder to the group, that way it will be the only node in the group and the function will only find that node and nothing else (or else you will get roads spawning in random spots!)

Think of it like this- we create the “new road holder” node, and its job is to organize/hold the roads you want to spawn. We add it to a group, “ObjectHolder” (from the function above).

The function looks for nodes in the ObjectHolder group, and we only want it to find new road holder and nothing else

BigTuna675 | 2022-10-07 19:06

This is how I did it and it works. God bless you. Thank you so much.

Gangster53 YT | 2022-10-07 19:09

When my game is finished, I will add your name to the credits section. Thank you very much again.

Gangster53 YT | 2022-10-07 19:10

Wow nice!! That’s awesome to hear, and wow thank you that’s very kind of you! :smiley: Good luck with the rest of your game friend!

BigTuna675 | 2022-10-07 19:16

By the way, do you use Discord? If so, can I add you as a friend?

Gangster53 YT | 2022-10-07 19:18

I actually don’t have one haha, but if I get one I will let you know! I’ll certainly keep an eye out for your questions on here though :slight_smile:

BigTuna675 | 2022-10-07 19:28

Now I noticed something the previous node is not deleted.
https://www.mediafire.com/file/th7yxfx36jshkcc/Power+Of+The+Cars+(DEBUG)+2022-10-07+22-36-44.mp4/file

Gangster53 YT | 2022-10-07 19:39

I think that is an MP4 file there

BigTuna675 | 2022-10-07 19:44

Yes. I chose mp4 to show the problem.

Gangster53 YT | 2022-10-07 19:46

I think the problem is that I have set the position of the newly created node incorrectly.

Gangster53 YT | 2022-10-07 19:53

Ok I solved the problem. Have a nice day.

Gangster53 YT | 2022-10-07 20:03

Nice! Glad to hear it

BigTuna675 | 2022-10-07 20:20

This is a split-second lag as each node is created and deleted. Is there any way to solve this? So I want to eliminate that split-second hookup, is it possible?

Gangster53 YT | 2022-10-08 13:19

You can try to use preload instead of load

By this I mean, somewhere at the top of your script, write this

const roadScene = preload("res://scenes/maps/test_road_load.tscn")

And then in your function, replace this line

var road = load("res://scenes/maps/test_road_load.tscn").instance()

with

var road = roadScene.instance()

BigTuna675 | 2022-10-08 13:26

Unfortunately, the stuttering still has not gone away and has even increased a bit.

Gangster53 YT | 2022-10-08 20:30

Can you share your script please?

BigTuna675 | 2022-10-08 20:33

So the difference between load and preload is that load starts loading the scene when the line of code is reached, and preload loads the scene ahead of time. You should in theory be able to prevent some lag by loading your scene ahead of time via preload

Somewhere outside of your function, you can use

const roadScene = preload("res://scenes/maps/test_road_load.tscn")

That will make it so that roadScene is able to be instance without needing to re-do the loading of it every time the function is called. It has to be outside of all functions. Ideally towards the top of your script so you can see it clearly in the future.

Then you simply do

var road = roadScene.instance()

when it’s time to instance the new roadScene in the function. Did you already try this and it’s still lagging?

BigTuna675 | 2022-10-08 21:17

Yes. Even after I did that it still hangs.

Gangster53 YT | 2022-10-08 21:21

Gotchya, I was asking because the code in the picture you shared is different than what I was suggesting.

Hmm well it will be hard for me to diagnose this without going through the rest of the project haha.

Instead of that, you can try to look at the Profiler. In the output console window, there is a tab called Debugger. When you click that, there is an option called Profiler. Hit start to begin the profiler and then test the game. It will help you narrow down the cause of the lag further

BigTuna675 | 2022-10-08 21:29

There was one HTerrain in the road scene. Although HTerrain is invisible, the game hangs because of it. I deleted it. It doesn’t hang out anymore, but the road looks very lousy like this. So I can’t add anything to the road scene. Because there are lags in the game.

Gangster53 YT | 2022-10-09 09:01

Is there a way to add something to the road scene without creating lags in the game?

Gangster53 YT | 2022-10-09 09:02