Here is a pythonic enemy with a ray based vision cone using scanning.
import bge
import copy
from mathutils import Vector
def main():
cont = bge.logic.getCurrentController()
own = cont.owner
if own['Go']==False:
own.worldLinearVelocity.x*=.25
own.worldLinearVelocity.y*=.25
#Reset Fire clock
if own['Fire']>=1:
own['Fire']-=1
#Reset forget enemy clock
if own['Reset']>=1:
own['Reset']-=1
own['Go']=True
else:
#forget target
if 'Target' in own:
del own['Target']
#look up and store child parts and add a few properties needed later
if 'Gun' not in own:
for child in own.childrenRecursive:
if 'Turret' in child:
own['Turret']=child
if 'Gun' in child:
own['Gun']=child
own['Sweep']=0
own['Flip']=False
else:
#If you don't have a target sweep the cannon back and forth
if 'Target' not in own:
own['Turret'].worldOrientation=own.worldOrientation
own['Turret'].applyRotation((0,0,own['Sweep']*.5),1)
if own['Flip']==False:
if own['Sweep']<1.5:
own['Sweep']+=.05
else:
own['Flip']=True
else:
if own['Sweep']>-1.5:
own['Sweep']-=.05
else:
own['Flip']=False
else:
local = own['Target'].worldPosition-own.worldPosition
local = own.worldOrientation.inverted()*local
#This defines a cone in front of the actor
if local.y>0 and (local.x-local.y)<.25:
#Aim at enemy if he is in front of you
V2 = own.getVectTo(own['Target'])
own['Turret'].alignAxisToVect(V2[1],1,.1)
own['Turret'].alignAxisToVect(own.worldOrientation.col[2],2,1)
else:
#Sweep for enemy
own['Turret'].worldOrientation=own.worldOrientation
own['Turret'].applyRotation((0,0,own['Sweep']*.5),1)
if own['Flip']==False:
if own['Sweep']<1.5:
own['Sweep']+=.05
else:
own['Flip']=True
else:
if own['Sweep']>-1.5:
own['Sweep']-=.05
else:
own['Flip']=False
rayE = own['Gun'].worldPosition+own['Gun'].worldOrientation.col[1]*15
ray = own.rayCast(rayE,own['Gun'].worldPosition,0,'Team',0,0,0)
if ray[0]:
if ray[0]['Team']!=own['Team']:
own['Reset']=60
own['Target']=ray[0]
if own['Fire']==0:
bge.render.drawLine(ray[1],own['Gun'].worldPosition,(1,0,0))
ray[0].applyImpulse(ray[1],own['Gun'].worldOrientation.col[1]*1)
own['Fire']=30
else:
#If you see a friendly engaged in combat and you don't have a target grab his
if 'Target' in ray[0] and 'Target' not in own:
own['Target']=ray[0]['Target']
own['Reset']=120
if 'RoutePlan' not in own:
#Look up NavTarget
for child in own.children:
if 'NavTarget' in child:
own['NavTarget']=child
child.removeParent()
# Gather List of points to visit
SubList = []
for objects in own.scene.objects:
if 'Tag' in objects:
if objects['Tag']==own['TagName']:
SubList.append([objects,objects['Route']])
#sort points by value of Route
SubList = sorted(SubList, key=lambda tup: tup[1])
#StorePlan
own['RoutePlan']=SubList
else:
if 'Target' not in own:
#if you dont' have a current trip plan one
if 'Current' not in own:
C=[]
for point in own['RoutePlan']:
C.append(point)
own['Current']= C
else:
own['N']=len(own['Current'])
if len(own['Current'])>0:
#Move target to trip point
Target = own['Current'][0][0]
own['NavTarget'].worldPosition=Target.worldPosition+Vector([0,0,1])
own.alignAxisToVect((0,0,1),2,1)
own.alignAxisToVect(own.getVectTo(own['NavTarget'])[1],1,.1)
own['Range']=own.getDistanceTo(own['NavTarget'])
# if you reach a point pop it off the trip plan
if own.getDistanceTo(own['NavTarget'])<.25:
own['Current'].pop(0)
else:
#if you are out of points to visit remove plan
del own['Current']
else:
#you have a target and it's more then 5 units away drive to it and aim at it
if own.getDistanceTo(own['Target'].worldPosition)>5:
own['NavTarget'].worldPosition = own['Target'].worldPosition
own.alignAxisToVect((0,0,1),2,1)
own.alignAxisToVect(own.getVectTo(own['NavTarget'])[1],1,.1)
own['Go']=True
#you have an enemy and it's closer than 5 units so stop moving and aim
else:
own.alignAxisToVect((0,0,1),2,1)
own.alignAxisToVect(own.getVectTo(own['NavTarget'])[1],1,.1)
own['Go']=False
main()
just keep looking at scripts until it makes sense.
logic bricks are amazing - for triggering python efficiently or for doing VERY simple things.
Attachments
PythonicEnemy.blend (499 KB)