Current state of A* with 2D & Tilemaps

Hi all, I’ve been trying out A* as a possible replacement for using NavMeshPlus (which uses the new unreleased/unsupported Unity NavMesh Components). I’d sorta assumed it would be a no-brainer upgrade, after a couple of days playing with A* I’m starting to accept that maybe it just isn’t a good fit for my project though.

Specific issues/confusing moments I’ve hit:

  • A* can only auto-generate pathfinding from a Unity tilemap by using a Grid Graph (because the tilemap colliders are 2D and Recast Graphs need 3D colliders to work). This seems inefficient vs. a navmesh and doesn’t match the world geometry nearly as well even with many thousands of nodes.
  • Tilemaps are often layered in order to put, for instance, a bridge across a river where the river has a collider, bridge is on a layer above without one. I can’t see an obvious way to make the bridge walkable using A* without creating a single layer tilemap world (which would then mean creating more art, would stop me from animating anything going underneath the bridge, etc.).
  • Adding a kinematic Rigidbody to the same GameObject as an AIPath component makes it stutter during pathing movement. Adding the rigidbody on a child GameObject seems to be fine.
  • Making a path go in a straight line was surprisingly difficult … I ended up using the funnel modifier, quality had to be set to high, unwrap is required to be on to work in 2D … all of which is creating a performance overhead.

So, I’m kinda perplexed by all this, it seems like from the forum questions, examples support, that the A* plugin is more focussed on 3D than 2D worlds and that for top-down-2D-using-tilemaps there’s not really a compelling reason to use this over other options. I do understand (I think!) that I could manually build a navmesh in Blender but … I’m not gonna do that.

I don’t mean this at criticism, just curious to get other takes, share some feedback as a new user. If I were working on a 3D project I could see this being really solid. As it is I’m slowly, grudgingly, preparing myself to roll back everything to use NavMeshPlus instead.

Yeah, I find the free version unfortunately limited in some ways. However, it seems that the basic features are open source, while the rest are available for purchase with the pro version on the Unity Asset Store. Considering that’s available, I have no complaints.

With all that said, I did figure out a way to make bridges possible (with the grid graph. May work for others too). To do so, you’re going to need to place a collider on your bridges and give them a specific layer or tag (something that is identifiable from a collision). Then, go to AstarPathfindingProject>Generators>Base, scroll to line 537 (or find the Check function), and edit the physics collider checks to not only see if there was a collision, but if that collision was with a bridge, return true (walkable). Relatively simple after reverse engineering it for… hours.

To make your unit movement less jittery with grid pathing, set a follow distance. Essentially, have the unit move to the next waypoint when it is X distance away from each waypoint. This makes the movement a lot less rigid, but also implements a potential problem. Depending on how big your follow distance is, your units will cut corners, which could be a problem for physics and or graphical reasons. As another option, you could instead create some sort of lerping rotation function that makes units move in their forward direction and rotate toward new waypoints at a less-than-instantaneous rate.

Also, this guy got 2D pathfinding working with a navmesh made in Unity. Not sure if this tutorial is plug-and-play with the A* Pathfinding Project, nor if it is easily applicable in the way you want it, but you can give it a shot!

Yeah, currently there is very little direct integration with tilemaps. The package only uses the 2D physics API to query which parts of the world are walkable and which ones are not.

I’m not quite sure I understand your bridge scenario. Regardless of the visuals the 2D colliders would have to be configured so that the top of the bridge would be traversable, right? And then the package would be able to pick it out?

I would suggest the RaycastModifier (with graph raycasting enabled) which is more suited to that. The FunnelModifier works too I suppose, but it will be more limited (though possibly a bit faster).

Thanks for the replies both, much appreciate the thoughts.

Ah, yup, that would work - nice find! @aron_granberg The ‘bridge problem’ is that you sometimes need to make a higher layer (like a bridge) walkable even though it has an unwalkable collider directly underneath it. Maybe you could include a ‘walkable override’ layer mask in a future asset version to get around this?

Is that different from ‘pick next waypoint distance’ ? I found with larger values agents would easily get stuck on the grid graph geometry, had to use a distance that was a % of the grid unit size to unstick them.

For my current agent setup this made it looks like he was walking up stairs … the longer path was straight but the path segment(s?) close to him would wiggle between nodes … looks like it’s better with ‘highest’ quality setting but, still noticeable.

1 Like

Hmmm, I’m not sure. I’m currently using the basic/open-source version of the project, and I don’t have that option. Or is that an agent option? I’m using my own agent, so that could be another reason why I haven’t seen it.

Hmmm… You might have better luck with other modifiers then. Check out the modifiers page to see if there’s one that might work better for your setup. The smooth modifiers are probably what you want.

That’s an option on the movement script (e.g. AIPath). So if you are using your own movment script you would not see it.

Would it be possible for you to post a video showing this behaviour? That sounds like it might be a bug.

… in my control scheme holding mouse1 sets the target destination, path is continually recalculated as the movement target is continually changing. This is with the raycast modifier on ‘medium’ quality …

Ok, playing around a little more with the settings of the raycast modifier … if I turn off ‘use physics raycasting’ and turn on ‘use graph raycasting’ it works well. Not sure what to make of that :slight_smile:

The only thing I can think about which could cause that to happen is if the raycast modifier is configured to treat the agent itself as an obstacle. Check the layer masks for that component.
Graph raycasting is usually more stable though, so I recommend it.

Sorry for necroing this from 7 months ago. But I encountered the exact same issue as mentioned above. Bridges above water are usually on a separate tilemap layer, but will get detected as obstacles (if the water is an obstacle). My own fix for this doesn’t include code changes. I have a tilemap layer with most of my water (which is an obstacle layer), and then another layer that has ONLY water tiles that are under bridges (that is not an obstacle layer). My bridges are on the same layer as the rest of my ground. This works well. However only downside is that both water tilemaps cannot be using “Chunk” mode, and must be switched to individual to be rendered right…

Just like another poster suggested above, it might be nice to have an option to have an “override” walkable layer, so that the bridge can override the water obstacle layer.