Smoke & Mirrors of Good Countdowns, Del 2

Vad du ska skapa

Förra gången tittade vi på nedräkningar i spel, hur de är inställda och vilka element du kan använda för att göra dem mer engagerande. Det finns dock mycket mer än vad som passar in i en enda artikel!

Detta fortsätter från del 1, varför vi börjar vid nummer sju.

Redo? Nu går vi!

7: Har en annan konstant Ticking Speed

Detta är ett enkelt trick som inte ens kräver att du ljuger för spelaren. Du säger bara "när timern löper ut" och visa en kryssande klocka. Vad du inte nämner är enhet som visas.

Om du visar en "10", kommer spelaren att intuita detta är 10 sekunder, men numret kan minska långsammare än sekunder skulle. Om du ändrar värdet med a 0,5 multiplikatorn, till exempel kommer den att springa efter 20 sekunder istället för bara 10.

Du kan titta på hur det här fungerar i mitt Ludum-Dare-spel, varje tio sekunder dricker en kattunge.

En timer i Varje tio sekunder dricker en kattunge. Timern är långsam nog för att ge spelaren en ganska lång tid samtidigt som den fortfarande är mycket låg

Temaet av sylt krävde det 10 sekunder används, men 10 faktiska sekunder är en alltför låg tid för att uppnå något meningsfullt.

8: Anpassa tickningshastigheten under spel

Detta fungerar också bättre om tidsenheter inte nämns och spelaren får bara en grov uppfattning om "tills det händer".

Om du har en serie paneler som tänds för att visa timerframsteg, behöver du inte aktivera dem i samma takt. Faktum är att det blir mer intensivt om de första fångar upp snabbt, och de senare har mer tid mellan dem. I värmen av actionfylld spelning kommer spelaren inte att inse det här och kommer att få en mycket mer intensiv upplevelse.

Detta bör inte vara anställd med aktuella tidsenheter, eftersom spelare kan känna sig lurade och ljög för. Bryt inte spelarens förtroende för ditt system.

Detta kan ses på en nivå av Starfox 64, där spelaren måste försvara en position mot ett närmarande jätte fartyg.

Minimap in Starfox 64. Det angripande moderskapet (den svarta cirkeln) rör sig mot basen i mitten, vilket ger spelaren en grov tickande klocka om hur mycket tid som finns kvar för att förstöra det

Vid första anblicken får du en grov uppfattning om hur mycket tid som är kvar, men själva skeppet verkar flytta med olika hastigheter och inte i en rak linje.

Timern är i huvudsak anpassad till flugan, vars process är dold bakom rök och speglar.

9: Använd ljud

Nedräkningar behöver inte vara rent optiska! Ett pip ljud varje par sekunder kommer kraftigt förbättra nedsänkning.

När du har det kan du också anpassa frekvensen när en viss tid har gått. Om pipen inträffar vart femte sekund, spelas spelaren under de sista 30 sekunderna av timern utan att behöva titta på numret och beräkna hur mycket det är kvar.

På samma sätt hjälper det också om en karaktär kommenterar framstegen. Att ha någon säga "Vi är halvvägs gjort!" ger dig en väl inramad information som är mycket lättare att förstå än att analysera den från en avläsning.

10: Använd skalningsvisualer

Detta fungerar väldigt bra när räknaren närmar sig slutet. När en annan sekund löper, skala upp hela räknaren i en halv sekund.

Förutom färg och ljud, kommer det att göra det mycket juicier.

11: Gör någonting när det når noll

Se till att en timer aldrig går negativ - det här kommer att vara förvirrande för många människor och verkar som en bugg, som buggged, dåligt skapade tidtagare brukar göra det.

Att ha det flash skulle vara en fin touch, eftersom det igen understryker att det bara har slutfört.

Om du har en positiv timer är det ett roligt element för att bara låta det fortsätta springa och använda det elementet som ett högt betyg. Spelet Devil Daggers gör en liknande sak, där huvudmålet är "Survive 500 seconds".

Gameplay från Devil Daggers

Vad som inte gör det skulle bryta spelarens förtroende

När reglerna för en timer har upprättats, borde de förbli ungefär konsekvent, med mer utrymme tillåtet desto mindre exakt är en timer. Huvudfrågan borde vara "Hur går den här dolda regeln till nytta för upplevelsen?"

