How to get turrets to lead enemies : Topdown 2d

Hello,

Thanks for reading. I’m Having some difficulty figuring out the code to have turrets lead their targets. My old code just had the turrets tracking the enemies, so when they fired, they were less likely to hit fast moving enemies.

What I’m stuck on at the minute is figuring out what direction the target is moving, and how fast. (Line 10 of first code block)

Here’s what I’ve got so far

// Get the distance to the enemy
float distanceToEnemy = Vector3.Distance(targetPosition, transform.position);
Debug.Log ("TurretGunScript.RotateTurret: Distance to enemy : " + distanceToEnemy);
		
// Get the amount of time it will take for bullet to hit enemy
float timeToHit = distanceToEnemy/bulletSpeed;
Debug.Log ("TurretGunScript.RotateTurret: Bullet travel time : " + timeToHit);
		
// Get the movement vector of enemy ??
		
// Multiply movement vector by time to hit to get the direction the turret should be facing
		
// Rotate turret to face that position
Quaternion neededRotation = Quaternion.LookRotation(direction);
transform.rotation = Quaternion.Slerp(transform.rotation, neededRotation, rotationSpeed * Time.deltaTime);

This is how the targets move:

rigidbody.AddForce (targetDirection.normalized * moveSpeed * Time.deltaTime);
transform.position = new Vector3(transform.position.x, 0, transform.position.z);

This is how bullets move:

transform.Translate(0, 0, moveSpeed * Time.deltaTime);
transform.position = new Vector3(transform.position.x, 0 , transform.position.z);

Thanks in advance!

Basic idea is to see what direction/speed the target is moving, guess how many seconds it will take to hit, then use seconds*movement to estimate where the target will be:

float secsFlightTime = (target.position - turret.position).magnitude / bulletSpeed;
Vector3 targetMvPerSec = target.rigidbody.velocity; // since you physics to move
targetMovePerSec.y=0; // since your code says they stay flat
Vector3 estHitPos = target.position + targetMovePerSec*secsFlightTime;

The math will be wrong for two reasons. One is you can’t know the actual flight seconds to where you’ll hit without already knowing where you’ll hit. So you just estimate based on current position. For faraway slow things, it works great. Otherwise, looping 2 or 3 times gets you really close (use estHitPos to re-figure flightTime and get a new estHitPos… .)

The other is your objects are constantly accelerating (AddForce.) If friction or something causes them to have a mostly constant speed, it should be OK.