Jak vytvořit klon Flappy Bird ve vizuálním jazyku Bolt v Unity
25.03.2021
Jak vytvořit klon Flappy Bird ve vizuálním jazyku Bolt v Unity

​​Dva nejdominantnější herní enginy na trhu jsou Unity a Unreal Engine 4. UE4 používá kromě klasického programování i systém grafického programování přes tzv. blueprinty. V Unity tato možnost oficiálně dlouho chyběla, až do minulého roku, kdy se tvůrci rozhodli do všech verzí Unity přidat systém grafického programování Bolt. V tomto článku se podíváme na základní funkcionalitu Boltu a vytvoříme s jeho pomocí klon legendárně úspěšné hry Flappy Bird. Pokud jste chtěli zkusit herní vývoj, ale programování vás doteď děsilo, Bolt může být snadný způsob jak začít!

Konečným produktem tohoto tutoriálu bude klon hry Flappy Bird s replikou původního ovládání létání a generátor překážek. Překážky se budou donekonečna generovat vpravo mimo obrazovku a budou putovat doleva a tvořit tak iluzi pohybu herní postavy doprava (tedy stejná metoda, kterou používá původní Flappy Bird a další hry typu infinite-scroller). Dejme se do toho!

Instalace Boltu

Nejprve vytvoříme nový 2D projekt v Unity 2020 a nainstalujeme Bolt (odkaz). Návod jak vytvořit nový projekt a importovat balík z Unity Asset Store naleznete v prvním dílu seriálu o herním vývoji v Unity (odkaz). Typ nového projektu zvolíme 2D. Po importu Boltu z Asset Store ho v Unity stáhneme přes Package Manager -> My Assets -> Download.

package manager.png

A nainstalujeme přes Tool -> Install Bolt. Pak stačí následovat Setup wizard

(Next -> programmer naming -> next -> generate).

install bolt.png

Herní charakter - Alien​

Jako hlavní herní charakter vytvoříme malého Aliena. Klepneme do okna hierarchie a vybereme 2D Object -> Sprite.

 2Dobjectsprite.png

Nový objekt přejmenujeme na Alien

 alien.png

V sekci Sprite Renderer pak zvolíme Sprite shipGreen_manned (dostupné v mém github repozitáři, odkaz v závěru). Další zajímavé grafické podklady můžete najít na kenney.nl.

 shipgreen.png

Přes tlačítko Add Component přidáme alienovi Polygon Collider 2D. Tím později zajistíme přesnou detekci kolizí s překážkami. A přidejme mu také komponentu RigidBody2D pro emulaci gravitace. Změníme parametry Mass a Drag na 0.1 a 1 aby se pohyb více podobal Flappy Birdovi.

 rigidbody.png

A pomocí šipek pro pohyb na ose posuneme objekt ve scéně doleva.

 dileva.png

Dále přidáme hlavní komponentu, Flow Machine, s logikou pro ovládání herního charakteru.

 flowmachine.png

A změníme Source na Embed. Pojmenujeme jako Alien a přidáme popis.

sourceTOembed.png

Po kliknutí na na tlačítko Edit graph se zobrazí grafické rozhraní, ve kterém se chováme podobně jako při reálném programování. Graf drží metody Start a Update.

startaupdate.png 

Nové funkce se přidávají přes výstupní šipku nebo kliknutí do prázdna. Tažením výstupní šipky se načte dialog pro vyhledání existujících metod. Najdeme tedy metodu pro vstup z klávesnice (Input.GetKeyDown), abychom mohli ovládat herní charakter.

input-key-down.png 

Létat budeme např. pomocí klávesy Space. Jako parametr key tedy zvolíme Space.

space.png

Pokračujeme přes Control -> Branch (ekvivalent podmínky if).

 control-branch.png

Dále potřebujeme získat referenci na RigidBody2D komponentu:

rigidbody2D.png

Vybereme RigidBody2D jako parametr type.

 type.png

A přidáme kinetický impuls přes funkci RigidBody2D.AddForce, který bude emulovat pohyb Flappy Birda.

addforce.png

Chceme, aby Alien "​poskakoval" nahoru, takže změníme souřadnici y vektoru force na 1 a mode přepneme na Impulse.

 impulse.png

Celá logika pak vypadá takto:

 cela logika.png

Když teď spustíme hru, můžeme aliena ovládat mezerníkem.

 mezernikem.gif

 

