Attention | Topic was automatically imported from the old Question2Answer platform. | |
Asked By | luckyNyaNya |
Deleting children doesn’t work properly when called on a parent node. Is it a known bug? How can I delete all nodes of a scene properly?
How to reproduce:
two scenes: SceneA with a reference var other
to other SceneB (append some children to SceneB root)
- instance both SceneA and SceneB
- set
other
to SceneB instance - call
queue_free()
on SceneB instance - check
var other
, it’s not null but it’s not a root of a SceneB, it holds some of the children (this happens sometimes)
I tried to use weak_ref but same thing since there is some reference to children nodes.
To clarify, queue_free()
doesn’t free nodes immediately, it does that at the end of the frame, so it’s normal if other
still holds a SceneB
right after.
I tried your reproduction steps in Godot 3.1, but all I got after a few frames was a debugger error saying access to 'previously freed instance'
, so all things run correctly here.
Do you have an example project which reproduces this bug?
Zylann | 2019-04-17 18:03
yeah, I know that it’s only queued for detetion. I call it not immediately, after some time (I do tower defence game, where tower shoots, then cooldown of 2 seconds, then I check if target is null or not)
I need a sec to upload my project to github
luckyNyaNya | 2019-04-17 18:11
make collision shapes visible in the project.
Now I don’t get any error (using weak_ref trick), dammit. Look at Planet.gd , method shoot(), so what I try to achive is when a creep dies, the planet script looks for new target
. Is there a better way to check for null instance?
luckyNyaNya | 2019-04-17 18:49
if target == null:
target = creeps[0]
else:
var wr = weakref(target)
There is a problem with how you expect weakref to work: it works with ref-counted types, however nodes are not such thing (they don’t inherit Reference
. In your use case, you should better use is_instance_valid
.
Weak references are instead used to have the ability to access a ref-counted object, but without owning a reference to it. For example, if a resource is referenced in two places, it won’t get freed until the two places stop referencing it (set to null). But, if one is using a weakref, then just setting the other to null will suffice, and the weakref will turn “invalid” automatically. But again, that doesn’t apply to nodes.
Now I test your project without the weakref
and it also does Invalid get index 'name' (on base: 'previously freed instance').
.
If I write if not is_instance_valid(target): print("erased")
, it correctly prints that the object is erased. Well, can’t reproduce here on Windows 10.
Zylann | 2019-04-17 20:37