web-dev-qa-db-fra.com

Unity - transmettre des données entre les scènes

Comment passer la valeur du score d'une scène à une autre?

J'ai essayé ce qui suit:

Scène un:

void Start () {
    score = 0;
    updateScoreView ();
    StartCoroutine (DelayLoadlevel(20));
}

public void updateScoreView(){
    score_text.text = "The Score: "+ score;
}

public void AddNewScore(int NewscoreValue){
    score = score + NewscoreValue;
    updateScoreView ();
}

IEnumerator DelayLoadlevel(float seconds){        
    yield return new WaitForSeconds(10);
    secondsLeft = seconds;
    loadingStart = true;
    do {        
        yield return new WaitForSeconds(1);
    } while(--secondsLeft >0);

    // here I should store my last score before move to level two
    PlayerPrefs.SetInt ("player_score", score);
    Application.LoadLevel (2);
}

Scène deux:

public Text score_text;
private int old_score;

// Use this for initialization
void Start () {    
    old_score = PlayerPrefs.GetInt ("player_score");
    score_text.text = "new score" + old_score.ToString ();      
}

mais rien ne s'affiche à l'écran, et il n'y a pas d'erreur.

Est-ce la bonne façon de transmettre des données?

J'utilise l'édition gratuite de Unity 5, je développe un jeu pour Gear VR (ce qui signifie que le jeu fonctionnera sur les appareils Android).

Toute suggestion?

14
Mina Fawzy

En plus de playerPrefs, un autre moyen sale est de conserver un objet pendant le chargement de niveau en appelant DontDestroyOnLoad dessus.

DontDestroyOnLoad (transform.gameObject);

Tout script attaché à l'objet du jeu survivra, tout comme les variables du script. La fonction DontDestroyOnLoad est généralement utilisée pour conserver l'intégralité d'un GameObject, y compris les composants qui lui sont attachés et tous les objets enfants qu'elle possède dans la hiérarchie.

Vous pouvez créer un GameObject vide et y placer uniquement le script contenant les variables que vous souhaitez conserver.

9
Isj

Il existe 3 façons de procéder, mais la solution dépend du type de données que vous souhaitez transmettre entre les scènes. Les composants/scripts et GameObjects sont détruits lors du chargement d'une nouvelle scène et même lorsqu'ils sont marqués comme static.

1. Utilisez le mot clé static.

Utilisez cette méthode si la variable à passer à la scène suivante n'est pas un composant, n'hérite pas de MonoBehaviour et n'est pas un GameObject alors faites que la variable soit static.

Types de données primitifs intégrés tels que int, bool, string, float, double. Toutes ces variables peuvent être transformées en une variable static.

Exemple de types de données primitifs intégrés qui peut être marqués comme statiques :

static int counter = 0;
static bool enableAudio = 0;
static float timer = 100;

Ceux-ci devraient fonctionner sans problème.


Exemple d'objets qui peut être marqués comme statiques :

public class MyTestScriptNoMonoBehaviour
{

}

ensuite

static MyTestScriptNoMonoBehaviour testScriptNoMono;

void Start()
{
    testScriptNoMono = new MyTestScriptNoMonoBehaviour();
}

Notez que la classe n'hérite pas de MonoBehaviour . Cela devrait fonctionner.


Exemple d'objets qui ne peut pas être marqués comme statiques :

Tout ce qui hérite de Object , Component ou GameObject sera ne fonctionne pas .

1A . Tout ce qui hérite de MonoBehaviour

public class MyTestScript : MonoBehaviour 
{

}

ensuite

static MyTestScript testScript;

void Start()
{
    testScript = gameObject.AddComponent<MyTestScript>();
} 

Cela ne fonctionnera pas car il hérite de MonoBehaviour .

1B . Tous GameObject :

static GameObject obj;

void Start()
{
    obj = new GameObject("My Object");
}  

Cela ne fonctionnera pas non plus car il s'agit d'un GameObject et GameObject hérite d'un Object .

Unity détruira toujours ses Object même s'ils sont déclarés avec le mot clé static.

Voir # 2 pour une solution de contournement.


2.Utilisez la fonction DontDestroyOnLoad.

Vous ne devez l'utiliser que si les données à conserver ou à passer à la scène suivante héritent de Object , Component ou est un - GameObject . Cela résout le problème décrit dans 1A et 1B .

Vous pouvez l'utiliser pour que ce GameObject ne se détruise pas lors du déchargement de la scène:

void Awake() 
{
    DontDestroyOnLoad(transform.gameObject);
}

Vous pouvez même l'utiliser avec le mot-clé static pour résoudre le problème de 1A et 1B :

public class MyTestScript : MonoBehaviour 
{

}

ensuite

static MyTestScript testScript;

void Awake() 
{
    DontDestroyOnLoad(transform.gameObject);
}

void Start()
{
    testScript = gameObject.AddComponent<MyTestScript>();
} 

La variable testScript sera désormais conservée lors du chargement d'une nouvelle scène.

3.Enregistrer sur le stockage local puis charger pendant la scène suivante.

Cette méthode doit être utilisée lorsqu'il s'agit de données de jeu qui doivent être conservées lorsque le jeu est fermé et rouvert. Par exemple, le score élevé du joueur, les paramètres du jeu tels que le volume de la musique, l'emplacement des objets, les données de profil du joystick, etc.

Il y a deux façons de l'enregistrer:

3A . Utilisez l'API PlayerPrefs .

À utiliser si vous n'avez que quelques variables à enregistrer. Disons que le score du joueur:

int playerScore = 80;

Et nous voulons enregistrer playerScore:

Enregistrez le score dans la fonction OnDisable

void OnDisable()
{
    PlayerPrefs.SetInt("score", playerScore);
}

Chargez-le dans la fonction OnEnable

void OnEnable()
{
    playerScore  =  PlayerPrefs.GetInt("score");
}

3B . Sérialisez les données au format json, xml ou binaray puis enregistrez en utilisant l'une des API de fichier C # telles que File.WriteAllBytes et File.ReadAllBytes pour enregistrer et charger des fichiers.

Utilisez cette méthode s'il existe de nombreuses variables à enregistrer.

Général, vous devez créer une classe qui n'hérite pas de MonoBehaviour . Cette classe que vous devez utiliser pour conserver vos données de jeu afin qu'elles puissent être facilement sérialisées ou désérialisées.

Exemple de données à enregistrer:

[Serializable]
public class PlayerInfo
{
    public List<int> ID = new List<int>();
    public List<int> Amounts = new List<int>();
    public int life = 0;
    public float highScore = 0;
}

Prenez la classe DataSaver qui est un wrapper sur File.WriteAllBytes et File.ReadAllBytes qui facilite la sauvegarde des données de this post.

Créer une nouvelle instance:

PlayerInfo saveData = new PlayerInfo();
saveData.life = 99;
saveData.highScore = 40;

Enregistrer les données de PlayerInfo dans un fichier nommé "joueurs":

DataSaver.saveData(saveData, "players");

Charger les données d'un fichier nommé "joueurs":

PlayerInfo loadedData = DataSaver.loadData<PlayerInfo>("players");
44
Programmer