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:
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.
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!
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 Spel
och 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:
int
, sträng
, flyta
, och bool
).Vector2
, Vector3
, Vector4
, quaternion
, Matrix4x4
, Färg
, rect
, och LayerMask
).UnityEngine.Object
(Inklusive GameObject
, Komponent
, MonoBehavior
, Texture2D
, och AnimationClip
).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.
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 listasavedGames = 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:
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.
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:
bf.Deserialize (fil)
samtal hittar filen på den plats som vi angav ovan och deserialiserar den. Lista
av typ 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);
.
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 listasavedGames = 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.