Simple AI in Gaming

Ok so today we are going to learn how to use vector dot product for line of sight checking for simple enemy a.i. If you are not familiar with vector dot product please read our a brief primer on Vector Maths. Huh? Back Already? Did you read it? Ok let’s go on then…

ezgif.com gif maker
Enemy only shoots player when player is in its line of sight

Ok so if you have read that article then you’d know that when two vectors are aligned with each other the dot product of the two vectors is a positive value. More the alignment more will be the value tending towards one. If the vectors are in the opposite direction the dot product value will tend towards negative one. Consider the picture below…

dvect55

As you can see the enemy has a forward vector which is nothing but its forward direction vector. We also have the direction vector towards player which is obtained by subtracting the enemy position vector from the player position vector. If you don’t know what position vectors are they are simply the point at which the object exists in a given space. In the picture above if we perform a dot product between the direction vector and the forward vector the value will be a positive number but nowhere near one as the two vectors are not aligned. The transparent green area represents the line of sight of the enemy but we will come to it later. Now consider the image below…

dvect5

In this image we can see that the player position is shifted such that the direction vector lies within the line of sight of the enemy. So in this case the dot product will be more towards a positive one value and thus the enemy will detect the player in this case. Here’s some code. Don’t worry about the code too much the concept is what matters the most and will be same for any language whether it’s c,c++,or python.

player_direction_vector=get_parent().get_node("KinematicBody2D").global_position-global_position
	player_direction_vector=player_direction_vector.normalized()
	dir=player_direction_vector.dot(transform.x)
	if dir>line_of_sight:
		look_at(get_parent().get_node("KinematicBody2D").global_position)
		var bulletx=bullet.instance()
		bulletx.position=bullet_pos.global_position
		bulletx.dir=transform.x
               
bulletx.player_dir=get_parent().get_node("KinematicBody2D").global_position
		get_parent().add_child(bulletx)

In the code above which runs per frame we are getting the direction vector per frame and then we are normalizing it. Normalizing a vector retains its direction while clamping its value to one. After that we are performing a dot product between the enemie’s forward vector represented by transform.x and the player direction vector. If the value of the dot product lies in the permissible range for line of sight which is .8 in this case the enemy rotates towards the player while spawning bullets. We can make the enemy to detect the player when behind the enemy if we set this line of sight to a negative value, but we don’t want that now do we? The final result is something that you see at the top. Hope this has been an enjoyable read. Cheers until next time!

Related :

Follow :