set_physics_process not working. Why not?

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

I have this project that I’ve been developing, and I decided to seek out a tutorial to disable enemies when they aren’t on screen. Some of them have a pathfinding logic built in, so they always head straight for the player’s position. I need them to not do that when they aren’t on screen so the player doesn’t get swarmed and enemies don’t leave the areas in which I have placed them. The logic to disable the enemies is as follows:

There is a Camera2D object with an Area2D and a CollisionShape2D attached to it. When a KinecticBody2D of type “ENEMY” entered this area, it triggers an event which enables physics processing, which is supposed to be off by default. Like this:

func _ready():
	if TYPE == "ENEMY":
		set_physics_process(false);

For some reason, the physics processes are always still on, even from the start.

Now when the enemies leave the Area2D, the physics processes are supposed to turn off. The code looks like this:

export var xWidth = 160;
export var yHeight = 128;
export var hudHeight = 16;
onready var collisionShape = $area/CollisionShape2D;


func _ready():
	var shape : Shape2D = collisionShape.shape;
	shape.set_extents(Vector2(xWidth /2, yHeight / 2));
	$area.connect("body_entered", self, "body_entered");
	$area.connect("body_exited", self, "body_exited");
	
func _process(delta):
	var pos = get_node("../Player").global_position - Vector2(0,hudHeight);
	var x = floor(pos.x / xWidth) * xWidth;
	var y = floor(pos. y / yHeight) * yHeight;
	global_position = lerp(global_position, Vector2(x,y), 0.1);

func body_entered(body):
	print ("Entered:");
	print (body.get("TYPE"));
	if body.get("TYPE") == "ENEMY":
		set_physics_process(true);

func body_exited(body):
	print ("Left:")
	print (body.get("TYPE"));
	if body.get("TYPE") == "ENEMY":
		set_physics_process(false);
		print ("Off");

Now all of that printing that you see results in an output that looks like this:

Entered:
ENEMY
Left:
ENEMY
Off
Left:
Null
Left:
PLAYER

So, as you can see, the events are indeed triggering, but the enemies keep moving. Which means that when I use “set_physics_process(false)”, Godot ignores me. Why does it do this?

Is this a bug, or am I doing something wrong?

I could not reproduce this. Works fine for me. Be aware though that _process is not the same as _physics_process, thus will continue to run. If you enemies (like your player) are moved in _process instead of physics_process, that would explain your issue.

njamster | 2020-03-01 13:21

:bust_in_silhouette: Reply From: wombatstampede

set_physics_process(false) tells a node to stop calling the _physics_process handler. But your code doesn’t show any!

I only see a _process handler in that code. If you want to stop that being called then use set_process(false)

I actually tried it both ways already, and neither way worked. I managed to get it to work by changing the process mode on the Camera2D from “Idle” to “Physics”. Don’t know why that worked, but I’m glad it did.

SawmillTurtle | 2020-03-01 19:15