How to temporarily freeze objects using a timer?

Godot Version

4.2

Question

How to temporarily freeze objects using a timer?

I’ve just started learning Godot and finished the official tutorial. I decided to add a couple features myself. One of the features is to spawn objects that can freeze all the mobs for a second. I added them as RigidBody2D without velocity.
Player’s _on_body_entered checks if hit a freeze object and emits a collected_freeze signal.

func _on_player_collected_freezer(body_id):
	var collected_freezer_body = instance_from_id(body_id)  # Get the body instance from the ID
	collected_freezer_body.queue_free()
	
	var mobs = get_tree().get_nodes_in_group("mobs")
	for mob in mobs:

		mob.call_deferred("freeze", true)

	var timer = Timer.new()
	add_child(timer)
	timer.wait_time = 1
	timer.one_shot = true
	timer.timeout.connect(_on_timer_unfreeze_mobss.bind(mobs))
	timer.start()

func _on_timer_unfreeze_mobs(mobs):
	for mob in mobs:
		mob.call_deferred("freeze", false)

This version doesn’t work at all, so the freezing doesn’t happen. I saw a bunch of examples and it seemed to be working for people. Also, some were saying that it works only for callable.

The other option was to add a new bool parameter for the enemy and set it directly

var frozen = false

func _process(delta):
	if frozen:
		freeze = true
	else:
		freeze = false

I can see that freeze value changes via debugger. The only problem I have is that it never unfreezes even if freeze == false

mob.call_deferred("freeze", true)

You mean to use set_deferred in this case, try that out. The _process function is pretty brute-force and I’m surprised it does work, maybe the mobs are sleeping at that point?

@gertkeno Oh, yeah, thanks. I updated the code, and I have the same behavior as with _process. Mobs freeze for 1 second and then unfreeze but without any movement. I checked a mob object in the debugger, and it looks identical before and after the freeze.

Adding repo with the code: GitHub - Antyk1234/godot-test