Jak stworzyć grę w Unity? Stawiam repozytorium, Gita i projekt w Unity [OZDGD #1]

Czy kiedykolwiek naszła was myśl, żeby stworzyć grę w Unity? Jeśli żadnej ciągle nie macie na koncie, to zapewne zderzyliście się w przeszłości ze ścianą, dowiadując się, że wcale nie jest to taki prosty proces. Jeśli jednak nadal żyjecie tym marzeniem i chcecie przekuć go na rzeczywistość albo po prostu towarzyszyć mi w tej przygodzie, będącej częścią serii Od Zera Do Game-Developera to możecie wspólnie przejść tę drogę i stworzyć własną unikalną produkcję z wykorzystaniem tego silnika. Zanim jednak w niego się zagłębimy musimy zadbać o filary projektu z Gitem na czele. 
Jak stworzyć grę w Unity? Stawiam repozytorium, Gita i projekt w Unity [OZDGD #1]

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:

Czym jest repozytorium i jak je stworzyć?

Robienie gierek jest fajne, ale jeśli nie jesteście częścią firmy, w której pracownicy robią część podstawowej pracy za was, to musicie poznać szczegóły tworzenia oprogramowania od podstaw. Oczywiście możecie rzucić się na głęboką wodę i zacząć tworzyć bez stawiania repozytorium i zapoznawania się z Gitem, ale jest to niczym rzucenie się na głęboką wodę bez koła ratunkowego – jeśli nie wiecie, co robicie, szybko pochłoną was odmęty zer i jedynek.

Nie bądźcie więc głupcami i swój projekt rozpocznijcie od stworzenia tak zwanego repozytorium. Jest to nic innego jak nazwa miejsca, w którym przechowywane są pliki związane najczęściej z rozwojem oprogramowania. To taki “zaawansowany folder” z projektem, który wykorzystuje system kontroli wersji, aby zapisywać wiele wersji plików i umożliwiać ich porównywanie oraz łączenie. Repozytorium może być skonfigurowane na lokalnym komputerze dla jednego użytkownika lub na serwerze, do którego ma dostęp wielu użytkowników.

Na całe szczęście postawienie repozytorium (w skrócie “repo”) nie jest wcale trudne. Wystarczy tylko założyć konto np. na darmowej platformie hostingowej GitHub, zalogować się i jednym kliknięciem zainicjować proces jego tworzenia.

Następnie musicie wybrać nazwę repozytorium i jego widoczność między opcją prywatną (dostęp mają tylko określone osoby) oraz publiczną (dostęp mają wszyscy). Kilka chwil warto poświęcić również na krótki opis projektu wybranie typu pliku .gitignore, stworzenie pliku ReadMe, w którym możecie opowiedzieć więcej o swojej inicjatywie czy wreszcie wskazanie licencji zależnie od upodobań. 

Nie ignorujcie pliku .gitignore

Wspomniany plik .gitignore to dosyć wyjątkowy plik tekstowy, który jest wykorzystywany przez Gita po to, aby ignorować określone pliki lub foldery w projekcie. Umieszcza się go najczęściej w głównym katalogu projektu tylko po to, aby upewnić się, że konkretne pliki nie będą wykrywane przez system kontroli wersji, co ma ogromne znaczenie w przypadku m.in. projektów Unity, w których to generowana jest cała masa plików, których nie ma sensu wysyłać na serwer z racji tego, że silnik tworzy je sobie “sam”. 

Na całe szczęście nie musicie bawić się w pisanie .gitignore od podstaw. Podczas tworzenia repozytorium możecie stworzyć ten plik automatycznie, a w razie jego braku możecie bez problemu pobrać jego stosowne warianty z sieci i również modyfikować na własną rękę. To prosty plik tekstowy, który rządzi się równie prozaicznymi zasadami. 

Czym jest Git i dlaczego jest tak ważny?

W branży tak wiele słyszy się o Gicie, jakby ten nigdy nie doczekał się alternatywy, ale ta rzeczywiście istnieje. Tyle tylko, że Git w porównaniu do jego zamienników jest niczym Windows na tle Linuxa. Jeśli więc dopiero co zaczynacie swoją przygodę w programowaniu, a nazwy takie jak Fossil, Mercuril SCM, Bazaar czy Pijul nie mówią wam nic, to lepiej zostańcie przy Gicie właśnie, bo jest zwyczajnie najpowszechniejszy wśród początkujących właśnie. 

Czytaj też: Game Boy na miarę 2023 roku. Ta retrokonsolka przywróciła mi radość z grania

Jeśli zastanawia was, czym dokładnie jest wspomniany kilka razy powyżej Git, czyli “system kontroli wersji”, to odpowiedź jest prosta. To narzędzie-marzenie każdego dewelopera. Wcale teraz nie przesadzam, bo to oprogramowanie jest niczym stróż projektu, śledzący każdą zmianę w plikach nieokreślonych w .gitignore, dzięki czemu pomaga, a tak naprawdę w ogóle umożliwia zespołom deweloperów dbanie o kod źródłowy. 

Bez systemu kontroli wersji rozwój oprogramowania byłby utrapieniem. To właśnie on odpowiada za gromadzenie wszystkich zmian oraz ich historii ze szczegółami pokroju nawet tego, kto i kiedy dokładnie wprowadził modyfikacje w danych plikach. Na tym jednak wyjątkowość Gita się nie kończy, bo poza śledzeniem zmian wszystkich commitów, zapewnia on również możliwość cofnięcia się do wcześniejszych wersji w ledwie kilka kliknięć, a w razie konfliktów (merge-conflicts) przy łączeniu zmian od dwóch programistów, pozwala dokładnie je obejrzeć i wybrać, na których fragmentach szczególnie nam zależy podczas tak zwanych “merge”. 

Innymi słowy, system kontroli wersji to taka bardzo, ale to bardzo inteligentna i przyjazna użytkownikowi baza danych, zapisująca wcześniejsze wersje plików i śledząca każdą zmianę. Dzięki niemu zapewniamy sobie możliwość cofnięcia zmian do momentu, w którym nagle niedziałający moduł jeszcze działał i łatwiej odkryć zmianę w kodzie, która stała za nową awarią. Innymi słowy, bez repozytorium i systemu kontroli wersji lepiej nie zaczynać tworzyć swojej gry, a jeśli uważacie inaczej, to czeka was to samo, co każdego, kto nie robił kopii zapasowej. Z czasem jedna wpadka po prostu was do tego przekona. 

Mamy repo, więc czas zaprząc do niego Gita

We wcześniejszym kroku udało się wam stworzyć repozytorium na platformie GitHub, więc najwyższy czas zrobić z niego użytek. Będziecie potrzebowali do tego najpierw aplikacji GitHub Desktop. Po jej pobraniu, zainstalowaniu i powiązaniu ze wcześniej założonym kontem na GitHub, możecie wreszcie sklonować na fizyczny nośnik swoje repozytorium. W tym celu dodajcie repozytorium poprzez klonowanie i wskażcie dla niego miejsce na dysku. Następnie wystarczy poczekać kilka chwil, aby pliki zostały pobrane.

Kolejnym krokiem jest instalacja aplikacji Unity Hub z odpowiednią wersją silnika, czyli najczęściej tą najnowszą z oznaczeniem LTS (Long Term Support). Określa ono wersję o długim wsparciu, co gwarantuje nam, użytkownikom, że deweloperzy Unity będą dbać dłużej o jej stabilność i walkę z bugami.

W momencie pisania tego tekstu najnowszą tego typu wersją jest 2021.3.20f1, po wybraniu której możecie określić wariant projektu (u nas to 2D Core), nazwać go i określić jego ścieżkę, a wreszcie wybrać, czy instalacja ma też objąć aplikację do tworzenia skryptów Microsoft Visual Studio. Jeśli nie wiecie, czym w ogóle ona jest, to albo po prostu się zgódźcie, albo pobierzcie interesującą was wersję oprogramowania z oficjalnej strony. 

Proces stawiania projektu potrwa kilka minut i zakończy się otworzeniem silnika Unity, w którym na tę chwilę nie zdziałamy zbyt wiele. Nie jest to jednak problemem, bo nas interesuje nadal GitHub Desktop. Kiedy do niego przejdziecie i zrobiliście każdy wcześniejszy krok zgodnie z instrukcją, powinniście zauważyć jedynie kilkadziesiąt wykrytych przez aplikację nowych plików.

Jeśli jednak widzicie całe kilkanaście tysięcy zmian, to musicie poprawić wpadkę z .gitignore, który znalazł się “zbyt wysoko” w hierarchii plików. Teoretycznie nie jest to błąd, ale w praktyce nigdy nie chcecie wysyłać na serwer takiej liczby bezużytecznych plików. 

Rozwiązanie problemu jest prozaiczne, bo w tym celu musicie albo przenieść plik do folderu z projektem (zalecane), albo zmodyfikować go tak, aby lepiej odzwierciedlał ścieżkę plików. Jeśli nie jesteście zaznajomieni ze ścieżkami, to już śpieszę ze wskazówkami. Powodem takiego nagromadzenia zmian jest przede wszystkim folder Library oraz Temp w plikach projektu, a tak się składa, że żadnego z nich nie potrzebujecie do upragnionego szczęścia.

Wspomnianą modyfikację zalecam zrobić na własną rękę po krótkim researchu w Google, które podczas programowania stanie się waszą drugą ręką. Dla leniwych polecam po prostu dodać “Temp/” oraz “Library/” w oddzielonych enterami linijkach w pliku (np. na samym dole), a najlepiej odszukanie oryginalnych określeń /[Ll]ibraty/ oraz /[Tt]emp/, które generują ten problem i usunąć pierwsze “/”. Warto to zrobić również przy pozostałych linijkach, a to tylko po to, aby zrozumieć, jak .gitignore działa. W praktyce jednak najlepiej wyjdziecie po przeniesieniu pliku do projektu. 

Kiedy już się z tym uporacie, a GitHub Desktop będzie wspominał o maksymalnie kilkudziesięciu plikach, to możecie przejść do najważniejszego – poznania podstawowych operacji stosowanych w Gicie, których na szczęście nie ma zbyt wiele i które w ogólnym rozrachunku są bardzo proste. Przynajmniej, jeśli korzystacie z interfejsu graficznego, bo w pierwotnej wersji Git był obsługiwany wyłącznie komendami, które wprawdzie znać warto, ale to już temat na inny artykuł.

Przechodząc już do najważniejszego, wspomniane zmiany wykryte przez GitHub Desktop musimy “skomitować” (commit), co wykonujemy poprzez ich zaznaczenie (ptaszek po lewej od nazwy plików), a następnie wpisanie widocznej dla współpracowników nazwy commita, która powinna być krótka i jednoznacznie określać to, czego dokonaliśmy w tych zmianach. W razie potrzeby możemy rozszerzyć ją o opcjonalny komentarz i wreszcie kliknąć “commit to main”.

Czytaj też: Spędziłem 2 lata z Xbox Series X. Czy nadal warto go kupić?

Po chwili zostaniecie poinformowani o tym, że na waszej maszynie nie znajdują się jakiekolwiek zmiany w projekcie, które interesują system kontroli wersji. Oznacza to, że zdołaliście zapisać zmiany w lokalnym repozytorium na konkretnej gałęzi (tutaj main), podpisaliście się pod nimi i możecie teraz wysłać je na zdalne repozytorium. Dokonacie tego jednym kliknięciem przycisku “push to main” na górnej belce. Po kilku sekundach (albo nawet kilkudziesięciu, jeśli wasze zmiany były rozległe) proces zostanie zakończony, co możecie zweryfikować w przeglądarce, przeglądając wasze repozytorium na Githubie.

Jeśli nadal nie wiecie, czego zdołaliście dokonać, to już śpieszę z wyjaśnieniem. W praktyce to, co robicie w Unity i co chcecie wysłać na serwer Githuba, można porównać do zarządzania oddzielonymi od siebie systemów plików. Commit jest niczym “zapisanie dokumentu” w Gicie, a push oznacza jego wysłanie na serwer. Jeśli pracujecie w grupie lub na różnych sprzętach, poznacie zapewne prędko określenie “fetch” (to odświeżenie lokalnych danych względem tego, co znajduje się na serwerze) oraz “pull”, co oznacza pobieranie najświeższych zmian z serwera względem wersji znajdujących na waszych lokalnych maszynach. 

O ile przy pracy w pojedynkę możecie zakończyć naukę Gita na tym poziomie, to jeśli pracujecie nad czymś dużym, w grupie lub na kilku komputerach, koniecznie musicie rozważyć wprowadzenie bardziej profesjonalnego podejścia do rozwijania projektu. W takich chwilach musicie operować już na oddzielnych gałęziach, bo wspomniane wcześniej “commitowanie i pushowanie na maina” oznacza, że wprowadzaliście zmiany bezpośrednio na waszą główną wersję projektu, gdzie powinny trafiać wyłącznie w pełni działające i sprawdzone zmiany i funkcje. 

Czym jest gałąź (branch) i jak zarządzać projektem Gita w grupie?

Dobrą praktyką korzystania z systemu kontroli wersji jest wykorzystywanie gałęzi do oddzielenia tego, nad czym aktualnie pracujecie. Jak już wspominałem, stworzona z początku gałąź “main” jest tą główną, ale nic nie stoi na przeszkodzie, aby z poziomu aplikacji GitHub Desktop tworzyć dodatkowe gałęzie, czyli generować kopię zapasową innej (najczęściej tej głównej), stosownie ją nazwać (np. Main Menu Implementing), wysłać na serwer poprzez opcję “Publish Branch” i pracować na niej bez ryzyka wprowadzenia nieodpowiednich zmian do głównego projektu. 

Kiedy już skończycie pracę nad daną funkcją, poprawicie błędy lub po prostu wprowadzicie jakkolwiek użyteczne zmiany na swojej gałęzi, które powinny znaleźć się na tej głównej, to musicie wystosować do waszego lidera (albo po prostu zrobić to samemu) prośbę (pull-request) o połączenie waszej gałęzi z tą główną. Ta powinna być zresztą ustawiona tak, aby uniemożliwić samodzielne łączenie gałęzi, które określa się mianem tak zwanego “merge”. Jego przeprowadzenie wymaga kilku kliknięć do wykonania zarówno w aplikacji, jak i przeglądarce i po którego zakończeniu oraz ewentualnie rozwiązaniu potencjalnych konfliktów (zdarzają się wtedy, kiedy para deweloperów zmienia te same pliki) zmiany wprowadzone na innej gałęzi zostaną przeniesione do tej docelowej (w domyśle głównej – main). 

Czytaj też: Wszyscy mówili: nie idź do gamedevu. Nie posłuchałem i dziś mogę się pochwalić pierwszą grą

Proces Fetchowania

Wtedy inni członkowie waszego zespołu powinni zadbać o zaktualizowanie swoich gałęzi poprzez odświeżenie zmian (fetch) oraz ich pobranie (pull). W praktyce kliknięcie “Fetch Origin” w GitHub Desktop wystarczy, bo wszelkie zmiany zostaną wykryte, a następnie aplikacja zaproponuje wam ich “zaciągnięcie” z serwera na lokalny komputer. 

Z tą oto wiedzą możecie zaczynać tworzenie gry w Unity, nie ryzykując, że dziesiątki godzin pracy pójdą do kosza tylko przez to, że nie zadbaliście o postawienie repozytorium i systemu kontroli wersji na początku przygody. Jeśli temat szczególnie was interesuje, to zapewne własny projekt popchniecie dalej po przeczytaniu tych słów już samodzielnie, ale jeśli tylko interesuje was cały proces powstawania gry, Unity oraz game-designu, to wyczekujcie kolejnych artykułów z tej części serii “Od Zera Do Game-Developera”, która zakończy się stworzeniem pełnoprawnej gry.