Jump to content

Load terrain from file


Guidos

Recommended Posts

hi all,

Is there a way to load a terrain from a saved file?

If I wanted to start a new project but use the same terrain shape Ive had in previous projects how do I do that?

In World Designer there is an option under advanced to save and load from file. Ive tried it but it just says I the settings file could not be loaded.

Thanks

Link to comment
Share on other sites

Hi,

To do this, I built an Editor script that unrolls terrain by terrain and retrieves the objects on the world, places them in a json per terrain.

I haven't found any other solution.

My var and text are Frensh Language.

The load function ... I don't know if it works well.

Indeed, I use a server that sends backups to clients and spawns objects. The logic is the same.

 

#if FLORA_PRESENT
using ProceduralWorlds.Flora;
#endif
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System;
using MyStruct;
using System.IO;
using UnityEngine.SceneManagement;

#if UNITY_EDITOR
using UnityEditor.SceneManagement;
//using UnityEngine.SceneManagement;



[CustomEditor(typeof(BuildWorld))]

public class editorBuildWorld : Editor
{
    public override void OnInspectorGUI()
    {
        DrawDefaultInspector();
        BuildWorld myScript = (BuildWorld)target;


        //-> load terrain
        if (GUILayout.Button("Ajouter lecteurDeScene (chaque tuile)"))
        {
            myScript.RunAddLoadSaveScene();
        }

        //-> Save terrain
        if (GUILayout.Button("Creation des fichiers de sauvegarde (chaque tuile)"))
        {
            myScript.RunCreationSauvegarde();
        }
    }
}


public class BuildWorld : MonoBehaviour
{
    // ---> Session and date gaia
    public string NameSessionGaia = "-20220403 - 15547";
    public string PathSessionGaia = "Assets/Gaia User Data/Sessions/2_512/Terrain Scenes/";
    public int NombreTuileX=0;
    public int NombreTuileY=0;

