[RESOLU] les Objects, les filtrer, récupérer un component, en Editor

Questions à propos du scripting. Hors Shader, GUI, Audio et Mobile.
Meudes
Messages : 11
Inscription : 05 Juil 2021 11:27

[RESOLU] les Objects, les filtrer, récupérer un component, en Editor

Message par Meudes » 05 Nov 2021 13:39

Bonjour les gros cerveaux !! :-D et les modaux généreux !

J'ai des scènes avec un terrain dedans (objectif : entre 10 000 et 100 000 de scènes) (le : "je sais ... oui ... je sais ..." de CloudAtlas).
Mes terrains sont setEnabled = false;
Sur les terrains, il y a des "Objects" (parapluies, parasols, ...), chacun ont un component partagé : script ObjetMap.cs.
Ses objets ont un tag "ObjetMap".
Il n'y a pas de caméra dans mes scènes.
Sur chaque scène, j'ai un prefab, vide, où il y a un script LoadSaveScene.cs.

Pour détailler le contexte :
J'ai une scène principale qui va load (a l'intérieur d'elle même) 9 scènes autour de ma caméra.
Si la camera se déplace, les scènes ajoutées s'unload et se load en fonction de la distance autour de ma caméra.
La caméra est accroché au Player qui spawn via MLAPI.
Mon problème est de faire la 1er sauvegarde de mes GamesObjects sur mes terrains.
(après, je les supprime, et je les instances à l'ouverture InGame de la scène)

Tout cela ... ça marche un peu ... des fois ... :taré1:

Donc le problème est :
1 Je souhaite faire le tour de tous mes scènes terrains (donc ouvrir chacune de mes scènes)
2 Parcourir les Objects ou GameObjects de la scène, récupérer le Transform de mes objets et les valeurs de mon script ObjetMap.
3 Pour chaque terrain mettre tout ça dans un json sauvegardé sur le disque (ou autre).

J'ai commencé par faire un script Editor qui fonctionne bien :
J'ajoute un bouton sur l'inspecteur, je clic, il envoie la fonction, la fonction ouvre terrain (après terrain), et tente de chercher mes objets.
C'est là où j'ai des problèmes : à la différence du GameObject, l'Object (on n'est pas en RunTime) n'a pas de Tag, manque cruellement de fonctions et n'est pas facile à prendre en main.
Donc, je prend tous les objets, et là, je n'ai pas trouvé comment : filtrer les objets
- soit par tag,
- soit par type,
- soit par prefab,
et encore moins récupérer le component script ObjetMap et ses valeurs ...

Y'a t-il une solution ?


Du coup, je me suis lancé dans le même type d'architecture mais en RunTime pour récupérer des GameObjects.
Mais ... C'est affreux à faire, j'ai pleins de problèmes ...
:pleur4:

Y a t-il une solution à partir des Objets en Editor pour récupérer les valeurs d'un component ?
ou pour les filtrer ?

Voici le code :

Code : Tout sélectionner

