Gra platformowa 2D w Unity Od Zera do Game-Developera [OZDGD]
W ramach serii Od Zera do Game-Developera, w której to chcę zachęcić innych do zainteresowania się nie tylko grami, ale też sferą ich produkcji, powstały już następujące teksty:
- Wszyscy mówili: nie idź do gamedevu. Nie posłuchałem i dziś mogę się pochwalić pierwszą grą
- Programujesz w Unity? Ten kreacyjny wzorzec projektowy musisz znać
- Jaki komputer do Unity? Zobacz porównanie trzech zupełnie odmiennych sprzętów
Niniejszy tekst jest kontynuacją serii, w ramach to której tworzę pełnoprawną, ale prostą platformową grę 2D:
- Jak stworzyć grę w Unity? Stawiam repozytorium, Gita i projekt w Unity [OZDGD #1]
- Poradnik Unity. Co musicie wiedzieć o tym silniku, żeby stworzyć własną grę? [OZDGD #2]
- Platformowa gra 2D w Unity. Tworzę GDD i rozpisuję mechaniki [OZDGD #3]
- Architektura kodu w grze platformowej. Opisuję najważniejsze podstawy [OZDGD #4]
- Platformówka 2D w Unity. Tworzę środowisko oraz postać gracza [OZDGD #5]
- Tworzę główną postać i ją programuję [OZDGD #6]
- Przeciwnicy i system walki w platformowej grze 2D w Unity [OZDGD #7]
Gra bez audio, to nie gra. Zabieramy się za udźwiękowienie
W gruncie rzeczy dotychczas wykonane etapy zapewniają podstawy do popchnięcia projektu w kierunku pełnoprawnej, zdesignowanej gry, ale wśród dodatkowych funkcji nadal brakuje nam kluczowego elementu. Gry wideo to przecież medium audio-wizualne, a grając w tę platformówkę, jedyny hałas, którego usłyszymy, będzie pochodził z samej klawiatury. Naprawimy to w dosyć prosty sposób – klasą SoundManager.
Jak możecie zobaczyć powyżej, wykorzystując prostą klasę z Singletonem, możemy zbudować miniaturowe “centrum dowodzenia” co do dźwięków. Po wrzuceniu takiego skryptu na scenę (najlepiej na kamerę), musimy zduplikować liczbę interesujących nas komponentów Audio Source i przeciągnąć je kolejno do stworzonych “źródeł” (source). Z racji poziomu skomplikowania oraz środowiska 2D nie musimy się przejmować ich nieodpowiednim pozycjonowaniem, a przeciwnicy niewidoczni dla nas nie będą hałasować, dzięki nowym metodom OnBecameVisible i OnBecameInvisible w ich skryptach.
Następnym etapem jest zbudowanie biblioteczki klipów audio, które będziemy mogli wprowadzić do projektu. Nie musicie bać się o potrzebę ich własnego skomponowania. Obecnie w sieci znajdziecie całą masę tego typu efektów dźwiękowych, które musicie zaimportować do projektu (skopiować je do odpowiedniego folderu), a następnie podpiąć w poszczególnych configach, rozszerzając je o linijki z obiektami AudioClip.
Oczywiście podejść do audio w Unity jest cała masa, ale to powyższe jest jednym z najprostszych. Ma jednocześnie swoje (ogromne) wady, z czego tą największą jest potrzeba współdzielenia źródeł dźwięku dla przeciwników, co w ogólnym rozrachunku jest problemem. Możemy go jednak rozwiązać w stosunkowo prosty sposób – generując ciągle nowe GO z komponentami AudioSource, albo tworzyć te komponenty w czasie rzeczywistym w pierwotnym GO i zajmować je np. w strukturze danych o nazwie Dictionary. Takie podejście załatwi problem, choć stworzy kolejny – tworzenie się w nieskończoność komponentów dla powtarzających się czynności (np. procesu chodzenia). Jak więc najlepiej to rozegrać? Ano tak:
W tym podejściu tworzymy zarówno listę źródeł dźwięku dla prostych efektów dźwiękowych, jak i słownik dla tych, które mogą występować ciągle i się powtarzać (odgłosy chodzenia). W pierwszym przypadku rozszerzamy listę zależnie od potrzeb, a w drugim przypisujemy każdemu gameobjectowi jego źródło w słowniku, dbając jednocześnie o jego regularne czyszczenie i rozszerzanie wedle potrzeby. Z całą pewnością nie jest to najbardziej wydajna metoda, ale nikt nie powiedział, że zabawa dźwiękami w Unity bez assetów jest prosta.
Znajdźki w grze, czyli jak zmusić gracza do eksploracji
Bez zbierania czegokolwiek na planszy gra staje się nieco jałowa, a sama forma znajdziek i tak naprawdę wszystkich przedmiotów zbieralnych jest fenomenalnym mechanizmem dla game i level designerów. Zapewnia im bowiem mechanizmy pośredniego sterowania graczem, a to coś wręcz bezcennego.
Na szczęście proces implementacji znajdziek w tym projekcie nie jest jakkolwiek trudny, bo nutki (aktualnie monetki przez brak grafiki), można sprowadzić do jednego skryptu wykrywającego kolizję z graczem i prostego prefabu, którego można rozstawiać po scenie, jak przeciwników.
W tej platformówce wykorzystam zarówno znajdźki, jak i przeciwników w roli weryfikatora zakończenia danego poziomu. Co to oznacza? Że dopiero kiedy zniszczymy wszystkich przeciwników i zdobędziemy określoną liczbę nutek, będziemy mogli przejść na nowy poziom. Wymaga to zarówno skryptu w roli Menadżera Gry (GameManager), w którym zawarłem całą logię związaną z prostym User Interface (UI), jak i proste UI właśnie.
Mając dostęp do takiego skryptu, możemy teraz stworzyć zarówno ekran przegranej, jak i wygranej, aby nie ładować nowego poziomu od razu po spełnieniu wymogów. To jednak jest również banalne, jako że wymaga tylko odpowiedniego GO z komponentem Canvas oraz odpowiednio połączonych z funkcjami przycisków, co może stanowić również punkty wyjściowy do zerowej sceny, czyli głównego menu.
Ostatecznym etapie jest zapisywanie postępów gracza. Jako że zależy nam wyłącznie na tym, które poziomy zdołał przejść gracz, musimy tylko zapisać np. prostą zmienną typu int, który przy wartości 0 będzie oznaczał dostęp tylko do pierwszego poziomu (indeks scen numeruje się od 0), przy 1 do drugiego i tak dalej. Użyjemy w tym celu naszego GM, który wymaga oczywiście modyfikacji, ale na szczęście niewielkich, bo:
Od tego momentu grą możecie się już dowolnie bawić. Możecie postarać się o pułapki, lepiej działającą kamerę, efekty pokroju imitacji krwi po każdym ataku, wstrząsów przy ataku, blokad do zniszczenia… po prostu wszystkiego, co przyjdzie wam na myśli i czego zaczniecie pragnąć podczas procesu level-designu.
Chociaż na tym etapie chciałem już skończyć ten projekt, sprowadzając go do tej jednej lokacji, to zdołałem popchnąć go dalej, dzięki małemu zespołowi, którego zgromadziłem na uczelni podczas procesu produkcji. Postanowiłem tym samym zostawić sobie jego podsumowanie na finalny już artykuł, w którym to doszlifuję grę do poziomu, na którym mogłaby teoretycznie trafić na Steama w cenie kilku złotych, a najlepiej za darmo. Bo za darmo, to uczciwa cena.