Game Development Community

Walkabout Navigation Toolkit help thread

by Daniel Buckmaster · in General Add-On Discussion · 11/08/2012 (3:57 pm) · 223 replies

This is the official Walkabout help thread. If you need a hand installing or using Walkabout, please ask away! But before you do, I'd really appreciate if you could follow a couple of guidelines:

  • Re-read the installation instructions! Seriously, I know how often I run into some ridiculous issue, then realise I'd missed a step or misread a line. It helps me and you!
  • If you're reporting an error in compilation, please tell me the errors you get and what files they're in, if you can!
  • If you're reporting a bug, please provide steps I can take to reproduce it!
Feature requests, comments and any other feedback are welcome here as well! If you have questions you'd prefer to keep between you and me, feel free to contact me directly.

Known issues

  • Release 1 Patch 3: no navmeshes appear in the browser list in the nav editor. Fix
  • Engine version > 3.5.1: project generator scripts are incorrect. Fix. Also, be sure not to include the Recast module in your project configuration!
  • On platforms that are not Windows, you may need to replace FLT_MAX with F32_MAX. In fact this is probably a good idea in Windows as well.

About the author

Studying mechatronic engineering and computer science at the University of Sydney. Game development is probably my most time-consuming hobby!

#141
02/17/2014 (1:50 pm)
Daniel, I've noticed I get quite a lot of failures in finding navPoints with "No NavMesh polygon near visit point (%g, %g, %g) of NavPath %s" in visitNext().

Mostly seems to happen on undulating terrain where there are considerable height differences. I tried tweaking various values and found that I had to go pretty extreme - and thus probably unsafe - to reduce them.

Any pointers that you can think of off the top of your head?
#142
02/18/2014 (10:18 pm)
I remember we discussed this a little before. Are you having to increase the search width, height, or both? Dropping a raycast to the ground may help, but obviously the navmesh can get somewhat off the terrain in steep locations. Unfortunately it's all Recast doing the search for the navmesh. The one thing I could do is make it search multiple times with increasing radii until a location is found. Shouldn't affect the regular cases, and may save some frustration with the edge cases!
#143
02/19/2014 (5:42 am)
It seemed to get more results by increasing maxStepheight *8 ... but I was wary of this incase it put a node on an unreachable ledge beyond Ai maxStepHeight ...

Thing is, the mesh is near the terrain, but the visit point is >20 units below both mesh and terrain ... which was a bit odd ...

I might just reduce my initial path to find a point halfway between the desired final destination ...

And just to note, I occaisionally still get that issue where the last node isn't the destination, the destination point is there but not attached the the path. Tends to be searches quite close (<50 units, so not the maxPathLength issue) and is a right bugger to try and reproduce at will. Just seen I didn't actually post about this in the thread before but think I did elsewhere ... anyhow, I scripted a workaround ... but just sayin' :P
#144
02/25/2014 (11:42 am)
Actually ... after picking my custom code apart the inability to find a visit point appears to a self-inflicted injury ... my apologies ...
#145
02/26/2014 (2:38 pm)
That's... good and bad to know? ;P Any chance you could tell me what was up? Or is it something nobody else is likely to run into?

Oh, so I thought you were increasing the dimensions of the search that is done to find walkable navmesh rather than adjusting the navmesh params itself. I should probably expose that so you can actually modify it without digging right into the source code :P.
#146
02/27/2014 (4:36 am)
No one will run into that - it was some of my custom function math for virtualizing movement along a path was off, so no need to panic on the "cannot find visit point".

;)

#147
03/02/2014 (11:36 pm)
ok dan, i need your expertise... in the nav editor i can select my ai bot and make him seek cover. I have my coverpoints in a cp folder, i made a AIPlayer::findcover function like so...

function AIPlayer::findCover(%this, %obj)
{
   if($AISK_WALKABOUT_ENABLE && %this.behavior.useWalkabout && %this.behavior.useCover && isObject(%this.getNavMesh()))
   {
      %position = LocalClientConnection.getControlObject().getPosition();
      %player = LocalClientConnection.player;
      %player.findCover(%position, $AISK_WALKABOUT_COVER_RADIUS);
      echo("Position: "@%position);
      echo("AIPlayer: "@%player);
   }
}

its being called in my defending case...

