So studio is a thing again, and as its now week 2, I had better get some bloggin done!
Week 1 started with an introduction to AI. The programmers have been tasked to make a killbot within a 2d arena to which we’ll be fighting each other in week 3 and 6. That means with a week left until to first fight, there’s still more work to be done.

What I’ve been doing the last week has been attempting to implement a form of predictive aiming in the bot. This was initially very difficult for me, as this was math that I thought I had left behind in highschool. I’ll simply go into detail about how I got the thing working.
I started with trying to follow this guide for predictive aiming in unity. It’s meant for c# and vecto3, but I figure the math will be exactly the same without the z axis.
The best I can figure, the code works like this
- Get a normalised direction
- get the vertical axis using dot product
- get the horizontal axis by getting the difference between the velocity and the vertical
- get the horizontal velocity of the bullet from the target horizontal axis
- then use Pythagoras to get the shot vertical velocity
- add the two shot velocities to get an aim vector
My code ended up looking slightly different from the original code, as I had to manually calculate things that unity normally does for you.
kf::Vector2 dirToTarget = _targetPos – _playerPos;
dirToTarget.normalise();kf::Vector2 targetVelOrth = (_targetVelocity.x * dirToTarget.x + _targetVelocity.y * dirToTarget.y) * dirToTarget;//dot product
kf::Vector2 targetVelTang = _targetVelocity – targetVelOrth;
kf::Vector2 shotVelTang = targetVelTang;
float shotVelSpeed = sqrt(shotVelTang.x * shotVelTang.x + shotVelTang.y * shotVelTang.y);//magnitude
float shotSpeedOrth = sqrt(_shotSpeed * _shotSpeed – shotVelSpeed * shotVelSpeed);
kf::Vector2 shotVelOrth = dirToTarget * shotSpeedOrth;kf::Vector2 temp = shotVelOrth + shotVelTang;
temp.normalise();//this is the biggest difference in the two codes
return temp;
Once I had implemented this, I still couldn’t get my bot to hit accurately. That’s because I had to manually calculate a few things:
- Time passed
- The distance the enemy travelled
- The speed of the enemy
- The velocity of the enemy using the previous data
The first problem with my calculations was that I was incorrectly calculating time. I originally had a variable oldTime which I was allocating to the system time during Update. This was the entirely wrong time to be doing this, as during Update I had no data on where the enemy was, so the measured time was wrong.
Secondly, even after I fixed this allocation, the engine that the Killbots runs in doesn’t use the system time. There is a function in the killbots that allows the game to be sped up and slown down. This means that any calculations are completely wrong once the game speed changes. So instead of using the system time, I simply made a float that is increased by 0.1 every update. As the bot logic is only called 10 times a second, the calculations end up being the same.
The next two calculations where thankfully easier. To get the distance travelled, I had to do two scans. Then taking the old position and the new position, I take the displacement by subtracting them, then use Pythagoras’ theorem to calculate the distance. C++ has a function called std::hypot() which does the same thing as manually calculating it, but is apparently faster.
If the distance is 0, all I need to do is aim at the bots position and fire like so:
toShoot1 = newEnemyPos – input.position;
I then calculate the speed by using the good old s = d/t.
I then needed to get the velocity as a vector2 so I could pass it into the function. I initially tried using the equation velocity = displacement/time, however, this returns a single number, and not a directional velocity. Through searching online, I came across this piece of code:
kf::Vector2f displacement= bPos – aPos;
float distance = std::hypot(displacement.x, displacement.y);
return displacement* (_speed / distance);
Mathematically, I’m not sure how it works. I’ll eventually look up how it works out, but I’m simply happy that this code works as intended.
Finally, we can use all this data to plug into the function, and it returns a normalised look direction that the bot can look at and shoot. The bot will hit if its target doesn’t change direction.
The downside to this code is that it can’t currently predict where the enemy will be in a time further from a single frame. I know I have all the information to calculate this out, however I’m currently still struggling with the maths behind it all. The site where I grabbed the intercept code had this at the bottom of it:
// Find the time of collision (distance / relative velocity)
float timeToCollision = ((shotOrigin – targetOrigin).magnitude – shotRadius – targetRadius)
/ (shotVelOrth.magnitude–targetVelOrth.magnitude);// Calculate where the shot will be at the time of collision
Vector3 shotVel = shotVelOrth + shotVelTang;
Vector3 shotCollisionPoint = shotOrigin + shotVel * timeToCollision;