Search Unity

SimplePath - Advanced Pathfinding for any Game Genre - RELEASED

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

  1. pated

    pated

    Joined:
    Jun 27, 2012
    Posts:
    31
    Thanks for such a quick response. :)

    Yes, sorry. The camera moves like in a vertical shooter, just like in Air Attack HD for instance (but instead of a plane you play as a character, on the ground). The camera keeps moving forward (so the Z axis).
    However, creating a unique pathgrid covering the entire level is not possible performance wise. I have to use a small pathgrid (with a reasonable Z lenght) that I reposition on the Z axis every x seconds to stay within the camera's field of view.

    All ai characters/agents "appear" just before entering the frame and are "deleted" when they are no longer visible by the camera. Their only behavior is chasing the player when he gets too close.

    I don't think so. Unless I misunderstood something on how Simplepath works! ^^

    Well, visible characters/agents need to be moving all the time with a replanning interval of 1 second. Is it a problem?

    Thanks for your help!
     
  2. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    There are two ways that you can change this behavior. Take a look at ObstacleGridComponent.cs This is a component on the grid, and it is responsible for looking at all obstacles in the game, in order to tell the grid which cells are obstructed. The component looks at any game object with a FootprintComponent. In other words, the "footprint" attached to an obstacle, represents the space that that obstacle will occupy, when it comes to pathfinding. Here are your two options:

    1. Modify the Rasterize function ObstacleGridComponent.cs.
    2. Inherit from ObstacleGridComponent, and override the Rasterize() function with your own implementation.

    I know someone else did this exact same thing for their game, and posted their solution in this forum thread somewhere, so you could try searching through the thread to find their solution. I think there post was in the first half of this thread.
     
  3. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    Parent the grid's transform to the camera's transform. In other words, the grid will always be moving with the camera. All SimplePath positional calculations are made relative to the grid origin, so this should just work.

    ex: pathGridComponent.gameObject.transform.parent = camera.gameObject.transform;

    So when you play your game with the debug grid view turned on, it should appear as if the grid is staying in the same location. When you are determing the destination for an agent, you should be picking positions inside this grid. Also, you should be using the MoveToGameObject function most likely, since your gameobjects will be moving with the camera, and this way when the replan occurs after 1 second, they will look at the updated position of their gameobject target, and move to that, rather than the static world position that they would be after with MoveToPosition.

    Also note that SimplePath clamps all position to be within the grid space. So if an agent requests to path to somewhere outside of the grid, it clamps the destination to the nearest location inside the grid. If the agent requests to path to a destination inside the grid, but the agent is outside the grid, then the agent will first move to the location nearest him inside the grid, and then move to his destination.
     
  4. pated

    pated

    Joined:
    Jun 27, 2012
    Posts:
    31
    Thanks Alex.
    That's one of the first things I tried. But like I said the problem is that the grid is moving but the agents keep moving within the original/start position of the grid. The agents don't care about the new coordinates of the grid.
    Also, with a pathgridwithobstacles, the new obstacles are not detected by the grid as it moves forward.

    That's what I really don't understand. Maybe I didn't understand everything you said!

    Oh, by the way, my agents are using MoveToGameObject already.

    If moving the grid isn't possible I'll just use an obstacle avoidance with raycast. ^^
     
  5. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    If the position of the obstacles changes, you can call Raserize() on the obstacle grid component, and it will recalculate the the blocked cells based on the new positions of the obstacles. If the grid is very large, it can be expensive to call rasterize, so be careful how frequently you call this function. But if your grid is small, you could just set a time interval and rasterize the grid every half second or so. There's also an option to rasterize the grid every frame, if you like. If you really need this to be speedy, you can optimize the obstacle grid component by writing some code to only re-rasterize the cells that have changed since that last rasterize call.
     
  6. simonheartscake

    simonheartscake

    Joined:
    Jan 27, 2012
    Posts:
    8
    Great script. Thanks :D
     
    Last edited: Jul 4, 2012
  7. pated

    pated

    Joined:
    Jun 27, 2012
    Posts:
    31
    Thanks.
    It's not the problem. : ( As I keep saying, the grid is moving but the agents keep moving within the original/start position of the grid. They don't care about the new coordinates of the grid. Same thing for the obstacles. Calling Rasterize() won't help as it rasterizes the obstacles within the original position of the grid only, even when the grid is elsewhere. I think I'm missing something... I don't know.

    I'm just going to use a simpler obstacle avoidance. Thanks for your time!
     
  8. Flatlander

    Flatlander

    Joined:
    Jul 4, 2012
    Posts:
    1
    Hey Alex,

    First I like to say I'm very impressed with your support on these forums, very awesome.

    I'm working on a 3D space sim (think Homeworld) and am planning on creating a new terrain rep using the pathgrid style and was hoping I could run my ideas past you first so you can point out any "gotchas" you see before they sneak up on me.

    I'm planning to create a new Grid.cs to include info for the Y axis, thus allowing for rows, columns, and stacks to create a fully 3D grid. Then a new Pathgrid.cs will change the neighbor directions for Top and Bottom and add a Front and Back, mostly for my own sanity in variable names.

    From there because of the way the A* stuff is written it shouldn't really change the way things work there and the path should still be found.

    Do you see any glaring things I should look out for? Or perhaps have a better idea of how I should approach this.

    Thanks in Advance.

    P.S. I just realized I was making a bit of an assumption that you knew what I was talking about with the Homeworld reference. Basically it's a classic RTS but in the realm of space so 3 dimensional travel is possible. You can raise or lower the ships without changing your X or Z locations. Items such as Debris and Asteroids will be scattered throughout the levels which will need to be navigated around by the various units in the game. Thanks again!
     
  9. ina

    ina

    Joined:
    Nov 15, 2010
    Posts:
    1,084
    Does pathfinding work for terrain or geometry that changes at runtime?
     
  10. whiterook

    whiterook

    Joined:
    Sep 20, 2011
    Posts:
    25
    You can watch the videos?
     
  11. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    Yes.
     
  12. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    This sounds viable to me. though, I have never worked on a game that used a 3D grid for pathfinding; anytime there was this requirement and the terrain representation was a grid, I just sort of faked it by having multiple layers of grids stacked on top of one another, and then making the agents somewhat intelligent about switching between layers.

    One think you may also need to modify, is the hueristic computation, which you can find in the function GetHCost().

    Also, how are you planning on handling obstacle avoidance? One thing that I try to remind everybody is that it is difficult to use planning to handle obstacle avoidance. There are three components to navigation: 1. planning, 2. obstacle avoidance, and 3. collision response; use those three categories of navigation as tools to solve your problem. For example, sometimes planning a path around an object is best, sometimes sliding off it is best, and sometimes it's best to write code to have the agent attempt to steer away from the object.
     
  13. darthbator

    darthbator

    Joined:
    Jan 21, 2012
    Posts:
    169
    I had a question that might be outside of the "scope" of general simple path support but I figured I would toss it out there anyways and see if anyone could help. I was trying to tackle movement of small groups. I figured the most efficient way to do this would be to have each group member path down the path with a different offset. The only issue I was worried about was guys getting caught on objects (which if I rasterize them into the grid should not be an issue right?). I was also wondering what the general method of setting up groups would be. I'm not using this for an RTS however that would be the closest analog to what I am thinking of.

    I gotta imagine this is a fairly common issue that would have an equally common solution. Thanks a lot for any help you guys might be able to provide!

    I did find this information about flocking and boids

    http://www.unifycommunity.com/wiki/index.php?title=Flocking

    I was starting to look in that direction but figured I could stop and work on another facet of the title while I let the community take a look at this so I could get pointed to "true North" for this particular issue.
     
    Last edited: Jul 10, 2012
  14. malcroff

    malcroff

    Joined:
    Jul 3, 2012
    Posts:
    4
    I have a similar problem to this (I think). My game is 2D tile based and the player should move along the X and Y coordinates, but in your prefabs the grid is set on the x and z coordinates, and I can't rotate it to fit my game. What should I do?
     
  15. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    You could change the axies in your game to match the axies used by SimplePath, which is also the same coordinate system used by Unity. Otherwise, you would need to transform two things (I did this for another game I worked on): 1) all points fed into SimplePath need to be transformed from your coordinate system, into simplepath's coordinate system. 2) all points output by simplepath need to be transformed from simplepath's coordinate system, into your coordinate system. The input points are the destination points, such as when you call MoveToPosition( dest ). The output points, are the points that are sent into the SteeringAgentComponent, in order to start steering along a path.
     
  16. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    It really depends on the nature of your game, and how you want the agents to act. Your solution may work for your game, or you may need something more complex.

    Chris Jurney wrote a good article on pathfinding for squads, and I think his implementation is the most solid I've seen, but you might not need something as robust as what he did. Basically what he did was he had a squad leader that would decide where the squad would move. Then, all the other members of the squad would have a formation slot behind the leader, and they would pathfind to that formation slot. Keep in mind the formation slot is always moving, because it is a position relative to the squad leader, which is also always moving. There were other more complicated rules, but that was the basic idea.

    Also, you can use collision response to help you. If two guys collide, make them slide off one another in their OnCollide or OnHit callbacks.
     
  17. Boji

    Boji

    Joined:
    Jul 10, 2012
    Posts:
    44
    Hi, just got Simple Path and I have a question: How can I get an Vector3 array of the points in the path planned betwen my agent and a position?

    Thank you.
     
  18. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    In SteeringAgentComponent.cs:

    m_path.Points
     
  19. Boji

    Boji

    Joined:
    Jul 10, 2012
    Posts:
    44
    Thank you for the quick response, works great, but I have a problem, first time it gets used in-game it always throws a "NullReferenceException: Object reference not set to an instance of an object", after that no problems.

    This is how I use it in a OnControllerColliderHit function:
    Code (csharp):
    1.  
    2. if (m_navigationAgent.MoveToGameObject(target, float.MaxValue)) {moveTarget=m_steeringAgent.m_path.Points[1];}
    3.  
    Should I only use it in an update function?

    Also do I need to have a steering agent component to get the points? Can't I acces them trough the Path or Navigation Agent? I use a character controller to move and don't need the steering.
     
  20. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    If you are only using pathfinding, then yes you can get the list of resulting points from elsewhere. Look in the NavigationAgentComponent.cs, and look to see where it calls SteerAlongPath on the steering agent component. The list of points that it passes, is the list of points that you want. You may need to cache a reference to the list of points here, since the SteeringAgentComponent is currently the only component that caches a reference to the smooth path (notice the NavigationAgentComponent performs the path smoothing). If you just need the rough path, you can access this from the PathAgentComponent, or from the PathRequest. But most likely you will need to cache a reference to the smooth path in the NavigationAgentComponent, and then access is from there.

    MoveToGameObject returns true if the request succeeds, but the path variable is not set until the OnNavigationRequestComplete is called (the solution path is passed to this function). In other words, you need to wait a few frames for the pathfinder to solve the path, and then you can access the solution path.
     
  21. malcroff

    malcroff

    Joined:
    Jul 3, 2012
    Posts:
    4
    Is it possible to change animations depending on the direction of the agent? Something like pacman. Or maybe if there is a way to get all the segments of the path and calculate angle? Is this possible?
     
  22. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    Yes this is possible. Your animation system should be separate from your navigation system. You could simply look at the direction of the agent, or look at other things like the angle in the path, the velocity of the agent, etc., to determine which animation to play.
     
  23. jorchrl1

    jorchrl1

    Joined:
    Jul 15, 2012
    Posts:
    14
    Hello, i just bought your package, its amazing how easy to use it is, however i would like to know how can i make an agent prefab or how to set the PathManagerComponent and the PatrolNodes via code as my brain totally refuses to figure out how hehehehe, thanks!
     
  24. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Het Alex.
    A quick question here. How would I know if an agent has reached it's destination?
    I could do this in other ways, but I wonder if SimplePath has something for it allready.
    Thanks
     
  25. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    OnNavigationRequestComplete is a message that is sent to the agent when he reaches his destination. So, any component on the agent will receive this message. (ex: look at the NavigationAgentComponent, or one of the Interaction scripts). m_bNavigationRequestComplete is set to true when his request is over; in other words, if he reached his destination, or if the request failed for some reason.
     
  26. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    Go here

    Read the "Agent" section, and then read the "Creating Your Own Agent" section.
     
  27. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Ok Alex. Thanks fo reply.
    By the way: Do you plan on making any update to SimplePath, adding all the good stuff that's been discussed and now being scatered in this thread, as well as possible some other?
     
  28. jorchrl1

    jorchrl1

    Joined:
    Jul 15, 2012
    Posts:
    14
    hi thanks for the answer however thats not what i meant, i had already read the user manual, what i meant is that i want this prefabs to instantiate on gameplay time so i need to set the PathManagerComponent and the PatrolNodes with a script, to be more specific i can't "Get" this components with GetComponent(), sorry if i seem so "basic" but i'm not a programmer, and the available documentation doesn't make things clear to me :)
     
  29. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    I'm open to suggestions for updates. What do you have in mind?
     
  30. jorchrl1

    jorchrl1

    Joined:
    Jul 15, 2012
    Posts:
    14
    it would be nice to have a way to create agents on game time, and set them up(via code), or if its already possible you should make a tutorial as part of the user's manual! :)
     
  31. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    Hm..Ok here are my suggestions since you asked :p

    Support for non square obstacles
    A visual way to define traversal costs on the grid
    A raycast simplifier
    Bit better steering

    Happily raise the price if you get those in :-D
     
  32. tezer86

    tezer86

    Joined:
    Jul 19, 2010
    Posts:
    90
    Hey Guys,

    Just bought this and having loads of fun with it!

    I have just been looking over all the previous threads to see if I can get this to work, its also interesting to see what people are doing with it!

    I tried the code below as it was posted that this was meant to do exactly the thing I want,

    However my knowledge of C# is terrible as I program in Java. I actually don't know what classes to include on the top of the code or anything! I know its pretty bad. Would it be possible for you to spell it out a bit more so people can just drop it on a C# script and it works.

    Im sure other people with severe C# deficenies would benefit from this.


    Again LOVE this asset!

    cheers
     
  33. yemo

    yemo

    Joined:
    Jul 18, 2012
    Posts:
    4
    i bought your packet, can you help me about it ...need to translate the actor_patrol allways in axis Z, or forwards
     
  34. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    You could change the axies in your game to match the axies used by SimplePath, which is also the same coordinate system used by Unity. Otherwise, you would need to transform two things (I did this for another game I worked on): 1) all points fed into SimplePath need to be transformed from your coordinate system, into simplepath's coordinate system. 2) all points output by simplepath need to be transformed from simplepath's coordinate system, into your coordinate system. The input points are the destination points, such as when you call MoveToPosition( dest ). The output points, are the points that are sent into the SteeringAgentComponent, in order to start steering along a path.
     
  35. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    Unfortunately I don't have time to write customized scripts for you, but I can help you with the process. The only function you should have to create with that code you pasted above, is the ScoreChaseObjectPriority function. If you are getting compile errors, maybe you could report then and I could help you fix them?
     
  36. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    I haven't made any updates to this package in a while, hmm maybe I will make a few more examples and improvements over the weekend. Here's what I have in mind.

    1. Improved steering. This means better control over turning (such as turn acceleration and deceleration).
    2. Collision response. Effectively, this means better steering, because agents will sort of push one another and slide off one another, preventing them from getting stuck as often.
    3. Coroutines for all navigation calls. This will make the interface cleaner in my mind, but all the old interfaces will still exist.
    4. Point and click navigation demo. You click somewhere in the world, and the agent travels to that location.
    5. Prioritized target demo. The agent will chase after the target that he decides best, based on a simple distance heuristic. In other words, he will chase after the guy nearest himself.
     
  37. tezer86

    tezer86

    Joined:
    Jul 19, 2010
    Posts:
    90
    Thats great, I wasn't asking for you to write scripts for me, what you have posted is great. I will give at a go and let you know what happens.

    Plus I just read your proposed changes. The sound great, I think it would be a good upgrade for the chase integration to have an array of game objects that you can list and a distance you can set for it to start following them.
     
    Last edited: Jul 19, 2012
  38. nuverian

    nuverian

    Joined:
    Oct 3, 2011
    Posts:
    2,087
    The improvments you mentioned sound nice. I dont know what you have in mind for the collision response, but I guess will be better than the sliding :)
    By the way. Do the OnNavigationRequestSucceeded have to continuesly been sent, or could it be sent only once?
    thanks
     
  39. RARoadkill

    RARoadkill

    Joined:
    Jul 17, 2012
    Posts:
    2
    Hey, love Simple Path, has made my life much easier.
    I have been having one issue. My enemies use the pathfinding to get to targets in the game world. When they destroy the target I change the pathfinders target. Randomly I get this error.

    "MissingReferenceException: The object of type 'GameObject' has been destroyed but you are still trying to access it."

    from what I can figure out it seems to put out a call to the old object before a new target has been reassign. What I need to do is add something into the path code to make it shut off when it doesn't have a target. Where would I put such a call.
     
  40. Gun Slinger

    Gun Slinger

    Joined:
    Jun 26, 2012
    Posts:
    58
    I have a question do you use a FSM or do you use the Update function?
     
  41. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    Call CancelActiveRequest on the NavigationAgentComponent before the GameObject is destroyed.
     
  42. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    I may not understand the question. All of the planning is time-sliced, and everything gets updated in the Update function of the PathManagerComponent. More specifically, each frame X number of A-Star steps are solved for all or most of the active path requests. You have tunable control over X, so that you have control of the performance hit that planning incurs. I don't use any FSMs.
     
  43. theLittleSettler

    theLittleSettler

    Joined:
    Jul 14, 2012
    Posts:
    36
    Hey,

    Does this work with trees painted on the terrain?
     
  44. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    Yes, that shouldn't affect anything in SimplePath.
     
  45. Gun Slinger

    Gun Slinger

    Joined:
    Jun 26, 2012
    Posts:
    58
    I meant do you use the Update funciton that is void Update or do you use a update system that you made such as a Finite State Machine(don't know if this is how you spell it)
     
  46. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    The update function on the PathManagerComponent calls the update function into my own system. The PathManagerComponent is a MonoBehavior. So the whole system is driven by Unity's Update function, which is the signal to tell my system that a frame has passed, and that it is okay to proceed with more processing.
     
  47. bugzilla

    bugzilla

    Joined:
    Dec 9, 2008
    Posts:
    196
    I am working in Javascript attempting to integrate SimplePath into my script. After reading the manual and adding the appropriate script components, I attempted to call the "MoveToPosition" method of the "NavigationAgentComponent". Usually, I get a component like this:

    Code (csharp):
    1. var navicomponent:NavigationAgentComponent;
    2. navicomponent=this.GetComponent("NavigationAgentComponent");
    But when I try that with SimplePath I get the error "NavigationAgentComponent does not denote a valid type"

    Any ideas how to fix this?
     
  48. nuverian

    nuverian

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

    I have 2 questions if you don't mind.

    1) For some reason MoveToPosition allways returns true even if the agent can't go to the target position. Is that normal? :p
    2) How do I actually check if an agent is able to go to a target position and then decide what to do. I want to iterate through some possible target positions to find and use the closest to the agent and then MoveToPosition him.

    Thanks Alex

    -edit: this auto documanted api is so hard to read :p
     
  49. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    In which script does that code you wrote exist? It needs to exist in a component that is attached to the same GameObject with the NavigationAgentComponent, is this the case?
     
  50. alexkring

    alexkring

    Joined:
    May 5, 2011
    Posts:
    368
    1. The MoveToPosition request returns true if the initial request succeeded, but this does not mean that the request as a whole succeeded. OnNavigationRequestFailed will be called if ultimately the request fails because the agent cannot reach his destination.

    2. You could make a request into just the pathfinding system, if you would like to see if a path exist between two positions. Take a look at the NavigationAgentComponent code to see how it is making path requests. The NavigationAgentComponent is a communication layer between the agent, and the pathing and steering. The pathfinding system can stand alone and handle such queries itself.

    If you are attempting to intelligently select target positions, I would create a separate component, name something like TargetSelectionComponent, that is responsible for selecting good target positions for your agent. It would make path requests to check for valid destinations, and do things related to finding a good target position for the agent. Once a good target position is selected, it can pass that along to the NavigationAgentComponent, and begin the navigation process.