public void AddCell(CellType cell, HexCoordinates coords) { CellStack stack = GetCellStackFromWorldCoords(coords); if (stack) { // Only trees can be placed on top of grass // So if something else is placed on top of grass, turn the grass into dirt if (stack.Peek() == CellType.Grass) { stack.Pop(); stack.Push(CellType.Dirt); } stack.Push(cell); GenerateMeshes(); } }
// Adds a tree on top of stack if certain criteria are met void AddTree(CellStack cellStack) { if (cellStack.Count() > terrain.waterLevel && (cellStack.Peek() == CellType.Grass || cellStack.Peek() == CellType.Dirt)) { Vector2Int offset = cellStack.indexWithinChunk; Vector3 treePos = transform.position + new Vector3(offset.x * HexMetrics.innerRadius * 2 + offset.y % 2 * HexMetrics.innerRadius, transform.localPosition.y + HexMetrics.height * cellStack.Count(), offset.y * HexMetrics.outerRadius * 1.5f); // Randomly rotate the tree so it looks less uniform float rotation = UnityEngine.Random.Range(0, 359); Vector3 treeRot = new Vector3(0, rotation, 0); TerrainObject tree = GameObject.Instantiate(treePrefab); tree.Init(cellStack.coordinates, offset); tree.transform.SetParent(transform); tree.transform.position = treePos; tree.transform.rotation = Quaternion.Euler(treeRot); terrainObjects[offset.x, offset.y] = tree; } }
void GenerateStackMesh(int x, int z, CellStack stack) { int stackHeight = stack.Count(); Vector2 worldOffset = new Vector2(x + chunk.offsetOrigin.x, z + chunk.offsetOrigin.y); Vector3 center = HexCoordinates.FromOffsetCoordinates(x, z).ToChunkPosition(); center += new Vector3(0, transform.localPosition.y, 0); center += stackHeight * HexMetrics.heightVector; CellType topCell = stack.Peek(); Material topMaterial = getTopMaterial(topCell); List <int> topMaterialSubmesh = getSubmesh(topMaterial); //Generates the horizontal part of the terrain (top of the stack) for (int i = 0; i < 6; i++) { AddTriangleToMesh( center, center + HexMetrics.corners[i], center + HexMetrics.corners[i + 1] ); AddTriangleToSubmesh( topMaterialSubmesh, center, center + HexMetrics.corners[i], center + HexMetrics.corners[i + 1] ); } HexCoordinates[] neighbors = stack.coordinates.GetNeighbors(); Vector3 topCenter = center; //Generates the vertical part of the terrain (sides of the stack) for (int i = 0; i < 6; i++) { center = topCenter; //If we have a neighbor in this direction, check its height //If it is taller than us, ignore it (it will create the vertical wall) //If it is the same height as us, ignore it (we don't need a vertical wall) //If it is shorter than us, create a vertical wall down to its height CellStack neighbor = chunk.GetCellStackFromWorldCoords(neighbors[i]); int neighborHeight = 0; if (neighbor != null) { neighborHeight = neighbor.Count(); } for (int elevation = stackHeight; elevation > neighborHeight; elevation--) { CellType currentCell = stack.PeekAt(elevation - 1); Material sideMaterial = getSideMaterial(currentCell); List <int> sideMaterialSubmesh = getSubmesh(sideMaterial); AddTriangleToMesh( center + HexMetrics.corners[i] - HexMetrics.heightVector, center + HexMetrics.corners[i + 1], center + HexMetrics.corners[i] ); AddTriangleToSubmesh( sideMaterialSubmesh, center + HexMetrics.corners[i] - HexMetrics.heightVector, center + HexMetrics.corners[i + 1], center + HexMetrics.corners[i] ); AddTriangleToMesh( center + HexMetrics.corners[i] - HexMetrics.heightVector, center + HexMetrics.corners[i + 1] - HexMetrics.heightVector, center + HexMetrics.corners[i + 1] ); AddTriangleToSubmesh( sideMaterialSubmesh, center + HexMetrics.corners[i] - HexMetrics.heightVector, center + HexMetrics.corners[i + 1] - HexMetrics.heightVector, center + HexMetrics.corners[i + 1] ); center -= HexMetrics.heightVector; } } }
void GenerateStackMesh(int x, int z, CellStack stack) { int stackHeight = stack.Count(); Vector2 worldOffset = new Vector2(x + chunk.offsetOrigin.x, z + chunk.offsetOrigin.y); Vector3 center = HexCoordinates.FromOffsetCoordinates(x, z).ToChunkPosition(); center += new Vector3(0, transform.localPosition.y, 0); center += stackHeight * HexMetrics.heightVector; CellType top = stack.Peek(); HexCoordinates[] neighbors = stack.coordinates.GetNeighbors(); for (int i = 0; i < 6; i++) { //Generates the horizontal part of the terrain (top of the stack) AddTriangle( center, center + HexMetrics.corners[i], center + HexMetrics.corners[i + 1] ); //Generates the vertical part of the terrain (sides of the stack) CellStack neighbor = chunk.GetCellStackFromWorldCoords(neighbors[i]); //If we have a neighbor in this direction, check its height //If it is taller than us, ignore it (it will create the vertical wall) //If it is the same height as us, ignore it (we don't need a vertical wall) //If it is shorter than us, create a vertical wall down to its height if (neighbor != null) { int neighborHeight = neighbor.Count(); float wallHeight = (stackHeight - neighborHeight) * HexMetrics.heightVector.y; if (wallHeight > 0) { Vector3 wallHeightVector = new Vector3(0, wallHeight, 0); AddTriangle( center + HexMetrics.corners[i] - wallHeightVector, center + HexMetrics.corners[i + 1], center + HexMetrics.corners[i] ); AddTriangle( center + HexMetrics.corners[i] - wallHeightVector, center + HexMetrics.corners[i + 1] - wallHeightVector, center + HexMetrics.corners[i + 1] ); } } else { AddTriangle( center + HexMetrics.corners[i] - HexMetrics.heightVector * stackHeight, center + HexMetrics.corners[i + 1], center + HexMetrics.corners[i] ); AddTriangle( center + HexMetrics.corners[i] - HexMetrics.heightVector * stackHeight, center + HexMetrics.corners[i + 1] - HexMetrics.heightVector * stackHeight, center + HexMetrics.corners[i + 1] ); } } }