[RESOLU] [DB-AL] Sauvegarde de gameobjects avec playerprefs

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
Auréane
Messages : 15
Inscription : 05 Sep 2017 10:10

[RESOLU] [DB-AL] Sauvegarde de gameobjects avec playerprefs

Message par Auréane » 05 Sep 2017 10:41

Bonjour à tous !

Avant toute chose je tiens à m'excuser si je ne m'exprime pas correctement ou si je me suis trompée dans la description du sujet.
C'est la première fois que je poste sur un forum alors j'étais un peu perdue en arrivant ^^" J'espère avoir mis mon topic au bon endroit....
J'ai vraiment besoin de l'aide de quelqu'un c'est pourquoi je viens ici.
J'ajoute aussi que je suis en stage et que je dois trouver une solution pour terminer le projet malgré mon niveau en C# donc soyez pas trop méchant avec moi svp si je cherche à faire des choses trop difficiles pour moi ^^

Alors voilà, je suis en train de coder en C# une application 2D pour Androïd, c'est une appli de géocaching. Mon soucis est dû au reset d'unity lorsque l'on passe d'une scène à une autre.

J'ai une scène qui me décrit un parcours de geocaching et dedans il y a un bouton que l'on peut activer ou désactiver si l'on a trouvé ou non la cache.
Si le bouton est activé j'aimerais qu'il le reste à chaque fois que l'on revient sur cette scène.

Image

J'ai réussi grâce à cette suite de tutos (https://www.youtube.com/watch?v=iFQjPdqEFj4) à utiliser PlayerPrefs et à recharger mes éléments lorsque l'on clique sur un bouton.
Avec ApplicationOnQuit() j'arrive à garder le bouton actif si on quitte l'application et qu'on revient sur cette scène mais dès que l'on passe sur une autre scène et que l'on revient il ne tient pas...

Mes codes pour sauvegarder mes gameObjects sont les mêmes que celui du tuto, les seules différences sont :
- je n'ai que deux objets,
-je n'ai pas enregistré les éléments en fonction de la scène comme il a fait car c'est la seule scène à avoir des objets à conserver donc je ne pensais pas avoir besoin de le spécifier à unity


Voilà désolée pour ce pavé ^^"

J'espère que quelqu'un pourra m'aider :s

Merci d'avance !!


Voici mes codes :
savGameManager

Code : Tout sélectionner

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class savGameManager : MonoBehaviour
{

    private static savGameManager instance;

    public List<saveableObject> SaveableObjects {get; private set;}

    public static savGameManager Instance
    {
        get
        {
            if (instance == null)
            {
                instance = GameObject.FindObjectOfType<savGameManager>();
            }

            return instance;
        }

    }



	// Use this for initialization
	void Awake ()
    {
        SaveableObjects = new List<saveableObject>();
        Load();


	}


    public void Save()
    {
        PlayerPrefs.SetInt("ObjectCount", SaveableObjects.Count);

        for (int i = 0; i < SaveableObjects.Count; i++)
        {
            SaveableObjects[i].Save(i);
        }
    }


    public void Load ()
    {

        foreach (saveableObject obj in SaveableObjects)
        {
            if(obj!= null)
            {
                Destroy(obj.gameObject);
            }
        }

        SaveableObjects.Clear();

        int objectCount = PlayerPrefs.GetInt("ObjectCount");

        for (int i = 0; i < objectCount; i++)
        {
            string[] value = PlayerPrefs.GetString(i.ToString()).Split('_');
            Debug.Log(value);

            //tmp = temporary
            GameObject tmp = null;

            switch (value[0])
            {
                case "trouvee":
                    tmp = Instantiate(Resources.Load("trouvee") as GameObject);
                    break;
                case "trouveeText":
                    tmp = Instantiate(Resources.Load("trouveeText") as GameObject);
                    break;
            }

            if (tmp != null)
            {
                tmp.GetComponent<saveableObject>().Load(value);
            }
            

        }
    }


    public Vector3 StringToVector (string value)
    {   //(1, 23, 3)
        value = value.Trim(new char[] {'(',')' });

        //1, 23, 3
        value = value.Replace(" ", "");

        //1,23,3
        string[] pos = value.Split(',');

        //[0] = 1 [1] = 23 [2] = 3
        return new Vector3(float.Parse(pos[0]), float.Parse(pos[1]), float.Parse(pos[2]));

    }


    public Quaternion StringToQuaternion(string value)
    {

    return Quaternion.identity;

    }


    void OnApplicationQuit()
    {
        PlayerPrefs.SetInt("ObjectCount", SaveableObjects.Count);
    }


}





specificObject

Code : Tout sélectionner

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class specificObject : saveableObject
{

    private float speed;

    private float strength;



    // Update is called once per frame
    void Update()
    {
         
    }



    public override void Save(int id)
    {
        base.Save(id);
    }



    public override void Load(string[] values)
    {
        base.Load(values);
    }


}





saveableObject

