[Résolu] [MY-AL] Copier un terrain et le modifier en runtime ?

Pour les scripts écrits en C#
Règles du forum
Merci de respecter la NOMENCLATURE suivante pour vos TITRES de messages :

Commencez par le niveau de vos scripts
DB = Débutant
MY = Moyen
CF = Confirmé

Puis le domaine d'application
-RS = Réseau
-AL = Algorithmie

Exemple :

[DB-RS] Mouvement perso multijoueur
Avatar de l’utilisateur
eldoir
Messages : 9
Inscription : 25 Août 2016 16:54
Localisation : France
Contact :

[Résolu] [MY-AL] Copier un terrain et le modifier en runtime ?

Message par eldoir » 10 Août 2017 14:10

Bonjour à tous,

Je poste ici en espérant avoir plus de chance que sur le forum Unity (https://forum.unity3d.com/threads/how-t ... it.487505/) et Unity Answers (http://answers.unity3d.com/questions/13 ... ck-to.html), où personne n'a encore répondu.

J'essaye de rotate un terrain en runtime, et quand je quitte le jeu (soit depuis l'éditor soit en Standalone), je veux que le Terrain Asset soit de retour à la normale. Parce que mon problème, c'est que les modifications d'un Terrain Asset en runtime sont conservées hors runtime !

J'ai donc pensé à cet algo :

- Copier le Terrain Data

- Rotate la copie

- Au quit, la copie est automatiquement détruite, et donc le terrain devrait reprendre son Terrain Asset original... Non ?

J'ai donc ce code, que vous pouvez tester (il faudra me dire pourquoi le forum met tout le code en mode dégueu) :

Code : Tout sélectionner

using UnityEngine;
public class RotateTerrain : MonoBehaviour
{
    [SerializeField]
    private Terrain terrain; void Start()
    {
        WorkOnNewCopy(); // Now we can safely modify our terrain... Can we?
        TerrainRotate(terrain, degrees: 90);
    }

    void WorkOnNewCopy()
    {
        TerrainData backup_terrainData = terrain.terrainData;
        backup_terrainData.name = terrain.terrainData.name + "_tmp";
        backup_terrainData = Instantiate(backup_terrainData);
        terrain.terrainData = backup_terrainData;
        terrain.GetComponent<TerrainCollider>().terrainData = backup_terrainData;
        terrain.Flush();
    }

    void TerrainRotate(Terrain terrain, float degrees)
    {
        // Super-secret code
    }
}
Ca fonctionne presque : comme vous pouvez le voir sur les deux images que j'ai jointes, il y a une différence entre avant de faire la rotation, et une fois que j'ai quitté l'appli. Tout semble revenu à la normale (les arbres, la végétation), excepté la splat map (texture du sol).

Des idées ? Merci d'avance ! :)

Image

Image
Dernière édition par eldoir le 16 Août 2017 12:48, édité 2 fois.

Avatar de l’utilisateur
Greg
Messages : 156
Inscription : 08 Mai 2017 15:22

Re: [MY-AL] Copier un terrain et le modifier en runtime ?

Message par Greg » 14 Août 2017 14:10

Bonjour,

je suis pas sur d'avoir tout saisi... ou passe la splat map au restart? elle est présente? mal positionnée? autre?

Sinon ce n'est pas possible de stocker les paramètres terrains en dur (méthode statique, playerpref ou fichier xml) et de réinitialiser celui-ci dans le start ou lors du ApplicationQuit?

:merci:
Mon jeu de développement cellulaire : MICROBIOME (encore quelques bugs...)
(merci bien à ceux qui passent mettre des étoiles ! ^^)

Avatar de l’utilisateur
eldoir
Messages : 9
Inscription : 25 Août 2016 16:54
Localisation : France
Contact :

Re: [MY-AL] Copier un terrain et le modifier en runtime ?

Message par eldoir » 16 Août 2017 12:47

Bonjour Greg,

J'ai dû mal m'exprimer :

La splatmap (vraiment le fichier de texture même) ne revient pas dans son état original après que je l'ai modifié en runtime...
C'est-à-dire qu'elle est bel et bien rotate en runtime, mais les changements sont conservés lorsque je quitte l'app.
Et seulement les changement sur la splatmap, le reste est revenu à la normale.

Et effectivement, ta proposition d'enregistrer dans un fichier ou les PlayerPrefs était bonne, c'est ce à quoi je me suis attelé ce matin alors que je n'avais pas encore lu ta réponse.

Réinitialiser les paramètres du bloc au ApplicationQuit : impossible puisque si le PC est éteint brutalement, ça sèche cette étape, et après ça fout le boxon.
Réinitisaliser les paramètres du bloc au Start : bof. Je suis moyen chaud pour qu'il y ait un chargement dès le démarrage de l'app à cause de ça (en plus ça fait freezer l'appli car la rotation est bloquante, elle consomme pas mal).

Je me suis donc vite rendu compte des contraintes de la méthode et j'ai recommencé à m'acharner à trouver un truc plus "propre".

Bref, j'ai répondu sur mes deux autres topics en anglais : j'ai trouvé la solution ! :)

Je suis tombé, au hasard de mes recherches, sur un gars qui a codé un "TerrainDataCloner".

Cependant son script avait un bug qu'il m'a fallu 1h à résoudre alors que c'était tout con : il avait fait un mauvais copier-coller qui empêchait les arbres de se cloner correctement.

La version révisée, par moi-même et fonctionnelle, se trouve ici : https://gist.github.com/Eldoir/d5a438df ... 5097dda1d4

Ensuite j'ai juste eu à écrire ceci :

Code : Tout sélectionner

 terrain.terrainData = TerrainDataCloner.Clone(terrain.terrainData);
 terrain.GetComponent<TerrainCollider>().terrainData = terrain.terrainData; // Don't forget to update the TerrainCollider as well
Après ça, j'appelle le code qui fait la rotation, et lorsque je quitte l'app, tout se remet à la normale. Exactement ce que je voulais ! :D
En tous les cas merci de ton aide ! ;)

Répondre

Revenir vers « (C#) CSharp »