Hex Tilemap Level Editor

Purpose

This level editor was mainly created for a game I had worked on with a small team. In essence, the environmental style of the game required discrete, hexagonal terrains.

Draw hexagon handle

// Draw handles as a hexagon
static void DrawHandlesHex(Vector3 center)
{
    Vector3 offsetX = Vector3.right * hexInnerRadius;
    Vector3 offsetY = Vector3.zero;
    Vector3 offsetZ = Vector3.forward * 0.5f * hexOuterRadius;

    // Set position of 6 points on hexagon
    Vector3 p1 = center + offsetY + Vector3.forward;
    Vector3 p2 = center + offsetY + offsetX + offsetZ;
    Vector3 p3 = center + offsetY + offsetX - offsetZ;
    Vector3 p4 = center + offsetY - Vector3.forward;
    Vector3 p5 = center + offsetY - offsetX - offsetZ;
    Vector3 p6 = center + offsetY - offsetX + offsetZ;

    // Draw lines from point to point to form a hexagon
    Vector3[] hexPoints = { p1, p2, p3, p4, p5, p6, p1 };
    Handles.DrawPolyLine(hexPoints);
}

Add tile

public static void AddTile(Vector3 position, GameObject prefab, bool isOptimizeMode)
{
    if (prefab == null) return;

    // Instantiate tile prefab
    GameObject newTile = (GameObject)PrefabUtility.InstantiatePrefab(prefab);
    // Make tile child of level parent
    newTile.transform.parent = LevelParent;
    // Place tile at current handle position
    newTile.transform.position = position;

    if (!isOptimizeMode)
    {
        // Register undo option for add action
        Undo.RegisterCreatedObjectUndo(newTile, "Add Tile");
    }

    // Mark scene as modified
    UnityEditor.SceneManagement.EditorSceneManager.MarkAllScenesDirty();
}

Remove tile

public static void RemoveTile(Vector3 position, bool isOptimizeMode)
{
    Transform[] tiles = LevelParent.GetComponentsInChildren<Transform>();

    // Iterating through all child of level parent
    // int i = 1 ignores parent transform
    for (int i = 1; i < tiles.Length; i++)
    {
        // Store distance squared from current position to tile
        float distanceToTileSqr = (tiles[i].position - position).sqrMagnitude;

        // If square distance to tile is under threshold square distance
        if (distanceToTileSqr <= 2f * hexDepthRadius * hexDepthRadius)
        {
            // If RemoveTile is used in optimization
            if (isOptimizeMode)
            {
                // Destroy tile, no undo register
                DestroyImmediate(tiles[i].gameObject);
            }
            else
            {
                // Destroy tile and register option to undo destroy
                Undo.DestroyObjectImmediate(tiles[i].gameObject);
            }

            // Mark scene as modified
            UnityEditor.SceneManagement.EditorSceneManager.MarkAllScenesDirty();
            return;
        }
    }
}

Replace tile

public static void ReplaceTile(Vector3 position, GameObject prefab)
{
    if (prefab == null) return;

    if (PositionContainsTile(position))
    {
        // Replace if tiles are not the same
        if (!PositionContainsSameTile(position, prefab))
        {
            RemoveTile(position + Vector3.down * hexDepthRadius, false);
            AddTile(position + Vector3.down * hexDepthRadius, prefab, false);
        }
    }
}

Painting tiles
Erasing tiles
Replacing tiles
Tony Nguyen
Tony Nguyen
Technical Game Designer

Tenacious game developer with an unwavering passion for overcoming game development challenges.