Search Unity

Poly|Nav: Pathfinding for Unity2D

Discussion in 'Assets and Asset Store' started by nuverian, Jan 27, 2014.

  1. gumboots

    gumboots

    Joined:
    May 24, 2011
    Posts:
    298
    No worries, I messaged you!
     
  2. Gavor

    Gavor

    Joined:
    Apr 12, 2013
    Posts:
    7
    Hi,

    I started using PolyNav a couple of months ago and everything has been fine until recently. As my game has grown the number of Nav Obstacles has also grown so there are now several dozen and I anticipate this may be a couple of hundred or more for each level. As it stands Polynav is causing a 10fps or more hit to performance.

    Does it scale up to this many different objects? Is there something I could do to improve/optimise my use of the add-in? Happy to provide a build and further explanation if necessary.
     
  3. SoftwareGeezers

    SoftwareGeezers

    Joined:
    Jun 22, 2013
    Posts:
    902
    PolyNav has been the backbone of my upcoming game and I have to congratulate you on a great job for a very simple to use polygon-based path-finding. There is one issue I'd really appreciate an update to though. I use PolyNav to set waypoints to a destination, but the destination itself lies within the bounding obstacles. If I try to get a path to the central point, PolyNav fails. If I use
    Code (csharp):
    1. If (!PolyNav.PointIsValid(end)) {
    2. end = GetCloserEdgePoint() }
    it produces a rather primitive result as the nearest point isn't necessarily wanted. The attached shows the sort of situation I'm encountering. The obvious place for the waypoint is right in front of the rock, but PolyNav traces a path to the back because the back edge is nearer the final destination (X) than the front edge.

    Image1.png

    Is there a way for me to get a direct path where the final waypoint is inside the collider, and return that the path is direct and needs handling in code? For me, with that info I'd set the waypoint a little distance outside the target waypoint and it'd be perfect.
     
  4. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Sorry for late replies everyone.

    I PMed you back just now :)

    Hello,
    Well, naturaly the more obstacles you have, the more the performance hit will be. To be total exact, the more vertices you have rather than polygons. So if you for example have a square that is more than 4 vertices, those vertices are of course still counting for pathing.
    So the best thing you can do is to minimize the vertices, and use one polygon collider instead of 2, if it can cover the same space.
    Last but not least, I don't know if that's true in your case, but having "Generate on change" ticked and transforming an obstacle, makes the whole map regenerate, which is quite slow if you have dozens of them.
    Can you tell me the number of nodes that the PolyNav2D inspector read at the very end?
    Also what part in the profiler you see causing the issue?

    Thanks


    Hello and thanks! :)
    It's a tricky situation.
    In cases where there is a more complex navigation map, CloserEdgePoint is going to be the one desired, but in your case it's a bit special. Right now, I can't come up with a way to handle this situation.
    I will try to come up with a solution in the weekend and let you know.
    Sorry that I can't provide a solution now :/
     
  5. nia1701

    nia1701

    Joined:
    Jun 8, 2012
    Posts:
    74
    Hi there,
    Great plugin! I've modified it so that polynav does not use the singleton so that I can have multiple nav areas in a scene. I feel this is useful for two areas that have nothing to do with each other but each need navigation. Instead of having many obstacles cutting up the main nav area, I feel this is more organized. There were only a few edits needed to make that happen, but I'm wondering if you would consider for the next update incorporating doing away with the singleton. Thanks so much.
     
  6. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hello and thanks :)
    I am glad you enjoy PolyNav.

    Some time back I was to do what you just did and on top of that add optional links between the different navigation maps.
    I can certainly incorporate what you did in the next update. It will be great if you want to share the changes :)
    PM if you wish so.

    Cheers and thanks
     
  7. Gavor

    Gavor

    Joined:
    Apr 12, 2013
    Posts:
    7
    Hi,

    Thanks for the reply. I spent quite a bit of time last week removing unnecessary vertices and making sure each object has only one collider (generally a polygon collider). I also minimised the number of nav obstacles by drawing them manually over certain areas (i used to have one nav object per section of wall for example).

    I definitely have generate on change turned OFF, I'd love to have it on as my game objects can move around quite a bit, but it create a huge performance hit.

    Actually it says nodes count 0.

    In the profiler I am seeing the frames/sec being the main issue - it is noticeably slower in game when things are moving and I have quite a new NPCs making their way around the map.

    I've added a couple of screenshots to show the number of nodes (you can see from the length of the list that there are a lot). Also included a zoomed out shot of the level showing all the poly objects.

    NodesCount.png

    StationWithPoly.png

    Thanks!
     
  8. nia1701

    nia1701

    Joined:
    Jun 8, 2012
    Posts:
    74
    Great! I didn't do much at all to make it non-singleton based.

    I removed the _current singleton from PolyNav2D and made any static lists or variables into regular non-static lists or variables.

    On PolyNavAgent and PolyNavObstacle I made the polyNav variable a public variable I can assign in the inspector.

    I moved the static list of polynavagents out of the polynavagent script and made in a list on the polynav2d object and added a register and deregister method just like you have for the obstacle class.

    Also this breaks the way you show in the inspector the list of current obstacles unless after assigning that obstacle a polynav you disable and then reenable it so it adds itself to the list.

    I think the only thing you will need to be careful of is that this will break peoples current implementation. So you may want to figure out a way to do both. Like if the polynav is null then use a singleton, but if it is assigned then use the assigned value. That would allow people to keep using the singleton method.

    Feel free to PM me if you want! Great product, gotta say for 2D this is the best NAV i've come across.
     
    Zelek likes this.
  9. SoftwareGeezers

    SoftwareGeezers

    Joined:
    Jun 22, 2013
    Posts:
    902
    Any progress on this? I've just had an idea that'd probably work for me. If I can get the index of the first node that is one of the final destination collider object's vertices, I can trace a straight path from the previous node. I suppose that in your path finding, the moment you are selecting nodes within the collider, you could stop there and provide a path to the first node. eg:
    Image1.png
    In this case, nodes 5, 6 and 7 are on the final collider. If I could get the info that node 5 is the first on the collider, I could trace a path directly from 4 to the centre (set waypoint PolyNav.radius distance from centre of final target in direction of node 4). Better yet, if PolyNav could end the path finding as soon as a node on the final collider was added and save a little bit of processing. Maybe offer a NearestCorner() method?
     
  10. Ax7

    Ax7

    Joined:
    Sep 25, 2012
    Posts:
    1
    Hi Nuverian,

    I'm interested in maybe picking up PolyNav for a 2D platformer our team is working on. Our physics system is currently setup using 3D colliders in Unity. Does PolyNav work with 3d colliders as well or would it have to be changed over to use 2d colliders? Again, to be clear our game is 2D in the x-y plane, we are just using the normal Unity physics system instead of the 2d physics. Thanks,
     
  11. SoftwareGeezers

    SoftwareGeezers

    Joined:
    Jun 22, 2013
    Posts:
    902
    PolyNav only works on 2D colliders. There's nothing stopping you using 2D colliders for path finding though. Path-finding is independent of physics interactions. If you want to use PolyNav's agent system, you could easily create dummy GameObjects for agents and have your 3D objects move to their positions.

    However, if your game is 2D only, swapping to 2D should be beneficial. It's lower overhead and allows for reasonable performance for polygon outlines. Something to consider regardless of PolyNav.
     
  12. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,412
    Good work, this is the kind of lightweight solution I needed for my project. Though I don't see the reason why you've only allowed one PolyNav2D component, especially now that the obstacles aren't based on layers. Ideally you would allow multiple ones and a simple way to move actors between them (e.g. some type of OffMeshLink system). But I can easily modify the code to suit my needs.

    [Edit]

    So I played around with the code some more and I have some thoughts:

    - Unless you specifically need Unity 4.5.1 features (I don't think you use any?), you should submit the asset using the earliest version you can get away with to prevent people (like me) who have older installs from buying it right away.
    - As I said earlier you should remove the singleton setup from the PolyNav2D component to allow for multiple paths. In my current setup I've made it so it still stores the static _current and any actors without a specifically assigned PolyNav2D will use that. Separating it is pretty easy, though it does cause other potential issues with actor avoidance.
    - You should make all the classes and fields serializable, because right now it doesn't survive a recompile during play mode.
    - The nav doesn't seem to update during play mode when you tweak stuff like the PolyNav2D.Radius
    - If the nav obstacles are designed to be children of the PolyNav2D, then why don't you calculate everything locally to it? That way you can have the entire map move/rotate/scale without any performance penalty (e.g. in my game I need actors to move around a moving spaceship).
    - The path inset code doesn't take the corner angle into account, giving you uneven borders for some shapes. Maybe in the future you can have settings for different corner modes.
    - Maybe do away with the Select/Remove obstacle list? It doesn't tell you which obstacle is which, so it's pretty useless, and you can already remove obstacles by destroying their GOs.

    For any other potential customers reading this: This asset is really good and does exactly what it says it does and will work great for 99% of games, I just have some very obscure requirements!
     
    Last edited: Oct 31, 2014
  13. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hello everyone and sorry for late replies

    Thanks for the screenshots. The nodes count will show the correct number in play mode.
    It would be great if you can send me a project (no graphics etc if you dont want to) to take a loot at in and possibly provide some answers for better performance, but as far as I can see it seems that every wall is a different polygon, where it could optimaly be one.

    Thanks!

    Hey,
    Thanks a lot for information. I will take a look at it.
    No worries, it will be backwards compatible and not break previous setups :)

    Cheers!

    Hey,

    To be honest, I didn't quite understoon your suggestion :)

    The thing is that what you are after practicaly only works in circular kind polygon shapes where the target position is the centre. Consider the following image.
    issue.png

    In this example, normaly the desired closer point is actually "A", but the desired closer point in a sense of what you are after, would result in point "B" (which is the intersecting point of a side of the polygon in which target position is in and a straight line from agent position to target position), which is not so desired in all other cases I think :)
    So this, can't be generic enough for all cases.

    Another possible solution since it's about circular shapes (unlike the example above), would be to set the agent stopping distance equal to the radious of the obstacle it is about to go to. For this you will of course need to have a radious per obstacle and when SetDestination for an agent, also set it's stopping distance. For this you could add a custom MonoBehaviour on each such circular (commet) polygon obstacle and when you are to set destination to that game object, read it's radious and set the agent stopping distance to about that radious. A bit dirty, but it works if the transform.position is in the centre.

    I can't really come up with any other solution, but someone smarter than be may definetely do so :)

    Hello,

    Well, prety much what Shifty Geezer said :)
    It only works with 2D colliders and even them are simply used as a drawing method for the polygons, meaning that the actual PolygonColliders2D are not really used as "colliders", but rather only as polygons.

    Hello and thanks.

    I am considering updating polynav as trothmaster suggested couple of posts above where it's actually what you also suggest, when I find some more available time.
    When that is done, an "offmesh link" kind of connection will also be added, but I can't really promise as to when this will be done right now :)

    Cheers!
     
  14. SoftwareGeezers

    SoftwareGeezers

    Joined:
    Jun 22, 2013
    Posts:
    902
    You're right that A is the closer point and the one someone would want when wanting the closest point. However, if you're wanting a path straight to the target and not the closest point, point B is the point you'd want. At the moment, GetPath always sets the target to closest. I think there should be two path-finding methods, 1) plots to the closest point (your point A), and 2) plots the most direct path, ending at the near-side collider edge (point B).

    As I say, at the very least if you could provide a GetPath method (GetPathDirect maybe) that stops the path at the nearest node to the ship, not the target, that'd be very workable. In your example, there are three nodes from agent to target. I'd only need, and want, the first node. I presume this would also save a little computation time.
     
  15. EmeralLotus

    EmeralLotus

    Joined:
    Aug 10, 2012
    Posts:
    1,462
    Nice 2D path system.
    I am procedurally generating a maze/dungeon at run time. Can PolyNav be created entirely at run time ?
     
  16. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hello again,
    I think this is what you need:

    Code (CSharp):
    1.         if (Input.GetMouseButtonDown(0)){
    2.             var target = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    3.             if (PolyNav2D.current.PointIsValid(target)){
    4.                 agent.SetDestination(target);
    5.             } else {
    6.                 target = PolyNav2D.current.GetCloserEdgePoint(target);
    7.                 PolyNav2D.current.FindPath(transform.position, target, delegate(List<Vector2> path)
    8.                 {
    9.                     agent.SetDestination(path[1]);
    10.                 });
    11.             }
    12.         }
    If the target position is valid, everythin is ok, just go there. Else if the target position is not (eg inside obstacle polygon), alter the target to that of the closest point and then find a path from the agent position to that closest point. Finaly go to the 2nd node of that path (1st is the agent position). I've tested this and seems to get what you need for your case :)

    Hello,

    Yes, you can generate PolyNav at runtime as well as update the obstacle polygons. You can also alter the shapes by directly aletering the PolygonCollider2D points.

    Let me know if you need more specifics.
    Cheers
     
  17. WarpRulez

    WarpRulez

    Joined:
    Sep 2, 2014
    Posts:
    8
    I don't understand how PolyNav is used on a physics-based platformer.

    I'm creating a platformer using Unity's 2D physics engine (gravity, 2D polygon colliders...) and I need path-finding for some non-playable characters.

    So I have followed the instructions and added a PolyNav2D object encompassing the entire scene. I then add eg. a ground sprite and add a Poly Nav Obstacle component to it, which also creates a Polygon Collider 2D component.

    However, the playable character just falls through the ground like the collider isn't there at all. The problem is that the "Is Trigger" flag is set for the Polygon Collider 2D of the ground sprite. If I disable the Poly Nav Obstacle component and uncheck the "Is Trigger" flag of the collider, it works properly (ie. the playable character does not fall through). However, if I then enable the Poly Nav Obstacle once again, the "Is Trigger" flag gets checked automatically. If I uncheck it and run the game, it again gets checked automatically, and the playable character falls through.

    How can I add a Polygon Collider 2D that both works as a collider for 2D physics objects and works with PolyNav?

    Do I need to duplicate the polygon collider or something? (Would seem like a waste of resources...) What is the proper procedure here? I tried to read this entire thread for instructions or questions related to this, but couldn't find any.
     
  18. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hello,

    Please comment out line # 57 in PolyNavObstacle.cs, where isTrigger is set to true OnEnable.
     
  19. WarpRulez

    WarpRulez

    Joined:
    Sep 2, 2014
    Posts:
    8
    That seems to work.

    There's another problem I encountered. The Poly Nav Agent seems to get stuck in corners. After some testing I concluded that this happens when it's decelerating (ie. the "Slowing Distance" is large enough that it's already decelerating when it's still behind one or more corners.) It seems that when this happens, it decelerates to each corner, rather than the deceleration being to the final target. This means that it basically decelerates and stops at each corner and then proceeds to the next.

    I'm not sure if this has already been addressed. It would be nice if there was a version number in the documentation or in the files, to corroborate that I have the latest version.
     
  20. SoftwareGeezers

    SoftwareGeezers

    Joined:
    Jun 22, 2013
    Posts:
    902
    Yes, that's a good idea. Have one object for PolyNav that can be greatly simplified, and another for your actual collision object. eg. Let's say you have an octagonal object. You want an octagonal physics collider for it to behave properly, but could get away with a square PolyNav collider for path calculations, having vertex counts. In my game, I have asteroids with maybe 12 vertices in their physics collider but a simple triangular PolyNav object to steer agents around the asteroid.
     
  21. oleanna

    oleanna

    Joined:
    May 21, 2014
    Posts:
    11
    Hi dude,

    Thank's a lot for your pathfinding solution :) !
    But i have a little problem (lag from main thread) when i disable
    the PolyNavObstacle script.
    Code (CSharp):
    1. if( (Input.GetMouseButtonDown(1))&&(peutouvrir==true) )
    2.     {
    3.         RaycastHit2D[] hits;
    4.         hits = Physics2D.RaycastAll(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);
    5.          foreach(RaycastHit2D hit in hits)
    6.         {
    7.             if (hit.transform.tag == "Porte")
    8.             {
    9.  
    10.                 switch(porteouverte)
    11.                 {
    12.                 case false:
    13.                     porteouverte = true;
    14.                     animcontrol.SetBool("isopen", true);
    15.                     _renderer.sortingOrder += -6;
    16.                     _polynavobs.enabled = false;
    17.                     audio.Play();
    18.                     break;
    19.                
    20.                 case true:
    21.                     porteouverte = false;
    22.                     animcontrol.SetBool("isopen", false);
    23.                     _polynavobs.enabled = true;
    24.                     audio.Play();
    25.                     break;
    26.                 }  
    27.             }
    28.         }
    29.  
    30.     }
    Do you have some recommandation to gain performance with PolyNav ?
    Thank's for your time :)
     
  22. gumboots

    gumboots

    Joined:
    May 24, 2011
    Posts:
    298
    Hiya!

    Would it be possible for future updates to change OnDrawGizmos to OnDrawGizmosSelected? Or have a toggle option on the main game object? Having obstacles drawn all the time adds quite a bit of clutter to the scene view while level building, and it'd be nice if they only showed up when I selected the main PolyNav object.
     
  23. stoomm

    stoomm

    Joined:
    Apr 7, 2013
    Posts:
    15
    Hello,

    Thanks for this asset !
    Question : Is it possible to have some obstacles activated for an agent but not another ?
     
  24. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hello,

    I am sorry, but I don't understand what you mean. Do you get slow performance the moment you disable a PolyNavObstacle? Also, what does your posted script has to do with the performance hit? :)
    Let me know. Thanks.

    Hello,
    You can disable/enable the gizmos in the Gizmos dropdown menu of the viewport. Disable the PolyNav2D in that list will no more show the gizmos. :) You can of course still edit the polygons if you select them.

    Cheers

    Hello,

    Thanks as well :)
    No, sorry. This is not possible to do, at least currently. I went ahead to see if it's easy to implement and I think I might add this when I find some free time :)

    Thanks.
     
  25. CarterG81

    CarterG81

    Joined:
    Jul 25, 2013
    Posts:
    1,773
    I am interested in purchasing Poly|Nav, but I have some questions.

    My game is a topdown game, like a NES rpg.

    pathfind.png

    I am either going to purchase Poly|Nav, or NavMesh 2D. I was fortunate enough to be able to demo NavMesh 2D with a friend. I liked it, but the inability to alter the navmesh at runtime is pretty awful, since that means I can't have characters block one another's movement.

    My first question would be, is there a demo? It would not take me long to figure out if I should purchase PolyNav or NavMesh if I could demo PolyNav in Unity. If no demo is possible, here are my questions:

    Q1) How "easy" is it to set up the navmesh (walkable/non-walkable areas) in Poly|Nav? In NavMesh 2D, I know I can just use 2D Collidors (Box Collider 2D is the only type I use) which are already on all my gameobjects. So I literally just place my objects (design the level) then hit "Bake". This means next to no work at all on my part. In the videos for Poly|Nav, I notice a ton of work creating and manipulating points? For an adventure game, that is very desirable. For my topdown rpg, it is unfortunately not.
    Does Poly|Nav automatically detect all gameobjects with BoxCollider2D's on a "NoWalk Layer"?

    Q2) I haven't really thought about it, but since Poly|Nav updates during runtime (NavMesh 2D cannot), does that mean I can attach non-walkable colliders to all characters, so they cannot walk through one another? Or do people usually handle character collision differently?


    My main need is to set up a scene very quickly by simply placing down prefabs of gameobjects, like a Barrel freefab, over a walkable floor, and have the barrel's colliders block movement. I don't want to have to create a polygon for every barrel I place down.

    My other need is less important but still desirable- to calculate paths around characters so they walk around each other (rather than through each other). Or something like blocking movement for enemy NPC's but NOT ally NPC's.
    Do people normally use Poly|Nav to handle character collision when pathfinding?

    Thank you!
     
  26. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hello,

    These are all very interesting questions.
    Unfortunately there is no demo for PolyNav available. I could make one by providing a DLL version with some limits, but there is none currently.

    1. First of all, PolyNav doesn't use the Unity layer system at all. Thus you are free to use layers for your own purposes. An 'obstacle' component defines if something is an obstacle or not and an obstacle's area is defined with PolygonCollider2D on that same game object.
    So the setup is simply that you add PolyNavObstacle component on your object (eg barel), define the obstacle using the PolygonCollider2D once and then drag and drop as many prefab barels as you want in the level and they will automatical be considered.(BoxCollider2D is not supported right now, but is trivial to add).
    You can even instantiantiate/enable or destroy/disable barrels in runtime and the navigation map will update.
    The adventure video doesn't use prefabs, because there is no need to :)
    All these obstacles are placed within one big walkable area which you define once.

    2. Avoidance is not handled the same way that obstacles do, or else there is a big performance hit. PolyNav has a simple agent avoidance feature, where you set the radius for each agent and then they avoid each other.
    PolyNavAvoidance.gif
    So to recap:
    • Yes you can work with prefabs, and simply pace them in the walkable area.
    • You can add/remove obstacle game objects at runtime.
    • BoxCollider2D is not supported, but I can do that.
    • Agent Avoidance is handled by defining a radius.
    • You can't select which agent avoids which others now. Every agent that has an avoidance radius > 0, will avoid and be avoided by every other agent that has a radius > 0.
    • Agent avoidance doesn't force an agent recalculate it's path. It simply moves the agent around the other agents.
    Furthermore, PolyNav comes with a steering agent component (as seen above) to use for your characters instead of coding your own.

    As a final notice, if your game is kind of grid based with huge maps, you might want to consider using a grid-based pathfinding solution instead.

    Let me know if you have further questions.
    Cheers!
     
  27. CarterG81

    CarterG81

    Joined:
    Jul 25, 2013
    Posts:
    1,773
    I purchased Poly|Nav, and so far it is working great- besides the learning curve. I didn't realize how important the radius options would be.

    Could you add support for BoxCollider2D?
    (Or do I just have to remove the PolygonCollider2D and add a BoxCollider2D? I assumed that would break it.)
    It would help so much, as these polygon collidors are a bit of a pain to form into perfect squares.
    BoxCollider2D works really well for my game, since it's a pixel game.


    The following is not very important. With BoxCollider2D support, I can do everything fine and dandy (well enough, anyway).
    I also have a future request. I tried to use a Radius with the polynav. It worked great for things like entering through a tiny door. However, I had to make the radius 10 to match the character's radius of 10. This meant the smallest possible obstacle I could create was 10x10. I couldn't create my smaller obstacles- they'd extend too far.
    Would there be any way to make the polynav radius apply to individual objects, not the entire polynav2D (everything or nothing)?
    I'd love to be able to have that radius for my doorways and benches, but disable it on objects that need to be smaller than the radius. It's not a big deal though. Right now I can just customize the size and placement of the box2Dcollider, calculating the extra area myself.

    Although honestly, instead of the above, I'd just prefer a type of "avoidance" for all non-walkable areas.
    What I mean is, I would be able to set the PolyNav2D radius to 0, and not use it. Instead, set the radius to 10 on my character (which works to avoid other characters with a radius >0) but also to have that 10 radius avoid non-walkable obstacles (it would have to be a square "radius", not circle "radius").

    That way the entire character (radius) is blocked by obstacles, rather than just the position of the character gameobject (1x1 spot). That way my characters don't overlap on obstacles. I realize this would be a more difficult feature to add, but much more preferred than the disable-radius feature alternative, maybe?
     
    Last edited: Nov 25, 2014
  28. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hello,
    Thanks for the purchase :)

    Yes, I've already gone ahead and added support for BoxCollider2D, There is now an enum where you select either Polygon or Box types for the PolyNavObstacle component.
    I've PMed you the code and this will be in the next update as well.

    Regarding your requests.

    An easy thing I can do, is to have kind of a extra offset on the PolyNavObstacle component. thus you could fine tune each obstacle offset seperately on top of the global radius offset (set in PolyNav2D).
    Thinking of this, I just did it :)

    Now, taking into account the agent radious for the pathfinding itself is something I want to do long time. I still have to figure an efficient way of doing this. Even when this is done, it will be a circle radius though, since circle calculations are just way faster. I will take a look at it again.

    Cheers!
     
  29. CarterG81

    CarterG81

    Joined:
    Jul 25, 2013
    Posts:
    1,773
    Wow, that is amazing. You're really good at what you do, and it shows. Really fast too.

    This was so worth the purchase! :)

    THANK YOU!
     
  30. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Thank you. You are most welcome!
    I am glad you like PolyNav.

    Cheers!
     
  31. lekima

    lekima

    Joined:
    Nov 24, 2014
    Posts:
    2
    Hi nuverian,

    I just bought your plugin and I have a few questions. It'd be great if you can give me some guidance, since I'm quite new to game programming and I mainly use Playmaker at the moment.

    1. I'm currently making a platformer and I'm having troubles creating an AI that can jump over gaps, or to a higher platform. What is the best approach to this situation?

    I took a look at your included demo but it's just a simple top-down scene. A platfomer is more complicated and sadly I don't see any example demonstrating that.

    2. I want to create a monster that keeps following the hero (update every frame), how can I do that? It'd be awesome if you can lead me through this only using the available Playmaker actions. (Should I use PolyNav for this behavior? Is it expensive to update the path continuously?)

    Thanks.
     
    Last edited: Nov 26, 2014
  32. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hello and thanks!

    Handling how and where a character jumps is unfortunately outside of the scope of PolyNav. Furthermore this is quite a complicated subject to be handled only by using Playmaker. Regardless, the easiest way I can think of, would be to create some paired nodes (triggers) and as soon as the character enters one of the nodes of the pair, temporary bypass the pathfinding and do a jump, climp or something else to make him go to the other node of the pair, from where he will continue his path.
    Such a thing of course should be handled in code for creating the linked pairs, as well as the animation that the character should play to reach the other linked node when he enters the first.

    I may investigate for something like this integrated in polynav, but then again, it is really outside of the scope of the asset unfortunately.

    Regarding your 2nd question, I've attached to this post some updated Playmaker actions that include "every frame" option for the move actions. It's quite ok to call it on update.

    Let me know if you have any questions.
    Cheers!
     

    Attached Files:

  33. lekima

    lekima

    Joined:
    Nov 24, 2014
    Posts:
    2
    Hi nuverian,

    1. I was also afraid that question is outside of the scope of PolyNav, but your answer actually helped me to understand it clearer and to know what approach I should take. Thank you.

    2. This is great! That little checkbox is exactly what I was looking for, thanks a lot. Could you please include this updated version of Playmaker actions to the next update of PolyNav? I believe there are some people out there who need the function too.
     
  34. CarterG81

    CarterG81

    Joined:
    Jul 25, 2013
    Posts:
    1,773
    Just curious, would it be trivial for you to also allow us to choose a box collidor for the @PolyNav2D?

    All my obstacles are rectangles, but the primary (walkable) is still a polygon I morphed into an imperfect square.

    It's not a big deal. Please don't waste the time unless it's trivial to implement. It's mainly my faux-OCD which is like "Oh man, I wish that was a BoxCillider2D too...it's so imperfect!" :p
     
  35. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hello,

    I am glad I could be of help. Again, I will see if I can somehow add extra features that could help in such an aproach for platformers. Can't promise anyhing though :)

    Sure. The next update will include this package as is. I should have put that "every frame" there to begin with.

    You are most welcome.
    Cheers!
     
  36. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hello,

    I've PMed you the code to be able to use a BoxCollider2D for the walkable area. Simply remove the PolygonCollider2D from the game object and add a BoxCollider2D. I will add inspector selection later on.
    This will also be on the next update :)

    Cheers!
     
  37. SoftwareGeezers

    SoftwareGeezers

    Joined:
    Jun 22, 2013
    Posts:
    902
    Hi,

    Just encountered a serious issue when one of my ships is inside a polynav obstacle and wanting a path to another part of the map. Instead of tracing the path, it stops at the nearest edge of the collider the ship is inside as the point is invalid. It shouldn't matter where the start point is when calculating a path - the path should always go from first node (where agent is) to first valid point, which ties in with my earlier issues. Even if a game doesn't want to have objects inside a polynav collider, if something freaky happens and something ends up there, it should be able to navigate out successfully.

    Edit: I think it's only in some path directions. In this example, the green ship should fly out to point 4, but it doesn't move. The path ends at its location, or at least very close on the polynav collider edge.

    Image2.png
     
    Last edited: Dec 2, 2014
  38. CarterG81

    CarterG81

    Joined:
    Jul 25, 2013
    Posts:
    1,773
    I think...I'd like to see a solution to this problem too.

    Maybe an option not to go the nearest point, but an option to go to the nearest point and then IGNORE colision. In this case, it would need to ignore collision, go to the nearest starting point, and then act as normal.

    Same premise either way though- it needs to ignore collision, calculate the nearest point and then follow a path, or vice versa. It needs to know where to start or end, and then what to do before/after.

    At the very least, try to move and if colliding, return the gameobject so the code knows which object to enable/disable temporarily. (If this is not already possible using the API.)
     
    Last edited: Dec 2, 2014
  39. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hello people,

    I am a little puzzled by when/how this problem occured to you, since an agent is never allowed within non walkable areas (an obstacle). It is always forced "pushed" out of it, if inside, and thus it's positions (and the first point of the path) is always a valid one.

    Have you done any modifications to the source code?
    If not can you please provide more information how to reproduce an agent that exists within an obstacle?

    Thanks :)
     
  40. CarterG81

    CarterG81

    Joined:
    Jul 25, 2013
    Posts:
    1,773
    I haven't gotten to that point yet, but I assumed I can simply move my gameobjects to specific locations outside of the collidors, and then using another movement script (not using polynav at all) to move the characters to specific locations. From there, they would be inside the collidor and need to move out of it to the next path.

    So I just assumed by his post, I will run into this problem.

    I need my characters to avoid walking into a bench, so there is a collidor surrounding the bench, but I need them to be able to move into the bench to sit down on it.

    In this way, the character needs to both know it is an obstacle to avoid using polynav, be able to move into the obstacle to "sit down" using either a custom movement script or polynav (disable the collidor maybe?), and then be able to get up from the bench and walk to a new point using polynav.

    The only problem with disabling/enabling the collidors to resolve the issue, is that if a character is trying to sit down by disabling the collidor on the bench (to walk to it) while at the same time as another character is walking to another location, that second character may end up walking through the bench.

    So my theoretical solution is to just make them walk to a point outside the collidor, then override polynav and just move the sprite via my AI.
    "PolyNav_GotoDestination1 --> Upon Destination ---> ForceMoveToPosition() ---> Wait 4 seconds ---> PolyNav_GotoDestination2"
     
  41. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hey,

    For your case or similar cases, the best approach would be to disable the PolyNavAgent component instead and not the Obstacle, then enable it back after the character stands up :)
     
    CarterG81 likes this.
  42. CarterG81

    CarterG81

    Joined:
    Jul 25, 2013
    Posts:
    1,773
    What about when the character is IN the collidor, and must then use PolyNavAgent to leave it to follow the new path? (This is what I thought was the problem with Shifty's pathfinding?)

    In the end, I guess that is the best way, to just use two methods of movement. Should be easy enough, since I'm already using Behavior Designer to do all this.
     
  43. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    When the character is already inside the obstacle polygon, you can either enable the PolyNavAgent which will result in the agent getting pushed out of the obstacle and to the closest valid point, or, you can move the agent manualy to the point of desire before enabling it again, if you want fine control, which in most cases you do :)

    I can't speak of Behavior Designer, since Im using NodeCanvas :p
     
    CarterG81 likes this.
  44. CarterG81

    CarterG81

    Joined:
    Jul 25, 2013
    Posts:
    1,773
    That's what I figured at first. I must be confused what Shifty's problem is then.

    Thanks for clearing that up for me.
     
  45. SoftwareGeezers

    SoftwareGeezers

    Joined:
    Jun 22, 2013
    Posts:
    902
    I don't use agents! ;)

    I use PolyNav to get a path, but I follow it with my own code. My ships only have rotate and thrust controls, including the NPCs. I get the path from PolyNav and have my ships fly towards nodes.

    I think it's a mistake to assume the agents are the intention for the use of the path finding, and I hope you can 'liberate' the path finding to make it more useful overall.
     
  46. gumboots

    gumboots

    Joined:
    May 24, 2011
    Posts:
    298
    Hiya!

    Do you think it would be possible to enable the ability to specify which GameObject should receive the sent messages? I've got my Polynav script on a parent class, but I want the messages to end up on a child object. A nice method like SetMessagesReceiver(GameObject) would be nice!
     
  47. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hello SG,

    I can of course understand why you would want to use your own steering code and you can certainly do use PolyNav just for finding paths.
    I have done my best to make the pathfinding indepentant from the agent, but maybe I missed some things.
    Since you are using you own code to traverse the path, one thing you can do is something like this:
    Code (CSharp):
    1. void FindPath(Vector2 goal){
    2.  
    3.     var start = this.transform.position;
    4.     if (!polyNav.PointIsValid(start) )
    5.         start = polyNav.GetCloserEdgePoint(start);
    6.    
    7.     polyNav.FindPath( start, goal, PathFound);
    8. }
    9.  
    10. void PathFound(List<Vector2> path){
    11.    
    12.     path.Insert(0, transform.position);
    13.     currentPath = path;
    14. }
    15.  
    16. void Update(){
    17.     //traverse path
    18. }
    Essentialy you ask a path from the closer edge point instead of the original in case it is not valid and then alter the "returned" path by inserting another position which is the original non valid one.

    This can also be done within PolyNav2D process. so that you avoid this code. Let me know and I will PM you the code changes for that if you want.

    Thanks!

    Hello,

    One thing I could change would be to use BroadCastMessage instead of SendMessage, so that it's more straightforward, but could also be slower of course.
    On the other hand, I can certainly add a SetMessageReceiver(GameObject) like you describe instead of the above :)

    Finaly, if the only messages you need are the OnNavigationReached and/or OnDestinationInvalid, you can as well use the overload SetDestination method which accepts an Action<bool>, to get a callback. For example:
    Code (CSharp):
    1. void FindPath(Vector2 goal){
    2.    
    3.     navAgent.SetDestination(goal, NavCallback);
    4.     //...
    5. }
    6.  
    7. //this is called either when the destination is reached, or it is or became invalid
    8. void NavCallback(bool succeed){
    9.     if (succeed){
    10.         // = OnNavigationReached
    11.     } else {
    12.         // = OnDestinationInvalid
    13.     }
    14. }
    In eithercase, I will go ahead and add a SetMessageReceiver.

    Cheers!
     
  48. gumboots

    gumboots

    Joined:
    May 24, 2011
    Posts:
    298
    Yeah I don't think changing to BroadCastMessage is a good idea, I think a SetMessageReceiver would work really well! Thanks! Also I haven't checked the Asset Store for an update yet, but I'm excited to be able to use BoxCollider2Ds, and am hopeful that I can use a combination of BoxCollider2Ds and PolygonCollider2Ds!
     
  49. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Yeah, SetMessageReceiver will work fine :) If you'd like me to send you the latest version and don't want to wait the asset store, please PM me your invoice and an email to send the package to.

    Cheers!
     
  50. SoftwareGeezers

    SoftwareGeezers

    Joined:
    Jun 22, 2013
    Posts:
    902
    Thanks. I've been doing similar so I'm not sure where the bug is. However, I've found a workaround for my specific use which takes the start and end locations as out-of-limits points and moves them a small distance towards the ship wanting a path. Then the 'closer edge point' is more correct and even outside the no-go zone. Hopefully I won't get the path-finding getting lost again.

    I would still recommend an update to PolyNav to allow out-of-limits waypoints though, so the start and end points are exactly the points as requested. That will be more useful in some games.

    Also, I changed one of your Magnitude tests to SqrMagnitude for performance. There might be a few more such optimisations you can make.

    Edit : Another also! Would it be possible to add a circular collider option? Obviously crossing it could be a serious issue, but for a start or end point, a simple radial distance check should be fast and accurate.