När du saktar ner en timer under de senaste tre sekunderna kommer det att göra situationen mer spänd och ge spelaren några mer faktiska sekunder för att utföra saker. Slumpmässigt sakta ner det i mitten, eller påskynda det, kommer bara att bryta spelarens förtroende för dina regler.

Låt oss bygga den

Detta fortsätter med kodbasen från den sista handledningen och bygger vidare på den. Om du inte har markerat det ännu, gör det nu! Du kan också ladda ner den färdiga källan till höger om den här artikeln.

När vi senast lämnade vår timer såg det så här ut:

Nu kommer nya tillägg att få det att fungera mer intressant. Vi fortsätter med countdown.cs-script, vilken ska se så här ut:

använder UnityEngine; Använda System.Collections; offentlig klass Nedräkning: MonoBehaviour float timer = 60f; offentliga AudioClip soundBlip; void Update () if (timer> 0f) timer - = Time.deltaTime;  annars timer = 0f;  om (timer < 10f)  GetComponent() .färg = Color.red;  annars om (timer < 20f)  GetComponent() .färg = Color.yellow;  GetComponent() .text = timer.ToString ("F2");  

Gör det pip

Låt oss göra vår timer pip varje sekund, så att spelaren vet att den minskar även utan att titta på den.

Först behöver vi ett bra blip ljudeffekt. Du kan hitta en ljudfil i källfilerna, eller skapa en bra med det fria verktyget BFXR. När du har en, kopiera den till din aktivmapp.

Lägg till en AudioSource-komponent i ditt nedräkningsobjekt via Komponent> Audio> AudioSource. Lägg till den här variabeln till nedräkningsskriptet:

offentliga AudioClip soundBlip;

Du måste också tilldela ljudfilen till soundBlip variabel:

Och lägg till det här blocket till Uppdatering fungera:

om (Mathf.Round (timer * 100) / 100% 1f == 0) GetComponent() .PlayOneShot (soundBlip); 

Detta kommer att kontrollera om timern är med fullt andra märke, och om så spelar ljudfilen.

Den faktiska funktionen av denna kod är lite mer komplicerad. Vad det gör är första omgången av flytpunkten till två decimaler, dividerar den sedan med 1 och ser om det finns en återstående. Om resten är noll betyder det att timern har nått en hel sekund och blip-ljudet kan spelas.

Om vi ​​inte gör det här kan systemet utlösa mycket oftare, vilket inte blir kul och bidrar till en bra timer.

Olika hastigheter

Detta kommer att lägga till en multiplikator som kommer att minska eller påskynda klockans klockfrekvens. Lägg till den här variabeln i början:

float multiplikator = 0,6f;

Hitta nu linjen som minskar timern, det är den här:

timer - = Time.deltaTime;

Och anpassa det så att det ser ut så här:

timer - = Time.deltaTime * multiplikator;

Om multiplikatorn är nedan 1,0 Timern kommer nu att springa långsammare, och om den är ovanför 1,0 det kommer att springa snabbare. Ställ in den vid 1,0 kommer inte göra någonting.

Försök att experimentera för att hitta ett bra värde! Jag känner en något lägre hastighet, som 0.85f, kommer att få spelaren att känna den krypande klockan mer.

Långsammare när låg

Nu när vi har en multiplikatorkomponent kan vi ändra det under spel!

Gå till koden för färgbyte av kod:

om (timer < 10f)  GetComponent() .färg = Color.red;  annars om (timer < 20f)  GetComponent() .färg = Color.yellow; 

Här har vi redan villkoren där en ändring i krypande hastighet skulle vara lämplig, så vi kan bara lägga till det!

om (timer < 10f)  GetComponent() .färg = Color.red; multiplikatorn = 0,6f;  annars om (timer < 20f)  GetComponent() .färg = Color.yellow; multiplikatorn = 0,8f;  annat multiplikator = 1.0f; 

När timern blir gul vid 20 sekunder kommer det nu att kryssa med 80% hastighet. När det blir rött, kommer det att gå ner till 60% vanlig hastighet. Annars ställs den till 100% hastighet.

Skalering när låg

Ett annat bra sätt att göra en timer som går ut ur tiden står ut mer är att skala upp varje passande sekund när den är låg. Eftersom vi redan har kod som utlöses varje sekund kan vi anpassa det vidare!

Först behöver vi en funktion för att öka och minska storleken på vår skärm. Lägg till den här funktionen:

