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 :

Sauvegarde d'une List dans un Json [C#]


Sujet :

Unity

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    64
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 64
    Points : 52
    Points
    52
    Par défaut Sauvegarde d'une List dans un Json [C#]
    Bonjour à tous,

    Je cherche à sauvegarde une list dans un Json. C'est un cas simple pour m'entrainer.
    Je veux donc sauvegarder les meilleurs score effectué par les joueurs. Je dois sauvegarder leur pseudo et score.

    Dans mes première version aucun soucis j'arrive a le faire mais la j'essaie d'améliorer un peu l'architecture histoire de m'entrainer à faire quelque chose de propre.

    J'ai donc créé une classe HighScore :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    [System.Serializable]
    public class HighScore
    {
        public string PlayerName;
        public int Score;
     
    }
    ensuite j'ai créé une classe HighScores (mais c'est peu être la que je fais fausse route)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    [System.Serializable]
    public class HighScores : List<HighScore>
    {
     
    }
    et je vais appeler le tout dans une petite méthode pour tester la sauvegarde

    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
     public void SaveHighScores()
        {
     
            HighScores highScores = new HighScores();
            HighScore highScore = new HighScore();
            highScore.PlayerName = "Test";
            highScore.Score = 25;
     
            highScores.Add(highScore);
     
            string json = JsonUtility.ToJson(highScores);
            string filePath = Application.persistentDataPath + "/savefile.json";
     
            File.WriteAllText(filePath, json);
        }
    Mon fichier Json reste vide malheureusement mais je n'arrive pas a voir pourquoi.

    J'ai bien trouver une solution en utilisant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    [System.Serializable]
    public class HighScores : List<HighScore>
    {
        public List<HighScore> highScores;
    }
    et pour la sauvegarde :

    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
    public void SaveHighScores()
        {
     
            HighScores highScores = new HighScores();
            HighScore highScore = new HighScore();
            highScore.PlayerName = "Test";
            highScore.Score = 25;
     
            highScores.highScores = new();
            highScores.highScores.Add(highScore);
     
            string json = JsonUtility.ToJson(highScores);
            string filePath = Application.persistentDataPath + "/savefile.json";
     
            File.WriteAllText(filePath, json);
        }
    Mais je ne trouve pas cela pas vraiment bien au niveau de l'écriture et lecture du code .

    Merci d'avance

    PS: Je viens du Java j'ai peut être pas bien fait les chose niveau C#

  2. #2
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 358
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 358
    Points : 20 369
    Points
    20 369
    Par défaut
    bonsoir je vais le répéter encore une fois mais lorsqu'on crée une instance de classe surtout d'un flux comme l'écriture de fichier il faut toujours tester si l'instance est nulle ou pas.
    Et dans les règles de l'art il faudrait encapsuler ça avec une gestion d'exception bref dans un try..catch
    Sinon ça peut être un problème de droit et de création de fichier comme administrateur vérifier les droits du répertoire où est généré le fichier json

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    64
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 64
    Points : 52
    Points
    52
    Par défaut
    Bonsoir,

    Merci pour ta réponse rapide.

    Il y a aucun soucis pour la création du fichier le problème viens plutôt du fait que rien n'est écrit dans le json dans le premier cas.

    Dans le Json je me retrouve avec :

    Un peu comme quand on oublie de mettre le [System.Serializable]
    Et oui je suis loin des règles de l'art mais c'est un petit projet perso pour comprendre comment les choses fonctionne.

    Mais avant de poser la question j'ai bien vérifier que j'avais bien les bonne données dans mes instances et pas de soucis.

  4. #4
    Membre chevronné
    Avatar de PixelJuice
    Homme Profil pro
    Ingénieur .NET & Game Designer
    Inscrit en
    Janvier 2014
    Messages
    639
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur .NET & Game Designer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2014
    Messages : 639
    Points : 2 148
    Points
    2 148
    Par défaut
    Bonjour,

    La classe JsonUtility n'aime pas vraiment les List, du coup vu que tu créer une autre liste, et bien il n'aime pas trop.

    En fait il suffit d'encapsuler le tout dans une classe prévue pour.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    [Serializable]
    public class ScoreData // J'ai rénommé ta classe HighScores pour que ça soit + parlant
    {
        public List<HighScore> highScores;
     
        public ScoreData()
        {
            highScores = new List<HighScore>();
        }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
        public void SaveHighScores()
        {
            ScoreData scoreData = new ScoreData();
            HighScore score = new HighScore();
            score.PlayerName = "Test";
            score.Score = 25;
     
            scores.highScores.Add(score);
     
            string json = JsonUtility.ToJson(scoreData);
            string filePath =  "D://savefile.json";
     
            File.WriteAllText(filePath, json);
        }
    Voilà, ça devrait fonctionner maintenant. Et puis tu pourras mettre dans ScoreData d'autres métadonnées si jamais le besoin s'en fait ressentir.

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    64
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 64
    Points : 52
    Points
    52
    Par défaut
    Bonjour,

    Merci pour la réponse. J'avais vu que pour les collections ce n'était effectivement pas la fête (Limité à List et ArrayList).
    J'ai une nouvelle question qui se pose mais plutôt au niveau de la conception cette fois ci.

    Si je devais maintenant sauvegarder des pièces d'or. Elles n'ont rien a voir avec mon score.

    Dans un premier temps j'aurais tendance à modifier un peu la classe (proposé par @PixelJuice)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    [Serializable]
    public class ScoreData // J'ai rénommé ta classe HighScores pour que ça soit + parlant
    {
        public List<HighScore> highScores;
     
        public ScoreData()
        {
            highScores = new List<HighScore>();
        }
    }
    En quelque chose comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public class DataToSave
    {
        public List<HighScore> highScores;
        public int numbersOfGoldCoins;
     
        public DataToSave()
        {
            highScores = new List<HighScore>();
        }
    Mais si je fais cela puis je toujours faire une sauvegarde juste pour le score et une sauvegarde pour l'or ? (techniquement oui c'est possible)
    Ou est ce que l'on attend de moi que faire une sauvegarde en un seul bloc.

    J'essaie de m'améliorer sur l'architecture et la conception et j'avoue que parfois je me coupe les cheveux en 4

  6. #6
    Membre chevronné
    Avatar de PixelJuice
    Homme Profil pro
    Ingénieur .NET & Game Designer
    Inscrit en
    Janvier 2014
    Messages
    639
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur .NET & Game Designer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2014
    Messages : 639
    Points : 2 148
    Points
    2 148
    Par défaut
    C'est comme tu le sens, c'est selon tes besoins et l'architecture de ton jeu aussi.

    Tu pourrais faire une classe par "type" de sauvegarde. Personnellement les meilleurs scores je les mettrais à part des données générales, comme l'or. Il faut bien compartimenter, si jamais tu veux reset les scores seuls par exemple.

    Tu pourrais aussi sauvegarder en données binaires si tu ne veut pas que ça soit modifiable en clair par tes joueurs. Plus flexible aussi, mais un peu plus complexe que de balancer en JSON directement.

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    64
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 64
    Points : 52
    Points
    52
    Par défaut
    Oui j'ai vu aussi la possibilité de chiffrer les données pour qu'il soit moins facile de tricher.
    Mais cela sera pour la V2.

    Pour le moment je suis entrain de m'arracher les cheveux sur les tests unitaires des sauvegarde justement

    J'ai une solution ou je compare chaque éléments du Json. Mais si dans le cas d'un Json compliqué cela n'est pas viable.

    J'ai trouvé JToken.DeepEquals qui vient de Newtonsoft.
    Mais je ne sais pas pourquoi impossible de l'ajouter a l'assembly des test unitaires.
    [Resolu] Il ne fallait pas ajouter Newtonsoft en Definition References mais en References donc cela marche. Il va falloir que je regarde la différence entre les deux car pour le moment cela fonctionne mais je ne sais pas trop pourquoi.

    Encore merci pour ton aide. Je vais compartimenter

Discussions similaires

  1. [PowerShell] Création d'un JSON avec liste
    Par Yann_br dans le forum Scripts/Batch
    Réponses: 2
    Dernier message: 18/05/2022, 12h33
  2. Créer une liste déroulante avec jquery et json
    Par beegees dans le forum jQuery
    Réponses: 2
    Dernier message: 30/04/2012, 11h46
  3. Mal a la tete avec liste chainée d'objet
    Par Raton dans le forum C++
    Réponses: 23
    Dernier message: 03/08/2005, 22h13
  4. Aide à la saisie avec liste déroulante
    Par Oluha dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 01/02/2005, 09h04
  5. Conditions avec liste de tuples
    Par Robert999 dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 12/07/2004, 11h01

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