How to set both dictionary and value from another node, dynamically?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Multirious

The Set() seems to not working with the dictionary value ( object.set("dict:key", value) ),

Using Expression: "object.dict[key] = value" give me an error (Error: Cannot use “=” In expression.)

Workaround[1] Is that you get an entire Dictionary then set the value then return them back. This is not very efficient.

Workaround[2] Is using tween just to set a value because it’s for some reason working with "dict:key" because tween can take NodePath but Set() does not? And this is still not very efficient since you literally have to add a node to set a variable.

edit: yeah do this object.get(dict_name)[key] = value

:bust_in_silhouette: Reply From: klaas

Hi,
you dont need an expression, just address the dictionary directly.

var object = get_node("path to the node") #or use any other method to get the node
var key = "my key"
var value = "my value"
object.dict[key] = value

What about the dictionary?

Multirious | 2021-07-06 17:27

i dont understand … what do you mean?

i thought the dictionary was in the other object!?

klaas | 2021-07-06 17:29

Wait, sorry I meant the dictionary cannot be changed

Multirious | 2021-07-06 17:32

no, with this …

var object = get_node("path to the node") 

you get the node from the node path. then you referr to it with

object.dict[key] = value

klaas | 2021-07-06 17:33

I wanted both dictionary and value to dynamically changeable.

Multirious | 2021-07-06 17:34

ah, wait you mean you want to address the dict with a string as the property name?

klaas | 2021-07-06 17:35

The thing is I already know how the fetch the object but I don’t know how to dynamically set the dictionary and value.

Multirious | 2021-07-06 17:35

Yes, basically

Multirious | 2021-07-06 17:37

okay … you can do this like this

object.get("dict")["key"] = "value"
#or
var dict_name = "name_of_the_dict"
var key = "the new key"
var value = "value to store"
object.get(dict_name)[key] = value

klaas | 2021-07-06 17:39

I tried that and it doesn’t work. I’m guessing .get() is getting the value but didn’t refer to it.

Multirious | 2021-07-06 17:41

Godot Documentation states: Dictionaries are always passed by reference.

This will work!

a nodes script:

extends Node2D

func _ready():
	print("Before")
	print($child.dict)
	var object = get_node("child")
	object.get("dict")["other"] = "another"
	print("Now")
	print($child.dict)

the child named “child”

extends Node2D

var dict ={
	"this": "that"
}

this will print …

Before
{this:that}
Now
{other:another, this:that}

klaas | 2021-07-06 17:46

??? I tried that again, it didn’t work the first time but it works the second time. I didn’t changed any code wth
I guess this is the solution then

The solution is basicall this object.get(dict_name)[key] = value

Multirious | 2021-07-06 17:48

Also,

Godot Documentation states: Dictionaries are always passed by reference.

This is actually new to me, I’ve been trying to find some information for something like this, but Godot is just too hard to actually navigate to what you actually wanted, man. Thank you

Multirious | 2021-07-06 17:57

you can find more informations about that here:
GDScript: An introduction to dynamic languages — Godot Engine (stable) documentation in English

but beware … even here it is not mentioned that poolarrays are passed by value and not by reference. This acception can only be found in the poolarray docs.

It’s somewhat tricky … but the docs are not too bad like some other api docs are.

klaas | 2021-07-06 18:10