I needed to write this for my own project, so I took some of Mobious’ code, and modified it.
Changes:
- Separate Elevation and Rotation (ie a barrel).
- You can specify the max turn speed in radians (ie 0.02 rad per frame) or the number of frames to track over (5 frames)
How to use:
- Add this to the body of your turret with an always sensor (ie Always -> Python (module mode, the turretAI function)
- Add to the turret the property ‘max speed.’ If the number is less than 1, this will be it’s maximum turn speed, if it is greater than 1, then it will be the number of frames to completely target the enemy.
- Add a barrel, parent it to the turret body, and give it the property ‘barrel’
This will currently track the object named ‘target’ but you can probably write your own code to chose an enemy. If you can’t, have a look at my AI snippets in the resources section, which has a function for that.
def turretAI(cont): target = bge.logic.getCurrentScene().objects['target']
aimPos = lead(target)
turret = cont.owner
barrel = [chi for chi in turret.children if 'barrel' in chi][0]
aimAt(aimPos, turret, barrel)
def lead(target):
#Will contain the necessary logic to lead ahead of a target
return target.worldPosition
def aimAt(aimPos, turret, barrel):
maxTurn = turret['maxTurn']
#Z axis stuff
turVec = turret.getAxisVect([0,1,0])
aimVec = aimPos - turret.worldPosition
aimVec.z = 0
angle = turVec.angle(aimVec)
if angle > 0:
if maxTurn > 1:
factor = 1/maxTurn
else:
factor = maxTurn/turVec.angle(aimVec)
turret.alignAxisToVect(aimVec, 1, factor)
#X Axis Stuff
barVec = barrel.getAxisVect([0,1,0])
aimVec = barrel.getVectTo(aimPos)[1]
aimVec[0] = turret.getAxisVect([0,1,0]).x
aimVec[1] = turret.getAxisVect([0,1,0]).y
angle = barVec.angle(aimVec)
if angle > 0:
if maxTurn > 1:
factor = 1/maxTurn
else:
factor = maxTurn/turVec.angle(aimVec)
barrel.alignAxisToVect(aimVec, 1, factor)