Get Started With A* – Part 3

In this part I will show you how to make a character move around on the grid you have just set up in part 2

First we are going to create our player, create a new capsule (GameObject–>Create Other–>Cylinder) gameObject and attach the Seeker script to it, name it “Player” and set the scale to 2,2,2.
The Seeker script will handle all pathfinding calls and store settings individual for that object.
See this page for more documentation about the Seeker component.
Set the “Debug Path” flag to true, this will make the script show the calculated path in the scene view.

The next thing you need to do is to attach the AIFollow script to the object.
This is the script which will move the player around and make the pathfinding calls to the Seeker.
See this page for more documentation about the AIFollow component.

To make the player be able to move we need to replace the default capsule collider with a Character Controller component (Component–>Physics–>Character Controller), a dialog screen will appear asking if you want to add or replace the collider, press “Replace”.

Next up we need something that can tell the player object where to move.
First, create a new sphere GameObject, name it “Target” and set the scale to 4,4,4, we will use this to indicate where the current path target is.

Next up, add the “Clicker” script to the Main Camera, this is the script which will listen for mouse clicks and then tell the player object to start pathfinding towards the point where the mouse is.
Also you should move the camera to a position where the whole pathfinding area can be viewed.

In the clicker component:
Set the Target transform to the Target gameObject we just created,
Set the Controller variable to point to the Player gameObject,
The Mask should be set to Everything
Leave the other two variables as they is.

Your scene should look something like this now:

Now….

Press Play!

Click on the plane and see what happens, if you have done everything right the player should be moving towards the point where you clicked and it should be avoiding all the obstacles in between!!

SUCCESS!!!

Something went wrong?
1. Read this page again and check for any errors.
2. Read the FAQ page
3. If you can’t find the error, write a comment to this page.

Hope this will get you started with the system.

