Use call_deferred() or set_deferred()

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

Hello, need help, not understand why there’s error. Thank you.

extends Area2D

onready var rock = preload("res://enemies_sprites/throw_goblin/rock_on_ground.tscn")

var player_position
var start_position
var arc_position
var t = 0

func _physics_process(delta):
	t += delta * 1

	_quadratic_bezier(start_position,arc_position,player_position,t)

func _quadratic_bezier(p0: Vector2, p1: Vector2, p2: Vector2, D: float):
	var q0 = p0.linear_interpolate(p1, D)
	var q1 = p1.linear_interpolate(p2, D)
	
	var r = q0.linear_interpolate(q1, D)
	
	position = r
	return r

func _on_rock_area_entered(area):
	if area.is_in_group("Player"):
	gone()

func _on_rock_body_entered(_body):
	gone()

func gone():
	var R = rock.instance()
	get_parent().add_child(R)
	queue_free()

E 0:00:07.122 body_set_shape_disabled: Can’t change this state while flushing queries. Use call_deferred() or set_deferred() to change monitoring state instead.
<C++ Error> Condition “body->get_space() && flushing_queries” is true.
<C++ Source> servers/physics_2d/physics_2d_server_sw.cpp:652 @ body_set_shape_disabled()
rock.gd:33 @ gone()
rock.gd:29 @ _on_rock_body_entered()

You are not showing us where the error is pointing.
In any case, in my experiments setting the monitoring property of an Area2D via code will not work directly.

$Area2D.monitoring = false     # this won't work

You have to use set_deferred():

$Area2D.set_deferred("monitoring", false)         

Similar changes to Collision properties such as disabled also need to use set_deferred.
See this post

LeslieS | 2023-01-29 03:56

:bust_in_silhouette: Reply From: Ertain

In the gone() function, the node calling queue_free() is being freed. The thing is, some other node still needs something from that node, but it’s going to be removed from the scene tree, i.e. freed. There could be code identified with body_set_shape_disabled, but I don’t know what that code is. The code for the gone() function may have to be tweaked like this:

func gone():
    var R = rock.instance()
    get_parent().call_deferred("add_child", R)
    queue_free()

But I don’t really know because I can’t find the code body_set_shape_disabled in the code you’ve provided.

It work, thank you.
Btw, what ‘call_deferred()’ do?

Evitca Ariz | 2023-01-29 03:02

it calls the method when the node isn’t “busy”, i.e. during idle times when calculations and other things aren’t being thrown around. When the parts of the node aren’t being removed from RAM via queue_free(), it’ll execute the code add_child() on the parent node.

Ertain | 2023-01-29 03:19