
Hexagon grid building tool
This semester, I built a hexagon grid layout in Unity for our sandbox game, right here I want to share my approach to implementing the system.
How Unity Render Mesh
Unity engine uses a Rendering Pipeline to render meshes, which is responsible for managing the various stages involved in rendering 3D graphics, including mesh processing, lighting, shading, and post-processing.
When Unity renders a mesh, it first processes the mesh data to create an optimized representation of the mesh. This includes calculating the vertex positions, normal vectors, and texture coordinates, which are managed by a Mesh Filter component.
Once the mesh data has been processed, Unity applies lighting and shading to the mesh via a component called Mesh Renderer. This involves calculating the lighting and shadowing effects that are applied to the mesh based on the position and intensity of the light sources in the scene.

Draw a hollow hexagon
To render a hollow hexagon, we can divide it into two parts: the outer ring and the inner ring. Vertices on the hexagon ring can be treated as every time a circle's radius rotates 60 degrees we mark a point. The point's position in Vector3 can be denoted as:
Vector3(radius * cos(angle), 0, radius * sin*(angle))

Now we have the position of the vertices, let's take a look at how to draw a hollow hexagon segment without considering its thickness.
In Unity, every mesh is represented by a number of triangles. For example, each hollow hex segment can be treated as two triangles: △AiBoAo and △AiBiBo.


To render a triangle, we need three lists that store the triangle's vertex position, its UVs, and the information on how the vertices are connected respectively.
The vertices list stores the involving vertices' positions in 3D space. The triangle list is a bit more tricky, it's an integer list with a size that can be evenly divided by 3 because every element is representing a vertex in the vertice array at that index, and every three elements represent how a triangle should be formed.
UV list is easier to understand, it should have a length that equals the length of the
vertices list. Each value defines the vertex in the vertices list that shares the same index
as the current UV value its UV position on the texture map. In the above example, we
are assigning pointAi's position on the texture map to be (0,0)

Now we know how to render a triangle, let's try to move to something harder, such as a hexagon segment. Let's define a struct that stores the key information to render a hexagon segment

Take a look back at the hollow hexagon segment and take its thickness into consideration, we can see that each hex segment consists of 4 surfaces.


Luckily, we can see all four faces are quadrilateral, which indicates that there can be a single method that can create a HexSegment object that stores the information of each face.
One thing worth mentioning is that, in Unity, the sequence of the vertices in the rendering vertices array matters because every triangle has a front face and a back face. Taking the right picture as an example, 012 is a counterclockwise rendering sequence, which will induce the triangle to be visible when we are looking at its back (because its front face is facing backward). If we flip the sequence to 210 we will make the triangle face forward.


Above is the helper method I created for calculating relevant information about a face and putting them into a HexSegment data structure. Noticing that it takes a boolean as an input parameter because we need to determine whether the face should face forward by default or backward. With the help of this function, we can find all the required faces for a single hexagon with their key information stored in the HexSegment object.

Last but not least, we need to glue all the segments together by merging their vertice list, UV list, and triangle list.


Result