Code : Tout sélectionner

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

enum ObjectType { trouvee, trouveeText }

public abstract class saveableObject : MonoBehaviour
{

    protected string save;

    [SerializeField]

    private ObjectType objectType;


	// Use this for initializationz
	private void Start ()
    {
        savGameManager.Instance.SaveableObjects.Add(this);

	}
	
	
    //prend en charge toutes les sauvegardes generales (ex: position, rotation...)
    public virtual void Save(int id)
    {
        PlayerPrefs.SetString(id.ToString(), objectType + "_" + transform.position.ToString());
    }


    public virtual void Load(string[] values)
    {
        transform.localPosition = savGameManager.Instance.StringToVector(values[1]);
    }



    public void DestroySaveable()
    {
        savGameManager.Instance.SaveableObjects.Remove(this);
        Destroy(gameObject);

    }

}
Dernière édition par Auréane le 06 Sep 2017 13:57, édité 1 fois.

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

Re: [DB-AL] Sauvegarde de gameobjects avec playerprefs

Message par boubouk50 » 05 Sep 2017 10:55

Auréane a écrit :
05 Sep 2017 10:41
Avant toute chose je tiens à m'excuser si je ne m'exprime pas correctement ou si je me suis trompée dans la description du sujet.
C'est la première fois que je poste sur un forum alors j'étais un peu perdue en arrivant ^^"
Mais j'ai vraiment besoin de l'aide de quelqu'un c'est pourquoi je viens ici.
j'ajoute aussi que je suis en stage et que je dois trouver une solution pour terminer le projet malgré mon niveau en C# donc soyez pas trop méchant avec moi svp si je cherche à faire des choses trop difficiles pour moi ^^
Mon dieu, mais quelle image désastreuse nous donnons... :o
Ne t'inquiètes pas, si ce n'est pas bon, nous recadrons (c'est le but de la modération) et expliquons. S'il y a eu des mécontentements, c'est vraiment quand le membre abusait (pas de politesse, exigence plutôt que demande, etc).

Pour montrer notre bonne volonté voici une aide: "Je vous rappel" dans ton texte doit être corrigé par "Je vous rappelle".

En ce qui concerne les PlayerPrefs, il te faut enregistrer les données à chaque fois que celles-ci le doivent c'est à dire lorsque ton bouton est pressé. Il faut ensuite les lire avant tout besoin d'affichage. Ça devrait être bon, puisque ça fonctionne au reboot.
"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

Auréane
Messages : 15
Inscription : 05 Sep 2017 10:10

Re: [DB-AL] Sauvegarde de gameobjects avec playerprefs

Message par Auréane » 05 Sep 2017 11:08

Je préfère le dire car on ne sait jamais vraiment comme les personnes peuvent réagir ^^"
Je préfère être claire sur le fait que je cherche depuis plusieurs jours et que je patauge dans la semoule en écumant tous les tutos possibles mais je n'en trouvait pas pour montrer comment enregistrer les gameobjects. Et même si j'ai une compréhension en anglais pas trop mal il y en avait qui était incompréhensible...

Donc vous êtes mon dernier recours ^^

Je ne vois pas ma faute sur "je vous rappelle " :O


Bref revenons en à mon problème ^^"

Alors je ne sais pas ce que j'ai fait mais maintenant ça fonctionne ^^"

Mais lorsque je reclique sur le bouton il ne se désactive pas, je pense que je peux utiliser ma fonction DestroySaveable() pour retirer les sauvegardes du playerprefs.

Je vais essayer de trouver comment l'atteindre avec un bouton

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

Re: [DB-AL] Sauvegarde de gameobjects avec playerprefs

Message par boubouk50 » 05 Sep 2017 11:41

Tu as écrit "Je vous rappel", rappel est un nom commun, le rappel. Ici, c’est un verbe, donc tu le conjugues. Il s'écrit alors "Je vous rappelle".

Les boutons, tel quel depuis l'interface ne prennent en compte que les fonctions publiques (ce qui est le cas). Par contre pour ce qui est des fonctions abstraites, je ne peux en être sur.
Je n'ai pas pris le temps de bien comprendre ce que tu fais, le script est plutôt balèze pour tes besoins (et j'ai pas tout compris, j'avoue).
L'utilisation des PlayerPrefs peut être très simple, c'est juste une clé et une valeur.
Par exemple, chaque bouton peut avoir un nom spécifique (qui serait donc la clé) et pour le coup une sauvegarde associée (on peut imaginer un entier 0 ou 1).
Lorsque tu cliques sur le bouton, il te faudrait simplement récupérer, inverser (1 - valeur) cette donnée et la sauvegarder. L'état dépendrait donc de cette valeur qui est facilement testable.
"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

Auréane
Messages : 15
Inscription : 05 Sep 2017 10:10

Re: [DB-AL] Sauvegarde de gameobjects avec playerprefs

Message par Auréane » 05 Sep 2017 12:02

Je me suis mal exprimée
Je vois bien qu'il y a une faute mais je ne trouvais pas le mot dans mon texte ^^"

En effet le script est mis en abstrait et n'est donc pas atteignable.

Je vais essayer avec playerprefs de cette façon :)

