+4 votes

I want to know how I can pass values NOT by reference, but by value. When I write:

var array1 = [1,2,3,4,77,788]
var array2 = array1
array2.push_back(1)
print(array1) #print': 1,2,3,4,77,788,1

They are passed by reference.
because array1 and array2 two "point" to the same data.
How can I duplicate them. I'm searching for something like:

array2 = array1.cloned()

For arrays specific I already know some work arounds but how do I do it with custom objects?

in Engine by (333 points)
edited by
There are somewhat related issues on github:
(about array cloning) https://github.com/godotengine/godot/issues/3697
(about duplicate) https://github.com/godotengine/godot/issues/3393
thank you these threads are both interesting!

4 Answers

+4 votes
Best answer

Since all objects that you create via script are Nodes, you can use

Node duplicate( bool use_instancing=false ) const

It will return a reference to a copy of the Node you are duplicating, so you can just store it on a var.

~EDIT~
As for the data structures, if there is no copy method embedded on it, I think you'd have to create a function yourself. Most of the basics Data Structures have a very straightforward copy mechanism, anyway.

by (309 points)
selected by
Thank you!
Are they really always nodes also if I don't write: extends Node ?
This is exactly what I was searching for.
I'm not too sure about this, but I think that when you are creating a script, you have to extend it from somewhere, UNLESS it is a "tool" tagged script (something you'll use on the Editor).
you don't need to use the extends Anything line (I already tried it without). The question is if it extends something as default.
+19 votes

Try this.

var array2 = [] + array1
by (9,784 points)
Good method. I already was aware of another less comfortable way to do it with arrays. So this can be quiet useful when I need it next time.

Anyone know a solution for dictionaries? As "+" is invalid for dicts for no good reason I can see :/

poster by Bojidar:

With str2var(var2str(...)), you can effectively clone any object, at the high cost of speed.

Wow... That's handy.

+3 votes

This answer is mostly compiled from the issues @kubecz3k linked.

With str2var(var2str(...)), you can effectively clone any object, at the high cost of speed.

Unfortunately, the following method doesn't actually work... It would create the array in Copy-on-Write mode in Godot 1.x/2.x, which is rather useless for cloning. Better use @volzhs answer, or the str2var method.
The Array constructor accept a array to clone, so you can just do Array(my_arr). There are similar use for the Dictionary and typed array constructors as well. Unfortunately, this doesn't work for everything (like custom object classes).

Nodes have a .duplicate method, but it is already covered in another answer.

by (1,608 points)
edited by

For some reason, the Array constructor doesn't work for me. It has the same effect as doing newArr = oldArr.

Actually, it seems like it was an unintended feature in Godot 2.x. It would actually create an array in Copy-on-Write mode, and it would be fixed in 3.0. So, for now, better clone it by yourself or use @volzhs method.

+6 votes

New methods in array and dictionary can be used for duplication.

For array
https://docs.godotengine.org/en/3.1/classes/class_array.html#class-array-method-duplicate

For dictionary
https://docs.godotengine.org/en/3.1/classes/class_dictionary.html#class-dictionary-method-duplicate

var first_array = [
                    {10 : [10, 20, 30, 40]},
                    {20 : [10, 20, 50, 80]}]
var second_array = first_array.duplicate(true)
second_array.append({30 : [10, 30, 40, 70]})
print(first_array)
print(second_array)

var first_dict = { 10: [10, 20, 30, 40],
                   20: [10, 20, 50, 80]}
var second_dict = first_dict.duplicate(true)
second_dict[30] = [10, 30, 40, 70]
print(first_dict)
print(second_dict)
by (26 points)

Didn't you read the selected answer?

I read the selected answer but did not know how to use it. So I created another answer instead of comment.

Fair enough.

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 Frequently asked questions and 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 [email protected] with your username.