Game Development Community

dev|Pro Game Development Curriculum

Flexible A* Pathfinding System

by Dan Keller · 04/08/2008 (2:15 pm) · 203 comments

1.8.1 version here!

Download

Note: The TGEA version in the download is newer than the TGE version. Most people are using TGEA now, anyways. If you want the newer version in TGE, you can port it yourself, it shouldn't be too bad. If there is some interest in it and someone does a port, just send it to me and I'll put it up here.

Installation - TGEA

Add aStar.h, aStar.cpp, aStarIO.cpp, and aStarMesh.cpp to your project (in T3D). Replace or merge aiPlayer.cpp and .h with the files in in the zip.

Add #include "T3D/aStar.h" on top of sceneState.cpp

Add the commented part in SceneState::renderCurrentImages():
PROFILE_START(RenderInstManagerRender);
   gRenderInstManager.render();
   PROFILE_END();
//aStar
#ifdef AI_RENDER
   AStar::Get()->render(this);
#endif
//aStar
   gRenderInstManager.clear();

   mInteriorList.clear();


Add this in game/tools/missionEditor/scripts/editors/creator.ed.cs line 146:
%Mission_Item[6] = "NavMesh";

Add the following function at the end of game/tools/missionEditor/gui/objectBuilderGui.ed.gui:
function ObjectBuilderGui::buildNavMesh(%this)
{
	%this.className = "NavMesh";
	%this.process();
}

In [game]/scriptsAndAssets/server/scripts/game.cs, at the end of startGame(), add
readPaths();

At the end of endGame(), add
deletePaths();

before resetMission();

For an example, add aiDemo.mis.


Installation - TGE

Add the aStar.cc and aStar.h files to your project. Replace or merge aiPlayer.cc and .h with the files in in the zip.

In sceneState.cc, after the includes, add
#include "game/aStar.h"

in renderCurrentImages(), around line 481, add the commented code
for (i = 0; i < mTranslucentEndImages.size(); i++)
      renderImage(this, mTranslucentEndImages[i]);
//aStar
#ifdef AI_RENDER
   gAStar.render(this);
#endif
//aStar
   glMatrixMode(GL_MODELVIEW);
   glPopMatrix();

Save and compile.

In creator/editor/EditorGui.cs, at line 1306, change
%Mission_Item[3] = "Trigger";
   %Mission_Item[4] = "PhysicalZone";
   %Mission_Item[5] = "Camera";

to

%Mission_Item[3] = "NavMesh";
   %Mission_Item[4] = "Trigger";
   %Mission_Item[5] = "PhysicalZone";
   %Mission_Item[6] = "Camera";

In creator/editor/objectBuilderGui.gui, at line 643, add
function ObjectBuilderGui::buildNavMesh(%this)
{
	%this.className = "NavMesh";
	%this.process();
}

In [game]/server/scripts/game.cs, at the end of startGame(), add
readPaths();

At the end of endGame(), add
deletePaths();

before resetMission();

For an example, add aiDemo.mis.

Use

To add navigation points, open the mission editor creator. NavMesh objects are under Mission Objects / Mission. The properties are:
Interval - distance between points
XSize - number of points in x direction
YSize - number of points in y direction
Height - how far up or down the object will look to place points

There are two global preferences you can change. One is $Pref::AStar::Render. It controls whether or not the navigation mesh is rendered. Turn it on when editing the mesh, turn it off otherwise. The other is $Pref::AStar::Clearence. This controls the minimum horizontal clearance between two nodes when building paths. If you change this after creating points, you need to call buildPaths for it to effect those points.

There are three functions for path caching. Do not call any of these while the mission editor is running, it may get all messed up. They are
- deletePaths Deletes all NavMesh objects and all nodes.
- writePaths Writes all nodes to a file (called [mission name].as) that is loaded automatically on mission startup. This is the only function you need to call manually; call it once you're done editing the nav mesh.
- readPaths Reads nodes from file. Returns true on success, false on faliure.

Also there is
- buildPaths Manually rebuilds navigation information, for example if an object has been moved in the way of some nodes.

There is also a compiler switch, AI_RENDER, at the top of aStar.h. Comment this out when you distribute the game to remove all the nav mesh rendering code.

There are five functions that can be called on the AIPlayer object. They will return 0 on success, -1 on failure, and 1 if the bot is already where you want it to go. They are
- findPathTo This takes either a point or an object as an argument, and simply finds a way to the point.
- findCoverFrom This also takes a point or object, and finds a place hidden from it.
- searchCover This takes no arguments, and makes the bot go to the nearest place it can't see.
- sneakUpOn This takes either a point and a vector or an object as an argument. It finds a path to the point or the object that can't be seen by it.
- wander This takes a distance as an argument and wanders around for this distance.
#101
03/05/2009 (10:54 am)
Thank you for your suggestions, but I tried them and it made no difference.