privat bool isBlinking = false; privat IEnumerator Blink () isBlinking = true; float startScale = transform.localScale.x; transform.localScale = Vector3.one * startScale * 1.4f; avkastning ger nya WaitForSeconds (0.3f); transform.localScale = Vector3.one * startScale; isBlinking = false; 

Detta är en IEnumerator, vilket är en typ av funktion som kan innehålla vänta kommandon. Vi behöver isBlinking variabel för att se till att vi inte ringer det flera gånger.

En gång initierad, kommer den att skala upp objektets storlek med en faktor på 1,4f, vänta 0,3 sekunder och sedan skala ner igen till originalstorleken.

Vi kallar det med den här specialkoden:

om (Mathf.Round (timer * 100) / 100% 1f == 0) GetComponent() .PlayOneShot (soundBlip); om (timer < 10f)  if(!isBlinking)  StartCoroutine(Blink());   

En IEnumerator måste initieras genom att ringa det via StartCoroutine, annars fungerar det inte.

Hela blocket kommer att ringas när en sekund passerar, vid vilken tidpunkt kan vi kontrollera om timern är tillräckligt låg för att få den att blinka.

Blinka i noll

Låt oss göra något när timern löper ut. Att ha det bara sitta där vid noll kan vara tråkigt, så låt oss få det att blinka.

Först behöver vi en annan IEnumerator fungera:

privat bool isZeroBlinking = false; privat IEnumerator ZeroBlink () isZeroBlinking = true; GetComponent() .enabled = false; yield returnera nya WaitForSeconds (1.5f); GetComponent() .enabled = true; yield returnera nya WaitForSeconds (1.5f); isZeroBlinking = false; 

Detta aktiverar och avaktiverar timern i 1,5-andra intervaller. Trigger den i blocket som redan kontrollerar om timern är noll.

om (timer> 0f) timer - = Time.deltaTime * multiplikator;  annars timer = 0f; om (! isZeroBlinking) StartCoroutine (ZeroBlink ()); 

Innan vi kör det måste vi avaktivera pipningen och blinka vid noll i sig, annars kommer det att kollidera beteenden.

Anpassa villkoren i blocket för att kontrollera om en sekund har passerat och även för att kontrollera om den aktuella tiden är mer än noll:

om (Mathf.Round (timer * 100) / 100% 1f == 0 && timer> 0f) GetComponent() .PlayOneShot (soundBlip); om (timer < 10f && timer > 0f) om (! IsBlinking) StartCoroutine (Blink ()); 

Detta säkerställer att regelbundet blinkar och blinkar utan att störa varandra.

Hela nedräkning Skriptet ska se så här ut:

använder UnityEngine; Använda System.Collections; allmän klass Nedräkning: MonoBehaviour float timer = 5f; float multiplikator = 0,6f; offentliga AudioClip soundBlip; void Update () if (timer> 0f) timer - = Time.deltaTime * multiplikator;  annars timer = 0f; om (! isZeroBlinking) StartCoroutine (ZeroBlink ());  om (timer < 10f)  GetComponent() .färg = Color.red; multiplikatorn = 0,6f;  annars om (timer < 20f)  GetComponent() .färg = Color.yellow; multiplikatorn = 0,8f;  annat multiplikator = 1.0f;  om (Mathf.Round (timer * 100) / 100% 1f == 0 && timer> 0f) GetComponent() .PlayOneShot (soundBlip); om (timer < 10f && timer > 0f) om (! IsBlinking) StartCoroutine (Blink ());  GetComponent() .text = timer.ToString ("F2");  privat bool isBlinking = false; privat IEnumerator Blink () isBlinking = true; float startScale = transform.localScale.x; transform.localScale = Vector3.one * startScale * 1.4f; avkastning ger nya WaitForSeconds (0.3f); transform.localScale = Vector3.one * startScale; isBlinking = false;  privat bool isZeroBlinking = false; privat IEnumerator ZeroBlink () isZeroBlinking = true; GetComponent() .enabled = false; yield returnera nya WaitForSeconds (1.5f); GetComponent() .enabled = true; yield returnera nya WaitForSeconds (1.5f); isZeroBlinking = false;  

Detta kommer att få jobbet gjort. Du kan förstås göra det mer elegant och kombinera kommandona till en effektivare kod.

Slutsats

Vår standardlilla nedräkning har blivit mycket mer intressant och engagerande. Om du bygger den här gången kan du använda den och ansluta den till något projekt du gör, oavsett hur liten det är.

Gå nu och lägg det i ett spel!