15# 1942 Classic 2.
Loď už nám lítá v rámci hry a nyní je na čase s ní začít střílet. První co vytvoříme si Asset z toho si vytvoříme Prefab a ten připojíme ke hráči.
Začneme tou jednoduchou částí. V KennySpace -> PNG -> Lasers si najdeme laser, který se nám líbí a přetáhneme ho do Sprites. Díky tomu ho snadno najdeme. Přetáhneme ho do hierarchie, vytvoříme si složku v Assets, kterou pojmenujeme Prefabs a do ni Laser přetáhneme. Tím jsme vytvořili Prefab a můžeme laser smazat ze scény. Jako poslední si otevřeme Player.cs (náš zatím jediný script) jediné co uděláme je jedno serializované pole pro GameObject se jménem projectile.
Uložíme, přepneme se do unity a v inspektoru hráče (Player) připojíme laser prefab do projectile.
Když už máme vytvořenou složku Prefabs, můžeme do ni umístit většinu věcí, které máme na scéně a budeme používat. Background, Canvas, Enemy, Player i Main Camera.
Přepneme se do Visual Studia. A začneme pracovat na střelbě. Uděláme si metodu FirePlayer() a budeme ji volat z Update().
Hráč nebude střílet automaticky (i když to do budoucna můžeme upravit), ale bude střílet po stisknutí tlačítka. Nyní využijeme kombinaci GetKeyDown a Axis. Můžeme nahlédnout do Unity do nastavení (Edit -> Project Settings -> Input). Budeme využívat Fire1, opět se zde vyskytuje 2x jednou pro klávesnici a myš, jednou pro GamePad. Když si otevřete nastavení pro Klávesnici/Myš zjistíte, že vychozí nastavení je na “left ctrl” o něco přesnější a pohodlnější by bylo použít mezerník. Ten je v základu použit pro skákání a to rozhodně potřebovat nebudeme. Jednoduše nahradíme “left ctrl” mezerníkem neboli “space”.
Přepneme se do Visual Studia a zde využijeme “tlačítko” Fire1. Ve funkci FirePlayer vytvoříme podmínku (if) pokud hráč zmáčkne tlačítko Fire1, vytvoř (Instantiate) na místě kde je hráč objekt projectile. Jako Projectile již máme připojený náš prefab Laseru a tak se o něj již nemusíme starat a můžeme jen používat slovo “projectile”.
Poslední část je rotace (otočení) nového objektu. Quaternion.identity jen říká, aby se objekt přidal bez rotace. Pokud se nyní přepnete do Unity a zapnete hru měla by vaše loď pokládat pod sebe lasery. Zatím nic nedělají, nemáme žádný zvuk a jen tak na scéně sedí.
Nyní musí laser dostat tělo, konkrétně RigidBody2D, protože bez něj se nemůže v Unity nic hýbat. Klikneme si na projektil v prefabs a v inspektoru Add component -> Rigidbody2D, všechno nastavení necháme bez změny a přepneme se do Visual Studia. Instantiate nám zde funguje jako vytvoření objektu. Aby na něj mohla působit fyzika přes Rigidbody musí to být herní object (GameObject). Proto před Instantiate dopíšeme GameObject se jménem laser do něj přiřadíme (=) Instantiate a na konec řádku dopíšeme “as GameObject” čím donutíme Instantiate vytvářet herní objekty. Těm pak můžeme dát například rychlost (velocity).
Samozřejmě zatím jsem do rychlosti napsal jen 5f a to by nemuselo být ideální číslo, pokud chceme testovat a zkoušet jiné rychlosti nejlepší je udělat Serializované pole, a používat místo 5f proměnnou.
Toto rozhodně není co jsme chtěli. Projektily se nám vrací protože na ně působí gravitace. Proto, v Prefabs -> Laser Projectile musíme udělat drobné úpravy. A máme dvě možnosti. Buď změníme Typ na Kynematic a projektily začnou ignorovat gravitaci. Nebo nastavíme Gravity Scale a Angular Drag na 0 čímž docílíme toho samého.
Poslední část bude odstranění nutnosti klikání. Sice děláme hru inspirovanou starou hrou, ale klikání není něco co je tou nejlepší součástí retro zážitku. Kvůli tomu začali vznikat turbo ovladače, které které vám dovolili místo klikání tlačítko držet. Dnes by jsme si mohli například udělat makro, ale lepší bude to napsat rovnou jako součást hry, zároveň se na tom naučíme Coroutines. Jsou to funkce, které dovolují čekání. Pokud by jsme totiž hráči dovolili spamovat laser každý snímek (Update) určitě by to pro lidi s výkonným pc byla velká výhoda.
Na začátek si uděláme jen výpis do konzole. Napíšeme coroutine, který nám vypíše jednu zprávu, počká 3 sekundy a vypíše druhou zprávu. To pak můžeme implementovat pro střelbu. Přepneme se do Unity a založíme si Coroutine. Ta se vždy definuje jako IEnumenerator jmenoFunkce(). Pokud by jste ji nechali zapnout přes Update … nedopadne to pravděpodobně dobře a bude se snažit spustit vícekrát. My ji zapneme přes start. Jako poslední infomaci, příkaz pro čekání je yield return new WaitForSeconds(x). Jako poslední IEnumerator je součástí System.Collections a tak tuto knihovnu musíme připojit.
Uložíme, přepneme se do unity a zapneme hru. Konzole by měla vypadat takto.
Naši testovací funkci si můžeme odstranit a místo toho uděláme již funkční pro FirePlayer(). Vytvoříme si funkci TurboFire(), která bude coroutine (IEnumerator). Ideálně ji dáme pod FirePlayer pro lepší přehlednost. Umístíme do něj vše co nám aktuálně dělá FirePlayer().
TurboFire má zatím červené podtržení, protože nemáme žádný yield return a s tím také nemáme žádné čekání, kvůli kterému to děláme. Proto přidáme řádek s čekáním velmi podobný tomu co jsme již dělali.
Takto by jsme čekali 0.1 sekundy mezi každou střelou, toto by fungovalo, ale z hlediska testování a úprav v budoucnosti je lepší nahradit pevnou hodnotu proměnnou a tu udělat jako serializované pole.
Ještě nám nic fungovat nebude, protože nemáme místo, kde zapínáme naší coroutine. To bude uvnitř podmínky FirePlayer().
Když uložíte a přepnete se do unity, můžete udělat krátký test, během kterého zjistíte, že sice klikáním můžete střílet. ale bohužel držení tlačítka stále nefunguje. Proto přidáme smyčku. Smyčky nám dovolí opakovat část kódu dokud není podmínka splněna. Jedna ze základních smyček je while (zatímco). Pokud ji do podmínky napíšeme True, bude probíhat do nekonečna. Takovou podmínku použijeme v TurboFire.
Pokud uložíte a zapnete hru, po prvním kliknutí začne loď střílet tak jak chceme, další kliknutí nám ale násobí firerate, protože se nám znovu a znovu zapíná smyčka se střelbou. Je to krok správným směrem, ale ještě to chce zvládnout tu smyčku zastavit, ideálně když pustíme tlačítko myši (if GetButtonUp). To bude součástí FirePlayer
Existuje příkaz “StopAllCoroutines()”, to by jsme mohli napsat pro zastavení střelby, ale díky tomu by jsme nemohli použít žádnou další coroutine. To určitě není dobré řešení a tak raději jednu konkrétní rutinu. Vytvoříme si proměnnou s názvem FireRoutine a type Coroutine.
Do té si uložíme jméno rutiny při jejím zapnutí.
A příkazem StopCoroutine() můžeme rutinu ukončit, kdy do závorek stačí napsat jméno proměnné, do které jsme si rutinu na začátku uložili.
Nyní to máme téměř dokonalé. Protože, pokud má naše hra drobný exploit. Pokud hráč použije pro střelbu klávesnici a myš najednou, střelba nepřestane. Zde by bylo asi více řešení ale nejrychlejší je mu vzít z Fire1 možnost používat myš (Edit -> Project Settings -> Input -> Fire1 -> Alt Positive Button).
Hotovo a pokračování v další lekci.
0 Comments