0 votes

Hi! I have big problem with my code, maybe it's a bug?

I need to save position of my rays in child node to revert it back after some movement of my character. I have written simple save() function what should get data from variable and store it for later use. But for some reason when variable in character is changing values are also changed in my saved data. Of course save() function I'm using only once.

Generally it's all what I have in scene for now, one object with rays variable and parent whit this save() function.

Why it happens? How to solve that?

CODE:

var history = []

func _process(delta):
    if Input.is_action_just_pressed("ui_accept"):
        save()
    if Input.is_action_just_pressed("ui_down"):
        for child in get_children():
            if child.get_class() == "StaticBody2D":
                print(child.rays_list)
        for hist in history:
            print(hist)

func save():
    history.clear()
    for child in get_children():
        if child.get_class() == "StaticBody2D":
            var data = child.rays_list
            history.append( data )

OUTPUT:

# just after save()
     # variable from child node
[[ray_0, (0, -128), (-1, -1), (-1, -1)], [ray_1, (128, -128), (1, -1), (1, -1)], [ray_2, (128, 0), (1, 1), (1, 1)], [ray_3, (0, 0), (-1, 1), (-1, 1)]]
     # variable from saved data (history), for now they are the same, so it's ok
[[ray_0, (0, -128), (-1, -1), (-1, -1)], [ray_1, (128, -128), (1, -1), (1, -1)], [ray_2, (128, 0), (1, 1), (1, 1)], [ray_3, (0, 0), (-1, 1), (-1, 1)]]



# after movement (without next save() )
     # variable from child node
[[ray_0, (-128, -128), (-1, -1), (-1, -1)], [ray_1, (0, -128), (1, -1), (1, -1)], [ray_2, (0, 0), (1, 1), (1, 1)], [ray_3, (-128, 0), (-1, 1), (-1, 1)]]
     # variable from saved data (history), why it's also changed?
[[ray_0, (-128, -128), (-1, -1), (-1, -1)], [ray_1, (0, -128), (1, -1), (1, -1)], [ray_2, (0, 0), (1, 1), (1, 1)], [ray_3, (-128, 0), (-1, 1), (-1, 1)]]
in Engine by (227 points)

1 Answer

+1 vote
Best answer

Arrays (and dictionaries) are shared. You've copied a reference into history variable. You need to duplicate() it:

history.append( data.duplicate() )
by (2,288 points)
selected by

I have try it, bit it's still not working :(

Right now code looks like this:

var history = []


func _process(delta):
    if Input.is_action_just_pressed("ui_accept"):
        save()
    if Input.is_action_just_pressed("ui_down"):
        for child in get_children():
            if child.get_class() == "StaticBody2D":
                print(child.rays_list)
        for hist in history:
            print(hist)


func save():
    history.clear()
    for child in get_children():
        if child.get_class() == "StaticBody2D":
            var data = child.rays_list
            history.append( data.duplicate() )

Ok, i see what's wrong - ray_list is an array of arrays and those arrays were not duplicated.
Try this:

var data = []
for ray in child.rays_list:
    data.append( ray.duplicate() )

history.append( data )

In Godot 3.1 there will be option to make deep copy via Array.duplicate( true ) - it will duplicate all nested arrays as well.

Thanks, it's works :-)

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.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.