• Godot Help
  • How can I automate creating instances of a scene?

I am a noob, but I know how to create something via this thing:

scene = load("res://player.tscn")
player = scene.instantiate()
add_child(player)
player.connect("hit", _jump)

Problem is, I have to manually name them and connect their signals for each one by name, and add them separately. But if I make a tower defense kind of thing, or a bullet hell with scaling, I need to create large amounts of instances, possibly infinite, with their signals connected, and no manual naming, by the number. How do I do that? I can't just create the same one in s cycle, and I can't alter them in it, so I am not sure how to approach it.

  • xyz replied to this.

    With manual name you mean the player variable? That is not really naming the scene. You just storing a reference for later use. In many cases (e.g. bullets) you may not even need to do that.

    If you do need to store references to multiple scenes, store them in an array. If you need to create several scenes of a type at once, create them in a for loop.

      Shrimp I can't just create the same one in s cycle

      Why not?

        xyz I can't make them behave individualy (or spawn, I am not sure), Lets's say I spawn an enemy every time player lelvels up. So I do
        player.connect("bar_full", _en_spawn)
        ###################################
        func _en_spawn():
        add_child(enemy)

        And I want it in a random spot each time. So for an enemy script I do

        func _ready():
        position = Vector2(randf_range(-85, 85),randf_range(-55, 55)

        the first one spawns, the second eather doesn't, or does in the same place.
        Or is "ready" doesn't work for that? And I need a signal or whantnot? And how do I adress a singular one from outside?

        Zini so I can just go, let's say
        add_child(load(res://bullet.tscn).instantiate())
        if I just need to spawn a thing, and naming is only for addresing this one istance and connecting signals?

          Shrimp no, bradher
          if you gon go on and do that youll soon find out that your gaem is gon stutter ebry tiem you load a thing or two.

          preload the thing the scene, then when you need it in the scene instantiate and then add_child()

            kuligs2 thank you, comrad. Instantiate right before adding, got it, I hink it warked. Do I have to connect their signals each time too, or can I connect all of them before hand? Each that will be spawned?

              Shrimp you need to think about it.. maybe structure your code diferently, but in general, when you instantiate object, then you have to connect all the signals from scratch for that new obj.

              If you know how many instances you need in the scene you can do that in ready function.

              Or make another function add_new_instance() where you do that automatically and just call one function instead of long string of code..

                kuligs2 got it. I just hoped there was a way to connect it from the scene file itself, so whatever instance of that thing is added, is is already connected. But I guess that does sounds kinda dumb.

                Shrimp Other than that you forgot the " around the file name this can be okay, if you don't need to connect signals and you only create bullets in one place in your code. load, preload, that really doesn't make a difference (other than that load can cause a light stutter when a scene is instanced for the first time and that preload increases the loading time).

                However a case can be made that you should declare all you references to packaged scenes (the thing you get from preload or load) as variables or constants near the beginning of the respective script. This way you have everything in one place, in case you need to change it manually for refactoring/directory structure reorganization.

                Also, my point wasn't really that you have to squeeze everything into a single line of code. You can declare the variable that holds the reference to the instance locally (i.e. var something = ) if you do not require a reference beyond the point of setup.

                @Shrimp Instantiating scenes is like making cookies. Each instance is a cookie. The packed scene resource is the cookie cutter. Connecting and adding to the scene is baking.

                Whenever you want to make a new cookie, you need to cut the cookie using the cookie cutter, and then bake the cookie.

                # wield the cookie cutter
                var cookie_cutter = preload("res://cookie.tscn")
                # cut a cookie
                var cookie = cookie_cutter.instantiate()
                # bake the cookie
                add_child(cookie)
                cookie.eaten.connect(...)

                You can of course make a batch of cookies at once.

                # wield the cookie cutter
                var cookie_cutter = preload("res://cookie.tscn")
                # cookie batch
                for n in how_many_cookies:
                	# cut a cookie
                	var cookie = cookie_cutter.instantiate()
                	# bake the cookie
                	add_child(cookie)
                	cookie.eaten.connect(...)