Seems the loop doesn't assign the result in the array.

Here the code example for Godot 3.2.

extends Node

func manually():
    var vecs: = [Vector2(0.0, 0.0), Vector2(0.0, 0.0)]
    vecs[0] += Vector2(0, 50) * rand_range(-1.0, 1.0)
    vecs[1] += Vector2(0, 50) * rand_range(-1.0, 1.0)
    return vecs
    
func loop():
    var vecs: = [Vector2(0.0, 0.0), Vector2(0.0, 0.0)]
    for i in vecs:
        i += Vector2(0, 50) * rand_range(-1.0, 1.0)
    
    return vecs
    
func _ready():
    print(manually())
    print(loop())

Did I miss something ?

I'll probably explain this wrong, but a for loop is not exactly accessing elements in the list, it is just allowing you to manipulate a copy of an element temporarily. In other words, the 'i' in vecs != vecs[index of i].

Python has a handy function 'Enumerate' which retrieves both the index in the array and the value, but this doesn't exist in GDScrpt (I think) so you can instead do:

for i in vecs.size():
	vecs[i] += Vector2(0, 50) * rand_range(-1.0, 1.0)

@Bimbam said: I'll probably explain this wrong, but a for loop is not exactly accessing elements in the list, it is just allowing you to manipulate a copy of an element temporarily. In other words, the 'i' in vecs != vecs[index of i].

This is what is happening and is a good explanation, at least in my opinion. :smile:

Bimbam's answer is correct, but you will need to keep in mind that some data types are 'primitives' in gdscript.

Datatypes like Color/Vector/Transform/Basis/Quat are "primitive" types in gdscript, not Objects. The distinction here is, at the script level, they are passed by value and not by reference, of which only objects are (Object and any subclass of Object such as resources, nodes, Spatials etc).

You have an array (an object) of primitive types (Vector2)

the statement

for i in vecs

assigns the value of each element in vecs to the variable i. Because Vector2 is a 'primitive' it is set by value. (if it were an array of objects like nodes then i would be a reference to an object)

the statement:

vecs[0] += Vector2(0, 50) * rand_range(-1.0, 1.0)

accesses the array element vecs[0] and modifies it with +=

The distinction has impacts in other things you might do in your project.

Eg: changing an object's transform origin object.transform.origin = Vector3.ZERO doesn't work but object.transform = Transform(object.transform.basis, Vector3.ZERO) does

2 years later