Search Unity

SimplePath - Advanced Pathfinding for any Game Genre - RELEASED

Discussion in 'Assets and Asset Store' started by alexkring, May 18, 2011.

  1. tatoforever

    tatoforever

    Joined:
    Apr 16, 2009
    Posts:
    4,369
    Removed.
     
    Last edited: Aug 10, 2011
  2. Logistic-Win

    Logistic-Win

    Joined:
    Apr 4, 2009
    Posts:
    107
    So I am STILL looking for the RIGHT places in your code where I can call an animation.Play command ONCE when a path is found so my character can go from a still position to a walking animation when movement starts. And of course I need a place in your code where I can call a animation.Stop command when the character has reached the destination. I've been asking this for weeks, and NEED to get this finished as my client is getting stressed. My last question seems to have been ignored or missed... can you PLEASE help me out here? BTW... I am NOT new to Unity. The only places I have found so far end up calling the .Play command repeatedly which causes the animation to tweak out. PLEASE HELP!
     
  3. xicidis

    xicidis

    Joined:
    Mar 2, 2010
    Posts:
    28
    Hello. I purchased SimplePath last week. I've got it working and I have 50 things moving at once and it's not slow at all. However, I sometimes block all paths to the point they are trying to reach. The game is a tower defense type that allows you to block off the path with walls anywhere on the map. If that happens the agents need to be able to find a path close enough to start attacking the walls.

    When I do this, the agents just stop moving. They don't find the nearest open path and go as close as possible. How can I get them to do that?
     
  4. c-Row

    c-Row

    Joined:
    Nov 10, 2009
    Posts:
    853
    Could you please upload an example image of the level setup and how the agents should behave? One possible solution would be to temporarily disable one obstacle's footprint once no valid path can be found.
     
  5. xicidis

    xicidis

    Joined:
    Mar 2, 2010
    Posts:
    28
    http://dl.dropbox.com/u/8951191/Screen shot 2011-07-12 at 12.46.48 AM.png

    But, disabling one of the footprints to let paths through is the entire reason that I wanted SimplePath. If I just wanted to get form point A to point B there are easier ways. I want to be able to move around obstacles, while also being able to move as close to the target as possible if there isn't an open path.
     
  6. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    You will know when this situation occurs, because the request will fail, and OnNavigationRequestFailed will be called. Once this gets called, you need some way of determining the obstacle that the unit should attack, which is the tricky part.

    Here are a couple ways you could solve this problem. Each solution varies in terms of performance cost and visual fidelity.

    1. Iterate over all obstacles that are near the AI. Pick the obstacle that is closest to the AI.
    2. Iterate over all obstacles that are near the AI. Pick the obstacle that has the shortest distance from AI to obstacle to goal.

    There are also several, more complicated ways of doing this using search, but I think either of these two simple solutions (the second option should give better results) will be good enough for what you need.
     
  7. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    I haven't tried using animation with simplepath before, but it shouldn't be any different than playing a regular animation in unity. Can you post your code to show how you are playing animations? I know several other users are playing animations with simplepath, so hopefully they can chime in and help.
     
  8. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    There actually is partial support for this. You will notice that each PathRequest has a m_priority variable that just gets assigned to 0, and PathRequest inherits from IComparable. The PathManagerComponent stores a list of these path requests. If you want to try to get this working, you could add a function to set the priority on a path request, and then sort the path requests in the PathRequestManager.

    I implemented this behavior in one other project, but I never ended up using it, because the pathfinding performance was never such an issue that we needed to use this prioritization feature. But, I could see how it would be useful for mobile devices.
     
  9. Logistic-Win

    Logistic-Win

    Joined:
    Apr 4, 2009
    Posts:
    107
    I am simply using "animation.Play ("walk", PlayMode.StopAll);" and "animation.Stop ("walk");" inside your scripts attached to the character I have the pathfinder setup for.
     
  10. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    Can you paste the code?
     
  11. Logistic-Win

    Logistic-Win

    Joined:
    Apr 4, 2009
    Posts:
    107
    I have told you many times that I have tried placing these lines in MANY places where they would be called only ONCE per "Path-Start" for .Play and "Path-Completed" for .Stop. The problem is that I CAN'T find any good place! What do you mean "Paste my code"? I just showed you the code I was trying to find a proper place for in my last post.
     
    Last edited: Jul 13, 2011
  12. tatoforever

    tatoforever

    Joined:
    Apr 16, 2009
    Posts:
    4,369
    Paste the code (where you want to play your animations).
     
  13. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
     
  14. bryanleister

    bryanleister

    Joined:
    Apr 28, 2009
    Posts:
    130
    It seems to me you are going to need use a flag, when the animation is triggered, isAnimating= true. Then, if when it's triggered again, do a check if isAnimating before playing it again.
     
  15. Logistic-Win

    Logistic-Win

    Joined:
    Apr 4, 2009
    Posts:
    107
    I am using the Interaction_Chase script with of course the 3 other scripts that are supposed to be attached (Path Agent, Steering Agent Component, Navigation Agent Component). But to answer your question... I have tried finding a suitable place in ALL of your scripts to add the animation commands with no success. I currently have reverted to using your unmodified scripts and waiting for your recommendation. So if it helps to clear up the situation, I am not trying to get MY code working... I am simply trying to insert the animation commands in to your code where it would simple fire correctly. This should be a simple/easy thing to do if there is a point in your code that is fired ONCE when a path is first put underway, and ONCE when the path destination is reached. That is all I need.
     
    Last edited: Jul 13, 2011
  16. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    Code (csharp):
    1.  
    2.  
    3. if ( m_navigationAgent.MoveToGameObject(m_chaseObject, m_replanInterval) )
    4. {
    5.         m_bNavRequestCompleted = false;
    6.         // TODO: Add your animation.Play call here
    7. }
    8.    
    9. private void OnNavigationRequestSucceeded()
    10. {
    11.     m_bNavRequestCompleted = true;
    12.         // TODO: Add your animation.Stop call here
    13. }
    14.  
    15. private void OnNavigationRequestFailed()
    16. {
    17.     m_bNavRequestCompleted = true;
    18.         // TODO: Add your animation.Stop call here
    19. }
    20.  
    21.  
     
  17. xicidis

    xicidis

    Joined:
    Mar 2, 2010
    Posts:
    28
    OK, I'm really having a problem with this. I would like to find the nearest open node to the target. I have no idea how one would go about doing that. But I tried your solution. I don't know where to put the new call. If the path fails it would find a new target and path there. I put it in the OnPathRequestFailed in the NavagationAgentComponent. It would work for some, but not for most of them, and it never worked on anything on the screen when I blocked the path. Where am I supposed to put it?
     
  18. HJP

    HJP

    Joined:
    Jul 8, 2009
    Posts:
    152
    @LogicTwilight: Why you don't do it in your own class? Take that as a trigger and move, animate there.
     
    Last edited: Jul 15, 2011
  19. xicidis

    xicidis

    Joined:
    Mar 2, 2010
    Posts:
    28
    Take what as a trigger? Id there something sent to my class when there isn't a path?
     
  20. HJP

    HJP

    Joined:
    Jul 8, 2009
    Posts:
    152
    @xicidis: no, you must monitoring that....

    I do all in my own class ... pathfinding is pathfinding and animation is animation ...

    Then I use a class that bring it together ..


    Why you buy that?
     
    Last edited: Jul 15, 2011
  21. Logistic-Win

    Logistic-Win

    Joined:
    Apr 4, 2009
    Posts:
    107
    Because only the PathFinder knows when a path starts and when it ends. Are you silly?
     
  22. Logistic-Win

    Logistic-Win

    Joined:
    Apr 4, 2009
    Posts:
    107
    Awesome, you rock! Thank you!
     
  23. HJP

    HJP

    Joined:
    Jul 8, 2009
    Posts:
    152
    i'm out ... I think you have to learn many things ...
     
  24. Logistic-Win

    Logistic-Win

    Joined:
    Apr 4, 2009
    Posts:
    107
    You're not making sense HJP. Only the pathfinder has the logic to know when a path starts and where it ends. A separate class would not help just to call animation.Play and animation.Stop. I think you need to think of many things.
     
  25. Logistic-Win

    Logistic-Win

    Joined:
    Apr 4, 2009
    Posts:
    107
    Again, thank you Alex.
     
  26. xicidis

    xicidis

    Joined:
    Mar 2, 2010
    Posts:
    28
    What functions need to be changed to allow for a unit to find another target if the path fails. I thought it was OnPathRequestFailed, but it doesn't really act right when I use it there.
     
  27. HJP

    HJP

    Joined:
    Jul 8, 2009
    Posts:
    152
    in your small world, its true. It's possible to do so many more ... sorry ... my last post ... pm me
     
  28. Logistic-Win

    Logistic-Win

    Joined:
    Apr 4, 2009
    Posts:
    107
    HJP... please stop.
     
  29. xicidis

    xicidis

    Joined:
    Mar 2, 2010
    Posts:
    28
    OK. I found out how to get the OnNavigationRequestFailed to call properly. But this is all fudged up. I have my Agent find the nearest obstacle that is in the way blocking the path. So, I want to make him move towards that obstacle and attack it right? Well I can't because it has a footprint. Now, I can't remove the footprint because all the other agents will just walk right through it. But, nothing will even move towards the obstacle because the footprint blocks the path.

    How can I find the nearest open node to an object? It seems like it would have to be in the code somewhere. If not, what am I supposed to do? This is the whole reason I paid for this software. Will you please help me get it to work properly?
     
  30. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    The easiest way, if something will dynamically block the path after some time, is to track such "additions" and if you detect that a previously available path is no longer available and no alternative either you would mark that object as object to destroy and let them search the path there (you can easily find the point right before that on the path they need to navigate too if if you store it when you detect the path intersection)
     
  31. xicidis

    xicidis

    Joined:
    Mar 2, 2010
    Posts:
    28
    I have them finding the nearest obstacle to attack, but since it has a footprint it can't navigate there. How can I "easily" find the open point on the path before it hits the footprint? I am completely lost on where to do that and how. Thank you for the response, and please help! =D
     
  32. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    Now that you have the nearest obstacle, you should find the best valid attack point, around that obstacle. The footprint of the object has a bounding box. Grab this bounding box, expand it by the size of 1 cell, and then gather all of the cells that intersect the boundary of this new bounding box. These cells will represent all of the valid attack points around the object. Pick the cell closest to the player, and have him move to this cell.
     
  33. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    Another variation to that option, which is less CPU intensive, is to store the possible attack points around the object, as a list of vectors that represents offsets from the center of the object. Then you just have to look at all the points (object center + attackVector), and choose the point closest to the player doing the search.
     
  34. xicidis

    xicidis

    Joined:
    Mar 2, 2010
    Posts:
    28
    Is there a way to check if a certain spot is blocked or not? That way I can prevent it from checking those spots around the target?
     
  35. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    There is an IsBlocked function on the grid. This can take in either a cell index, or a position.
     
  36. xicidis

    xicidis

    Joined:
    Mar 2, 2010
    Posts:
    28
    OK. now I'm getting somewhere, lol.

    I have a set of targets set up so if the path is blocked, it will pick the nearest open one. Then, when they arrive, they do an OverlapSphere to see what is around it. I will check the colliders that are north of it (the target is always the top middle) for the closest one. Next I will use the collider and find the direction to it. It will check that direction (say south) from it and if that is blocked check the next two (south east and south west), then the next 2 then the last. If that doesn't produce a result, it will OverlapSphere again and chose a different obstacle. Repeat until it finds an opening.

    I think this is the best way, and I'll get on it. Only question so far is how do I call the path's function? I have a PathGridWithObsticales. So I should use GetComponent<PathGridComponent>.IsBlocked(targetSouthVector3); right?
     
  37. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    Yep, that will work.
     
  38. xicidis

    xicidis

    Joined:
    Mar 2, 2010
    Posts:
    28
    Type `PathGridComponent' does not contain a definition for `IsBlocked' and no extension method `IsBlocked' of type `PathGridComponent' could be found (are you missing a using directive or an assembly reference?)

    I can't find an IsBlocked method on any of the scripts I'm using... PathGridComponent, PathManagerComponent, nor the AStarPlanner has it. What am I doing wrong now?
     
  39. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    Err sorry, it's GetComponent<PathGridComponent>.PathGrid.IsBlocked( Vector3 or Int ); If you just do a Ctrl+Shift+F, you can search all of the files in the solution, in the monodevelop project, and you can search for IsBlocked to see where you can access the function.
     
  40. xicidis

    xicidis

    Joined:
    Mar 2, 2010
    Posts:
    28
    Ah, I use Unitron actually. I should use monodevelop. I just haven't really gotten around to it. I got it finding. Now I just need to figure it all out and get it all together.
     
  41. reddotgames

    reddotgames

    Joined:
    Apr 5, 2011
    Posts:
    707
    Any ideas how to work on multiply grids?

    So i have 2 grids and actor need to walk from one to another (start in grid1 and end in grid2) - how to bite this?
     
  42. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    First you will need to decide the crossover point from grid1 to grid2, and set this as the destination for navigating from the agent's current location to the edge of grid1. Once the agent reaches this destination, you should call CancelActiveRequest on his navigation component, and then set the m_pathManager variable on his PathAgentComponent to the pathmanager of grid2. Now, you can make a navigation request to the final destination in grid2.

    The GetCellIndexClamped might be a useful function for you to use, to find the crossover point. For a simple test, you could do:

    Vector3 intermediateDest = GetCellIndexClamped(finalDest);

    And this will find the closest destination in grid1, to grid2. Of course, this position could be blocked, so you might have to do something more complicated like scan the border of the grid to determine the best unblocked crossover point.

    Let me know if you need me to explain anything in more detail.
     
  43. reddotgames

    reddotgames

    Joined:
    Apr 5, 2011
    Posts:
    707
    Thank you Alex - I'll try to implement this.
     
  44. c-Row

    c-Row

    Joined:
    Nov 10, 2009
    Posts:
    853
    Just out of curiosity - wouldn't it be possible to use one grid and simply block large chunks of it rather than trying to work with additional grids to connect several areas? The "500 agents" demo shows that SimplePath can handle very large grids. Maybe not as elegant as passing the agent from one grid to another, but might be an idea for testing and prototyping.
     
  45. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    The most common way of dealing with really large grids, is to have a hierarchical terrain representation. For a grid-based terrain, this means there would be a lower resolution grid on top of the higher resolution grid, which acts as a layer of abstraction. To solve the path, you would find the solution on the high resolution grid, and then incrementally refine it into the lower resolution path. HPA* is one such algorithm, and is the most common hierarchical pathfinding algorithm used in the games industry.

    To make an analogy, let's say I want to go from California to Florida. I might first plan out which states I want to go through, and then plan out the actual roads I want to take. This is analogous to the high level and low level path solutions, respectively.

    But, this can be time consuming to implement, especially if you are new to pathfinding. If reddotgames doesn't need something this robust, then I think his solution will suffice.
     
  46. reddotgames

    reddotgames

    Joined:
    Apr 5, 2011
    Posts:
    707
    OK thanks for answer about grid switching.
    I bump into another problem.

     
  47. Unity.Darren

    Unity.Darren

    Joined:
    Jul 9, 2011
    Posts:
    7
    Hi, is this path finding system capable ( or can be adapted ) to simulate cars and pedestrians in a city? For example cars would find other cars as obstacles and sometimes attempt to surpass them based on speed.

    Thanks.
     
  48. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    What is the problem?
     
  49. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    It can help you to solve this problem, but you will need to do some of your own programming to get this exact behavior.
     
  50. reddotgames

    reddotgames

    Joined:
    Apr 5, 2011
    Posts:
    707
    As u can see - straight line to target is shorter than this what system picked (going up and and than down)

    ps. there is no colliders (footprint components) in this scene.