Pathfinding in 2D

This page shows how to get pathfinding working in a 2D game.

Introduction

The package contains 2 example scenes that show 2D setups. They are called Example15_2D and Example16_RVO 2D.

There are many types of pathfinding one could want to do in 2D games. Primarily there are 2 types.

  • Top-down pathfinding. Used in games in which one looks down on the world from above. This is the case in the image above.

  • Platformer pathfinding. Similar to for example classic Super Mario. This package does unfortunately not, at the moment, support this type of pathfinding. One can do quite a lot with point graphs and creating custom connections, but it is not supported out of the box.

This video will walk you through how to create a simple 2D scene with pathfinding.

Graph support

All graphs support pathfinding in the XY plane and support 2D physics.

Grid graphs

The grid graph and layered grid graph has good support for working in the XY plane. In fact grid graphs can be rotated in any direction and they will still work. For 2D games you should check the '2D' toggle on the grid graph which will rotate the graph so that it lines up with the XY plane. If you are using 2D colliders you will also want to enable the 'Use 2D Physics' checkbox.

Point graphs

Point graphs support pathfinding in the XY plane. Similarly to grid graphs you will want to enable the 'Use 2D Physics' checkbox if you have the 'Raycast' setting enabled and you are using 2D colliders.

Recast graphs

Recast graphs can be rotated to work in the XY plane (and any other orientation). If you want to use 2D colliders, you can change the dimensions field to 2D.

The recast graph supports rasterizing normal 3D meshes, 3D colliders and 2D colliders. It does not support rasterizing sprites as meshes at the moment.

Navmesh graphs

Navmesh graphs can similarly be rotated to work in any orientation. However you must take care so that the 'up' direction of the graph corresponds to the desired up direction. For example if you want to use a navmesh graph in the XY plane you need to set the rotation field to (-90,0,0), you cannot simply rotate the mesh in Maya or Blender.

Tilemaps

Both grid graphs and recast graphs have support for tilemaps. Take a look at Pathfinding on tilemaps to learn how to use them for pathfinding.

Graph updates

Graph updates work basically the same in 2D games as in 3D games, however there are a few things that are good to think about.

Navmesh cutting, that can be used to update recast and navmesh graphs, work in 2D and any other orientation.

Note

If you are using one of the legacy navmesh cut modes (rectangle/circle), or your own custom mesh, then you need to make sure that the navmesh cuts are rotated correctly. Legacy navmesh cuts are represented as 2D outlines that are projected down on the graph's surface. If a legacy navmesh cut is rotated incorrectly the 2D outline could be projected down to just a single line and that wouldn't cut the graph in the way you want it to (see the image below). The useRotationAndScale checkbox must always be enabled when using navmesh cutting with a graph that is not horizontal.

Graph updates and 2D Colliders

A common way of performing a graph update in 3D games is something like: var guo = new GraphUpdateObject(GetComponent<Collider>().bounds);
guo.updatePhysics = false;
guo.modifyWalkability = true;
guo.setWalkability = false;
AstarPath.active.UpdateGraphs(guo);
For 2D games, the code requires some minor adjustments before it can work. The reason is that 2D colliders are infinitely thin so the bounds will have a zero volume. Since the graphs check if the nodes' positions are inside the bounds they will never update a single node because no node can be inside something that is infinitely thin. To solve this you can extend the bounds along the Z axis to make sure you cover all nodes. var bounds = GetComponent<Collider2D>().bounds;
// Expand the bounds along the Z axis
bounds.Expand(Vector3.forward*1000);
var guo = new GraphUpdateObject(bounds);
// change some settings on the object
AstarPath.active.UpdateGraphs(guo);

Movement scripts

The included movement scripts have varying support for different graph orientations.

  • The AIPath movement script supports movement in any graph orientation for grid graphs, navmesh graphs and recast graphs, it will orient itself automatically. You may want to disable the 'gravity' setting to prevent the agent from falling off the map.

  • The AILerp movement script supports movement in any graph orientation. For many 2D games you may want the +Y axis to be the forwards direction of the agent instead of the +Z axis as is common in 3D games. If so you can enable the AILerp.orientation checkbox.

  • The FollowerEntity movement script supports movement in any graph orientation, it will orient itself automatically to the graph. You may want to disable the 'gravity' setting to prevent the agent from falling off the map.

  • The RichAI movement script does not support any other orientation than the XZ plane at the moment. However a large part of the work to make it support it has already been done and I expect it to be included in a future update.

2D Movement on Point Graphs

Point graphs have no well defined up direction so the AIPath script cannot know how it is supposed to orient itself. If you know the orientation that you want to use, you can subclass the AIPath component and override the UpdateMovementPlane method to force it to use a particular orientation.

class AIPathSub : AIPath {
protected override void UpdateMovementPlane () {
var graphRotation = new Vector3(-90, 0, 0);
movementPlane = new SimpleMovementPlane(Quaternion.Euler(graphRotation));
}
}
The graphRotation variable could of course be changed to any rotation you wish.

Local avoidance

Local avoidance works in the XY plane. The only thing you have to do is to change the movementPlane setting on the RVOSimulator component to XY. You can take a look at the example scene called "RVO 2D" which shows how an example of how to configure it.