public void RunCreationSauvegarde()
    {
        int compteurX = 0;
        int compteurY = 0;
        string nomSceneTerrain = "";
        while (compteurX < NombreTuileX)
        {
            compteurY = 0;
            while (compteurY < NombreTuileY)
            {
                nomSceneTerrain = PathHDD+ "Terrain_" + compteurX + "_" + compteurY +  ".unity";
                Debug.Log("Traitement de " + nomSceneTerrain);

                EditorSceneManager.OpenScene(nomSceneTerrain);

                Debug.Log("-------------------------------"+ allObjects.Length);
                int compteur = 0;
                // TerrainObjet : est une class conteneur simple de "ObjetMapSerial" pour créer le json.
                TerrainObjet myTerrain = new TerrainObjet ();
                foreach (UnityEngine.Object objet  in allObjects)
                {
                    Debug.Log("XXXXXXXXXXXXXXXXXX OBJET TROUVE : "+objet.name);

                    ObjetMapSerial objetConstruction = new ObjetMapSerial();
                    
                    /* impossible car nous ne sommes pas sur des GameObject : 
                    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.x;
                    objetConstruction.RotationY = objet.GetComponent<Transform>().rotation.y;
                    objetConstruction.RotationZ = objet.GetComponent<Transform>().rotation.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.Parent = objet.GetComponent<Transform>().parent; // Conteneur de l'objet (où il est

                    
                    objetConstruction.PrefabNom = objet.GetComponent<ObjetMap>().PrefabNom;
                    objetConstruction.Auteur = objet.GetComponent<ObjetMap>().PrefabNom;

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

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

                    // OBJET VIE
                    objetConstruction.PointsVieMax = objet.GetComponent<ObjetMap>().PointsVieMax; // Point de vie max de l'objet SAUVEGARDE
                    objetConstruction.PointsVieValeur = objet.GetComponent<ObjetMap>().PointsVieValeur; // Point de vie actuel de l'objet SAUVEGARDE
                    objetConstruction.DicoDeDegats = objet.GetComponent<ObjetMap>().DicoDeDegats; // <Type Dégats ,  Valeur dégats> Dégat de l'objet SAUVEGARDE
                    objetConstruction.DicoDeResistances = objet.GetComponent<ObjetMap>().DicoDeResistances; // <Type Résistance, Valeur résistrance> Résistance de l'objet SAUVEGARDE

                    // OBJET RECETTE
                    objetConstruction.TabRecetteSupp = objet.GetComponent<ObjetMap>().TabRecetteSupp;
                    objetConstruction.TabRecetteSuppNombre = objet.GetComponent<ObjetMap>().TabRecetteSuppNombre;

                    myTerrain.DicoObjetTerrain.Add(compteur, objetConstruction);
                    */
                    
                    Debug.Log("---------------"+ objet + compteur);
                    compteur++;
                }

                string sauvegardeJson = JsonUtility.ToJson(myTerrain);
                File.WriteAllText(pathSaveTerrain + "\\" + "Terrain_" + compteurX + "_" + compteurY + ".json", sauvegardeJson);

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

    }
    
Si vous avez une solution ou des pistes ! Merci par avance ! ::d

Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 6208
Inscription : 28 Avr 2014 11:57
Localisation : Saint-Didier-en-Bresse (71)

Re: les Objects, les filtrer, récupérer un component, en Editor

Message par boubouk50 » 05 Nov 2021 15:19

Je ne comprends pas trop sur quoi tu travailles, en éditeur comme en runtime une scène possède des gameObjects dont le transform est accessible. (d'ailleurs juste go.transform suffit, pas besoin du GetComponent <Transform>())

Du coup, tu ne travailles pas sur la scène ouverte mais sur l'asset de la scène?
"Ce n'est pas en améliorant la bougie, que l'on a inventé l'ampoule, c'est en marchant longtemps."
Nétiquette du forum
Savoir faire une recherche
Apprendre la programmation

Meudes
Messages : 11
Inscription : 05 Juil 2021 11:27

Re: les Objects, les filtrer, récupérer un component, en Editor

Message par Meudes » 05 Nov 2021 15:49

mmmmmm !
Merci pour ta réponse : je sens le ciel bleu après plusieurs jours de galère...
Je confond bien des trucs !!

Code : Tout sélectionner

EditorSceneManager.OpenScene(nomSceneTerrain); 
Ce code m'ouvre bien la scène dans l'éditeur. Donc, on est bien sur la scène.

Pour récupérer mes Objects / GameObjets dans un tableau : j'ai choisi cette fonction :

Code : Tout sélectionner

UnityEngine.Object[] allObjects = FindObjectsOfType<UnityEngine.Object>() as UnityEngine.Object[]; 
car :
(

Code : Tout sélectionner

 GameObject[] allObjects = GameObject.FindGameObjectsWithTag("ObjetMap"); 
et

Code : Tout sélectionner

 GameObject[] allObjects = FindObjectsOfType<GameObject>() as GameObject[]; 
)
ne remplissait pas ma table.
J'en ai donc déduit que les GameObject ne pouvaient être accessible qu'en Runtime (d'où le nom "Game Object").

Mais avec ton message, je me demande si ma table est vide car comme dit : par default, mon terrain dans chaque scène (qui est le père de tous les autres objets) est enable = false.

Je vais tester ! avec des terrains enable = true

:super:

Meudes
Messages : 11
Inscription : 05 Juil 2021 11:27

Re: les Objects, les filtrer, récupérer un component, en Editor

Message par Meudes » 05 Nov 2021 16:31

L'erreur venait bien de là ...
Directement avec une fonction de l'editeur, on peut récupérer des Games Objects ....
des heures et des heures à cause de cette méconnaissance ...

Pour info, pour récupérer des objets non actif non référencés dans une scène, j'ai fais cela :

Code : Tout sélectionner

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

 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))
            allObjects.Add(go);
 }
Merci pour ce dépannage express ! :coeur:

Répondre

Revenir vers « Scripting »