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
#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 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) poly_areas.append(round(area)) 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 area_index.append(index) #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 + (u*(v2-v1)) + (v*(v3-v1)) y = v1 + (u*(v2-v1)) + (v*(v3-v1)) z = v1 + (u*(v2-v1)) + (v*(v3-v1)) #Move own to the random point own.position = [x, y, z]