case "Defending":
        //Set the bot's move speed back to normal
        %obj.setMoveSpeed(1.0);
        %obj.isLost = 0;
        %obj.assisting = 0;
        %obj.nextNode = 0;
        %obj.setAIPose(1);
        
        //bot needs cover!!!
        %this.findCover(%obj);

        //Set the bot to it's highest awareness
        %obj.attentionlevel = 1;
        //Set the hldcnt to 1 less than the max
        %obj.holdcnt = $AISK_HOLDCNT_MAX - 1;

        //Sidestep to a random position
        %this.sidestep(%obj, true);
        
        //Set our action to 'Holding'
        %obj.action = "Holding";
        //Set a quick think schedule to start us looking for targets quickly.
        %this.ailoop = %this.schedule($AISK_QUICK_THINK, "Think", %obj);

        default:
        %obj.action = "Holding";
        %this.ailoop = %this.schedule($AISK_QUICK_THINK, "Think", %obj);
    }

    %this.displayBotNames(%obj);
}

I setup my cover as instructed in the tutorial an it didnt work so I tried this way, I dont know if this is the right way or im doing it wrong... thank you in advance for any help an heres what the consoles gives me when i shoot the ai and he doesnt see me. when i shoot him and he does see me he go into his chase behavior and shooots back as expected....

scripts/server/UAISK/aiThought.cs (580): Unknown command findCover.
  Object (1052555) Player -> ShapeBase -> GameBase -> SceneObject -> NetObject -> SimObject
Position: -24.682 59.6596 256.519
AIPlayer: 1052555
#148
03/02/2014 (11:45 pm)
if i make my function like this...

function AIPlayer::findCover(%this, %obj)
{
   if($AISK_WALKABOUT_ENABLE && %this.behavior.useWalkabout && %this.behavior.useCover && isObject(%this.getNavMesh()))
   {
      %position = LocalClientConnection.getControlObject().getPosition();
      %player = LocalClientConnection.player;
      %obj.findCover(%position, $AISK_WALKABOUT_COVER_RADIUS);
      echo("Position: "@%position);
      echo("AIPlayer: "@%player);
   }
}

i get this in console...

scripts/server/UAISK/aiThought.cs (582): Unable to find object: '-21.4908 61.8031 256.606' attempting to call function 'findCover'
Position: -21.4908 61.8031 256.606
AIPlayer: 1052555

i only changed %player.findCover(%position, $AISK_WALKABOUT_COVER_RADIUS); to %obj.findCover

if i change it to %this.findCover the game crashs when i shoot the bot...
#149
03/03/2014 (6:28 am)
Do you have Torsion? I'd advise stepping through that. It looks to me like you'll end up recursively calling that function infinitely by calling ::findCover() inside of ::findCover()....

Additionally, this question really probably belongs in the UAISK forum - while finding cover is related to pathfinding and Walkabout's cover system the AI's behavior is far more related to the AI system....
#150
03/03/2014 (4:25 pm)
ya I will post over there to and keep working on it, how ever i followed the tutorial on adding cover with walkabout and still didnt work?? thanks richard....
#151
03/03/2014 (7:36 pm)
%this.findCover(%obj);
Echo the value of %this before that line, see if it's what you expect. Also yes, you're calling findCover recursively which is a bad thing. If you're making your own cover-seeking method I'd name it something different!
#152
03/03/2014 (9:01 pm)
Ok, thank you daniel, that helped a ton... this is in my defending case;

//bot needs cover!!!
        echo("AIPlayer: "@%this);
        %this.SeekCover(%obj);

and this is my new function;

function AIPlayer::SeekCover(%this, %obj)
{
   if($AISK_WALKABOUT_ENABLE && %this.behavior.useWalkabout && %this.behavior.useCover && isObject(%this.getNavMesh()))
   {
      echo("Seeking Cover...");
      echo("this: "@%this);
      echo("obj: "@%obj);
      %position = LocalClientConnection.getControlObject().getPosition();
      %player = LocalClientConnection.player;
      %this.findCover(%position, $AISK_WALKABOUT_COVER_RADIUS);
      echo("Player Position: "@%position);
      echo("Player: "@%player);
   }
}

now heres the new console display;

AIPlayer: 1056513
Seeking Cover...
this: 1056513
obj: 1056513
Position: -25.2051 58.5676 256.356
Player: 1052555

now i see whats happening, the position is actually the players position and not the bots position, no wonder hes not taking cover from his location!! so im gonna try to get his position and post back if i cant figure it out...
#153
03/04/2014 (1:43 pm)
Donnie - check the Walkabout documentation, section 2a on scripting. findCover expects to be given the position to take cover from, i.e. the position of the attacker. The bot already knows its own position! So assuming you want the bot to always take cover from the LocalClientConnection player, the code you have is correct.