Překážky

Stejně jako pro Aliena vytvoříme nový Sprite přes menu 2D object -> Sprite a pojmenujeme ho Obstacle. Ve Sprite Renderer nastavíme sprite elementMetal055 (také dostupný v mém repozitáři níže).

 elementmetal55.png

A přidáme Box Collider 2D.

boxcollider2D.png

Pomocí Rect nástroje pak změníme rozměr překážky, aby víc odpovídal předloze ve Flappy Bird. Překážku posuneme mimo viditelnou plochu.

 prekazkamimoplochu.png

prekazkamimoplochu2.png

Teď vytvoříme prázdný "​rodičovský" objekt, který pojmenujeme ObstacleHolder a asociujeme s ním předešlé 2 Obstacle objekty, a to jejich označením a přetažením nad ObstacleHolder.

 obstacleholder.png

obstacleholder2.png

Musíme také vytvořit tzv. prefab z objektu ObstacleHolder. Stačí vzít ObstacleHolder a přetáhnout do okna Assets.

 obstacletoassets.png

Tak budeme schopni tvořit instance stejného objektu ze skriptu generátoru, který bude na objekt držet referenci. Původní ObstacleHolder objekt můžeme ze scény smazat, budeme používat už jenom jeho prefab.

Generátor překážek

Vytvořme prázdný objekt (Create Empty), který bude sloužit jako generátor překážek. Pojmenujme ho Generator. Přidáme mu novou komponentu Flow Machine a stejným způsobem jako u Aliena a otevřeme editor grafu.

V levém podokně editoru grafu vytvoříme novou proměnnou typu GameObject, která bude držet referenci na prefab s objektem ObstacleHolder. Ten přetáhneme do parametru Value z okna Assets (lze vidět na vlevo dole na obrázku zobrazeném níže).

 gameobject.png

Přes menu editoru přidáme nový uzel grafu, a totiž Timer. Ten bude zodpovědný za pravidelné generování nových překážek. Timer začne počítat při vytvoření generátoru, proto ho budeme volat z metody Start. Trvání nastavíme na 4 sekundy.

 start.png

Každou instanci překážky budeme generovat s náhodným posunutím na ose y. Použijeme funkci Random.Range, která bude generovat náhodné číslo od 0.2 do 0.7 (otestoval jsem, že tyto hodnoty jsou nejlepší pro běžná rozlišení obrazovky).

Hodnotu pak předáme jako parametr do uzlu Vector3, kde ještě upravíme souřadnici x na hodnotu 1.4 (tzn. bude 40 % za "koncem" obrazovky).

 vector3.png

​​

Tento Vector3 předáme do funkce ViewportToWorldPoint, která přeloží námi zadané hodnoty na souřadnice na obrazovce. Jako parametr zvolíme hlavní kameru - Main Camera.

 maincamera.png


Na takto vypočtené pozici už můžeme vygenerovat překážku. K tomu využijeme funkci Instantiate. Předáme jí dříve vytvořenou proměnnou obstacle s referencí na ObstacleHolder (funkce Get Variable -> Graph -> zvolit obstacle), vypočítanou pozici a nakonec rotaci (get Quaternion identity).

 quaternion.png

Teď už jen přidáme nové instanci objektu Rigidbody2D, nastavíme ho na kinematický typ (set RigidBody2D.bodyType) a rychlost na ose x nastavíme na -2 (set RigidBody2D.velocity). Tím zajistíme posun překážek doleva.

Nakonec vše napojíme na metodu Destroy, která bude instanci překážky automaticky ničit po 20 sekundách - tedy když bude už dávno mimo dohled. Jako parametr musíme vzít objekt překážky vytvořený několik uzlů zpět ve funkci Instantiate.

instantiate.png 

Posledním krokem je napojení proudu zpět na Timer (časovač), aby se celý cyklus spustil znovu.

timer.png

timer2.gif

Pro úplnost můžeme přidat detekci kolize hráče s překážkou. Pokud se tak stane, celá scéna se načte znovu (prakticky se restartuje hra).

 kolize.png

Tím máme hotovo!

hotovo.gif

Pokud jste si tento návod užili, můžete zkusit i moje další články na téma herního vývoje zde na portálu. Odkaz na první díl je výše v textu. Celý tento projekt jsem zveřejnil na svém githubu (odkaz). Na shledanou u dalšího článku!


Jan Jileček