Working with Maps

[info]This tutorial explains how to construct a grid in code. If you want to setup grids in the editor instead, see Working with grids in the editor.[/info]

Maps convert between Unity world coordinates and grid coordinates. They are useful for positioning game objects in the shape of your grid, and for determining what cell corresponds to a world coordinate (for example, to determine which cell the player clicked on).

Each grid type has at least one map provided by default. For example, the map used for flat triangular grids is PointyTriMap. The Grid Index gives the default maps for built-in grids.

Maps are constructed using the constructor(s) provided, and using one of the several modifier functions.

IMap map = new PointyTriMap(cellPrefab.Dimensions)
    .AnchorCellTopLeft() //Anchor before layout!
    .WithWindow(ExampleUtils.ScreenRect)
    .AlignTopLeft(grid2)
    .Translate(10, 10);

The example above assume that your sprites are anchored at the top left. The grid is also aligned to the top left of the screen, with 10 pixels from the top and left edges.

Once constructed, you can use index notation to convert between Vector2 and grid points.

Vector2 worldPoint = map[gridPoint1]; //Converts a grid point to a world point
PointyTriPoint gridPoint2 = map[worldPoint]; //Converts a world point to a grid point

This is not quite what we want; instead, we would like the map to convert to 3D vectors instead of 2D. You can chain either To3DXY or To3DXZ methods at the end to do this. Note that the type of the map is now different.

IMap3D map = new PointyTriMap(cellPrefab.Dimensions)
    .AnchorCellTopLeft() //Anchor before layout!
    .WithWindow(ExampleUtils.ScreenRect)
    .AlignTopLeft(grid2)
    .Translate(10, 10)
    .To3DXY();

Anchoring

By default, maps anchor cells in the center of the cell. If your sprites are anchored differently, you have to specify this in the map. If you do not use a WithWindow layout function, anchoring in different locations does not alter the world coordinates of a grid point, but it does affect how world points are mapped to grid points.

Layout

You can use WithWindow(rect) followed by one of the alignment functions to position a grid relative to the rectangle. The rectangle is specified in world 2D world coordinates. For 2D games, it is often convenient to pass the rectangle that corresponds to the screen. This depends of course on how you set up your camera. In a typical setup the camera is set to orthographic, with its size half the screen height. In this scenario, one pixel corresponds with one Unity unit, and the screen rectangle is given by

Rect screenRect = (-Screen.width/2, -Screen.height/2, Screen.width, Screen.height);

Because the layout functions need to know the grid size, they take the grid as a parameter.

Working with 3D

As mentioned earlier, there are two functions provided to have maps work in 3D: To3DXY (when the grid is in the XY-plane) and To3DXZ (when the grid is positioned in the XZ-plane). For more complicated scenarios, you must provide your own map.

  1. Define a new class My3DMap, and let it implement IMap3D (see Map3DXY in the API documentation for an example). Let it take an IMap as a parameter in it’s constructor, so that you can use 2D maps for the basic calculations.
  2. Provide an extension method for IMap that can be called to construct the map from a 2D map.
//Extension method to construct a My3DMap
IMap3D ToMy3DMap(this IMap map2D, /* some other parameters*/ )
{
  return new MyMap3D(map2D, /* some other parameters */ );
}

Other Uses for Maps

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to Top