Have you set the cover radius global variable?
#154
03/04/2014 (9:42 pm)
thanks dan, i increased the cover radius to 300 and that helped big time... i also had to comment these two out in defending case;

//bot needs cover!!!
        %this.SeekCover(%obj);
        
        //Set the bot to it's highest awareness
        %obj.attentionlevel = 1;
        //Set the hldcnt to 1 less than the max
        %obj.holdcnt = $AISK_HOLDCNT_MAX - 1;

        //Sidestep to a random position
        //%this.sidestep(%obj, true);   <--------HERE
        
        //Set our action to 'Holding'
        //%obj.action = "Holding";      <--------HERE
        //Set a quick think schedule to start us looking for targets quickly.
        %this.ailoop = %this.schedule($AISK_QUICK_THINK, "Think", %obj);

and this is my new function;

function AIPlayer::SeekCover(%this, %obj)
{
   if($AISK_WALKABOUT_ENABLE && %this.behavior.useWalkabout && %this.behavior.useCover && isObject(%this.getNavMesh()))
   {
      %position = LocalClientConnection.getControlObject().getPosition();
      // Try to take cover....
      %this.findCover(%position, $AISK_WALKABOUT_COVER_RADIUS);      
   }   
}

Now he crouches and seeks cover like hes suppose to, however when he reaches one of the cover points, he doesnt stay but returns to his spawn marker.... im gonna try to schedule a hold count and id like access the coverpoint data. As in prone/crouch/stand flags so when the AI does reach the desired coverpoint he sets his pose accordingly... Thats my plan anyways, sorry for bugging you, i'm trying my best to learn as much as I can not being an experienced programmer. Thanks for this great pathfinding kit, well worth the money....
#155
03/05/2014 (6:26 pm)
Hey Dan, got it worked out and I posted it on UAISKs forum with what I done as to not take space up here and thanks for the help and advice. If I could bug you one more time, any advice on how to access the coverpoint flags in script, so I can set the bots pose accordingly to crouch/prone/stand when reaching cover???
#156
03/05/2014 (9:13 pm)
If you have the cover point's handle, you can just access its .size property:
%cover.size
It'll be one of "Stand", "Crouch" and "Prone" (same as in the editor).

But that has suddenly given me the awful realisation that I don't make the cover point handle visible to scripts - when you call findCover the AIPlayer just goes there.

If you want to do that, change the findCover console method in aiPlayer.cpp:
DefineEngineMethod(AIPlayer, findCover, S32, (Point3F from, F32 radius),,
   "@brief Tells the AI to find cover nearby.\n\n"

   "@param from   Location to find cover from (i.e., enemy position).\n"
   "@param radius Distance to search for cover.\n"
   "@return Cover point ID if cover was found, -1 otherwise.\n\n")
{
   if(object->findCover(from, radius))
   {
      CoverPoint* cover = object->getCover();
      return cover ? cover->getId() : -1;
   }
   else
   {
      return -1;
   }
}

That way you could write:
%cover = %aiplayer.findCover(%enemyPos, %radius);
if(%cover != -1) {
   %pose = %cover.size;
   ...
}
#157
03/06/2014 (7:05 am)
Hey dan, got this error compiling;

Error	28	error C2248: 'AIPlayer::getCover' : cannot access private member declared in class 'AIPlayer'	C:Torque3DEnginesourceT3DaiPlayer.cpp	929

31	IntelliSense: function "AIPlayer::__engineExportScope" cannot be defined in the current scope	c:\torque3d\engine\source\t3d\aiplayer.cpp	31

32	IntelliSense: function "AIPlayer::getCover" (declared at line 119 of "C:/Torque3D/Engine/source/T3D/aiPlayer.h") is inaccessible	c:\torque3d\engine\source\t3d\aiplayer.cpp	929


#158
03/06/2014 (2:19 pm)
Whoops, sorry - in aiPlayer.h find the line that declares findCover and move it into a public: section.
#159
03/06/2014 (7:58 pm)
you do mean this right???

bool findCover(const Point3F &from, F32 radius);
#160
03/06/2014 (9:25 pm)
Ok dan, cant figure this out, I put it every where in public I think.. I admit im still learning and sorry if im bugging you to much. The coverpoint pose feature would be great and a great addon to the kit. thanks for helping me figure this out..