How would I make an AI system for a tank?

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

Hello, so in my tank game, I am trying to create these enemy tanks which will do the following:

  • Chase the player and try to run into them
  • Shoot at the player

I feel like the shooting bit can be done easily by pointing the barrel at the player and shooting, but the other part seems a bit harder for one reason: the tanks don’t immediately turn, they have a turning time.

https://i.imgur.com/ItYhNs2.mp4

So, the tank moves smoothly like that. I was thinking that if the player was relatively straight in front of the enemy, the enemy could just move forward and rotate left/right if necessary. But if the player is more far away, then the enemy would first turn in place until it’s in a comfortable range where going forward and turning will be enough.

Here the red tank is where the player would be
enter image description here

So the question is, how would I go about coding this? I was thinking somehow using raycasting to detect if the enemy is looking at the player or not, and if not, then it would rotate, and when it is in range, it will begin moving forward. There could be a small and big collision circle around the player, if the raycast hits the small one (sized the same as the tank) it would just go forward, but it if would only hit the bigger one (around the tank), it would move forward and turn. I suppose it could work, only problem is how would it know if to turn left or right? Or is there a better way to do this?

:bust_in_silhouette: Reply From: Inces

I would go for something different. I would define Vector leading from tank to his current forward movement, and Vector leading straight to player. I would measure dot product of these vectors to compare progression of turning towards player. ( dot 0.8-1.0 would mean tank is already heading straight at the player). I would get sign of difference of these Vectors to get if players it to the left or right. Finally I would code unified movement - tank is supposed to move forward and lerp() its forward velocity vector towards Vector leading to player, and speed of this lerp() would be proportional to 1.0 - dot product - which means it would turn faster the larger angle of difference towards the player.

Hi, thanks for the answer, do you have a code to show me how would you do this please? Thanks!

leosefcik | 2022-02-21 16:55

I can give You some pseudocode to explain better :
in tank script :

var currentdir = Vector2(1,0) #default starting facing direction - to the right]
var desireddir : Vector2

in process() :

desireddir = (global_position - player.global_position).normalized()

#current direction to the player is updated every frame

var torque = currentdir.dot(desireddir) 

#dot of two vectors results closer to 1.0 the more these vectors are similar to each other. So when current direction is the same as desired direction - torque = 1

currentdir = currentdir.lerp(desireddir, delta * (1-torque))

#Tank will be turning towards the player while moving, with the speed proportional to how far he needs to change the angle. You will also need to multiply weight (2nd argument of lerp)by some number to your liking to tweak turning speed

movement = currentdir * speed

your movement in general, fit it to whatever You use - rigid movement, kinematic or position update, just use currentdir as direction to move along

Inces | 2022-02-21 19:36