Pathfinding in 2D

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

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 'Super Mario'. This package does unfortunately right now not 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

  • 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 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 can be rotated to work in the XY plane (or any other orientation), however they currently do not support 2D colliders or using sprites as input for the rasterization process. If you use normal meshes it will work.

  • Navmesh graphs work similarly to recast graphs behind the scenes so they also 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.

Graph updates

Navmesh cutting that can be used to update recast and navmesh graphs works in 2D or any other orientation. However make sure that the navmesh cuts are rotated correctly. Navmesh cuts are represented as 2D outlines that are projected down on the graph's surface. If a 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.

2D Colliders

When using graph updates a common way to do this for 3D games is var guo = new GraphUpdateObject(GetComponent<Collider>().bounds);
// change some settings on the object;
For 2D games the corresponding code which uses 2D colliders will not work however. 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
var guo = new GraphUpdateObject(bounds);
// change some settings on the object;

Movement scripts

  • 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. 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 make a simple modification to the AIPath script to force it to use a particular orientation. // In the AIPath.cs script, find the line that looks like
    // movementPlane = graph != null ? graph.transform : GraphTransform.identityTransform;
    // and replace it with
    var graphRotation = new Vector3(-90, 0, 0);
    movementPlane = new GraphTransform(Matrix4x4.TRS(, Quaternion.Euler(graphRotation),;
    The graphRotation variable could of course be changed to any rotation you wish.

  • 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.

  • 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.

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.