41 Responses to Get Started With A* – Part 3

  1. Willem says:

    Howdy there, great starting tutorial, very easy to follow :)

    Having one problem though. I get this error:

    MissingComponentException: There is no ‘Camera’ attached to the “Sphere” game object, but a script is trying to access it.
    You probably need to add a Camera to the game object “Sphere”. Or your script needs to check if the component is attached before using it.

    Any ideas how I would solve this problem? Thanks for any help :)

  2. Admin says:

    @Willem

    I think you have a mistake and attached the Clicker script to the sphere (which should be named “Target”) instead of to the Main Camera.

  3. Willem says:

    That would be it. Thanks :) .

    Is it possible to define a set point for the seeker to go, instead of having the user click?

  4. Willem says:

    Disregard that, I have figured it out.

    Probably a noob question but is there any way to tell if there are no walkable nodes? A return or some such? My seeker needs to be able to tear down things in his way when he cant move any farther.

    Sorry for the bother :)

  5. Paul says:

    Hello,

    Firstly, great work with developing this algorithm for Unity :)

    I’m quite new at working in Unity so the problem I’m having might not even exist.

    However, after I followed your tutorial step by step, everything seems to be perfect except that my Cilindrical Hero doesn’t move at all :(

    The log says that A* Pathfinding Completed Succesfuly and the cilinder even rotates in the correct direction but does not move whatsoever.

    I think I might have overlooked something with the CharacterController.

    Thank you in advance for the help.

  6. Admin says:

    Hi Paul

    What I think you have missed is the Speed variable on the AIFollow script attached to the cylinder, try setting it to a higher value.

    -Aron

  7. Paul says:

    Hello,

    Thanks alot for the prompt response. I was just writing you back to tell you that I have figured it out. The speed variable in the AIFollow script wasn’t the problem:

    For some reason I thought it was a great ideea to set Min Move Distance to 0.3 in the Character Controller component.
    When I synchronized the settings with your screenshot (Min Move Distance set to 0 ), it worked just fine.

    I’m still not quite sure what does Min Move Distance stand for but for now, I’m very pleased that the A* algorithm works for me too :)

    Again, thank you very much for the help

    -Paul

  8. Willem says:

    Howdy again :) . Ran into another problem that I was hoping you might be able to shed some light on.

    I recently migrated from A* 2.2 to 2.5 and now my controllers have stopped moving. I have a little bit of code that was working with 2.2. Basically what I am doing is Instantiating a prefab with a Seeker script, and an AI script attached to it. The Start() calls GetMoving(), here is GetMoving()

    thetarget = GameObject.Find(“Family”);
    controler.StartPath (controler.transform.position,thetarget.transform.position);

    This used to cause the controller to go happily plodding along the map towards the destination, but now they just sit there. The Debug log shows as paths being computed successfully but no movement. The grid is generating fine, nodes are walkable, and the controller is spawning inside of the white box. Any idea what could be going on?

  9. Admin says:

    @Willem

    Ah, I think I know what the problem is:
    There are some syntax changes between 2.2 and 2.5, in 2.2 the Seeker script sends a SendMessage to a function named “SetPoints” but in 2.5 I renamed it to “PathComplete”.
    I think that your AI script is listening for a function call to “SetPoints” instead of “PathComplete”.
    Take a look at this page for more info.

  10. Willem says:

    Ah I figured it out, as it turns out I didnt even have the right version of the Pathfinding scripts ;o

    For some reason when I imported the Unity package I got an AI JS script instead of the AIFollow I was supposed to have. A simple switch later and away my zombies go :D .

    Thank you very much. I will certainly be mentioning you in the credits when this game finally rolls off the production line.

  11. Admin says:

    @Willem

    Yes, my bad. I didn’t remember to delete the old AI.js script when I released 2.5.

  12. Willem says:

    Encountering some odd problems. Mainly the zombies have this tendency to burrow under the ground. Is there any way to lock the yaxis without breaking the pathfinding? Ive tried adding a configureable joint and locking yaxis movement, but it has the added benefit of breaking A*.

    Also I have the nodes all generated, walkable and unwalkable. In one place I have a house, with 4 walls. There are some doors, and the unwalkable nodes surround the walls, but the pathfinding keeps trying to go through them anyway. The zombies move up to the wall and just stop, pressing endlessly against it. Sometimes they can make it through the door, but not too often. Any ideas?

  13. Admin says:

    Hi Willem

    There can be several reasons, here’s what I think.
    1. The script you use to move the zombies searches for the nearest waypoint (all) instead of when the next waypoint is near enough. When they walk past a wall, the waypoints on the other side of the wall are closer than the ones on this side of the wall, the zombie would then try to walk through the wall.
    Do you see that the generated path is actually going through the walls? (turn Debug Path on the Seeker script to true).

    2. You should use the Character Controller to move the zombies, and your look-towards-the-next-waypoint script should set the y property of the look direction to zero before applying it. Look in the AIFollow script in the RotateTowards function for some example code.

  14. Vimalakirti says:

    First of all, this is a really fine piece of work. I love it and will be sending you a check as soon as I have a game that will be for sale!

    I’m having the same problem as Willem. Obstacles are getting in the way. The blue debug line goes through them, the character doesn’t stay on the grid waypoints. I made the grid of small squares, so the blue line is about as long as 6 grid squares. I’m trying to track down a variable to tweak, without much luck. It looked like maybe pickNextWaypointDistance or maxStop but I reduced both with no change. Any help would be appreciated on how to make the character stay closer to the grid.

    That’s my main struggle right now. I need to pass targets to the script without using the mouse click method, but I think I can track that down.

    One other thing that would be nice to know is how to implement multiple grids like you were talking about. Your example was to use one for an interior space and another one for terrain. My question is how to do that. Each A* object with the Astar Path script attached?

  15. Admin says:

    Hi Vimalakirti

    Hmm, seams like I have to dig a bit deeper with this problem.
    Do you think you can send me a simplified project that I can take a look at? (me email is aron[dot]g[at]me[dot]com)

    Second, you can find the StartPath call syntax on a page in the docs.

    Third, this is only possible with the Grids mode, don’t make two instances of the AstarPath script, the script is a singleton class (maybe I should write a warning about that somewhere), you simply click the Add Grid button in the static settings under ‘Grids’ and then you can adjust it to any position you want.
    The grid highest up in the list has the highest priority (it will be chosen if two grids are overlapping).

  16. Emanuele says:

    Hi! Thanks for the great tools youre providing! I’d like to use your pathfinding algorithm to make a bunch of enemies follow the player. I’ve created the grid, created the player and the enemy, on the enemy i have the Seeker and AIFollow scripts.
    On AIFollow, i set the “Target” to my player transform, checked the “continous target search”, Target Search Frequency to 0.1.
    But it only goes to the first place my player was at the start of the game. How can i make it follow it continuosly?
    Thanks a lot.
    Emanuele

  17. Admin says:

    Hi Emanuele

    From what I can see from your comment it should work.
    Do you get any error messages/warnings.
    You can try to lower the max angle on the Seeker if your terrain is not flat.

    If nothing works, try to set up the system in an empty scene with just a flat plane as the floor minimizing the error possibilities.

    Aron

  18. Emanuele says:

    Hi, thanks for the fast reply! I’m now noticing that i get a “Start is not inside any grids”. But i have my enemy within the grid and within the box (even with height).
    From the console i get:
    Grid contains 1 Area(s)
    A* Pathfinding Completed successfully
    A* Pathfinding Completed successfully
    A* Pathfinding Completed successfully
    and from those on i only get this “Start is not inside any grids”.

    Oh yeah, i forgot (sorry if i doublepost but cannot edit). The terrain is flat :D (but I can, now there is only one post ; )

    What to do? :)
    Thanks!

  19. Admin says:

    Make a test in the scene view, select the enemy, so you can see it’s position (make sure you have pivot mode selected and not center), track it to the point where the console starts to say “Start is not inside any grids”, then check if it is inside the grid (make sure it isn’t exactly on the edge either since floating point errors can occur).
    If it doesn’t work, do you think you can send me a screenshot of your scene to me (with the enemy selected), my email is aron[dot]g[at]me[dot]com.

  20. Emanuele says:

    Oh, sorry, it was on the edge on the LOWER edge of the containing box, didn’t notice that. Just offsetted a little and now it works flawlessly! Thanks a lot Aron :D

    Aron: Great! (no new bugs to fix)

  21. Emanuele says:

    Well, here we go, another question since we’re there :P
    How to up the count of nodes in the grid? The only thing i can do is scale the grid x and z.

    And another thing :)
    I have a bunch of enemies following my hero character. Obviously right now they follow the same path to reach it (they’re all aligned in front of my character). Is there a way to say “hey, there is already a seeker there, just go to the nearest path”?
    To better explain, it already does, since they have colliders, they don’t stay in the same exact point when they follow/reach, but i’d like a more “heterogeneus” way. I can offset a little by randomizing the speed of my enemies a little but that’s not the same thing.
    Don’t know if it’s doable or, to say better, do i have to implement some sort of upper AI that interacts with the A* that recognizes if a path is already taken?
    I hope i’ve explained myself :P

    Thanks
    Emanuele

  22. Admin says:

    Hi Emanuele

    There are width and depth values which correspond to the number of nodes in the grid.

    The thing you want to do is very complicated!
    I have been working on a test project doing just that for about two weeks (working on it sometimes), so far I have been able to make units stick to the group formation while moving, I have tried avoiding each other but I haven’t got very far.
    The units move a bit more naturally now though. And actually only one pathfinding call is made for the whole group.
    Here’s a demo: http://www.arongranberg.com/unity/a-pathfinding/coordinated/

  23. rocket100 says:

    I am using A* Pathfinding project 2.5 with unity iPhone, I have followed the getting started guide, but when I click scan map I get an error saying,”Failed to call function Scan of class AsterPath”.
    Please help, Thanks!

  24. Admin says:

    Oops, sorry, my bad.
    I had some bad code which didn’t work on Unity iPhone.
    It is fixed now, you just have to download the project again (the only script changed is AstarPath.cs).

  25. Rick says:

    Is there a written demo for terrains and how to limit navmeshes based on the slop of the terrain?

  26. Jiwan says:

    Thanks a lot for your easy-to-follow tutorial. I think it is really brillant! (Really, so easy that it even works for someone like me XD)

    Now I’m playing around with the project and I have a question to ask for this tutorial.

    I’m trying to make these cubes used for obstacles clickable so that when I click one of the cubes, the chracater will move towards to the object, and when it reaches, it stops (currently, it is aggressively trying to pierce through the cube) and then play certain animation. So is there any options I can do to achieve this? In other words, making character stop when it meets obstacle (not keep trying to walk pass it but keep failing) and when obstacle was clicked, does certain function.

    I hope it wasn’t so rude for asking some ideas… :S

  27. Jiwan says:

    I suppose my question that I submitted earlier was inappropriate or something…? It got deleted… :S

  28. Admin says:

    Hi Jiwan

    It wasn’t inappropriate at all, It’s just a bit hard to keep up with all the comments (I hadn’t approved it yet), this is only a hobby project you see ;)

    To stop the character if it meets an obstacle, you could just do a regular Physics.Raycast from the AI towards the nearest waypoint (you can probably figure out what is the nearest waypoint in the AIFollow script).

    You could also set End Point to Snapped in the Seeker component or raise the Max Stop distance in the AIFollow component.

  29. Jiwan says:

    Thanks for answering kindly, aron(may be I was bit too hurrying and not waiting for moderation earlier on) – actually I forgot to ask you the real important question – the “playing certain animation” what I said ealier was sitting animation. How can I make character play sit animation and stay as it is(showing sitting stance) when I clicked the chair object while using your A* pathfinding? (Showing me example script can be a great help since I am really terrible coder) – I’ve been wandering around the forum asking question about this, but no one really answered me in detail…

    Conditions that I’m trying to implement is:
    Check if user clicked the chair object
    Check if character has collided with chair object on the way
    Stop Character from moving (Raycast thingy you suggested kinda confuses me T_T)
    Play sitting animation.
    Keep sitting stance until user clicks other point and attempts to move to different position.

    Sorry to bother you with such complicated situation for your hobby project :S

    currently my chair object in the layer “Walls” so that character can go around it if user didn’t clicked the chair but the point behind the chair. Weirdly, it can still reach chair even though Grid Debug shows there’s no grid(or path) on where chair is located.

  30. Charlie says:

    I’m having an issue where I cannot change the mask (layer). I followed the tutorial verbatim from within a new project which I opened up. When you go to change the mask to “walls” it will not accept the change. “Scan map” turns green but the mask reads as “Default Transparent FX” and will not change to anything else reguardless of what I select. I have the Walls gameobject named walls, with cubes parented to it. The game object and children are all layered as walls.

    I tried deleting the project folder and re-extracting the a*star download. The first time I made the a* gameobject I got a popup asking me if I wanted to check for updates, documentation, etc. I haven’t gotten that again, the project also still refuses to accept the layer mask change and tells me in the error log to “change the layer mask”, which is what I did….argh.

    Any advice?

  31. Admin says:

    Hi Charlie

    When you try to change the mask, you open a popup which shows the different layers, to the left of them there should be some signs showing if it is selected or not (I think it is an O), as default, all layers are selected, when you click on a layer the O to the left of it will disappear which means it isn’t selected anymore. My Layer Mask implementation isn’t exactly the same as Unity’s, so when you have selected a lot of layers, only the first three or two will be shown (Default | Transparent FX etc), so you wont see exactly which layers are selected before you open the popup.

    Hope this helps you.

  32. Admin says:

    What I suggest is that you make the player move to a position in front of the chair when it is clicked, then, when the player has arrived, rotate it to the correct rotation and play the sitting animation, I will try to build a example scene for you.

  33. jorge aldana says:

    Listo funciono, gracias

  34. Paco says:

    Hi i follow the tutorial, but send this message “Target is not inside any grid”.

  35. Admin says:

    @Paco

    This is because your player isn’t inside the white bounding box in the scene, remember to check this while you are in the Pivot mode and not in the Center mode (a toggle at the top of the Scene view window).
    Even if your player is right at the edge of the bounding box floating point errors might occur and the script will think the player is outside the grid, so it is best to have a small margin to the edge of the grid.

  36. Admin says:

    Hi Jiwan

    I have built a small sample scene for you.

    You can download it here: arongranberg.com/wp-content/uploads/help/AstarHelp_Jiwan.zip

    The example is in the Texture scene.
    Since I haven’t got any sitting animations I used a Shooting animation and the Take 001 animation.
    The shooting animation is played when the player arrives to the chair, and the Take 001 animation is played when it leaves the chair.

    The script I have changed in is the AIFollow.cs script.

  37. wyliam says:

    All I have to say is… Fantastic job on this!
    It’s been really easy to implement, and modify for my own needs. My hat off to you on such fruitful work!

  38. Jorshasaur says:

    Thanks a bunch for posting all this Aron, I’m learning a ton following your code!

  39. Baroni says:

    Hello!
    First, thanks for offering this awesome script to the community. It’s a great time saver.
    Well, i assigned your work to my scene, and a question pops up.
    I have a flat terrain which size grows with buttons, so the grid (capsule mod) doesn’t fit anymore.
    Is there any way to change the size of the grid by code while playing within other scripts?
    I looked for Grid Width and – Depth in the AstarPath.cs, but can’t integrate it.
    Also, if the bigger grid fits the terrain, it needs to recalculate the map in runtime…
    Can’t access your scripts by code very well, hope you can please give me a hint how to do that. Greetings

  40. Admin says:

    Hi Baroni

    First, to access the astar scripts from javascript (if you are using that) you need to place the Pathfinding folder inside the Standard Assets folder (if you haven’t got one, create one).

    The variable you should look at is the myGrid.nodeSize, that’s the width in world units of one node, after changing it you need to recalculate the grid though, you can do that by calling myAstarscript.Scan ();

    You can access the grid using myAstarscript.grids[0] this will return the first grid in your scene.

  41. Baroni says:

    Hey Aron,
    thanks for your answer and this useful informations, it’s all working very well like desired!
    Much appreciated

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>