IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Unity Discussion :

Enregistrer la position de la caméra dans un fichier texte


Sujet :

Unity

  1. #1
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 648
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 648
    Points : 11 137
    Points
    11 137
    Par défaut Enregistrer la position de la caméra dans un fichier texte
    Bonjour,

    je suis chargé de modifier un script C# dans une application Unity. Il s'agit d'enregistrer les déplacements de la caméra. Je n'ai aucun souci pour récupérer les coordonnées avec camera.transform.position, mais la question que je me pose est la suivante :

    à quel moment et comment enregistrer les données sans que cela nuise aux performances du jeu ?

    J'utilse un StreamWriter pour écrire les données.
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    Update()
    {
         // mes instructions
         // écriture des données :
        writeData();
    }
     
    private void writeData()
    {
    	string camPos;
    	float x, y, z;
    	float rx, ry, rz;
     
    	x = _camera.position.x;
    	y = _camera.position.y;
    	z = _camera.position.z;
     
    	rx = _camera.rotation.x;
    	ry = _camera.rotation.y;
    	rz = _camera.rotation.z;
     
    	camPos = String.Format("{0:F3}\t{1:F3}\t{2:F3}\t{3:F3}\t{4:F3}\t{5:F3}", x, y, z, rx, ry, rz);
    	dataWriter.WriteLine(camPos );
    	dataWriter.Flush();
    }

    ou créer un Coroutine (je ne suis pas sûr de la syntaxe du yield) ?
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    Update()
    {
         // mes instructions
         // écriture des données :
        StartCoroutine(writeData());
    }
     
    IEnumerator writeData()
    {
    	string camPos;
    	float x, y, z;
    	float rx, ry, rz;
     
    	x = _camera.position.x;
    	y = _camera.position.y;
    	z = _camera.position.z;
     
    	rx = _camera.rotation.x;
    	ry = _camera.rotation.y;
    	rz = _camera.rotation.z;
     
    	camPos = String.Format("{0:F3}\t{1:F3}\t{2:F3}\t{3:F3}\t{4:F3}\t{5:F3}", x, y, z, rx, ry, rz);
    	dataWriter.WriteLine(camPos );
    	dataWriter.Flush();
     
    	yield return null;
    }

    Merci pour votre aide

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Salut,

    coroutine ou non ça sera la même chose : ton script sera exécuté pendant la frame. https://docs.unity3d.com/Manual/ExecutionOrder.html
    Pour pas nuire aux performances la solution est simple : ne pas enregistrer à chaque frame.
    Si tu fais l'enregistrement 1 fois de temps en temps, tu ne verras aucun impact.
    Pense aussi à ouvrir le fichier au début plutôt qu'à chaque fois : il sera bien plus rapide de juste rewind le fichier que de le réouvrir.

    Sinon tu peux créer un thread C# à part, qui sera donc dissocié de Unity et sa frame loop. Là tu seras plus libre et auras un impact minime sur ce que Unity fait.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 648
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 648
    Points : 11 137
    Points
    11 137
    Par défaut
    Merci Bousk pour ta réponse. Le fichier est ouvert durant l'événement Start() puis fermé lors du OnApplicationQuit(). J'ai environ 100 octets de données à écrire pour chaque trame.
    Je pensais que la Coroutine était exécutée entre deux trames.

    Si j'utilise un thread il faudra que j'accède au contenu de camera.transform.position au bon moment. Remplir une pile (Enqueue) lors de chaque Update() puis dépiler (Dequeue) dans mon thread ? Je vais étudier cette voie.


    -----------
    J'ai aussi pensé à la solution ci-dessous. J'avoue que les coroutines et les yield return sont des concepts assez flous dans mon esprit. Toujours une Coroutine mais ajouter un yield return new WaitForEndOfFrame(); au début. Si j'ai bien compris, avec cette instruction, j'attends la fin de la trame pour exécuter la fin du code. Donc d'après le diagramme que tu m'as donné le code sera exécuté après la trame, juste avant la pause et avant une nouvelle trame. Ou je me trompe complètement ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void Update()
    {
         // mes instructions
         // écriture des données :
        StartCoroutine(writeData());
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    IEnumerator writeData()
    {
    	yield return new WaitForEndOfFrame();
    	string camPos;
    	float x, y, z;
    	float rx, ry, rz;
     
    	x = _camera.position.x;
    	y = _camera.position.y;
    	z = _camera.position.z;
     
    	rx = _camera.rotation.x;
    	ry = _camera.rotation.y;
    	rz = _camera.rotation.z;
     
    	camPos = String.Format("{0:F3}\t{1:F3}\t{2:F3}\t{3:F3}\t{4:F3}\t{5:F3}", x, y, z, rx, ry, rz);
    	dataWriter.WriteLine(camPos );
    	dataWriter.Flush();
     
    	yield return null;
    }

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Les coroutines sont toujours exécutées après les Update et avant l'affichage - cf le graph. Donc en plein milieu de la frame. Le yeld est là uniquement pour indiquer après combien de temps (au moins) elle doit se réexécuter.
    Oui si tu utilises un thread tu vas avoir besoin de synchronisation.
    Tu peux aussi te contenter de flush toutes les X frames. C'est le flush qui est l'opération lente de l'écriture d'un fichier. Si tenté que l'écriture ne force pas un flush également...
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  5. #5
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 648
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 648
    Points : 11 137
    Points
    11 137
    Par défaut
    Très bien, je vais m'orienter vers les thread. Visiblement la prise en main n'est pas trop difficile. Il faut que je pense à utiliser un Queue.Synchronized(new Queue).

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 18
    Dernier message: 14/08/2011, 15h15
  2. Réponses: 6
    Dernier message: 30/03/2010, 21h15
  3. Réponses: 6
    Dernier message: 01/04/2009, 09h49
  4. enregistrer le contenu d'un Edit dans un fichier texte
    Par tapouni dans le forum C++Builder
    Réponses: 3
    Dernier message: 16/05/2008, 23h02
  5. Enregistrer les données d'une table dans un fichier texte word ou excel
    Par maamar1979 dans le forum Connexion aux bases de données
    Réponses: 2
    Dernier message: 14/06/2006, 13h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo