Topic was automatically imported from the old Question2Answer platform.
Asked By
Diet Estus
I am working in Godot 3.1 alpha 4, downloaded from here.
I have a breakable box which spawns a coin when the player attacks it.
The breakable box is an Area2D and the coin is a KinematicBody2D. When my player attacks, he generates an attack box which is also an Area2D. This attack box calls a destroy() method on the breakable box during emission of its on_area_entered signal. The destroy() method in turn calls a function from a singleton which spawns a coin.
You’re trying to call this function in a notification generated by flush_queries. It appears that flush_queries is finding all the overlaps and pushing out notifications based on those, but it’s setting a variable flushing_queries to true while it’s doing that. Any other function that adds, removes, enables or disables collision data is disabled via the FLUSH_QUERY_CHECK macro at the beginning of those functions.
The short of it is it appears you can’t do that from a collision notification. It’s advising you to use call_deferred which will defer the physics-modifying code that’s causing the problem to the idle time.
Thanks for the answer! You seem to be correct. You cannot add new Area2Ds to a scene during a call of another Area2Dson_area_entered(). Using call_deferred() solves the problem. It’s interesting that you don’t get these errors in Godot 3.0.6.
Diet Estus | 2018-12-31 23:01
I know I’m a little late for this, but can you explain a little more detailed about the call_deffered()? I tried using it instead of add_child()but then when I try to use the new “new child” tween node, it says that start: Tween was not added to the SceneTree!. What should I do?
`
MicasiO | 2020-05-12 14:11
MicasiO it means you are trying to start() a tween while it’s not in the tree yet. call_deferred executes a function later, not immediately. So if you want to call start after calling add_child in a deferred way, you must also call start using call_deferred. Alternatively, you can create a custom function doing these things and use call_deferred once on that function instead.
If you still have issues I suggest you create a new question because that’s unrelated to flushing queries.