Merci !

Auréane
Messages : 15
Inscription : 05 Sep 2017 10:10

Re: [DB-AL] Sauvegarde de gameobjects avec playerprefs

Message par Auréane » 05 Sep 2017 13:57

Bon ben je n'arrive pas à modifier le script selon mes besoins :/

J'ai cette erreur qui ne fait qu'apparaître et qui ne permet plus à unity de sauvegarder avec playerprefs :

NullReferenceException: Object reference not set to an instance of an object
savGameManager.Load () (at Assets/scripts/testScripts/saveGameObjects/savGameManager.cs:88)
savGameManager.Awake () (at Assets/scripts/testScripts/saveGameObjects/savGameManager.cs:33)

Je n'arrive pas à comprendre pourquoi unity me met cette erreur

J'avoue que j'ai énormément de mal à comprendre la logique de playerprefs qui ne semble pourtant pas compliqué...
J'avais essayé de faire un script plus simple en changeant la variable comme vous me l'aviez dit mais je n'y arrive pas :/

Est-ce que je peux abuser encore un peu de votre temps et vous demander si vous avez un exemple concret pour sauvegarder des gameobjects? (je ne demande pas un script complet juste un exemple pour que je vois comment m'y prendre concrètement)

La plupart des tutos sont bien expliqué mais j'en trouve pas qui utilisent playerprefs pour autre chose que des scores et c'est bête mais ça me bloque niveau compréhension :/

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

Re: [DB-AL] Sauvegarde de gameobjects avec playerprefs

Message par boubouk50 » 05 Sep 2017 14:21

Score ou autre, c'est le même principe. Tu sauvegardes une donnée: int, float ou string.
La doc: https://docs.unity3d.com/ScriptReferenc ... Prefs.html
Cherche un peu sur le forum en tapant playerprefs tu trouveras 36 pages qui en parlent et donc les codes associés.

Un Set enregistre ta donnée, un Get la récupère, un Save sauvegarde sur le disque. Il faut juste vérifier qu'elle existe pour ne pas avoir d'erreur.
Donc quand tu as une info a stocker -> Set puis Save.
Quand tu dois connaitre la valeur -> Get
Au final, ça s'utilise comme une variable, sauf que c'est stockée ailleurs et donc il faut aller chercher l'info.
"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

Auréane
Messages : 15
Inscription : 05 Sep 2017 10:10

Re: [DB-AL] Sauvegarde de gameobjects avec playerprefs

Message par Auréane » 05 Sep 2017 14:29

Dac je vais regarder sur le forum, j'avais déjà regardé vite fait mais le fait que ce soit un score me fait un blocage ^^'

Je vais bien finir par trouver ;)

Cette page de la doc j'ai fini par la connaitre par cœur :p mais c'est dans l'application que j'ai du mal ^^"

Merci beaucoup pour ton aide en tout cas !

Avatar de l’utilisateur
evereal
Messages : 109
Inscription : 06 Nov 2015 18:46

Re: [DB-AL] Sauvegarde de gameobjects avec playerprefs

Message par evereal » 05 Sep 2017 15:06

Hello,

Code bien fait, un peu trop complexe pour ton utilisation mais du moment que ça marche ça ira ^^.
Je ne sais pas comment est géré ta liste "List<saveableObject> SaveableObjects", il faut bien faire attention de garder la valeur de ton playerpref "ObjectCount" à jour lorsque tu instancies ou modifies ta liste (en appelant ta fonction Save).

Pour la question sur la fonction DestroySaveable, tous tes 'SpécificObject' héritent de la fonction DestroySaveable, tu peux l'appeler sans soucis. Surement avec bouton qui appelle une fonction prenant un int en paramètre :

Code : Tout sélectionner

public DestroyAt(i) {
  SaveableObjects[i].DestroySaveable();
}
Pour ta nouvelle erreur, ça indique la ligne 88. Hors dans le code du premier poste, c'est une ligne vide, je suppose que tu l'as modifié, pourrais tu l'éditer afin de mettre le code à jour ?

D’ailleurs, ce code est il appelé sur chacune de tes scène ?
“La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi. Ici, nous avons réuni théorie et pratique : Rien ne fonctionne... et personne ne sait pourquoi !”

Moi 1971
Messages : 727
Inscription : 29 Sep 2015 13:38

Re: [DB-AL] Sauvegarde de gameobjects avec playerprefs

Message par Moi 1971 » 05 Sep 2017 16:02

Bonjour,
"Mon soucis est dû au reset d'unity lorsque l'on passe d'une scène à une autre." => DontDestroyOnLoad
La Doc : https://docs.unity3d.com/ScriptReferenc ... nLoad.html
Bonne journée.

Répondre

Revenir vers « (C#) CSharp »