Jump to content

Stop import for a big operations!


antonidiuss

Recommended Posts

I think that when Gaia uses editing a lot of file one after another - there shold be using of Batching. But I have a question and do not expect answer.

https://docs.unity3d.com/ScriptReference/AssetDatabase.StopAssetEditing.html
https://docs.unity3d.com/Manual/AssetDatabaseBatching.html

image.png.5105dbf3e71acef41ecb7c5f34cae1cd.png

 

Someone know why after using batching importing still continues? I made custom script that uploads scene, executes chosen spawners, saves and unloads for a multiple terrains one after another. Any idea make it faster? 

 

using Gaia;
using System;
using System.Collections;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.SceneManagement;
#endif
using UnityEngine.SceneManagement;
using UnityEngine;
using UnityEngine.Events;


[ExecuteInEditMode]
public class AutogenerationControlBiome : MonoBehaviour
{
#if UNITY_EDITOR
    public bool BiomeLogging = false;
    public bool CheckMeToStartSpawns = false;
     

    [Space(12)]
    [SerializeField] [TextArea] string IgnoreTerrains = string.Empty;
    [SerializeField] bool DoTerrainsFromList = false;
    [SerializeField] [TextArea] string DoTerrains = string.Empty;
    [Space(11)]
    [SerializeField] bool DoTerrainsFromRectangle = false;
    [SerializeField] Vector2Int RectangleBottomLeftCoord = Vector2Int.zero;
    [SerializeField] Vector2Int RectangleSize = Vector2Int.one;
    [Space(10)]

    [SerializeField] List<BiomeController> BiomeList;
    [SerializeField] List<Spawner> Spawners;
    [SerializeField] int TerrainsSize = 256;
    [SerializeField] Vector2Int OriginOffset = new Vector2Int(80, 80);
    
    
    UnityEvent<Vector2Int> SpawnEndEvent = new UnityEvent<Vector2Int>();

    List<Vector2Int> ignoreTerrainsCoords = new List<Vector2Int>();
    List<Vector2Int> doTerrainsCoords     = new List<Vector2Int>();
    public List<Vector2Int> alreadyCreatedCoords = new List<Vector2Int>();


    private static readonly string PATH_SCENES_FOLDER = "Assets/Gaia User Data/Sessions/GS-20220527 - 155930/Terrain Scenes/";

    private Scene currentTerrainScene;
    private DateTime startTerrainTime;

    Vector2Int curTerrainInWork;
    void Update()
    {
        InitScriptEssentialsData();


        if (CheckMeToStartSpawns)
        {
            CheckMeToStartSpawns = false;
            AssetDatabase.StartAssetEditing();  
            TrySpawnNextTerrain();
        }
    }

    void InitScriptEssentialsData()
    {

        //events



        //data
        ignoreTerrainsCoords = GetTerrains(IgnoreTerrains);
        doTerrainsCoords = GetTerrains(DoTerrains);
    }



    IEnumerator SpawnBiomesOnLocal(Vector2Int currentCoords) //TODO possible change to task for parallel computing 
    {
        startTerrainTime = DateTime.Now;
        Debug.Log($"Start spawn biomes on land {currentCoords.x}_{currentCoords.y} at {startTerrainTime}");
        Spawners[0].OnSpawnFinished += OnSpawnersEnd; 
        foreach (var spawner in Spawners)
        {

            if (spawner == null)
                continue;
            spawner.FitToTerrain();
        }
        curTerrainInWork = currentCoords;

            BoundsDouble spawnArea = new BoundsDouble(new Vector3((currentCoords.x - OriginOffset.x)*TerrainsSize + TerrainsSize / 2, 0, (currentCoords.y - OriginOffset.y) * TerrainsSize + TerrainsSize / 2), Vector3.one*TerrainsSize);

        Spawners[0].m_updateCoroutine = Spawners[0].AreaSpawn(Spawners, spawnArea);
        Spawners[0].StartEditorUpdates();
        yield return null;
    }
    void OnSpawnersEnd()
    {
        Spawners[0].OnSpawnFinished -= OnSpawnersEnd;

        alreadyCreatedCoords.Add(curTerrainInWork);

        double spentTime = Math.Round((DateTime.Now - startTerrainTime).TotalMinutes, 2);
        Debug.Log($"Spawn ended on {curTerrainInWork.x}_{curTerrainInWork.y}. Spent time: {spentTime}.");
        UnloadScene(currentTerrainScene);

        TrySpawnNextTerrain();
    }
    /// <summary>
    /// Main cycle iteration. Start and end of cycle.
    /// </summary>
    void TrySpawnNextTerrain()
    {
        var nextCoord = GetNextCoordToSpawn();

        if (nextCoord.HasValue)
        {
            StartCoroutine(SpawnBiomeAtCoords(nextCoord.Value));
        }
        else
        {
            Debug.Log("Spawn ended!");

            string finalSpawnedList = string.Empty;

            foreach(var coord in alreadyCreatedCoords)
            {
                finalSpawnedList += $"{coord.x}_{coord.y};";
            }
            if (finalSpawnedList.Length > 0)
                Debug.Log("Final list of spawnded is: " + finalSpawnedList);

            StopGeneration();
        }
    }

