Buggy navigation / collision detection

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

Hi, I’m having an issue on a pacman clone I’m building. Basically when a ghost is inside the home area, it will go up until it collides with a wall, then it will start chasing the player. I’m using a tilemap for the level design / collisions / navigation, and kinematic bodies for the player and the ghosts.

Everything works fine most of the time, the ghosts chase the player without issue, but there is a bug that’s driving me crazy. It only happens if the player is in the right side of the screen when a ghost leaves home, and it makes the ghost jitter up and down for some reason. If the player moves to the left side the ghost starts chasing him. If the player doesn’t move, the navigation path defaults to going left, and the ghost chases the player just fine.

There are no differences between the left or the right side of the level, and I’ve been trying to debug this for hours to no avail. I’ve uploaded a project where you can reproduce this if you want: download

Also here’s a gif that kinda shows what I mean, but you can’t see the ghost jittering because well, it’s a gif:

If you have any ideas of what might be wrong, please let me know.

:bust_in_silhouette: Reply From: Andrea

the problem is in path[1].
Since the position of the ghost is not exact, sometimes point[1] and point[0] are basically identical, and in that case what you need for is point[2]
Change

var new_direction = position.direction_to(path[1])

to

	var new_direction
	if (path[1]-path[0]).length()>1:
		new_direction = position.direction_to(path[1])
	else:
		new_direction = position.direction_to(path[2])

Thank you so much!! I ended up making a function a little more sophisticated than that, just to make sure this doesn’t bite me in the ass again. Here it is in case anyone finds it helpful:

func _get_next_point(path):
	if path.size() > 2 and (path[1] - path[0]).length() < 1:
		path.remove(0)
		return _get_next_point(path)
	else:
		return path[1]

SoKeT | 2020-05-27 19:59