Hur man sparar och laddar dina spelares framsteg i enhet

Vad du ska skapa

I denna handledning lär du dig att implementera ett enkelt system för att skapa och hantera spara spel för dina Unity-spel. Vi kommer att bygga ramverket för a Final Fantasy-som huvudmeny som gör det möjligt för spelare att skapa nya, unika spara filer och att ladda befintliga. De principer som demonstreras gör att du kan utöka dem till vad som helst i ditt spel. 

I slutet av handledningen har du lärt dig hur man:

  • spara och ladda speldata inom Unity3D med serialisering
  • använd statiska variabler för att fortsätta data över scenförändringar

Obs! Det här sättet att spara och ladda speldata fungerar på alla plattformar förutom webbspelaren. För information om hur du sparar speldata i Web Player, ta en titt på de officiella dokumenten på Unity Web Player och webbläsarkommunikation.

Låt oss få seriell

Det första vi ska göra är att skapa en kod som gör det möjligt för oss att serialisera vår speldata, det vill säga konvertera den till ett format som kan sparas och senare återställas. För detta, låt oss skapa ett C # -skript och kalla det Spara last. Detta skript kommer att hantera alla spara och ladda funktioner. 

Vi kommer att referera till detta skript från andra skript, så låt oss göra det till en statisk klass genom att lägga till ordet statisk mellan offentlig och klass. Låt oss också ta bort : MonoBehaviour del, för att vi inte behöver bifoga den till en GameObject. Och eftersom det inte längre ärver från MonoBehaviour, låt oss ta bort Start och Uppdatering funktioner. 

Den resulterande koden ska se ut så här:

använder UnityEngine; Använda System.Collections; offentlig statisk klass SaveLoad 

Nu ska vi lägga till lite ny funktionalitet till det här skriptet, så omedelbart under var det står Använda System.Collections;, lägg till följande:

använder System.Collections.Generic; använder System.Runtime.Serialization.Formatters.Binary; använder system.IO;

Den första raden tillåter oss att använda dynamiska listor i C #, men detta är inte nödvändigt för serialisering. Den andra raden är det som gör att vi kan använda operativsystemets serialiseringsfunktioner inom skriptet. I den tredje raden, IO står för Ingång / utgång, och det som låter oss skriva till och läsa från vår dator eller mobilenhet. Med andra ord tillåter denna rad oss ​​att skapa unika filer och sedan läsa av dem senare.

Vi är nu redo att serialisera vissa data!

Att göra serialiserbara klasser

Nu när vårt skript har möjlighet att serialisera, måste vi sätta upp några klasser för att kunna serialiseras. Om du tycker om en grundläggande RPG, gillar du Final Fantasy, Det ger spelare möjligheten att skapa och ladda olika sparade spel. Så skapa ett nytt C # -skript som heter Speloch ge det några variabler att hålla tre objekt: a riddare, en skurk, och a trollkarl. Ändra koden för det här skriptet för att se så här ut:

använder UnityEngine; Använda System.Collections; [System.Serializable] public class Game public static Game current; allmän karaktär riddare; allmän karaktär allmän karaktärsguiden offentligt spel () knight = nytt tecken (); rogue = nytt tecken (); guiden = ny tecken (); 

De [System.Serializable] linjen berättar för enhet att detta skript kan vara serialiserade-med andra ord, att vi kan spara alla variabler i det här skriptet. Häftigt! Enligt de officiella dokumenten kan Unity serialisera följande typer:

  • Alla grundläggande datatyper (som int, sträng, flyta, och bool).
  • Vissa inbyggda typer (inklusive Vector2, Vector3, Vector4, quaternion, Matrix4x4, Färg, rect, och LayerMask).
  • Alla klasser som ärva från UnityEngine.Object (Inklusive GameObject, Komponent, MonoBehavior, Texture2D, och AnimationClip).
  • Enums.
  • Arrayer och listor med serialiserande typ.

Den första variabeln, nuvarande, är en statisk referens till a Spel exempel. När vi skapar eller laddar ett spel ska vi ställa in den här statiska variabeln för den specifika spelinstansen så att vi kan referera till det aktuella spelet från var som helst i projektet. Genom att använda statiska variabler och funktioner behöver vi inte använda en gameObject's GetComponent () fungera. Praktisk! 

Observera att det refererar till något som heter a Karaktär? Vi har inte det ännu, så låt oss skapa ett nytt manus för att hylla den här klassen och ringa den Karaktär:

använder UnityEngine; Använda System.Collections; [System.Serializable] public class Character public string name; allmän karaktär () this.name = ""; 

Du kanske undrar varför vi behövde en helt ny klass om vi bara lagrar en strängvariabel. Vi kan faktiskt bara ersätta Karaktär i Spel skript att använda sträng istället. Men jag vill visa dig hur djupt kaninhålet kan gå: du kan spara och ladda klasser som hänvisar till andra klasser, och så vidare, så länge som varje klass är serialiserbar

Nu när våra klasser är inrättade för att bli räddade och laddade, låt oss hoppa tillbaka till vår Spara last skript och lägga till möjligheten att spara spel.

Spara ett spelets tillstånd

En "Ladda spel" -meny visar vanligtvis en lista över sparade spel, så låt oss skapa en Lista av typ Spel och kalla det savedGames. Gör det till en statisk lista, så att det bara finns en lista med sparade spel i vårt projekt. Koden ska se så här ut:

