Imparare C#Imparare UnityPrincipianti

Il PlayerPrefs

Il PlayerPrefs è la classe di Unity che ci permetterà di effettuare i salvataggi permanenti, ovvero, tramite esso potremmo salvare lo stato del gioco nel momento della chiusura e ricaricare i dati alla riapertura dello stesso.
Esistono diversi modi per salvare permanentemente i dati su disco, il PlayerPrefs è sicuramente quello più immediato, anche se limitato ad una serie ristretta di tipi di dati.
Con il PlayerPrefs potremmo infatti salvare i dati di tipo float, int e string. Vedremo in seguito che esiste uno script non proprietario di Unity che permetterà di ampliare questo limite.
La classe PlayerPrefs non usa il salvataggio su file. La locazione dei salvataggi varia a seconda del dispositivo per cui si è sviluppato il gioco ma il funzionamento a livello di codice è il medesimo.
Vediamo il suo funzionamento in pochi brevi passaggi.

Appena scriveremo la parola PlayerPrefs , ci verranno elencati i metodi statici disponibili su questa classe. Prendiamo in esame i tre metodi che iniziano con la parola Set e i i tre corrispettivi metodi Get.
Set
sta per “setta“(salva) mentre Get sta per “prendi“(carica).
Come si può facilmente intuire, con SetFloat andremo a salvare un numero di tipo float mentre con GetFloat lo andremo a caricare.

Se peresempio volessimo salvare lo stato dell’energia del giocatore, potremmo scrivere:

 PlayerPrefs.SetFloat("EnergiaPlayer", playerEnergy);

Abbiamo usato il metodo SetFloat della classe PlayerPrefs che richiede due parametri, il nome con i quale andremo a salvare il dato (di tipo string) e il dato in questione (in questo caso, di tipo float).
In questo modo avremo salvato il dato di tipo float playerEnergy su disco, sotto il nome di EnergiaPlayer. Per convenzione, i nomi con cui salviamo le variabili su PlayerPrefs vengono chiamate keys (chiavi).
Notare che il nome scelto (la key) per il salvataggio è (e dovrà sempre essere) una stringa.

Per caricare lo stesso dato salvato su disco dovremmo usare l’istruzione GetFloat:

 playerEnergy = PlayerPrefs.GetFloat("EnergiaPlayer");

In questo modo abbiamo impostato la variabile playerEnergy uguale al dato presente su disco sotto il nome EnergiaPlayer.

Potremmo creare una semplice classe per il salvataggio dei dati chiamata SaveAndLoad con questi due metodi, uno per il salvataggio e uno per il caricamento:

using UnityEngine;

public class SaveAndLoad : MonoBehaviour {


    public float playerEnergy;

	void SavePlayerState () 
	{
        PlayerPrefs.SetFloat("EnergiaPlayer", playerEnergy);
	}


    void LoadPlayerState()
    {
        playerEnergy = PlayerPrefs.GetFloat("EnergiaPlayer");
    }
    

}

 

In questo modo avremo salvato solo un dato, ovvero l’energia del giocatore.
Sappiamo però che in un gioco complesso sarà necessario salvare molti più dati.
Per esempio, potremmo aggiungere il nome del giocatore e il suo punteggio attuale. Due variabili rispettivamente di tipo string e int.

using UnityEngine;

public class SaveAndLoad : MonoBehaviour {


    public float playerEnergy;
    public int playerPoints;
    public string playerName;

	void SavePlayerState () 
	{
        PlayerPrefs.SetFloat("EnergiaPlayer", playerEnergy);
        PlayerPrefs.SetInt("PuntiPlayer", playerPoints);
        PlayerPrefs.SetString("NomePlayer", playerName);
	}


    void LoadPlayerState()
    {
        playerEnergy = PlayerPrefs.GetFloat("EnergiaPlayer");
        playerPoints = PlayerPrefs.GetInt("PuntiPlayer");
        playerName = PlayerPrefs.GetString("NomePlayer");
    }
    

}

 

In questo modo abbiamo visto tutt e tre i tipi di variabili salvabili tramite PlayerPrefs, float, int e string.

 

Salvare un Vector3 su PlayerPrefs

E se volessimo salvare l’attuale posizione del player nella scena?
Come abbiamo visto non ci sono i Vector3 tra le variabili salvabili. Dovremmo quinti salvare tre variabili float corrispondenti alle tre componenti del Vector3, X,Y,Z.
Per caricarle dovremo in seguito “ricomporre” il Vector3 position del player.

using UnityEngine;

public class SaveAndLoad : MonoBehaviour {


    public float playerEnergy;
    public int playerPoints;
    public string playerName;
    public Transform Player; //Il Transform del player

	void SavePlayerState () 
	{
        PlayerPrefs.SetFloat("EnergiaPlayer", playerEnergy);
        PlayerPrefs.SetInt("PuntiPlayer", playerPoints);
        PlayerPrefs.SetString("NomePlayer", playerName);
        
        //Salvo individualmente le tre componenti della position del player
        PlayerPrefs.SetFloat("posizionePlayerX", Player.position.x);
        PlayerPrefs.SetFloat("posizionePlayerY", Player.position.y);
        PlayerPrefs.SetFloat("posizionePlayerZ", Player.position.z);
	}


    void LoadPlayerState()
    {
        playerEnergy = PlayerPrefs.GetFloat("EnergiaPlayer");
        playerPoints = PlayerPrefs.GetInt("PuntiPlayer");
        playerName = PlayerPrefs.GetString("NomePlayer");
        
        //Carico i valori su tre variabili temporanee
       float Xpos = PlayerPrefs.GetFloat("posizionePlayerX");
       float Ypos =  PlayerPrefs.GetFloat("posizionePlayerY");
       float Zpos =  PlayerPrefs.GetFloat("posizionePlayerZ");
       
       //Assegno i tre valori alla position del player
        Player.position = new Vector3(Xpos,Ypos,Zpos);
        
    }
    

}

 

Abbiamo salvato in modo separato le tre componenti della posizione del giocatore, rispettivamente con i keys:

  • posizionePlayerX
  • posizionePlayerY
  • posizionePlayerZ

Per caricarli dovremmo quindi “ricomporre” il Vector3 posizionePlayer caricandoci le tre variabili salvate su disco.
Questa operazione sembra un po’ troppo macchinosa, seppur necessaria. Considerando che sarà probabile che dovremmo salvare un sacco di posizioni di oggetti durante un gioco, dovremmo fare questa operazione per ogni Vector3.
A questo proposito, vi invito a dare un’occhiata allo script aggiuntivo presente in questo articolo. che ci permetterà di salvare i Vector3 con una sola riga di codice.

 
Se tentiamo di caricare qualche key che non esiste?

Prima di fare un caricamento potremmo controllare che sul PlayerPrefs esista una determinata key.
Con questa riga:
PlayerPrefs.HasKey(“nomeKey”)
che restituisce un valore booleano, vero se nomeKey esiste e falso se nomeKey non esiste.

if(PlayerPrefs.HasKey("EnergiaPlayer"))
{    
    //se esiste un dato salvato con il nome NomePlayer, assegnalo alla variabile playerName 
    playerName = PlayerPrefs.GetString("NomePlayer");
}
else
{
    //Se non esiste nessun dato salvato con la key NomePlayer, assegnagli "Pippo" di default 
    playerName = "Pippo";
    
}

 

Senza fare un controllo, nel caso la key che si tenta di caricare non esista, non avremo un errore, ma alla variabile sarà assegnato un valore di default (stringa vuota in caso di string, e 0 in caso di float o int).

Un pensiero su “Il PlayerPrefs

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *