Instantiating a scene as a child to a node without a transform

I was pretty surprised when the approach chosen for the instantiation of the rocket projectile was to instantiate it as the child of a node which doesn’t have a transform.
The approach that is usually used and recommended, if you want your instance to be independent from the script/node spawning it, is to instantiate something as a child of the root of the scene tree - so get_tree().get_root().add_child(instance).
Doing it as a child of a nested node of type node has the same effect in regards to relative movement, however it obscures the fact that the instances are not living independently in the scene tree and instead still remain children of the player instance.

What would be the benefit of this approach?
A clear downside here is that if the parent node, in this case the player is destroyed, all bullet instance are destroyed too. For the player this may not matter as much, but if this approach were used on a shooting enemy, it would be very weird behavior.

4 Likes

i personally tend to instantiate bullets etc as children of a ‘node’ in the same way, as i just use it as a container for organisation, but i normally have this container node as part of the scene structure that is static and wont change. just makes it easier for me to turn down that node contents when looking at the remote tree information when debugging.

but as you say, having this sort of overridden transform info as a child of a dynamic object like the player could be messy.

2 Likes

I agree with you on this point.

In my past projects made in Unity (im sure it translates over to Godot as well), I would create a empty container that is not a child of the player or any other gameobject, but of the world and just add all projectiles under that container. This made it seperate from the player and any other entity while keeping all the projectiles contained for easier debugging if needed.

Edit: I got it working.

Add the container in the main Game Node
image

Create a variable that gets the Projectile Container from the parent node since the player will most likely not have a parent node other than the Game world.

@onready var projectile_container : Node = get_parent().get_node("Projectiles")

Then when instantiating the rocket (Handling shooting), I add the rocket to the projectile container while also doing a check to make sure the container is not null so I dont get any errors.
image

And now they get added to the projectile container!
image

Another thing I did in this step was to create a unique name for each rocket being instantiated. Since i cant stand the node type being show as the name. This will help when having multiple projectiles being instantiated!

var count_index : int = 1

func shoot():
	if projectile_container != null:
		var rocket_instance = rocket_scene.instantiate()
		
		var unique_name = "Rocket_" + str(count_index)
		rocket_instance.name = unique_name
		count_index += 1
		
		projectile_container.add_child(rocket_instance)
		rocket_instance.global_position = shoot_point.global_position

And now the projectiles show new names instead of those Area2D ones!
image

New to Godot 4 is the “set as top level” which can be found under Visibility in the inspector or added by code as screenshotted:

This allows the rocket to move independently as well.

3 Likes

Thanks for this. I will be using this way from here on out.

Hey guys, wanted to share my thoughts about this.
Please don’t forget that this is a course designed for absolute beginners.
I try to teach everything step by step and try not to confuse or overwhelm the student.
This sometimes results in omitting the best way to do something for the sake of teaching other things.
If you are a more experienced game dev taking the course this might frustrate you because you might see opportunities to do certain things more efficiently.
In that case please go ahead and use your own solution.
Just keep in mind that I’m trying to teach the fundamentals of Godot and programming. I’m not trying to show how to write the “best” way to do things.
That would be covered in a intermediate or advanced course where I can confidently teach because I know the student knows what they are doing.

1 Like

@kaanalpar is there a chance of an intermediate course being made. most course I find are aimed at beginners - there seems to be a lack of intermediate and advanced courses.

While I agree that beginners do have to start somewhere, teaching them a way that very easily leads to a wrong/incomplete understanding of what they are doing is only going to lead to frustration down the line.

As I noted in my OP, instantiating something as a child to a node which doesn’t have a transform is a workaround/hack which currently does work in this situation, however it has some significant issues.

  • First off, it obscures the fact that the projectiles are in fact still children of a parent to which they don’t have any other obvious connections. Free the parent and the projectiles all disappear. Give the node a transform later, bullets start misbehaving. Both these things will not be obvious to beginners, as from what is thought, the lecture really gives the impression that if you instantiate a node, that’s just it. It then just kinda lives there.
    However, aside from this one particular circumstance - the missing transform - instantiating a node as a child of another ALWAYS creates connection between the child’s and parent’s transforms. This is something beginners will have to learn on their own the very next time they’ll instantiate anything else.

  • Then, as others have pointed out, the top_level flag actually creates the intended behavior but is omitted in the material. I know this is a relatively new feature, but it’s there to address this very issue.
    I can only guess why someone who’s making a “Complete” Godot 2D course would not be aware of it.

  • And lastly, this section misses the rather important chance to explain to beginners the fundamentals of transforms. What they are, what’s local and global space, and most importantly why instantiating a node alone does not do anything and why we always have to make it a child of something (and inherit that things transform).

There’s giving beginners the tools they need to get out the gate and then there’s telling them to go left when everyone else is over there on the right.
I recon this falls on the latter side.

I voiced my complaints about this course in other places, so I won’t repeat them here. But one thing I do want to say is that, no, this isn’t a course for absolute beginners only. The title says “Complete Godot 2D”, not “Intro to Godot for Absolute Beginners”. Either way, though, beginners still should still not be taught an approach which will inevitably lead to a bug when they ever try it without the existing workaround.

Kaan, I’m saying this without malice - I know it may not come across like it. But the course you ported over from YT to here is not complete at all and still has some major issues.
I know it’s really hard to make these right. There’s so much stuff to cover, the engine is incredibly complex and constantly changing. The same is true for the topic of gamedev in general. The other “Complete” courses gamedev.tv offers are all significantly longer for a reason.
This course doesn’t even cover how to build the game so others can play it - the whole reason people make games in the first place.

Hey man I understand you have some issues with the course. I don’t think you are being fair but I’m not gonna try to change your mind because I don’t think I can.
Goal of this course is teaching absolute beginners the fundamentals of Godot and programming. And it accomplishes that goal very well. Almost everyone who takes the course are happy with it and leave good reviews.

@TyN Yes! We just released the Godot Mobile course. This builds on the things we learned in the Godot 2D course and teaches how to make a fully featured mobile game. This is a good course to take if you want to learn intermediate skills, even if you don’t want to make mobile games. And if you are also interested in mobile games this is the perfect course for you :slight_smile:

1 Like

If you set the void add_child(node: Node, force_readable_name: bool = false, internal: InternalMode = 0) 's method second parameter to true

projectile_container.add_child(rocket_instance, true)

, it will give you better names :slightly_smiling_face: :

2024-05-05 17_23_42-game.tscn - AlienAttack - Godot Engine

1 Like

Privacy & Terms