Noam Riahi
Noam Riahi

Reputation: 173

Read JSON file before runtime on UNITY

I develop a game and I have a "recorder system" that finds objects by their tags and saves their position and rotation in a JSON file and also saves their tags.

Then I have a scene that creates objects and gives the objects the position and rotation of the objects by the frame we are in.

Now, I want to use a specific prefab for every tag, so I need to read from the JSON what tags I record and to every tag give a prefab, but I want to do that with a SerializeField and I want it to happen before press on play.

Is there a way to read the JSON file and create a list while using a SerializeField before press play?

Upvotes: 0

Views: 666

Answers (1)

derHugo
derHugo

Reputation: 90833

So as said for doing something before entering play mode you could e.g. attach a listener to EditorApplication.playModeStateChanged and check for PlayModeStateChange.ExitingEditMode like e.g.

public static class Example
{
    [InitializeOnLoadMethod]
    private static void Init()
    {
        EditorApplication.playModeStateChanged -= LogPlayModeState;
        EditorApplication.playModeStateChanged += LogPlayModeState;
    }

    private static void LogPlayModeState(PlayModeStateChange state)
    {
        if(state == PlayModeStateChange.ExitingEditMode)
        {
            // TODO
        }
    }
}

In order to do the same right before a build you can implement IPreprocessBuildWithReport.


I would use a ScriptableObject for this so you can simply reference it anywhere you want and do e.g.

[CreateAssetMenu]
public class MyObject : ScriptableObject
#if UNITY_EDITOR
, IPreprocessBuildWithReport
#endif
{
    public List<Whatever>() yourList;

#if UNITY_EDITOR

    // Shared method for serialization
    private void JsonToList()
    {
        string json = /*Wherever you get your json from*/;
        yourList = /*However you deserialize the json into list*/;
        EditorUtility.SetDirty(this);
        AssetDatabase.SaveAssetIfDirty(this);
        AssetDatabase.Refresh();
    }

    // Implementation of the Build-Pre-Processor
    public void OnPreprocessBuild(BuildReport report)
    {
        JsonToList();
    }

    // Implementation for getting all PlayMode enters
    [InitializeOnLoadMethod]
    private static void Init()
    {
        EditorApplication.playModeStateChanged -= LogPlayModeState;
        EditorApplication.playModeStateChanged += LogPlayModeState;
    }
    
    private static void LogPlayModeState(PlayModeStateChange state)
    {
        if(state == PlayModeStateChange.ExitingEditMode)
        {
            // Find all instances of this ScripableObject and call the serialize method on them
            var guids = AssetDatabase.FindAssets($"t:{nameof(MyObject)}");
            foreach(var guid in guids)
            {
                var path = AssetDatabase.GUIDToAssetPath(guid);
                var asset = AssetDatabase.LoadAssetAtPath<MyObject>(path);
                asset.JsonToList();
            }
        }
    }
#endif
}

Upvotes: 2

Related Questions