Unable to iterate on object of type 'Object'.
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
- Edited
- Edited
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()`
- Edited
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?
- Edited
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.
- Edited
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
- Edited
Looks like we are going in circles here. A few observations:
- call_deferred is not useful in this case.
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 thread - The main issue is
objects
. 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.
- Edited
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.