    /// <summary>
    /// Move camera to position and start use spawners at terrain
    /// </summary>
    /// <param name="coords"></param>
    /// <returns></returns>
    IEnumerator SpawnBiomeAtCoords(Vector2Int coords) //TODO call OnGUI in this block and load terrains not by camera. Gives opportunity to parallel computing
    {
        Vector3 camPosition = TerrainToWorldCoords(coords);
        SceneView.lastActiveSceneView.pivot = camPosition;
        SceneView.lastActiveSceneView.Repaint();
        currentTerrainScene = LoadScene(coords.x, coords.y);
        yield return null;

        StartCoroutine(SpawnBiomesOnLocal(coords));
    }


    Vector3 TerrainToWorldCoords(Vector2Int coords) => new Vector3((coords.x - OriginOffset.x) * TerrainsSize + TerrainsSize/2, 100, (coords.y - OriginOffset.y) * TerrainsSize + TerrainsSize / 2);
    
    /// <summary>
    /// Check each possible coord to spawn if it was spawned and is not ignored. If nothing left - returns null.
    /// </summary>
    /// <returns></returns>
    Vector2Int? GetNextCoordToSpawn()
    {
        if(DoTerrainsFromList)
        {
            foreach(var terrainCoord in doTerrainsCoords)
            {
                if(!alreadyCreatedCoords.Contains(terrainCoord) && !ignoreTerrainsCoords.Contains(terrainCoord))
                    return terrainCoord;
            }
        }
        if(DoTerrainsFromRectangle)
        {
            for (int y = 0; y < RectangleSize.y; y++)
            {
                for (int x = 0; x < RectangleSize.x; x++)
                {
                    var coord = new Vector2Int(x, y) + RectangleBottomLeftCoord;
                    if (!alreadyCreatedCoords.Contains(coord) && !ignoreTerrainsCoords.Contains(coord))
                        return coord;
                }
            }
        }
        return null;
    }


    private List<Vector2Int> GetTerrains(string importString)
    {
        List<Vector2Int> result = new List<Vector2Int>();
        if (importString.Length == 0) return result;
        string[] terrainPos = importString.Split(';');
        foreach (var s in terrainPos)
        {
            string[] coords = s.Split('_');
            result.Add(new Vector2Int(int.Parse(coords[0]), int.Parse(coords[1])));
        }
        return result;
    }

    private static Scene LoadScene(int sceneNameX, int sceneNameY)
    {
        //middle terrain (0,0) is 20_20

        string sceneName = $"Terrain_{sceneNameX}_{sceneNameY}-20220527 - 160015.unity";
        return EditorSceneManager.OpenScene(PATH_SCENES_FOLDER + sceneName, OpenSceneMode.Additive);

    }
    private static void UnloadScene(Scene openedScene)
    {
        //middle terrain (0,0) is 20_20
        EditorSceneManager.SaveScene(openedScene);
        EditorSceneManager.CloseScene(openedScene, true);
    }

    public void StopGeneration()
    {
        DoTerrainsFromList = false;
        DoTerrainsFromRectangle = false;
        AssetDatabase.StopAssetEditing();
    }
#endif
}

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Tell a friend

    Love Canopy - Procedural Worlds? Tell a friend!
  • Need help?

    We work with some of the biggest brands in global gaming, automotive, technology, and government to create environments, games, simulations, and product launches for desktop, mobile, and VR.

    Our unique expertise and technology enable us to deliver solutions that look and run better at a fraction of the time and cost of a typical project.

    Check out some of our non-NDA work in the Gallery, and then Contact Us to accelerate your next project!

×
×
  • Create New...