string SaveTextureToFile(Texture2D tex, string fileName)
    {
        byte[] bytes  = tex.EncodeToPNG();
        string folder = EditorUtilityFunctions.GetGeneratedAssetsFolder();
        string path   = folder + fileName;

        File.WriteAllBytes(path, bytes);
        return(path);
    }
    public static GameObject GenerateNewTilePrefab(string type, Sprite prefabSprite = null)
    {
        string         prefabName = EditorUtilityFunctions.tilePrefix + type;
        string         prefabPath = EditorUtilityFunctions.GetGeneratedAssetsFolder() + prefabName + ".prefab";
        GameObject     tile       = new GameObject();
        SpriteRenderer tileSR     = tile.AddComponent <SpriteRenderer>();

        if (prefabSprite)
        {
            tileSR.sprite = prefabSprite;
        }
        GameObject newPrefab = PrefabUtility.CreatePrefab(prefabPath, tile);

        UnityEngine.Object.DestroyImmediate(tile);

        return(newPrefab);
    }
    void Generate(Texture2D spriteSheet, int[,] mapAsTileIndices)
    {
        // Game specific setup
        if (templateGame == TemplateGame.zelda)
        {
            roomHeight = 11;
        }
        else
        {
            roomHeight = 15;
        }

        // Load Sprites
        var spriteSheetPath = AssetDatabase.GetAssetPath(spriteSheet);

        Sprite[] spriteArray = AssetDatabase.LoadAllAssetsAtPath(spriteSheetPath).OfType <Sprite>().ToArray();

        // Read in the map data
        int height = mapAsTileIndices.GetLength(1);
        int width  = mapAsTileIndices.GetLength(0);

        // Root parent to store rooms and tiles
        Transform root = new GameObject("Level").transform;

        // Rooms for organization
        Transform[,] rooms = null;
        int numRoomsX = width / roomWidth;
        int numRoomsY = height / roomHeight;

        rooms = new Transform[numRoomsX, numRoomsY];
        string     roomPrefabPath = EditorUtilityFunctions.GetGeneratedAssetsFolder() + "Room.prefab";
        GameObject roomInstance   = new GameObject("Room");
        GameObject roomPrefab     = PrefabUtility.CreatePrefab(roomPrefabPath, roomInstance);

        DestroyImmediate(roomInstance);

        //Metroid rooms are grouped together in halls
        Dictionary <char, GameObject> hallsDict = new Dictionary <char, GameObject>();

        string[] hallsMatrix = null;
        if (templateGame == TemplateGame.metroid)
        {
            hallsMatrix = metroidRooms.text.Split(new char[] { '\n' }, System.StringSplitOptions.RemoveEmptyEntries);
        }

        // Now generate all of the rooms
        for (int y = 0; y < numRoomsY; y++)
        {
            for (int x = 0; x < numRoomsX; x++)
            {
                // In zelda, every room is the same size
                if (templateGame == TemplateGame.zelda)
                {
                    GameObject roomGO = (GameObject)PrefabUtility.InstantiatePrefab(roomPrefab);
                    roomGO.transform.position = new Vector2(x * roomWidth, y * roomHeight);
                    roomGO.name             = "Room (" + x + "," + y + ")";
                    roomGO.transform.parent = root;
                    rooms[x, y]             = roomGO.transform;
                }
                //In metroid, rooms are connected
                else
                {
                    char thisRoomChar = hallsMatrix[numRoomsY - y - 1][x];
                    if (!hallsDict.ContainsKey(thisRoomChar))
                    {
                        GameObject roomGO = (GameObject)PrefabUtility.InstantiatePrefab(roomPrefab);
                        roomGO.transform.position = new Vector2(x * roomWidth, y * roomHeight);
                        roomGO.name             = "Room " + thisRoomChar;
                        roomGO.transform.parent = root;
                        rooms[x, y]             = roomGO.transform;
                        hallsDict.Add(thisRoomChar, roomGO);
                    }
                    else
                    {
                        rooms[x, y] = hallsDict[thisRoomChar].transform;
                    }
                }
            }
        }

        // Create a new tile prefab
        GameObject tilePrefab = EditorUtilityFunctions.GenerateNewTilePrefab("NONE");

        // Place tiles on the map
        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                int typeNum = mapAsTileIndices[x, y];
                if (typeNum == 0)
                {
                    continue; // Skip past empty black tile
                }
                GameObject tile = (GameObject)PrefabUtility.InstantiatePrefab(tilePrefab);
                tile.transform.position = new Vector3(x, y);
                tile.transform.parent   = rooms[x / roomWidth, y / roomHeight];
                tile.GetComponent <SpriteRenderer>().sprite = spriteArray[typeNum];
            }
        }

        //Delete Empty rooms
        for (int y = 0; y < numRoomsY; y++)
        {
            for (int x = 0; x < numRoomsX; x++)
            {
                if (rooms[x, y] && rooms[x, y].childCount == 0)
                {
                    DestroyImmediate(rooms[x, y].gameObject);
                }
            }
        }

        // Sort metroid rooms
        if (templateGame == TemplateGame.metroid)
        {
            SortChildrenByName(root);
        }
    }