gm3 / boom-tools

This is a unity dev tool that can randomize layers, and output VRMs, and erc1155 metadata.
Creative Commons Zero v1.0 Universal
29 stars 8 forks source link

Converting JSON files to empty GameObjects #83

Open gm3 opened 1 year ago

gm3 commented 1 year ago
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;

public class JSONToObjectConverter : MonoBehaviour
{
    [System.Serializable]
    public class JSONData
    {
        public string description;
        public string type;
        public string project;
        public string name;
        public string image;
        public string animation_url;
        public string model_url;
        public List<Trait> attributes;
    }

    [System.Serializable]
    public class Trait
    {
        public string trait_type;
        public string value;
    }

    [MenuItem("Tools/Convert JSON to GameObjects")]
    public static void ConvertJSONFiles()
    {
        string[] filePaths = Directory.GetFiles(Application.dataPath + "/Resources/", "*.json", SearchOption.AllDirectories);

        GameObject masculineParent = null;
        GameObject feminineParent = null;

        foreach (string filePath in filePaths)
        {
            string jsonContent = File.ReadAllText(filePath);
            JSONData jsonData = JsonUtility.FromJson<JSONData>(jsonContent);

            // Find the "Body" trait
            Trait bodyTrait = jsonData.attributes.Find(trait => trait.trait_type == "Body" && (trait.value == "Masculine" || trait.value == "Feminine"));

            if (bodyTrait != null)
            {
                // Create parent objects for "Body" trait values "Masculine" or "Feminine"
                if (bodyTrait.value == "Masculine" && masculineParent == null)
                {
                    masculineParent = new GameObject(bodyTrait.value);
                }
                else if (bodyTrait.value == "Feminine" && feminineParent == null)
                {
                    feminineParent = new GameObject(bodyTrait.value);
                }

                GameObject parentObject = bodyTrait.value == "Masculine" ? masculineParent : feminineParent;

                foreach (Trait trait in jsonData.attributes)
                {
                    if (trait.trait_type != "Body")
                    {
                        GameObject traitObject = FindChildByName(trait.trait_type, parentObject) ?? new GameObject(trait.trait_type);
                        traitObject.transform.SetParent(parentObject.transform);

                        // Check if a child with the same value already exists
                        if (FindChildByName(trait.value, traitObject) == null)
                        {
                            GameObject valueObject = new GameObject(trait.value);
                            valueObject.transform.SetParent(traitObject.transform);
                        }
                    }
                }
            }
        }

        Debug.Log("Conversion complete!");
    }

    public static GameObject FindChildByName(string name, GameObject parent)
    {
        Transform[] allChildren = parent.GetComponentsInChildren<Transform>(true);
        foreach (Transform child in allChildren)
        {
            if (child.name == name)
            {
                return child.gameObject;
            }
        }
        return null;
    }
}
gm3 commented 1 year ago

Here's a breakdown of how the script works:

First, the script defines two classes: JSONData and Trait. These are used to model the structure of the JSON data that you provided. Each JSONData object contains a list of Trait objects.

In the ConvertJSONFiles function, the script first gets all the file paths of .json files in the Resources folder.

The script then creates two GameObject variables, masculineParent and feminineParent, which will serve as the top-level parent objects for the masculine and feminine bodies.

For each file path in the list, the script reads the file content and deserializes it into a JSONData object.

The script then finds the Trait in the JSONData object where the trait type is "Body" and the value is either "Masculine" or "Feminine". If such a trait is found, the script creates the appropriate parent GameObject (if it hasn't been created yet).

For each Trait in the JSONData object that is not "Body", the script creates a child GameObject under the appropriate parent (masculine or feminine) for the trait type, if it doesn't exist yet, and a child GameObject under the trait type for the trait value, if it doesn't exist yet.

The FindChildByName function is a helper function that searches for a child GameObject with a given name under a given parent GameObject. If such a GameObject is found, it is returned; otherwise, null is returned.

Once all the Trait objects in the JSONData have been processed, the script moves on to the next file path. When all the file paths have been processed, the function logs "Conversion complete!" to the console.

In summary, this script goes through each .json file in the Resources folder, deserializes the file content into a JSONData object, and creates a hierarchy of GameObjects based on the traits in the JSONData object. The hierarchy is structured such that there are two top-level parent GameObjects, "Masculine" and "Feminine", and under each parent, there are child GameObjects for each trait type, with further child GameObjects under each trait type for each trait value.

gm3 commented 1 year ago

This was created for specific project but need to port it to boom-tools importer, this version looks for 2 main classes in the Body trait, specific JSON data, and uses that for specific nesting, so have to make it work more modular, and perhaps have some options to on which triats string names would be the Parent->Trait_type->Value structure