0 votes

Hi there!
So, I'm super new to godot and programming in general. Here's what I'm trying to do... when a scene loads, I want to create 4 instances of an object in specific positions. Here's the code I'm using so far:

var wallLoader = load("res://scenes/wall.tscn")
var wallInstance = wallLoader.instance()

func _ready():
    wallSpawner()

func wallSpawner():
    add_child(wallInstance)
    wallInstance.position = Vector2(24, 120)

    add_child(wallInstance)
    wallInstance.position = Vector2(104, 120)

    add_child(wallInstance)
    wallInstance.position = Vector2(24, 360)

    add_child(wallInstance)
    wallInstance.position = Vector2(104, 360)

I can see that everytime that I call wallInstace.position I'm changing the position of all the previously created instances. Is ther a way for me to set the position of these instances individually?

Thanks! :)

asked May 3 in Engine by andreluizgollo (39 points)

3 Answers

0 votes
Best answer

you are adding the instance and then changing his position
you have to create the instance, change position, and then add it

var wallLoader = preload("res://scenes/wall.tscn")
# I'll make a list of positions, this will be hepfull for less code
var positions = [Vector2(24, 120), Vector2(104, 120), Vector2(24, 360), Vector2(104, 360)]
....

func wallSpawner() -> void:
    for i in Range(positions.size()): 
        # positions.size() = 4 -> 'i' is going to iterate from 0 to 3
        var wallInstance = wallLoader.instance()
        wallInstance.position = positions[i]
        # positions[0] = Vector2(24, 120)
        # positions[1] = Vector2(104, 120) and so
        add_child(wallInstance)

If you get a bit lost with the array and the "for" I recommend you to check those concepts (there are universal on programming)

answered May 3 by Omar13 (164 points)
selected May 4 by andreluizgollo

It worked nicely! I am familiar with arrays and loops, I studied a little bit of JavaScript a while back. Tho, I never got far enough to be capable to apply it in code. But I know their concepts, hehe. Thanks dude! :)

Messing around with the code you provided, actually trying to understand everything in it, I'm left with 2 doubts... why did you declare the "var wallInstance = wallLoader.instance()" again inside de function, if it was already declared in the beginning of the code? I tried removing it and the function stopped working hahahaha. Plus, what the "-> void" does?

"void" is the expected return for the func (in this case... nothing). I like to work with static typing, is a bit slower at start but saves a lot of bug fixing time.

I declared the var only inside wallspawner (didnt declare at top of all) 'cause I don't want to use memory until that very moment inside wallspawner (a function that may or may not be called).

If you want to call only at the start than do it, just be sure is an onready var. And inside wallspawner only call whatever you want to do with that var

0 votes

I think you need to move the spawned nodes, not the instance . . . Can you find the ' position - name ', of the new nodes . . .? <3 <3

answered May 3 by jasperbrooks79 (85 points)

A spawned node is the instance! There is the abstract concept of node: the scene. And the concrete realization of that same concept in the game: the node/instance.

+1 vote

If you check the "Debugger"-tab, you should see three errors produced by your code, all stating the same: add_child: Can't add child 'wall' to '...', already has a parent '...' The problem is simple: you're creating one (and only one!) instance in the beginning and then try to add that same instance in four different places! Like humans, a node cannot be in four different places at the same time though. However, four instances (or humans) can! So what you actually have to do is this:

enter code herevar wallLoader = load("res://scenes/wall.tscn")

func _ready():
    wallSpawner()

func wallSpawner():
    add_child(wallLoader.instance())
    wallInstance.position = Vector2(24, 120)

    add_child(wallLoader.instance())
    wallInstance.position = Vector2(104, 120)

    add_child(wallLoader.instance())
    wallInstance.position = Vector2(24, 360)

    add_child(wallLoader.instance())
    wallInstance.position = Vector2(104, 360)
answered May 3 by njamster (8,874 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.