använder UnityEngine; Använda System.Collections; använder System.Collections.Generic; använder System.Runtime.Serialization.Formatters.Binary; använder system.IO; offentlig statisk klass SaveLoad offentlig statisk lista savedGames = ny lista(); 

Låt oss sedan skapa en ny statisk funktion för att spara ett spel:

 offentlig statisk tomgång Spara () savedGames.Add (Game.current); BinaryFormatter bf = ny BinaryFormatter (); FileStream file = File.Create (Application.persistentDataPath + "/savedGames.gd"); bf.Serialize (file, SaveLoad.savedGames); file.Close ();  

Linje 2 lägger till vårt nuvarande spel i vår lista över sparade spel. Den listan är vad vi ska serialisera. För att göra det måste vi först skapa en ny BinaryFormatter, som kommer att hantera serialiseringsarbetet. Så här gör linje 3.

I rad 4 skapar vi en Filestream, som i grund och botten är en väg till en ny fil som vi kan skicka data till, som att fisk simma nedströms i en flod. Vi använder File.Create () att skapa en ny fil på platsen vi skickar in som sin parameter. Bekvämt har Unity ett inbyggt läge för att lagra våra spelfiler (vilka uppdateringar bygger automatiskt på vilken plattform ditt spel är byggt till) som vi kan referera till med Application.persistentDataPath

Eftersom vi skapar en ny fil kan vi dock inte bara säga var filen är, vi måste också kappa bort den här vägen med namnet på själva filen. Det finns två delar till den här filen:

  1. filnamnet
  2. filtypen

Vi ska använda savedGames för filnamnet, och vi använder en anpassad datatyp gd (för "speldata") för filtypen. Vårt resultat är en spelfil som heter savedGames.gd på den plats som anges av Application.persistentDataPath. (I framtiden kan du spara andra typer av saker till den här datatypen, till exempel kan du spara användarnas alternativinställningar som options.gd.)

Notera: Du kan göra filtypen du vill ha. Till exempel använder Elder Scrolls-serien .ESM som filtyp Du kunde ha sagt så enkelt savedGames.baconAndGravy.

I linje 5 ringer vi på serialisera funktionaliteten hos BinaryFormatter för att rädda vårt savedGames lista till vår nya fil. Därefter har vi nära filen vi skapade, i rad 6. 

Badda bing, badda boom. Våra spel är sparade.

Laddar en spelstat

I Spara funktionen serialiserades vår lista över sparade spel på en viss plats. Omvänt bör koden för att ladda våra spel se ut så här:

 statisk statisk tomgång Load () if (File.Exists (Application.persistentDataPath + "/savedGames.gd")) BinaryFormatter bf = new BinaryFormatter (); FileStream file = File.Open (Application.persistentDataPath + "/savedGames.gd", FileMode.Open); SaveLoad.savedGames = (Lista) Bf.Deserialize (fil); file.Close (); 

I linje 2 kontrollerar vi om en sparad spelfil finns. (Om det inte gör det kommer det inte att läsas, självklart.) I rad 3 skapar vi en BinaryFormatter på samma sätt som vi gjorde i Spara fungera. I rad 4 skapar vi en Filestream-men den här gången simmarar fisken uppströms från filen. Således använder vi Fil.Öppna, och peka på var vår savedGames.gd existerar med samma Application.persistentDataPath sträng. 

Linje 5 är lite tät, så låt oss packa upp det: 

  • De bf.Deserialize (fil) samtal hittar filen på den plats som vi angav ovan och deserialiserar den. 
  • Vi kan inte bara spotta binära i Unity och förvänta oss att det ska fungera, men vi konvertera (eller cast) vår deserialiserade fil till den datatyp vi vill att den ska vara, vilket i detta fall är a Lista av typ spel. 
  • Vi ställer sedan in den listan som vår lista över sparade spel. 

Slutligen, i linje 6 stänger vi den filen på samma sätt som vi gjorde i Spara fungera. 

Notera: Datatypen som du kastar de deserialiserade dataen kan ändras beroende på vad du behöver det för att vara. Till exempel, Player.lives = (int) bf.Dererialize (file);.

Slutsats

Vår Spara last Skriptet är nu klart och bör se ut så här:

använder UnityEngine; Använda System.Collections; använder System.Collections.Generic; använder System.Runtime.Serialization.Formatters.Binary; använder system.IO; offentlig statisk klass SaveLoad offentlig statisk lista savedGames = ny lista(); // det är statiskt så vi kan kalla det från var som helst statisk statisk tomt Spara () SaveLoad.savedGames.Add (Game.current); BinaryFormatter bf = ny BinaryFormatter (); //Application.persistentDataPath är en sträng, så om du ville att du kan lägga in det i debug.log om du vill veta var spara spel finns FileStream file = File.Create (Application.persistentDataPath + "/savedGames.gd"); // du kan kalla det vad du vill bf.Serialize (file, SaveLoad.savedGames); file.Close ();  statisk statisk tomgång () if File.Exists (Application.persistentDataPath + "/savedGames.gd")) BinaryFormatter bf = new BinaryFormatter (); FileStream file = File.Open (Application.persistentDataPath + "/savedGames.gd", FileMode.Open); SaveLoad.savedGames = (Lista) Bf.Deserialize (fil); file.Close ();  

Det är grunderna att spara och ladda i Unity. I den bifogade projektfilen hittar du några andra skript som visar hur jag hanterar att ringa dessa funktioner och hur jag visar data med hjälp av Unitys GUI.

Om du behöver en start med din spelutveckling, försök Unity3D-mallarna som finns på Envato Market.