Huge performance issues with get_simple_path

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

Hey! To put it simply:

  • I’m making a 2D top down game
  • Tilemap & Navigation2D are done
  • I have a player, and several enemies that can successfully chase the player around the map (they avoid walls and all)

However, if there is half a dozen enemies or more, the game becomes extremely laggy. After some trial and error, I discovered that it’s caused by get_simple_path, used in I’m pretty much sure I’m using it wrong.

Basically, what I do is:

var path

func _physic_process(delta):
	# [Things...]

	var stuck_distance = 0.3
	var stuck = global_position.distance_to(last_position) <= stuck_distance

	path = ELEMENTS.paths.get_simple_path(global_position, ELEMENTS.player.global_position, stuck)
	last_position = global_position

	if path.size():
		move_and_slide((path[0] - global_position).normalized() * speed)

	# [Things...]

I guess I shouldn’t call get_simple_path every time _physic_process is called, but how else am I supposed to update my enemies’ pathfinding?

I tried putting a small time restriction (just on the get_simple_path and path.remove(0) lines), but it makes the enemy’s movements buggy.

:bust_in_silhouette: Reply From: Magso

A time restriction would alleviate the workload, last time I used get_simple_path I updated it every 0.25 seconds and the framerate kept to a steady 30 (with post processing). The enemy movements will be buggy because move_and_slide is only moving towards the first point in the path so if the enemy gets there before get_simple_path updates it will stop and start. The index needs to increase as the enemy moves to the next point, so you’ll need to code something like this.

if global_position == path[point]:
    point += 1
move_and_slide((path[point] - global_position).normalized() * speed)

Thank you for the help, but the enemy’s movements is still buggy. I tried with a 100 ms restriction, but it appears global_position == path[0] is never true, so I have no clue why setting a time restriction causes this kind of “stuttering”.

Ortcel | 2019-12-30 17:38

Try using distance_to

if global_position.distance_to(path[point]) < 1:

Magso | 2019-12-30 17:45

It works! Thank you very much.

Ortcel | 2019-12-30 17:54