private static void SetupSceneGrid(GameObject gridGameObject)
    {
        if (!gridGameObject.HasComponent <ConvertToSimEntity>())
        {
            gridGameObject.AddComponent <ConvertToSimEntity>();
        }

        Grid gridComponent = gridGameObject.HasComponent <Grid>() ? gridGameObject.GetComponent <Grid>() : gridGameObject.AddComponent <Grid>();

        gridComponent.cellSize    = new Vector3(1, 1, 0);
        gridComponent.cellGap     = new Vector3(0, 0, 0);
        gridComponent.cellLayout  = GridLayout.CellLayout.Rectangle;
        gridComponent.cellSwizzle = GridLayout.CellSwizzle.XYZ;

        LevelGridAuth levelGridAuth = gridGameObject.HasComponent <LevelGridAuth>() ? gridGameObject.GetComponent <LevelGridAuth>() : gridGameObject.AddComponent <LevelGridAuth>();

        levelGridAuth.Grid = gridComponent;

        LevelGridSettings globalGridSettings = AssetDatabase.LoadAssetAtPath <LevelGridSettings>(SETTINGS_ASSET_PATH);

        if (globalGridSettings == null)
        {
            Debug.LogError($"Global Grid Settings missing (GridSettings.asset), please create the file in {SETTINGS_ASSET_PATH}");
            return;
        }
        levelGridAuth.GlobalGridSettings = globalGridSettings;
    }
    private static void RevertUnwantedOverrides(LevelGridAuth castedTarget)
    {
        Transform transform = castedTarget.transform;

        ////////////////////////////////////////////////////////////////////////////////////////
        //      Cache Data
        ////////////////////////////////////////////////////////////////////////////////////////
        SimAsset simAsset = castedTarget.PrefabSimAsset;

        // Tilemaps
        TilemapCache[] tilemapCaches = new TilemapCache[transform.childCount];
        for (int i = 0; i < transform.childCount; i++)
        {
            var tilemap = transform.GetChild(i).GetComponent <Tilemap>();
            if (tilemap != null)
            {
                tilemapCaches[i] = CacheTilemap(tilemap);
            }
        }

        ////////////////////////////////////////////////////////////////////////////////////////
        //      Revert
        ////////////////////////////////////////////////////////////////////////////////////////
        PrefabUtility.SetPropertyModifications(castedTarget.gameObject, new PropertyModification[0]);

        ////////////////////////////////////////////////////////////////////////////////////////
        //      Restore
        ////////////////////////////////////////////////////////////////////////////////////////
        castedTarget.PrefabSimAsset = simAsset;

        // Tilemaps
        for (int i = 0; i < transform.childCount; i++)
        {
            var tilemap = transform.GetChild(i).GetComponent <Tilemap>();
            if (tilemap != null && i < tilemapCaches.Length)
            {
                RestoreTilemap(tilemap, tilemapCaches[i]);
            }
        }

        EditorSceneManager.MarkSceneDirty(castedTarget.gameObject.scene);
    }
    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();

        LevelGridAuth castedTarget = (LevelGridAuth)target;

        if (castedTarget.gameObject.scene.IsValid())
        {
            if (GUILayout.Button("Revert Unwanted Overrides"))
            {
                RevertUnwantedOverrides(castedTarget);
            }


            if (GUILayout.Button(castedTarget.PrefabSimAsset == null ? "Generate Asset Files" : "Update Asset Files"))
            {
                GenerateAssetFiles(castedTarget);
            }
        }
    }
    public static void Generate(LevelGridAuth levelGridAuth)
    {
        if (levelGridAuth == null)
        {
            Log.Error($"No {nameof(LevelGridAuth)} found.");
            return;
        }

        if (!levelGridAuth.gameObject.scene.IsValid())
        {
            Log.Error("Can only generate assets for levelGridAuth in scenes");
            return;
        }

        GameObject sceneGrid = levelGridAuth.gameObject;

        string simAssetPath  = GetGeneratedFilePath(sceneGrid, isForView: false);
        string viewAssetPath = GetGeneratedFilePath(sceneGrid, isForView: true);

        // Create & Save Assets
        {
            GameObject simGridPrefab = new GameObject();
            simGridPrefab.AddComponent <SimAsset>();
            simGridPrefab.GetComponent <SimAsset>().HasTransform = true;
            simGridPrefab.GetComponent <SimAsset>().Editor_SetShowGhost(false);
            simGridPrefab.GetComponent <SimAsset>().ViewTechType = ViewTechType.GameObject;

            GameObject viewGridPrefab = new GameObject();
            viewGridPrefab.AddComponent <Grid>();
            viewGridPrefab.GetComponent <Grid>().cellSize    = new Vector3(1, 1, 0);
            viewGridPrefab.GetComponent <Grid>().cellGap     = new Vector3(0, 0, 0);
            viewGridPrefab.GetComponent <Grid>().cellLayout  = GridLayout.CellLayout.Rectangle;
            viewGridPrefab.GetComponent <Grid>().cellSwizzle = GridLayout.CellSwizzle.XYZ;

            SetupSceneGrid(sceneGrid);

            foreach (TilemapRenderer tilemapRenderer in sceneGrid.GetComponentsInChildren <TilemapRenderer>())
            {
                // Simulation Grid doesn't need to be copied in a prefab
                if (tilemapRenderer.sortingLayerName == GameConstants.LAYER_GRID_SIMULATION)
                {
                    continue;
                }

                Tilemap tilemap = tilemapRenderer.GetComponent <Tilemap>();
                if (tilemapRenderer == null || tilemap == null)
                {
                    Log.Error("Grid is invalid since there's no tilemap or tilemaprenderer");
                    continue;
                }

                GameObject tilemapCopy = CloneTilemap(tilemapRenderer, tilemap);
                tilemapCopy.transform.parent = viewGridPrefab.transform;
            }

            PrefabUtility.SaveAsPrefabAsset(simGridPrefab, simAssetPath);
            simGridPrefab.DestroyImmediate();

            PrefabUtility.SaveAsPrefabAsset(viewGridPrefab, viewAssetPath);
            viewGridPrefab.DestroyImmediate();
        }

        // Bind assets
        {
            GameObject simPrefab  = AssetDatabase.LoadAssetAtPath <GameObject>(simAssetPath);
            GameObject viewPrefab = AssetDatabase.LoadAssetAtPath <GameObject>(viewAssetPath);
            simPrefab.GetComponent <SimAsset>().Editor_SetBindedViewPrefab(viewPrefab);
            EditorUtility.SetDirty(simPrefab);

            sceneGrid.GetComponent <LevelGridAuth>().PrefabSimAsset = simPrefab.GetComponent <SimAsset>();
            PrefabUtility.RecordPrefabInstancePropertyModifications(sceneGrid.GetComponent <LevelGridAuth>());
        }

        EditorSceneManager.MarkSceneDirty(sceneGrid.scene);
        AssetDatabase.SaveAssets();

        DebugEditor.LogAssetIntegrity($"Grid Assets Updated");
    }
 private static void GenerateAssetFiles(LevelGridAuth castedTarget)
 {
     GridGenerator.Generate(castedTarget);
 }