[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.
IMapmap = 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.
IMap3Dmap = 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.
- Define a new class
My3DMap
, and let it implementIMap3D
(see Map3DXY in the API documentation for an example). Let it take anIMap
as a parameter in it’s constructor, so that you can use 2D maps for the basic calculations. - Provide an extension method for
IMap
that can be called to construct the map from a 2D map.
//Extension method to construct a My3DMap IMap3DToMy3DMap(this IMap map2D, /* some other parameters*/ ) { return new MyMap3D(map2D, /* some other parameters */ ); }
Other Uses for Maps
- Maps can be used to wrap grids onto various shapes. See for example: How to Use a Rectangular Grid on the Inside of a Torus and Tiling a Sphere with Hexes.
- Maps can change over time. As an example of this, see the function Animate, which is provided as an extension for
IMap
. An example is included with the package to show how to use this. - Maps can be used to calculate UVs so that you can display single textures on over multiple cells.
- Maps can be used to construct meshes for grids. See for example A Quick Hex Mesh Generation Script (with Proper Texturing).
- Maps can be used to sample textures (such as Perlin noise) for procedural content generation.