I denna handledning bygger vi ett enkelt spel där spelaren kan spola tillbaka framsteg i enhet (det kan också anpassas till arbete i andra system). Denna första del kommer att gå in i systemets grunder, och nästa del kommer att krossa den och göra den mycket mångsidigare.
Först, även om vi tar en titt på vilka spel som använder det här. Då tittar vi på de andra användningarna för denna tekniska installation, innan vi slutligen skapar ett litet spel som vi kan spola tillbaka, vilket borde ge dig en grund för din egen.
En demonstation av den grundläggande funktionalitetenDu behöver den senaste versionen av Unity för detta och borde ha lite erfarenhet av det. Källkoden är också tillgänglig för nedladdning om du vill kontrollera dina egna framsteg mot den.
Redo? Nu går vi!
Prince of Persia: Sands of Time är ett av de första spelen som verkligen integrerar en tidspolar mekaniker i sin gameplay. När du dör måste du inte bara ladda om, men du kan spola tillbaka spelet några sekunder till var du levde igen och försök igen omedelbart.
Prince of Persia: The Forgotten Sands. De Sands Of Time Trilogi integrerar tidspolning vackert i sin gameplay och undviker nedsänkningshastighet snabbt omladdning.Denna mekaniker integreras inte bara i spelningen, men också berättelsen och universum och nämns i hela berättelsen.
Andra spel som använder dessa system är Fläta, till exempel, som också är centrerad kring tidens lindning. Hjälte Tracer in Overwatch har en kraft som återställer henne till en position för några sekunder sedan, i huvudsak omlindningsmaskin hennes tid, även i ett multiplayer-spel. De RUTNÄT-serie racing spel har också en ögonblicksmekaniker, där du har en liten pool av återspolning under en tävling, som du kan komma åt när du har en kritisk krasch. Detta förhindrar frustration som orsakas av krascher nära slutet av tävlingen, vilket kan vara särskilt oroande.
Men det här systemet kan inte bara användas för att ersätta snabbbesparande. Ett annat sätt som detta är anställt är spöken i tävlingsspel och asynkron multiplayer.
Replays är ett annat roligt sätt att använda denna funktion. Detta kan ses i spel som Superhot, de maskar serier, och i stort sett majoriteten av sportspel.
Sport-replays fungerar på samma sätt som de presenteras på TV, där en åtgärd visas igen, möjligen från en annan vinkel. För detta är inte en video inspelad utan snarare användarens handlingar, vilket gör det möjligt för replay att använda olika kameravinklar och -bilder. Worms-spelen använder detta på ett humoristiskt sätt, där mycket komiska eller effektiva dödar visas i en omedelbar replay.
SUPERHOT registrerar också din rörelse. När du är färdig spelar hela din framsteg på nytt och visar några sekunder av den aktuella rörelsen som hände.
Super Meat Boy använder detta på ett roligt sätt. När du avslutar en nivå ser du en återspelning av alla dina tidigare försök som ligger ovanpå varandra, vilket kulminerar med din avslutande körning som den sista vänstra stående.
End-of-level replay i Super kött pojke. Var och en av dina tidigare försök spelas in och spelas sedan upp samtidigt.Race-Ghosting är en teknik där du kappar för den bästa tiden på ett tomt spår. Men samtidigt kämpar du mot en spöke, vilket är en spöklikt transparent bil, som driver det exakta sättet du körde förrän på bästa försök. Du kan inte kollidera med det, vilket innebär att du fortfarande kan koncentrera dig på att få den bästa tiden.
I stället för att köra ensam kommer du till konkurrera mot dig själv, vilket gör tidförsök mycket roligare. Denna funktion visas i de flesta tävlingsspel, från Behov av hastighet serie till Diddy Kong Racing.
Racing ett spöke i Trackmania Nations. Den här har silver svårigheten, vilket betyder att jag kommer att få silvermedalj om jag slår dem. Observera överlappningen i bilmodeller, vilket visar att spöken inte är kroppslig och kan drivas igenom.Asynkron Multiplayer-Ghosting är ett annat sätt att använda denna inställning. I denna sällan använda funktion uppnås multiplayer-matchningar genom att spela in data från en spelare, som sedan skickar sin körning till en annan spelare, som senare kan slåss mot den första spelaren. Uppgifterna appliceras på samma sätt som en tidsprövning-spöke skulle vara, bara att du tävlar mot en annan spelare.
En form av detta dyker upp i Trackmania-spel, där det är möjligt att tävla mot vissa svårigheter. Dessa inspelade racers ger dig en motståndare att slå för en viss belöning.
Få spel erbjuder detta från get-go men används rätt det kan vara ett roligt verktyg.Team Fortress 2 erbjuder en inbyggd replay-editor, med vilken du kan skapa egna klipp.
Uppspelningsredigeraren från Team Fortress 2. När en gång spelats in kan en match ses från något perspektiv, inte bara spelarens.När funktionen har aktiverats kan du spela in och titta på tidigare matchningar. Det viktiga är det allt är inspelad, inte bara din åsikt. Det betyder att du kan flytta runt den inspelade spelvärlden, se var alla är, och ha kontroll över tiden.
För att testa detta system behöver vi ett enkelt spel där vi kan testa det. Låt oss skapa en!
Skapa en kub i din scen, det här blir vår spelar-karaktär. Skapa sedan ett nytt C # -script-samtal Player.cs
och anpassa Uppdatering()
-funktion att se så här ut:
void Update () transform.Translate (Vector3.forward * 3.0f * Time.deltaTime * Input.GetAxis ("Vertikal")); transform.Rotate (Vector3.up * 200.0f * Time.deltaTime * Input.GetAxis ("Horizontal"));
Detta kommer att hantera enkel rörelse via piltangenterna. Fäst detta skript i spelarkuben. När du nu träffar spel borde du redan kunna flytta runt.
Vinkla sedan kameran så att den ser kuben ovanifrån med rum på sidan där vi kan flytta den. Slutligen skapa ett plan för att fungera som golv och tilldela olika material till varje objekt så att vi inte flyttar det inuti en tomrum. Det ska se ut så här:
Prova det, och du borde kunna flytta din kub med WSAD och piltangenterna.
Skapa nu ett nytt C # -skript som heter TimeController.cs
och lägg till det till en ny tom GameObject. Detta kommer att hantera den faktiska inspelningen och efterföljande återspolning av spelet.
För att göra detta arbete registrerar vi spelarens karaktärs rörelse. När vi trycker på spolningsknappen kommer vi att anpassa spelarens koordinater. För att göra så börja med att skapa en variabel för att hålla spelaren, så här:
allmän GameObject-spelare;
Och tilldela spelaren objektet till den resulterande luckan på TimeController så att den kan komma åt spelaren och dess data.
Då måste vi skapa en matris för att hålla spelardata:
offentlig ArrayList playerPositions; void Start () playerPositions = new ArrayList ();
Vad vi kommer att göra är att kontinuerligt spela in spelarens position. Vi kommer att ha den position som lagrats där spelaren var i den sista bilden, läget där spelaren var 6 ramar sedan och läget där spelaren var 8 sekunder sedan (eller hur länge du ställer in den för att spela in). När vi senare trycker på en knapp kommer vi att gå bakåt genom vårt utbud av positioner och tilldela det ram för bildram, vilket resulterar i en tidsåterkallningsfunktion.
Låt oss först spara data:
void FixedUpdate () playerPositions.Add (player.transform.position);
I FixedUpdate ()
-funktion vi registrerar data. FixedUpdate ()
används när den körs med en konstant 50 cykler per sekund (eller vad du än väljer), vilket möjliggör ett bestämt intervall för att spela in och ställa in data. De Uppdatering()
-Funktionen fungerar under tiden beroende på hur många ramar CPU hanterar, vilket skulle göra det svårare.
Denna kod lagrar spelarens position för varje ram i arrayen. Nu måste vi tillämpa det!
Vi lägger till en check för att se om spolningsknappen trycks ned. För detta behöver vi en boolesisk variabel:
allmän bool är Reversing = false;
Och en check i Uppdatering()
-funktionen för att ställa in beroende på om vi vill spola tillbaka spel:
void Update () if (Input.GetKey (KeyCode.Space)) isReversing = true; else isReversing = false;
För att göra spelet köra bakåt, Vi kommer att tillämpa data istället för inspelning. Den nya koden för inspelning och tillämpning av spelarpositionen ska se ut så här:
void FixedUpdate () if (! isReversing) playerPositions.Add (player.transform.position); annars player.transform.position = (Vector3) playerPositions [playerPositions.Count - 1]; playerPositions.RemoveAt (playerPositions.Count - 1);
Och hela TimeController
-skript så här:
använder UnityEngine; Använda System.Collections; offentlig klass TimeController: MonoBehaviour public GameObject player; offentlig ArrayList playerPositions; allmän bool är Reversing = false; void Start () playerPositions = new ArrayList (); void Update () if (Input.GetKey (KeyCode.Space)) isReversing = true; else isReversing = false; void FixedUpdate () if (! isReversing) playerPositions.Add (player.transform.position); annars player.transform.position = (Vector3) playerPositions [playerPositions.Count - 1]; playerPositions.RemoveAt (playerPositions.Count - 1);
Glöm inte att lägga till en check till spelare
-klass för att se om TimeController
Återspolar eller ej, och rör sig bara när det inte går tillbaka. Annars kan det skapa buggybeteende:
använder UnityEngine; Använda System.Collections; allmän klass spelare: MonoBehaviour privat TimeController timeController; void Start () timeController = FindObjectOfType (typof (TimeController)) som TimeController; void Update () if (! timeController.isReversing) transform.Translate (Vector3.forward * 3.0f * Time.deltaTime * Input.GetAxis ("Vertikal")); transform.Rotate (Vector3.up * 200.0f * Time.deltaTime * Input.GetAxis ("Horizontal"));
Dessa nya linjer kommer automatiskt att hitta TimeController
-objekt i scenen vid uppstart och kontrollera det under körtiden för att se om vi spelar för närvarande spelet eller återspolar det. Vi kan bara styra karaktären när vi för närvarande inte går tillbaka.
Nu borde du kunna flytta runt om i världen och spola tillbaka din rörelse genom att trycka på mellanslag. Om du laddar ner byggpaketet som bifogas denna artikel och öppnas TimeRewindingFunctionality01 du kan prova det!
Men vänta, varför fortsätter vår enkla spelare-kub i den sista riktningen vi lämnade in dem? Eftersom vi inte kom omkring för att spela in dess rotation!
För att du behöver en annan matris för att behålla dess rotationsvärden, för att inställa den i början och för att spara och tillämpa data på samma sätt som vi hanterade positionsdata.
använder UnityEngine; Använda System.Collections; offentlig klass TimeController: MonoBehaviour public GameObject player; offentlig ArrayList playerPositions; offentlig ArrayList playerRotations; allmän bool är Reversing = false; void Start () playerPositions = new ArrayList (); playerRotations = new ArrayList (); void Update () if (Input.GetKey (KeyCode.Space)) isReversing = true; else isReversing = false; void FixedUpdate () if (! isReversing) playerPositions.Add (player.transform.position); playerRotations.Add (player.transform.localEulerAngles); annars player.transform.position = (Vector3) playerPositions [playerPositions.Count - 1]; playerPositions.RemoveAt (playerPositions.Count - 1); player.transform.localEulerAngles = (Vector3) playerRotations [playerRotations.Count - 1]; playerRotations.RemoveAt (playerRotations.Count - 1);
Testa! TimeRewindingFunctionality02 är den förbättrade versionen. Nu kan vår spelare-kub ligga bakåt i tiden, och kommer att se på samma sätt som den gjorde när det var just nu.
Vi har byggt ett enkelt prototypspel med ett redan användbart tidspolningssystem, men det är långt ifrån gjort än. I nästa del av serien kommer vi att göra det mycket stabilare och mångsidigare och lägga till några snygga effekter.
Här är vad vi fortfarande behöver göra:
Vi ska också titta på hur du förlänger detta system förbi bara spelartecken: