Exemplo n.º 1
0
    void Execute()
    {
        // Generate new prefabs
        foreach (string type in prefabTypesNeeded)
        {
            GameObject newPrefab = EditorUtilityFunctions.GenerateNewTilePrefab(type);
            prefabDict.Add(type, newPrefab);
        }

        // Update tiles
        foreach (KeyValuePair <string, List <GameObject> > entry in changesToBeMade)
        {
            if (entry.Key == "NULL")
            {
                continue;
            }
            // WALL is fine. NULL is not in the dictionary...

            GameObject prefab = prefabDict[entry.Key];
            foreach (GameObject oldTile in entry.Value)
            {
                if (oldTile == null)
                {
                    continue;
                }

                GameObject newTile = (GameObject)PrefabUtility.InstantiatePrefab(prefab);
                newTile.transform.position = oldTile.transform.position;
                newTile.GetComponent <SpriteRenderer>().sprite = oldTile.GetComponent <SpriteRenderer>().sprite;
                newTile.transform.parent = oldTile.transform.parent;
                DestroyImmediate(oldTile);
            }
        }
    }
Exemplo n.º 2
0
    void Check(Transform root)
    {
        // Load all tile prefab assets into a dict
        prefabDict = new Dictionary <string, GameObject>();
        List <GameObject> prefabs = EditorUtilityFunctions.GetTilePrefabs();

        foreach (GameObject prefab in prefabs)
        {
            string prefabKey = prefab.name.Substring(EditorUtilityFunctions.tilePrefix.Length); // Get the part after Tile_, like WALL
            prefabDict.Add(prefabKey, prefab);
        }

        // Parse input txt file
        string[] prefabByIndexArray = tilePrefabsMap.text.Split(new char[] { ' ', '\n' }, System.StringSplitOptions.RemoveEmptyEntries);

        // Check to see if any new prefabs are needed
        prefabTypesNeeded = new List <string>();
        foreach (string prefabType in prefabByIndexArray)
        {
            if (prefabType == "NULL" || prefabDict.ContainsKey(prefabType) || prefabTypesNeeded.Contains(prefabType))
            {
                continue;
            }
            prefabTypesNeeded.Add(prefabType);
        }

        changesToBeMade = new Dictionary <string, List <GameObject> >();
        foreach (Transform room in root)
        {
            foreach (Transform child in room)
            {
                if (!child.name.StartsWith(EditorUtilityFunctions.tilePrefix)) // Only worrying about tiles
                {
                    continue;
                }
                SpriteRenderer childSpriteRenderer = child.GetComponent <SpriteRenderer>();
                if (childSpriteRenderer == null)
                {
                    continue;
                }
                string idAsString = childSpriteRenderer.sprite.name.Substring(EditorUtilityFunctions.spriteSheetIDPrefix.Length);
                int    id         = int.Parse(idAsString);

                GameObject currentPrefab = (GameObject)PrefabUtility.GetPrefabParent(child.gameObject);
                string     currentType   = currentPrefab.name.Substring(EditorUtilityFunctions.tilePrefix.Length);
                string     targetType    = prefabByIndexArray[id];

                if (currentType == targetType)
                {
                    continue;
                }
                if (!changesToBeMade.ContainsKey(targetType))
                {
                    changesToBeMade.Add(targetType, new List <GameObject>());
                }
                changesToBeMade[targetType].Add(child.gameObject);
            }
        }
    }
    string SaveTextureToFile(Texture2D tex, string fileName)
    {
        byte[] bytes  = tex.EncodeToPNG();
        string folder = EditorUtilityFunctions.GetGeneratedAssetsFolder();
        string path   = folder + fileName;

        File.WriteAllBytes(path, bytes);
        return(path);
    }
    void OnGUI()
    {
        // Check for errors
        if (EditorUtilityFunctions.GetRoomPrefab() != null)// If room prefab exists
        {
            GUILayout.Label("Room prefab already exists!\nScript will not rerun in order to ensure this prefab isn't overwritten. Delete the prefab if you want to regenerate the map.", EditorStyles.boldLabel);
        }
        else if (EditorUtilityFunctions.GetTilePrefabs().Count > 0)// If any Tiles exist
        {
            GUILayout.Label("Tile prefabs already exist!\nScript will not rerun in order to ensure these prefabs aren't overwritten. Delete the prefabs if you want to regenerate the map.", EditorStyles.boldLabel);
        }
        else if (GameObject.Find("Level") != null)
        {
            GUILayout.Label("This scene already has a Level GameObject!\nThe script will not continue.", EditorStyles.boldLabel);
        }
        else
        {
            GUILayout.Label("Generate Map Into Current Scene", EditorStyles.boldLabel);
            GUILayout.Label("", EditorStyles.boldLabel);
            inputMap     = (Texture2D)EditorGUILayout.ObjectField("Input Map Texture:", inputMap, typeof(Texture2D), false);
            templateGame = (TemplateGame)EditorGUILayout.EnumPopup("Game:", templateGame);
            if (templateGame == TemplateGame.metroid)
            {
                metroidRooms = (TextAsset)EditorGUILayout.ObjectField("Room Grouping:", metroidRooms, typeof(TextAsset), false);
            }

            if (inputMap == null)
            {
                GUILayout.Label("Input map texture not provided!\nAdd an input map to run the script!", EditorStyles.boldLabel);
            }
            else if (templateGame == TemplateGame.metroid && metroidRooms == null)
            {
                GUILayout.Label("Room groupings not provided!\nAdd room groupings to continue.", EditorStyles.boldLabel);
            }
            else if (GUILayout.Button("Generate!"))
            {
                Texture2D newSpriteSheet;
                int[,] mapAsTileIndices;
                Parse(out newSpriteSheet, out mapAsTileIndices);

                Generate(newSpriteSheet, mapAsTileIndices);

                Debug.Log("Map Generation Successful! Check your hierarchy view and _GeneratedAssets folder for new content.");
                this.Close();
            }
        }
    }
    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);
        }
    }