Useful Script for AI and Spawning Characters.

Hey guys. I’m working on a game for my high school’s programming club. I’m moving on to AI programming pretty soon, so I needed to come up with this script, and I think some people might find it useful.

Basically what it does, is it moves the object (own) to a random point ON the navigation mesh (nav_mesh). This script is very useful, because you can use it to make AI wander around randomly (attach this script to an object that the AI pathfinds to, then run the script when the AI gets close to the object, so the AI will continue to walk around the navigation mesh randomly).

It can also be used for spawning AI or other NPCs. You would run it on an empty, then have the empty add a character. If you want, you could make it an invisible cube and test for collisions first, so a character won’t be spawned inside a tree or something.

This was written for navigation meshes, which only have tris. It still works with quads though, but it only really calculates 3 of the vertices. I have added comments and tried to show simply how the script works.

For best performance, I advise that you save the variable “area_index” as a permanent property on an object and remove that part of the script, along with the “poly_areas” part. Only do this if you know that you won’t be editing or creating a new navigation mesh.

I hope you guys find this useful. Tell me if you find any problems with it, though I believe I fixed them all :slight_smile:

#Sampling Random Point on Mesh written by Janz Dott
import GameLogic
import mathutils
import random
cont = GameLogic.getCurrentController()
own = cont.owner
scene = GameLogic.getCurrentScene()
objects = scene.objects
#Get navigation mesh and retrieve # of polys
nav_mesh = objects.get("nav_mesh").meshes[0]
polys = nav_mesh.numPolygons
#Write the area of each poly to a list, in order
poly_areas = []
p = 0
while p < polys:
    poly = nav_mesh.getPolygon(p)
    v1 = nav_mesh.getVertex(0, poly.v1).getXYZ()
    v2 = nav_mesh.getVertex(0, poly.v2).getXYZ()
    v3 = nav_mesh.getVertex(0, poly.v3).getXYZ()
    area = mathutils.geometry.area_tri(v1, v2, v3)
    p = p + 1
#Create a new list where each poly's index is repeated for its area
#This is done so larger polys are more likely to be chosen      
area_index = []
for index, area in enumerate(poly_areas):
    a = 0
    while a < area:
        a = a + 1
#Retrieve the random poly and location of its vertices
randpoly = nav_mesh.getPolygon(area_index[random.randint(0, len(area_index)-1)])
v1 = nav_mesh.getVertex(0, randpoly.v1).getXYZ()
v2 = nav_mesh.getVertex(0, randpoly.v2).getXYZ()
v3 = nav_mesh.getVertex(0, randpoly.v3).getXYZ()
#Method for finding random point in 3D triangle
u = random.random()
v = random.random()
if u+v>=1:
    u = 1-u
    v = 1-v
x = v1[0] + (u*(v2[0]-v1[0])) + (v*(v3[0]-v1[0]))
y = v1[1] + (u*(v2[1]-v1[1])) + (v*(v3[1]-v1[1]))
z = v1[2] + (u*(v2[2]-v1[2])) + (v*(v3[2]-v1[2]))
#Move own to the random point     
own.position = [x, y, z]

You can simply expand the code for quads by splitting the quad into two triangles:
A = v1,v2,v3
B = v3,v4,v1

You just need to randomly pick one of the two triangles.

BTW. Your method prefers dense mesh arrays. This can come pretty handy :).

Could you post a blend of this in action.I cant seem to get it to work.I love the idea of a lot of random stuff
in games.

I am trying to correct the code of member Jay-Dee-892 useful script for ai and spawning characters because it is not working for me.I am using blender 2.62.

You should really release a test blend, some people like me don’t know too much about python, i only know the basics and i can’t get this to work :S

Everybody is good, I want to pass through here to meet more friends

I am not good i want my question answered one way or the other.