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.
A nainstalujeme přes
Tool -> Install Bolt. Pak stačí následovat Setup wizard
(Next -> programmer naming -> next -> generate).
Herní charakter - Alien
Jako hlavní herní charakter vytvoříme malého Aliena. Klepneme do okna hierarchie a vybereme
2D Object -> Sprite.
Nový objekt přejmenujeme na
Alien
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.
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.
A pomocí šipek pro pohyb na ose posuneme objekt ve scéně doleva.
Dále přidáme hlavní komponentu,
Flow Machine, s logikou pro ovládání herního charakteru.
A změníme
Source na
Embed. Pojmenujeme jako
Alien a přidáme popis.
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.
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.
Létat budeme např. pomocí klávesy Space. Jako parametr
key tedy zvolíme
Space.
Pokračujeme přes
Control -> Branch (ekvivalent podmínky if).
Dále potřebujeme získat referenci na
RigidBody2D komponentu:
Vybereme
RigidBody2D jako parametr
type.
A přidáme kinetický impuls přes funkci
RigidBody2D.AddForce, který bude emulovat pohyb Flappy Birda.
Chceme, aby Alien "poskakoval" nahoru, takže změníme souřadnici
y vektoru
force na 1 a
mode přepneme na
Impulse.
Celá logika pak vypadá takto:
Když teď spustíme hru, můžeme aliena ovládat mezerníkem.
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).
A přidáme
Box Collider 2D.
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.
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.
Musíme také vytvořit tzv.
prefab z objektu
ObstacleHolder. Stačí vzít
ObstacleHolder a přetáhnout do okna
Assets.
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).
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.
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).
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.
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).
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.
Posledním krokem je napojení proudu zpět na
Timer (časovač), aby se celý cyklus spustil znovu.
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).
Tím máme hotovo!
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