I'm currently working on an inventory system and when I use a for loop to call on my individual inventory slots I get this error for gd:10, Unable to iterate on object of type 'Object'.
What is the cause for this error?
I'm currently working on an inventory system and when I use a for loop to call on my individual inventory slots I get this error for gd:10, Unable to iterate on object of type 'Object'.
What is the cause for this error?
You can iterate only on collection type objects such as arrays or dictionaries. Here you're trying to iterate over a GridContainer which is just a regular object and thus not iterable. The error message is telling you exactly what the problem is.
I'm guessing you want to iterate over GridContainer's children. In that case you should get an array of its children using get_children() method.
for slot in inventory_slots.get_children():
Again, note that get_children() returns an array, which is iterable. You can check that it is indeed so by:
var slots = inventory_slots.get_children():
print(slots)
Hello, I have pretty similar error in Godot 4.2
I used get_children(), but it gave me:
MyScriptNameHere.gd:25 @ _thread_process(): Caller thread can't call this function in this node (/root/World/Chunks). Use call_deferred() or call_thread_group() instead.
error
Okay, maybe I should try both? I tried, and I have now:
Unable to iterate on object of type 'Nil'.
from call_deferred("get_children")
and the same error from call_deferred_thread_group("get_children")...
I don't know how to fix error
pls help
Yes it's different, I meant Unable to iterate on object of type 'Nil'.
error is looks pretty same, sorry for the confusion
`func thread_process(userdata):
while(true):
for c in objects.get_children():
var cx = c.object_position.x
var cz = c.object_position.y
var px = floor(player.position.x / Global.DIMENSION.x)
var pz = floor(player.position.z / Global.DIMENSION.z)
var new_x = posmod(cx - px + load_radius/2, load_radius) + px - load_radius/2
var new_z = posmod(cz - pz + load_radius/2, load_radius) + pz - load_radius/2
if (new_x != cx or new_z != cz):
c.set_object_position(Vector2(int(new_x), int(new_z)))
c.generate()
c.update()`
Butab MyScriptNameHere.gd:25 @ _thread_process(): Caller thread can't call this function in this node (/root/World/Chunks). Use call_deferred() or call_thread_group() instead.
What is line 25 of MyScriptNameHere.gd?
for c in objects.get_children():
If what, objects is onready variable with $Objects value
And when are you iterating? The engine is telling you that you can’t yet, and if you need to at that point, use call_deferred
How is thread_process called? Either call it using call_deferred, or place its contents in a separate function, and call that function using call_deferred.
DaveTheCoder Either call it using call_deferred, or place its contents in a separate function, and call that function using call_deferred.
Tried, game launched and after few seconds Windows says it's not responding lol
Thread_process is called with: load_thread.start(Callable(self, "_thread_process").bind(null))
at _ready() function
Looks like we are going in circles here. A few observations:
call_deferred("get_children")
will always return null. You can't get return values via call_deferred. Calling the entire function deferred also does not make sense. Your are trying to run code in another thread. But call_deferred puts it back into the main threadobjects
. What is it? A node that is part of the scene tree? If yes, then what you want to do is impossible. You can not manipulate the scene tree from another thread. The scene tree is not thread-safe.You could try replacing:
load_thread.start(Callable(self, "_thread_process").bind(null))
with:
(func(): load_thread.start(Callable(self, "_thread_process").bind(null))).call_deferred()
I haven't used Threads in Godot, and don't know if that will make a difference.
That's from a hypothetical document called "Weird lambda tricks".
DaveTheCoder That shouldn't work either. The thread is probably started from the main thread anyway, so calling deferred shouldn't make a difference to begin with. Also the get_children function would still be called from another thread, so it doesn't even address the problem.
If the situation is what I think it is then @Butab will have no option but to go back to the drawing board and either design a new multi-threading design from scratch or drop multi-threading all together.