    // ---> path to save world
    public string pathSaveTerrain = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments) + "\\Les Freres Sorciers\\Experience\\SauvegardeWorld";


    [ExecuteInEditMode]
    public void RunAddLoadSaveScene()
    {
        int compteurX = 0;
        int compteurY = 0;
        string nomSceneTerrain = "";
        while (compteurX < NombreTuileX)
        {
            compteurY = 0;
            while (compteurY < NombreTuileY)
            {
                
                nomSceneTerrain = PathSessionGaia+"Terrain_" + compteurX + "_" + compteurY + NameSessionGaia+".unity";
                Debug.Log("Traitement de " + nomSceneTerrain);

                EditorSceneManager.OpenScene(nomSceneTerrain);

                // Le terrain est lu : on ajoute notre game object
                // ----> instantiate Prefab
                PrefabUtility.InstantiatePrefab(AssetDatabase.LoadAssetAtPath("Assets/Prefabs/LoadSaveScene/LoadSaveScene.prefab", typeof(GameObject)));

                // ----> save map
                bool saveOK = EditorSceneManager.SaveScene(EditorSceneManager.GetActiveScene(), string.Join("/", nomSceneTerrain));
                EditorSceneManager.SaveOpenScenes();

                compteurY++;
            }
            compteurX++;
        }
    }

    public void RunCreationSauvegarde()
    {
        int compteurX = 0;
        int compteurY = 0;
        string nomSceneTerrain = "";
        ulong IDTerrainObjet=0;

        // ---> terrain by terrain
        while (compteurX < NombreTuileX)
        {
            compteurY = 0;
            while (compteurY < NombreTuileY)
            {
                // open terrain
                nomSceneTerrain = PathSessionGaia + "Terrain_" + compteurX + "_" + compteurY + NameSessionGaia + ".unity";
                Debug.Log("Traitement de " + nomSceneTerrain);

                EditorSceneManager.OpenScene(nomSceneTerrain);

                List<GameObject> allObjects = new List<GameObject>();

                // ---> we take list of object with tag ObjetMap
                foreach (GameObject go in Resources.FindObjectsOfTypeAll(typeof(GameObject)) as GameObject[])
                {
                    if (!EditorUtility.IsPersistent(go.transform.root.gameObject) && !(go.hideFlags == HideFlags.NotEditable || go.hideFlags == HideFlags.HideAndDontSave))
                    {
                        if ( go.tag=="ObjetMap" )
                            allObjects.Add(go);
                    }
                }


                TerrainListeObjet myTerrain = new TerrainListeObjet();
                if (allObjects.Count >= 1)
                {
                    myTerrain.ParentLocalPositionX = allObjects[0].GetComponent<Transform>().parent.transform.localPosition.x;
                    myTerrain.ParentLocalPositionY = allObjects[0].GetComponent<Transform>().parent.transform.localPosition.y;
                    myTerrain.ParentLocalPositionZ = allObjects[0].GetComponent<Transform>().parent.transform.localPosition.z;

                    myTerrain.ParentPositionX = allObjects[0].GetComponent<Transform>().parent.transform.position.x;
                    myTerrain.ParentPositionY = allObjects[0].GetComponent<Transform>().parent.transform.position.y;
                    myTerrain.ParentPositionZ = allObjects[0].GetComponent<Transform>().parent.transform.position.z;
                }


                foreach (GameObject objet  in allObjects)
                {
                    // My objects have a script to identify them :
                    ObjetSurTerrainSerial objetConstruction = new ObjetSurTerrainSerial();

                    objetConstruction.IDTypeObjet = objet.GetComponent<ObjetSurTerrain>().IDTypeObjet;
                    objetConstruction.IDObjetSurTerrain = IDTerrainObjet;

                    objetConstruction.PositionLocalX = objet.GetComponent<Transform>().localPosition.x;
                    objetConstruction.PositionLocalY = objet.GetComponent<Transform>().localPosition.y;
                    objetConstruction.PositionLocalZ = objet.GetComponent<Transform>().localPosition.z;

                    objetConstruction.RotationLocalX = objet.GetComponent<Transform>().localRotation.eulerAngles.x;
                    objetConstruction.RotationLocalY = objet.GetComponent<Transform>().localRotation.eulerAngles.y;
                    objetConstruction.RotationLocalZ = objet.GetComponent<Transform>().localRotation.eulerAngles.z;

                    objetConstruction.PositionX = objet.GetComponent<Transform>().position.x;
                    objetConstruction.PositionY = objet.GetComponent<Transform>().position.y;
                    objetConstruction.PositionZ = objet.GetComponent<Transform>().position.z;

                    objetConstruction.RotationX = objet.GetComponent<Transform>().rotation.eulerAngles.x;
                    objetConstruction.RotationY = objet.GetComponent<Transform>().rotation.eulerAngles.y;
                    objetConstruction.RotationZ = objet.GetComponent<Transform>().rotation.eulerAngles.z;


                    objetConstruction.ScaleX = objet.GetComponent<Transform>().localScale.x;
                    objetConstruction.ScaleY = objet.GetComponent<Transform>().localScale.y;
                    objetConstruction.ScaleZ = objet.GetComponent<Transform>().localScale.z;

                    // OBJET POSITION
                    
                    objetConstruction.PrefabNom = objet.GetComponent<ObjetSurTerrain>().PrefabNom;
                    objetConstruction.Auteur = objet.GetComponent<ObjetSurTerrain>().PrefabNom;

                    objetConstruction.DesignationPersonnel = objet.GetComponent<ObjetSurTerrain>().DesignationPersonnel; // Nom personnalisé 
                    objetConstruction.Auteur = objet.GetComponent<ObjetSurTerrain>().Auteur; // Nom de l'auteur 

                    // OBJET SAC A DOS
                    objetConstruction.Poids = objet.GetComponent<ObjetSurTerrain>().Poids;

                    // OBJET VIE
                    objetConstruction.PointsVieMax = objet.GetComponent<ObjetSurTerrain>().PointsVieMax; // Point de vie max de l'objet SAUVEGARDE
                    objetConstruction.PointsVieValeur = objet.GetComponent<ObjetSurTerrain>().PointsVieValeur; // Point de vie actuel de l'objet SAUVEGARDE

                    objetConstruction.ListeDeDegats = objet.GetComponent<ObjetSurTerrain>().ListeDeDegats; // <Type Dégats ,  Valeur dégats> Dégat de l'objet SAUVEGARDE
                    objetConstruction.ListeDeDegatsValeur = objet.GetComponent<ObjetSurTerrain>().ListeDeDegatsValeur; // <Type Dégats ,  Valeur dégats> Dégat de l'objet SAUVEGARDE

                    objetConstruction.ListeDeResistances = objet.GetComponent<ObjetSurTerrain>().ListeDeResistances; // <Type Résistance, Valeur résistrance> Résistance de l'objet SAUVEGARDE
                    objetConstruction.ListeDeResistancesValeur = objet.GetComponent<ObjetSurTerrain>().ListeDeResistancesValeur; // <Type Résistance, Valeur résistrance> Résistance de l'objet SAUVEGARDE

                    // OBJET RECETTE

                    objetConstruction.ListeIDRecetteSupp = objet.GetComponent<ObjetSurTerrain>().ListeIDRecetteSupp;
                    objetConstruction.ListeIDRecetteSuppQuantite = objet.GetComponent<ObjetSurTerrain>().ListeIDRecetteSuppQuantite;

                    myTerrain.ListeObjetTerrain.Add(objetConstruction);

                    IDTerrainObjet++;
                }
                // ----> We build json terrain
                string sauvegardeJson = JsonUtility.ToJson(myTerrain);

                // ---> We save terrain
                File.WriteAllText(pathSaveTerrain + "\\" + "Terrain_" + compteurX + "_" + compteurY + ".json", sauvegardeJson);

                compteurY++;
            }
            compteurX++;
        }
        EditorSceneManager.OpenScene("Assets/Scene/EditorTools.unity");

    }
}

#endif

 

 

 

 

Link to comment
Share on other sites

Thank you.

 

Seems odd to me this isn't a feature. A way to just import terrain from another project would enable developers to maintain consistence of a wold across different projects. 

Link to comment
Share on other sites

On 4/10/2022 at 9:02 AM, Guidos said:

If I wanted to start a new project but use the same terrain shape Ive had in previous projects how do I do that?

There are a few options that you can do for this: 

1. 


2. You can use the terrain scanner - from the Gaia Manager. 
Scan the Terrain and then export the .exr heightmap file to the new project and then stamp that on the terrain. 

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...