AI Patrol

I am currently working on a game and I would like to implement a patrol system for a city guard, I know next to nothing about python so currently I only work with logic bricks (if that matters). It is not really important but I would like to learn how.

Thanks for any help

Fredstash

P.S. if you need clarification just ask all my stuff is crazy

ok, I will try and come up with something,

you want waypoints you can drag and drop, and to use a navmesh to get between them?

Way points are good. The simple method I used recently was to get the nearest way points and choose randomly which one to go to. Then add that waypoint to a list of visited points.
Next time when choosing the nearest waypoint dont choose any that are on the list. You can clear the visited list either when it gets too long or when there are no near waypoints to choose from.

tada!

this uses the object.child hierarchy to set the order of the list,

so Player has NavTarget (steering target) and a NavPoint parented to it, NavPoint 2 is parented to NavPoint, NavPoint 3 is Parented to NavPoint2 , and NavPoint 4 is Parented to NavPoint3

this way it gets the hierarchy an you can see the route as a dotted black line on the screen

note Made in 2.74.5 (rc 0)

Attachments

Patrol.blend (488 KB)

I don’t really understand all this jargon (I know thats terrible), I will try to pick apart the .blend but I have no python knowledge.

Can I use all the stuff from this?

NavTarget = where he is going to

NavPoint = patrol point,

NavList = list of all navpoints in order

and feel free to use anywhere,

let me know if you need help implementing anything,


import bge




def main():


    cont = bge.logic.getCurrentController()
    own = cont.owner

    ## store list of navpoints and steering target
    if 'NavTarget' not in own:
        own['NavList']=[]
        for child in own.children:
            if 'SteerTarget' in child:
                own['NavTarget']=child
                child.removeParent()
            if 'Nav' in child:
                own['NavList'].append(child)
                
                if child.children:
                    own['NavList'].append(child.children[0])
                    
                    if child.children[0].children:
                        own['NavList'].append(child.children[0].children[0])
                        
                        if child.children[0].children[0].children:
                            own['NavList'].append(child.children[0].children[0].children[0])
                                
                        
                        
        for NavTargets in own['NavList']:
            NavTargets.removeParent()

    else:
        ## if you are at your target pick another
        if own.getDistanceTo(own['NavList'][own['Next']])<1:
            own['Next']+=1

            #if you are done with the last target pick the first
            if own['Next']>=len(own['NavList']):
                own['Next']=0
        else:
            own['NavTarget'].worldPosition=own['NavList'][own['Next']].worldPosition        

        ## delete the pound symbol before these two lines to print debug info 
        ##for NavTarget in own['NavList']:
            ##print('Name is '+NavTarget.name+" and number is "+str(NavTarget['Nav']))             


main()




Yarp. I tend to make up names, and use them over and over forever, even though I made them up,
I forget others don’t know :smiley:

I need to .append(this information) into my main.

Well Monster, you are always telling people to choose variable names which are meaningful. Surely navtarget is better than “nt” or “jiggypuff” or anything like that. I think BPR’s names are pretty well chosen. In a large game there might be a lot of "target"s or “points” and certainly a lot of lists, so calling them by a meaningful name is a good idea isn’t it?

I did a section on patrolling AI as part of my stealth tutorial. Maybe that can help, I’ve explained how the python works, so hopefully it’s relatively jargon free. In it I used ordered waypoints so that AI follows a fixed route.

I used the .blend BPR gave and Just had my Guard follow the box around the map.

Though offtopic, I think this warrants writing:

The “jargon” of the script BluePrintRandom posted is the fact that there are few variables used, regardless of their names.

I started to rewrite the script, but without the Blend I quickly realised that it wasn’t going to be useful, but for reference:


import bge




def main(cont):
    own = cont.owner


    # Get previously setup data
	try:
		waypoints = own["waypoints"]
		index = own["waypoint_index"]
		steering_target = own["steering_target"]
		
	# Setup data as this is the first frame
	except KeyError:
		waypoints = own["waypoints"] = [o for o in own.scene.objects if "waypoint" in o]
		steering_target = own["steering_target"] = next(o for o in own.children if "steering_target" in o)
		index = own["waypoint_index"] = 0
		
	# Skip all waypoints that we're close too
	min_waypoint_distance = 1.0
	
	while True:
		try:
			waypoint = waypoints[index]
			
		except IndexError:
			return
		
		if own.getDistanceTo(waypoint) > min_waypoint_distance:
			break
			
		index += 1


	own['index'] = index
	steering_target.worldPosition = waypoint.worldPosition        



Things like the recursive children could have been handled more intuitively, rather than just iterating over 3 deep.

for some reason I am having a hard time using sort,

I would just do

for child in own.childrenRecursive:

but I was worried about preserving order, since I suck at sort.

I know I can just use the property Nav’s value, and put in order by value, but I did not take the time to try and get sort working,

Something like this might help:

You might also have used a recursive algorithm :slight_smile:

As far as I see there is no sorting requested ;).

I wanted him to walk the path in order, (this time)
that way you can make a circular route,

if I were to do it over, I would do smokings knock off method,
go to closest unless you have been there, until you have been everywhere, if you have been everywhere reset list.

that is easier anyway so the enemy can pursue they player, forget about the player if he loses him, and go back to patroling, without returning to where he left the route,

If you make a module or a function it’s better to use names like target or point, but BPR usually doesn’t so it’s better to use names which reflect the task he’s doing.

anyway, on topic: I think it’s a good idea to use waypoints to generate a graph, that way you only need to calculate distances and check for blocked paths on initialization.

For way point in your scene:
Get closest neighbors
check if route to each is blocked.
If not: Store close neighbors as a propery on the way point.

Then patrolling agent gets closest way point. Goes to it. When reached: find next nearest neighbor from that waypoint’s list of neighbors if not on visited list.

I’m a little late to this party, but:

There’s a few ways I do enemy AI patrolling a beat or whatever. Animate the enemy to walk a beat, but it’s predictable. Use a Motion & a Radar with an angle of say 55 and a distance of 3 looking for the property avoid. when the radar is positive it turns your enemy 90 degrees. Then create a “fence” (if you will) with the property avoid (see Scene 2 on the blend) Still predictable

I know you said you didn’t use Python, I’m not a Python coder either, but I use a Track_to_closest object script with a motion actuator. I found it in resources, I think Cotax wrote it. I modified it slightly.
Then spawn nodes for the enemy to track to…
The enemy will move towards the node, when the enemy collides with the node it disappears using end object logic brick. I loop a Timer property < interval to re-spawn the nodes, (when the timer reaches a certain number it resets to 0) There are other ways of doing it. (see the blend)
Then it’s a matter of moving empties around in your environment, and tweaking the Timer properties

I use states on my enemy patrol.

state 1 - Walking the beat
state 2 - Looking
state 3 - switch
state 4 - Chase

I’ll use a Random sensor with a seed of 2 > say 100 with an “and” & “nand” controller. switching between state 1 & 2. So the enemy will walk the beat, but at random times, stop and look around. With the nodes spawning and ending, it can create a bit of unpredictability as the enemy turns toward a new node.

I’ll use a ray on the enemy, or a group of rays, to look for the player. If the ray is positive, the enemy switches to state 4. Then uses the navmesh to chase the player. Or, I’ll have the player spawn nodes at every corner, so the enemy can chase the player around buildings an such without a navmesh.

See the attached Blend. it isn’t;t perfect, I just threw it together quickly.
I couldn’t get the navmesh to work so I deleted it.
But you should get the idea.

Use WSAD to move the player.
The Radar set up is on Scene 2

http://www.pasteall.org/blend/36550