It is ok though, I think we will just lay down the meshes where they are needed. It is a slower way but more precise and it works better for our AI because they tend to get stuck on walls.

Thank you for your help Dan.
#102
03/07/2009 (6:36 pm)
Hi Dan, the download link is no longer working. Can you fix or I can provide a mirror if you like?
#103
03/08/2009 (1:08 pm)
It works for me, so I'm not sure exactly what the problem is.
#104
04/26/2009 (12:41 pm)
Absolutely great resource! Thanks.
Everything seems to work without any problems (on TGEA 1.8.1).

Just one question: is there any simpler way of creating the "pathfinding map" than to add every NavMesh manually? It's just... a little bit depressing, imagining that I'd want to fill the whole map (even 512x512) with nodes for my bots to use. Especially considering that the in-game editor is not the most comfortable tool for quick mass object creation...
#105
04/26/2009 (1:06 pm)
Not really. You could try a very large navmesh, but that probably wouldn't have the control you need.
#106
04/26/2009 (1:56 pm)
Hmmm... yes indeed.
Thank you, anyway, this system helped me a lot already.
If I ever come up with a way to automate this process I promise to share. ;)
#107
05/05/2009 (3:56 pm)
@Dan
Is it possible that you change the NavMesh class so that it can be used in conjunction with the Torque Mission Editor Snapping Tool?
It could spent a lot of work....
#108
05/05/2009 (7:28 pm)
In what way?
#109
05/06/2009 (12:59 am)
If I use the Snapping Tool with the NavMesh Torque crashes. So I thought that it would be nice that you can use the Snapping Tool also with the NavMesh.
#111
05/18/2009 (12:09 pm)
You can use findPathTo, all you need to do is add
Vpoints.push_front(Pend);
between these two lines
Vpoints.clear();

Vpoints.push_front(end->loc);
near the end of AStar::findBasicPath in aStar.cpp
#112
05/19/2009 (1:05 pm)
I've seen that some people are able to get it working with the later versions of TGEA. Me, I'm using 1.8.1 and I'm not so lucky, though my C programming doesn't extend out past "Hello World".

The 2 problems I've ran into were, first, "sim/sceneObject.h" and "sim/simPath.h" are not found. However, "sceneGraph/sceneObject.h" and "sceneGraph/simPath.h" are.

So I changed the #include and I get a few syntax errors like below
12>... sceneGraph/simPath.h(91) : error C2146: syntax error : missing ';' before identifier 'smStateBlock'

Would any one be willing to share how they got it working? St. I see you got it working in 1.8.1

Thanks
#113
05/28/2009 (5:53 pm)
Hi... all, any one can help me? I want to implementing this resource for AiWheeledVehicle2, how to joining?

any script can i learns?

Thanks
#114
07/07/2009 (7:20 pm)
Has anyone made this work with T3D?
#115
07/08/2009 (2:58 pm)
Not that I know of. I don't own T3D, so I can't do it now.
#116
07/12/2009 (3:41 am)
My engine crashes when i insert the NavMeshs and save the mission and after that reloads them..

I can open a mission and create the navmesh.. i can see the Navmesh and i can configure it but if i try to open up a mission where navmesh is already created it crashes.. If i use my regular exe without A* configurations it works fine except the fact that a* aren't turned on.. My console say nothing but this:

Quote: *** LOADING MISSION: arcane.fx/data/missions/NavMesh_Test.mis
*** Stage 1 load
*** Stage 2 load
Executing arcane.fx/data/missions/NavMesh_Test.mis.

Of course it writes down all the loaded scripts etc...

I have tried to add breakpoints in the mission file where it creates the navmesh's but they never trigger..
#117
07/12/2009 (6:44 pm)
are you on TGE or TGEA?
#118
07/14/2009 (12:00 am)
What i did to get it working on TGEA 1.8.1 is this:

open astar.h and at the top change:

#ifndef _SIMPATH_H_
#include "sceneGraph/simPath.h"
#endif

to this:

#ifndef _PATHMANAGER_H_
#include "sceneGraph/pathManager.h"
#endif

that got it to compile for me. and got rid of the errors i was getting on simPath.h
#119
07/16/2009 (1:39 am)
if anyone is interested, with a few small changes, this builds with T3D.
#120
07/19/2009 (8:34 am)
@Dan
Quote:
are you on TGE or TGEA?

I run TGE 1.5.2