Beispiel #1
0
    // Converts the top cell to sand if certain criteria are met
    // This modifies terrain based on neighbor stacks
    // Thus it should only be called after all cell stacks are generated
    void AddSand(CellStack cellStack)
    {
        if (cellStack.Count() == terrain.waterLevel)
        {
            HexCoordinates[] neighbors = cellStack.coordinates.GetNeighbors();
            for (int i = 0; i < 6; i++)
            {
                CellStack neighbor = GetCellStackFromWorldCoords(neighbors[i]);

                // The neighbor cell stack might not be in this chunk
                if (neighbor == null)
                {
                    TerrainChunk neighborChunk = terrain.GetChunkFromWorldCoords(neighbors[i]);
                    if (neighborChunk != null)
                    {
                        neighbor = neighborChunk.GetCellStackFromWorldCoords(neighbors[i]);
                    }
                }

                if (neighbor != null)
                {
                    if (neighbor.Count() < terrain.waterLevel)
                    {
                        cellStack.Pop();
                        cellStack.Push(CellType.Sand);
                        break;
                    }
                }
            }
        }
    }
Beispiel #2
0
    CellStack CreateCellStack(int x, int z, int height)
    {
        CellStack      cellStack        = ScriptableObject.CreateInstance <CellStack>();
        HexCoordinates coords           = HexCoordinates.FromOffsetCoordinates(x + (int)offsetOrigin.x, z + (int)offsetOrigin.y);
        Vector2Int     indexWithinChunk = new Vector2Int(x % size, z % size);

        cellStack.Init(coords, indexWithinChunk);
        cellStack.Push(CellType.Bedrock);

        int numStoneTiles = (int)(height * terrain.stoneHeightPercentage);

        // Generate terrian based on stack height
        for (int i = 0; i < height; i++)
        {
            CellType newCell;

            if (height >= terrain.waterLevel - 1 && i == height - 1)
            {
                newCell = CellType.Grass;
            }
            else if (i < numStoneTiles)
            {
                newCell = CellType.Stone;
            }
            else
            {
                newCell = CellType.Dirt;
            }

            cellStack.Push(newCell);
        }

        if (showCoordinates && gridCanvas != null)
        {
            Vector3 position = cellStack.coordinates.ToChunkPosition();
            position += HexMetrics.heightVector * (cellStack.Count() + 1);

            Text label = Instantiate <Text>(terrain.cellLabelPrefab);
            label.rectTransform.SetParent(gridCanvas.transform, false);
            label.rectTransform.anchoredPosition3D = new Vector3(position.x, position.z, -position.y);
            label.text = cellStack.coordinates.ToStringOnSeparateLines();
        }

        return(cellStack);
    }
Beispiel #3
0
    // 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;
        }
    }
Beispiel #4
0
    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;
            }
        }
    }
Beispiel #5
0
    private void TouchCell(TerrainChunk chunk, HexCoordinates coords)
    {
        try {
            CellStack stack = chunk.GetCellStackFromWorldCoords(coords);

            ghostCellPrefab.SetActive(true);

            Vector3 ghostPosition = stack.coordinates.ToWorldPosition(terrain) + HexMetrics.ScaledHeightVector(terrain) * stack.Count();
            ghostCellPrefab.transform.localPosition = ghostPosition;
        }
        catch (NullReferenceException e) {
            Debug.LogWarning("Trying to access null cellstack");
        }
    }
    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]
                    );
            }
        }
    }