advanced AI with obstacle avoidance
edit : noticed if the agent was too close to a target, the path was always None in the recalculate path section
fixed it with a if None path -> if too close -> del target and del path
import bge
from mathutils import Vector
from random import randint
def main():
cont = bge.logic.getCurrentController()
own = cont.owner
#get navmesh from connected steering actuator
if "navMesh" not in own:
own["navMesh"] = cont.actuators["Steering"].navmesh
#if you do not have a destination get one
if "Path" not in own:
Possible =[]
#lookup possible destinations
for object in own.scene.objects:
if "destination" in object:
Possible.append(object)
#choose a random destination
Target =None
#This is used if recalculate path failed
if "Target" in own:
Target = own["Target"]
else:
X = randint(0,len(Possible) - 1)
Target = Possible[X]
#get path
P = own["navMesh"].findPath(Target.worldPosition, own.worldPosition)
#make sure there is a valid path
if P!= None:
if len(P)>0:
# save patb and target
own["Path"] = P
own['Target'] = Target
#navigate to destination
else:
if own.getDistanceTo(own['Target'])>2.5:
if bge.logic.getRandomFloat()>.975:
P = own["navMesh"].findPath(own['Target'].worldPosition, own.worldPosition)
#make sure there is a valid path
if P!= None:
if len(P)>0:
# save patb and target
own["Path"] = P
else:
del own["Path"]
else:
if own.getDistanceTo(own['Target'])<2.5:
del own['Target']
del own['Path']
index = 0
#Debug Path
if own['Debug']==True:
for point in own['Path']:
if index==0:
p1 = own['Target'].worldPosition.copy()
p1.z =own.worldPosition.z
else:
p1 = own['Path'][index-1].copy()
p1.z = own.worldPosition.z
p2 = own['Path'][index].copy()
p2.z = own.worldPosition.z
bge.render.drawLine(p1,p2,(1,0,0))
index+=1
if len(own['Path'])>=1:
#we have a path point to navigate to
rayE = own.worldPosition+own.worldOrientation.col[0]*1.75
ray = own.rayCast(rayE,own.worldPosition,0,'Team',0,0,0)
# check for obstructions
if ray[0]:
local2 = own.worldPosition - ray[0].worldPosition
local2 = ray[0].worldOrientation.inverted()*local2
if local2.x>0:
# if obstructions are ahead and facing you check to see if there
# is ground to your left
ray2E = own.worldPosition+(own.worldOrientation*Vector([0,1.5,-1.5]))
ray2S = own.worldPosition+(own.worldOrientation*Vector([0,1.5, 1 ]))
ray2 = own.rayCast(ray2E,ray2S,0,'',0,0,0)
if ray2[0]:
#if there is ground side step
if own.localLinearVelocity.y<1.5:
own.applyForce((0,100,0),1)
else:
#Don't fall off edge
own.localLinearVelocity.y*=.5
else:
#Back up and let other person go
own.applyForce((-100,0,0),1)
P = own["Path"][-1].copy()
P.z += 1
local = P-own.worldPosition
local = own.worldOrientation.inverted()*local
V2 = own.getVectTo(P)
own['Read']=str(local)
#if target is ahead of you
if local.x>0:
#rotate while moving
if local.y>.05:
own.applyRotation((0,0,.025),1)
elif local.y<-.05:
own.applyRotation((0,0,-.025),1)
V2 = own.getVectTo(P)
if V2[0]>1:
if (abs(local.y)-local.x )<0:
#if path in front of you in a cone
if own.localLinearVelocity.x<5:
#servo motion forward
own.applyForce((50,0,0),1)
else:
#Stop if the path is not in fron
own.localLinearVelocity.x*=.5
#Stop sideways sliding
own.localLinearVelocity.y*=.25
else:
#Stop you are not facting correctly
own.localLinearVelocity.x*=.25
else:
#at destinatino
own["Path"].pop(-1)
else:
if abs(local.magnitude)>2:
own.localLinearVelocity.x*= .9
own.localLinearVelocity.y*= .9
#rotate in place
if local.y>0.1:
own.applyRotation((0,0, .05),1)
elif local.y<-0.1:
own.applyRotation((0,0,-.05),1)
else:
own["Path"].pop(-1)
else:
#Reached target
del own['Path']
del own['Target']
else:
#Reached target
del own['Path']
del own["Target"]
main()
edit: new file update has _update in file name
Attachments
Traveler2x_update.blend (454 KB)