Professional Documents
Culture Documents
O autorze . ..............................................................................................................................19
Wprowadzenie . ..................................................................................................................21
Iteracja . ...............................................................................................................................157
Pętla while ..........................................................................................................................157
Pętla for ...............................................................................................................................158
Podsumowanie .................................................................................................................159
Pytania i odpowiedzi .....................................................................................................159
Warsztaty . ..........................................................................................................................159
Quiz ........................................................................................................................................160
Odpowiedzi ........................................................................................................................160
Ćwiczenie . ..........................................................................................................................160
Warsztaty . ..........................................................................................................................190
Quiz ........................................................................................................................................191
Odpowiedzi ........................................................................................................................191
Ćwiczenie . ..........................................................................................................................191
Skoki ......................................................................................................................................253
Popychanie obiektów ....................................................................................................254
Pełny kod skryptu ...........................................................................................................255
Podsumowanie .................................................................................................................256
Pytania i odpowiedzi .....................................................................................................256
Warsztaty . ..........................................................................................................................256
Quiz ........................................................................................................................................256
Odpowiedzi ........................................................................................................................257
Ćwiczenie . ..........................................................................................................................257
Instalacja Unity
Aby rozpocząć korzystanie z środowiska Unity, najpierw musisz je pobrać
i zainstalować. Obecnie instalacja oprogramowania to całkiem łatwy proces,
a Unity nie jest pod tym względem wyjątkiem. Jednak zanim będzie można
cokolwiek zainstalować, najpierw warto zapoznać się z dwiema dostępnymi
licencjami Unity, czyli Unity Free i Unity Pro. Wersja Unity Free jest w zupełności
wystarczająca do wykonania wszystkich przykładów i projektów przedsta‐
wionych w książce. Unity Free zawiera wszystko, co jest niezbędne do komer‐
cyjnego tworzenia gier. Jeśli jednak chcesz uzyskać dostęp do jeszcze potęż‐
niejszych możliwości (i przy okazji wydać pieniądze), Unity Pro oferuje
rozszerzony zestaw narzędzi składający się na „drogi” silnik gier. Oprogramo‐
wanie Unity Free jest dostarczane wraz z 30‐dniową wersją testową Unity Pro,
co pozwala na wypróbowanie funkcji oferowanych przez Unity Pro, ale bez
konieczności ponoszenia kosztów związanych z zakupem licencji. Sprawdź
obie dostępne wersje i samodzielnie przekonaj się, która jest najlepsza dla
Twoich potrzeb. Przeglądając informacje w witrynie internetowej Unity, możesz
zauważyć, że dostępne są licencje dla wtyczek przeznaczonych dla systemów
Android i iOS. W najnowszych wydaniach Unity podstawowe wtyczki dla sys‐
temów mobilnych są bezpłatne i dostarczane wraz z Unity.
RYSUNEK 1.1.
Wybór
instalowanych
komponentów
RYSUNEK 1.2.
Wybór katalogu,
w którym zostanie
zainstalowane
środowisko Unity
RYSUNEK 1.3.
Wybór licencji
środowiska Unity
28 Lekcja 1. Wprowadzenie do Unity
RYSUNEK 1.4.
Logowanie
do konta Unity
Łącza internetowe
Wszystkie łącza internetowe były aktualne w trakcie powstawania tej książki.
Jednak adresy stron internetowych czasami ulegają zmianom. Jeżeli szukany
materiał nie znajduje się na stronie, do której prowadzi podane łącze inter-
netowe, wtedy właściwą treść najczęściej można znaleźć za pomocą dobrej
wyszukiwarki internetowej.
RYSUNEK 1.5.
Okno dialogowe
Project
Wypróbuj samodzielnie
Projekty i pakiety
Być może na początku będziesz chciał zaznaczyć wiele różnych pakietów
w oknie dialogowym Create New Project. W tym miejscu ostrzegam przed
lekkomyślnym dodawaniem pakietów do projektu, ponieważ niepotrzebne
elementy zajmują cenne miejsce i jednocześnie spowalniają działanie two-
rzonej aplikacji. Niewykorzystywane pakiety po prostu jedynie zabierają miej-
sce i nie oferują w zamian żadnych korzyści. Naprawdę warto wstrzymać się
z dodawaniem pakietów aż do chwili, gdy rzeczywiście okażą się potrzebne.
Jednak nawet wtedy importuj tylko te fragmenty pakietów, które zamie-
rzasz wykorzystywać w projekcie.
Interfejs Unity
Zainstalowałeś już Unity i wyświetliłeś okno dialogowe Project. Najwyższy
czas przejść nieco dalej i skorzystać z środowiska. Po pierwszym otworzeniu
nowego projektu Unity zobaczysz zbiór szarych okien (nazywanych panelami),
które praktycznie pozostają puste (patrz rysunek 1.7). Nie obawiaj się, wkrótce
zaczną tętnić życiem. W kolejnych punktach poznasz poszczególne panele. Jed‐
nak najpierw spójrz na układ jako całość.
RYSUNEK 1.7.
Interfejs Unity
Jeżeli chcesz powielić panel, możesz to zrobić dość łatwo. Wystarczy kliknąć
prawym przyciskiem myszy dowolną kartę panelu (karta zawiera nazwę
panelu) i wybrać opcję Add Tab. Na ekranie zostanie wyświetlona lista paneli
(patrz rysunek 1.8). Być może zastanawiasz się, dlaczego miałbyś powielać
panel. Istnieje niebezpieczeństwo, że w gorączce przenoszenia i przesuwania
paneli przypadkowo zamkniesz jeden z nich. Dodanie nowej karty pozwala na
przywrócenie zamkniętego panelu. Ponadto rozważ możliwość utworzenia
wielu paneli Scene. Każdy panel Scene może wyświetlać określony element
sceny lub można go wyrównać do wybranej osi w projekcie. Chcesz zobaczyć,
jak to działa? Otwórz wbudowany układ Split, wybierając opcję Window/
Layouts/4 Split (jeśli przygotowałeś panel, który chcesz zachować, zapisz go
przed wybraniem wymienionej opcji).
Teraz bez zbędnych ceregieli mogę przejść do omawiania poszczególnych paneli.
Panel Project
Wszystkie elementy tworzone dla projektu, czyli pliki, skrypty, tekstury,
modele itd., są dostępne w panelu Project, który pokazano na rysunku 1.9. Panel
ten jest oknem przeznaczonym na wszystkie zasoby projektu i pozwala na
zarządzanie nimi. Po utworzeniu nowego projektu zauważysz, że istnieje poje‐
dynczy katalog o nazwie Assets. Jeżeli w menedżerze plików systemu opera‐
cyjnego przejdziesz do katalogu projektu, zobaczysz, że on również zawiera
podkatalog Assets. Panel Project w Unity po prostu odzwierciedla zawartość
katalogu projektu zapisanego na dysku. Jeśli utworzysz plik lub katalog w pro‐
jekcie Unity, odpowiedni element pojawi się na dysku (i na odwrót). Przeno‐
Poznajemy edytor Unity 33
RYSUNEK 1.8.
Dodanie
nowej karty
RYSUNEK 1.9.
Panel Project
Zasoby
Zasób to dowolny element istniejący jako plik w podkatalogu Assets.
Wszystkie tekstury, modele, pliki dźwiękowe, skrypty itd. można uznać za
zasoby. Z drugiej strony, jeśli utworzysz obiekt gry, dla którego na dysku nie
ma pliku, wtedy wspomniany obiekt nie jest zasobem.
Przenoszenie zasobów
Unity zachowuje połączenia między różnymi zasobami projektu, dlatego też
usunięcie lub przeniesienie zasobu poza projekt Unity może doprowadzić
do problemów. Ogólnie rzecz biorąc, zaleca się, aby wszystkie operacje
zarządzania zasobami były przeprowadzane tylko w edytorze Unity.
34 Lekcja 1. Wprowadzenie do Unity
Zarządzanie projektem
Zarządzanie projektem jest niezwykle ważne. Wraz z rozbudową projektu
liczba zasobów zacznie gwałtownie rosnąć i wówczas odszukanie czego-
kolwiek może być prawdziwą udręką. Możesz uniknąć frustracji, kiedy pod-
czas zarządzania projektem zastosujesz kilka prostych reguł.
Dla każdego typu zasobu (takiego jak sceny, skrypty, tekstury itd.)
powinien zostać utworzony oddzielny katalog.
Każdy zasób powinien być umieszczony w katalogu.
Jeżeli zamierzasz korzystać z podkatalogów w katalogu zasobów
danego typu, wtedy upewnij się, że tworzona struktura ma sens.
Kolejne podkatalogi powinny być coraz bardziej szczegółowe, a nie
niejednoznaczne lub ogólne.
Stosowanie się do wymienionych powyżej kilku prostych reguł naprawdę
może pomóc w efektywnym zarządzaniu zasobami.
Panel Hierarchy
Po wieloma względami pokazany na rysunku 1.11 panel Hierarchy przypomina
omówiony wcześniej panel Project. Jedyna różnica polega na tym, że na panelu
Hierarchy wyświetlane są wszystkie elementy bieżącej sceny, a nie całego pro‐
jektu. Po utworzeniu projektu w Unity zawiera on scenę domyślną, która jest
praktycznie pusta, ponieważ składa się z tylko jednego elementu — kamery
głównej. Wraz z dodawaniem kolejnych elementów na scenie pojawiają się one
Poznajemy edytor Unity 35
RYSUNEK 1.10.
Wyszukiwanie
zasobów
w sklepie Unity
Asset Store
RYSUNEK 1.11.
Panel Hierarchy
Panel Inspector
Panel Inspector pozwala na wyświetlenie wszystkich właściwości aktualnie
wybranego elementu. Wystarczy po prostu kliknąć dowolny zasób bądź obiekt
w panelach Project lub Hierarchy, a panel Inspector zostanie automatycznie
wypełniony odpowiednimi informacjami.
36 Lekcja 1. Wprowadzenie do Unity
Zagnieżdżanie
Zagnieżdżanie to pojęcie oznaczające istnienie relacji między dwoma ele-
mentami lub większą ich liczbą. W panelu Hierarchy kliknięcie elementu
i przeciągnięcie go na inny spowoduje zagnieżdżenie jednego elementu
w drugim. To bardzo często nosi nazwę relacji nadrzędny-potomny. W oma-
wianym przypadku obiekt wyświetlany na górze jest nadrzędny, natomiast
poniższe są potomnymi. Na zagnieżdżenie obiektu wskazuje wcięcie jego
nazwy w panelu. Jak się przekonasz dalej w tej książce, zagnieżdżanie obiek-
tów w panelu Hierarchy może mieć wpływ na sposób ich zachowania.
Sceny
Scena to w środowisku Unity pojęcie używane do opisania tego, co możesz
znać pod nazwą poziom gry. W trakcie pracy nad projektem Unity każda
kolekcja obiektów i zachowań powinna być umieszczona na własnej scenie.
Dlatego też jeśli tworzysz grę, w której akcja toczy się na dwóch poziomach
(na śniegu oraz w dżungli), powinny być one umieszczone na oddzielnych
scenach.
Zarządzanie sceną
Pierwszym krokiem po rozpoczęciu pracy nad nowym projektem Unity
powinno być utworzenie za pomocą panelu Project podkatalogu Scenes
w katalogu Assets. W ten sposób wszystkie sceny (czyli poziomy) będą
przechowywane w tym samym miejscu. Upewnij się, że nadajesz scenom
opisowe nazwy. Na początku nazwa Scena1 może wydawać się świetna, ale
gdy gra zawiera 30 scen, wymieniona nazwa będzie dezorientująca.
RYSUNEK 1.12.
Panel Inspector
Panel Scene
Panel Scene (patrz rysunek 1.13) jest najważniejszy podczas pracy, ponieważ
pokazuje wygląd tworzonej gry. Za pomocą myszy oraz kilku skrótów klawi‐
szowych możesz poruszać się po elementach sceny oraz umieszczać obiekty
w wybranych miejscach. W ten sposób zyskujesz dość dużą kontrolę nad sceną.
38 Lekcja 1. Wprowadzenie do Unity
Już wkrótce omówię temat poruszania się po scenie, ale najpierw skoncen‐
truję się na kontrolkach będących częścią panelu Scene.
Tryb wyświetlania. Kontrolka określa sposób wyświetlenia sceny.
Trybem domyślnym jest Textured, co oznacza, że obiekty będą
wyświetlane wraz z teksturami.
Tryb generowania. Kontrolka określa sposób generowania obiektów
na scenie. Trybem domyślnym jest RGB, co oznacza, że obiekty będą
wyświetlane w pełnej palecie kolorów.
Oświetlenie sceny. Kontrolka określa, czy obiekty na scenie będą
oświetlone domyślnym światłem otoczenia, czy światłami znajdują‐
cymi się na scenie. Ustawienie domyślne powoduje użycie wbudo‐
wanego światła otoczenia, ale to ulega zmianie wraz z pierwszym
światłem umieszczonym na scenie.
Warstwy gry. Kontrolka określa, czy elementy, takie jak niebo lub
komponenty graficznego interfejsu użytkownika, będą wyświetlane
w panelu Scene. Ponadto omawiana kontrolka wskazuje, czy widoczna
będzie siatka ułatwiająca rozmieszczanie elementów.
Tryb dźwięku. Kontrolka określa, czy mają być odtwarzane dźwięki
powiązane z daną sceną.
Wybór ikon pomocniczych. Kontrolka pozwala na wskazanie, które
„ikony pomocnicze” będą wyświetlane w panelu Scene. Tego rodzaju
ikony są graficzną reprezentacją obiektów w edytorze i pomagają
w ich identyfikacji na scenie.
Poznajemy edytor Unity 39
Panel Game
Ostatnim panelem omawianym w tej lekcji jest Game. W gruncie rzeczy panel
Game pozwala na „uruchomienie” gry w edytorze, a tym samym zapewnia
pełną symulację bieżącej sceny. Wszystkie elementy gry będą funkcjonowały
w panelu Game dokładnie w taki sam sposób jak w ukończonym produkcie.
Na rysunku 1.14 pokazano przykładowy panel Game. Warto w tym miejscu
dodać, że wprawdzie — z technicznego punktu widzenia — przyciski Start,
Pauza i Dalej nie należą do panelu Game, ale kontrolują jego działanie i dla‐
tego zostały pokazane na rysunku.
40 Lekcja 1. Wprowadzenie do Unity
RYSUNEK 1.14.
Panel Game
RYSUNEK 1.15.
Pasek
narzędziowy
Narzędzie Hand
Pokazane na rysunku 1.16 narzędzie Hand (skrót klawiszowy Q) oferuje
możliwość poruszania obiektami w panelu Scene za pomocą myszy. Omawiane
narzędzie jest szczególnie użyteczne, gdy używasz myszy z tylko jednym przy‐
ciskiem (inne metody wymagają myszy z dwoma przyciskami). W tabeli 1.1
pokrótce przedstawiono kontrolki narzędzia Hand.
RYSUNEK 1.16.
Ikona narzędzia
Hand w sekcji
narzędzi
transformacji
Różne kamery
Podczas pracy w środowisku Unity spotkasz się z dwoma rodzajami kamer.
Pierwsza to standardowa kamera obiektu gry. Jak możesz zobaczyć, scena
domyślnie zawiera jedną tego rodzaju kamerę. Drugi typ to bardziej
wyimaginowana kamera. Ujmując rzecz dokładniej, to nie jest kamera
w tradycyjnym znaczeniu tego słowa. Określa, co można zobaczyć w panelu
Scene. W tej lekcji, gdy jest mowa o kamerze, chodzi o drugi z wymie-
nionych typów. Nie będziesz przeprowadzać żadnych modyfikacji kamery
obiektu gry.
Tryb Flythrough
Tryb Flythrough pozwala na poruszanie się po scenie za pomocą tradycyjnego
schematu panelu pierwszej osoby. Tryb ten jest doskonale znany każdemu, kto
grywał w gry 3D w perspektywie pierwszej osoby (np. popularne gry typu
First-person shooter). Jeżeli nie grałeś w tego rodzaju gry, do trybu Flythrough
będziesz musiał się przyzwyczaić. Gdy tylko do niego przywykniesz, stanie
się Twoją drugą naturą.
Naciśnięcie i przytrzymanie prawego przycisku myszy powoduje przejście
do trybu Flythrough. Wszystkie operacje wymienione w tabeli 1.2 wymagają
przytrzymania prawego przycisku myszy.
Podsumowanie
W tej lekcji ogólnie poznałeś środowisko Unity. Pracę rozpocząłeś od pobrania
i instalacji Unity. Dowiedziałeś się, jak tworzyć nowe projekty i otwierać ist‐
niejące. Poznałeś różne panele istniejące w edytorze Unity. Ponadto umiesz już
poruszać się po panelu Scene.
44 Lekcja 1. Wprowadzenie do Unity
Przybliżanie i oddalanie
Niezależnie od wybranej metody nawigacji, ruch kółkiem myszy zawsze
będzie powodował przybliżanie i oddalanie panelu na scenie. Domyślnie
scena jest przybliżana i oddalana na środku panelu Scene. Jeżeli w trakcie
operacji przytrzymasz klawisz Alt, przybliżanie i oddalanie będzie następo-
wało w aktualnym miejscu położenia kursora. Śmiało, wypróbuj to!
Kontrolki przyciągania
Istnieje wiele sposobów zapewnienia dokładnej kontroli podczas nawigacji
po scenie. Czasami po prostu trzeba szybko poruszać się po scenie. W takiej
sytuacji warto użyć tego, co nazywam kontrolkami przyciągania. Jeżeli chcesz
szybko się poruszać lub przybliżać i oddalać obiekt gry na scenie, kliknij
dany obiekt w panelu Hierarchy, a następnie naciśnij klawisz F. Zauważysz,
że scena „przyciągnie” ten obiekt gry. Inną kontrolkę przyciągania pozna-
łeś już wcześniej. Ikona pomocnicza na scenie pozwala na szybkie przy-
ciągnięcie kamery do dowolnej osi. W ten sposób można zobaczyć obiekt
z dowolnego kąta bez konieczności ręcznego poruszania kamerą po scenie.
Upewnij się, że umiesz obsługiwać kontrolki przyciągania oraz szybko
poruszać się po scenie za ich pomocą!
Pytania i odpowiedzi 45
Pytania i odpowiedzi
Pytanie: Czy zasoby i obiekty gry to jest to samo?
Odpowiedź: Nie. Podstawowa różnica polega na tym, że zasobowi odpowiada
plik lub grupa plików na dysku, podczas gdy obiektowi gry nie. Ponadto
zasób może, choć nie musi, zawierać obiekt gry.
Pytanie: Istnieje wiele różnych kontrolek i opcji. Czy muszę od razu
zapamiętać wszystkie?
Odpowiedź: Nie. Większość kontrolek i opcji jest ustawiona w stanie
domyślnym, który jest odpowiedni w wielu sytuacjach. Wraz
z poszerzaniem wiedzy o środowisku Unity będziesz dowiadywał się
coraz więcej o różnych dostępnych kontrolkach. W tej lekcji jedynie
pokazano kontrolki, aby umożliwić Ci przyzwyczajanie się do nich.
Warsztaty
Poświęć nieco czasu i odpowiedz na zamieszczone poniżej pytania, a także
upewnij się, że przyswoiłeś sobie materiał omówiony w tej lekcji.
Quiz
1. Aby tworzyć gry, konieczne jest zakupienie Unity Pro. Prawda czy fałsz?
2. Który panel pozwala na wizualne modyfikowanie obiektów na scenie?
3. Zawsze powinieneś zarządzać plikami zasobów z poziomu Unity
i nie używać do tego menedżera plików oferowanego przez system
operacyjny. Prawda czy fałsz?
4. Podczas tworzenia nowego projektu powinieneś w nim umieścić każdy
zasób, który uważasz za doskonały. Prawda czy fałsz?
5. Do którego trybu przejdziesz w panelu Scene po naciśnięciu
i przytrzymaniu prawego przycisku myszy?
Odpowiedzi
1. Fałsz.
2. Panel Scene.
3. Prawda.
4. Fałsz.
5. Tryb Flythrough.
46 Lekcja 1. Wprowadzenie do Unity
Ćwiczenie
Poświęć chwilę na utrwalenie koncepcji omówionych w tej lekcji. Solidne
opanowanie podstaw edytora Unity jest bardzo ważne, ponieważ zdobytą tutaj
wiedzę będziesz nieustannie wykorzystywać na różne sposoby. Wykonaj zatem
zaprezentowane poniżej ćwiczenie.
1. Utwórz nową scenę, wybierając opcję File/New Scene lub naciskając
klawisze Ctrl+N (Command+N w Macu).
2. Korzystając z panelu Project, utwórz podkatalog Scenes w katalogu
Assets.
3. Zapisz scenę, wybierając opcję File/Save Scene lub naciskając klawisze
Ctrl+S (Command+S w Macu). Upewnij się, że zapisałeś scenę
w utworzonym wcześniej podkatalogu Scenes oraz nadałeś jej opisową
nazwę.
4. Na scenie umieść sześcian. W tym celu przejdź do menu GameObject
na górze okna, umieść kursor myszy nad menu Create Other, a następnie
wybierz opcję Cube.
5. W panelu Hierarchy zaznacz nowo utworzony sześcian, a następnie
w panelu Inspector poeksperymentuj z jego właściwościami.
6. Poćwicz nawigację w panelu Scene przy użyciu trybu Flythrough,
narzędzia Hand oraz kontrolek przyciągania. Wykorzystaj sześcian
jako punkt odniesienia pomagający w nawigacji.
Lekcja 2
Obiekty gry
RYSUNEK 2.1.
Kwadrat (2D)
kontra sześcian
(3D)
Poznawanie systemów 2D i 3D
Unity to silnik 3D, dlatego też we wszystkich projektach tworzonych w Unity
wykorzystane zostały trzy wymiary. Być może zastanawiasz się więc, jaki
jest cel omawiania układów współrzędnych 2D. Musisz je znać, bo nawet
w projektach 3D znajdują się elementy 2D. W teksturach, elementach ekranu
oraz technikach mapowania używa się dwuwymiarowego układu współ-
rzędnych. Warto zatem poznać układy współrzędnych 2D, ponieważ są
powszechnie wykorzystywane.
RYSUNEK 2.2.
Punkty
w odniesieniu
do początku
układu
współrzędnych
Obiekty gry
Każdy kształt, model, światło, kamera, system cząsteczek itd. w grze opartej
na silniku Unity łączy jedna wspólna cecha: wszystkie są obiektami gry. Jak
pewnie się domyślasz, obiekt gry jest podstawową jednostką każdej sceny.
Transformacje 51
Nawet prosty obiekt gry oferuje potężne możliwości. W gruncie rzeczy obiekt
gry to nieco więcej niż transformacja (co szczegółowo omówię dalej w tej
lekcji) i kontener. Kontener jest przeznaczony do przechowywania różnych
komponentów, dzięki którym obiekty gry charakteryzują się dynamizmem
i są istotne. To, co dodasz do obiektu gry, zależy tylko od Ciebie. Istnieje wiele
komponentów, które znacznie się różnią. W tej książce dowiesz się, jak korzy‐
stać z komponentów.
Obiekty wbudowane
Nie każdy obiekt gry jest na początku pustym obiektem. Środowisko Unity
zawiera wiele wbudowanych obiektów gry gotowych do natychmiastowego
użycia. Większość domyślnie oferowanych obiektów gry możesz przejrzeć,
klikając menu GameObject wyświetlane w górnej części okna edytora Unity,
a następnie wybierając opcję Create Other. Podczas poznawania Unity nieco
czasu poświęcisz na pracę z wbudowanymi oraz samodzielnie przygoto-
wanymi obiektami gry.
Transformacje
Poznałeś już różne układy współrzędnych i miałeś okazję poeksperymentować
z pewnymi obiektami gry. Najwyższy czas połączyć oba wymienione elementy.
Podczas pracy z obiektami 3D bardzo często będziesz spotykać pojęcie trans-
formacja. W środowisku Unity transformacja jest często określana wyrażeniem
komponent transformacji. Zapewne pamiętasz, że komponent transformacji
to jedyny komponent, który znajduje się w każdym obiekcie gry. Nawet pusty
obiekt gry zawiera komponent transformacji. Za pomocą omawianego kom‐
ponentu można zobaczyć bieżącą transformację obiektu, a także ją zmienić.
W tym momencie może to brzmieć dziwnie, ale jest całkiem proste. W krótkim
52 Lekcja 2. Obiekty gry
Wypróbuj samodzielnie
Translacja
Zmiana współrzędnych obiektu (czyli położenia tego obiektu) w układzie
współrzędnych 3D nosi nazwę translacji. To jest jednocześnie najprostsza
transformacja, jaką można zastosować na obiekcie. Podczas translacji obiekt
jest przesuwany wzdłuż wskazanych osi. Na rysunku 2.6 pokazano translację
kwadratu wzdłuż osi X.
Transformacje 53
RYSUNEK 2.4.
Opcje
transformacji
w panelu
Inspector
RYSUNEK 2.5.
Narzędzia
transformacji
RYSUNEK 2.6.
Przykładowa
translacja
RYSUNEK 2.7.
Ikony pomocnicze
translacji
54 Lekcja 2. Obiekty gry
Rotacja
Rotacja obiektu nie powoduje jego przesunięcia w przestrzeni. Zmienia tylko
relację obiektu względem przestrzeni, w której się znajduje. Ujmując rzecz
najprościej, rotacja pozwala na ponowne zdefiniowanie kierunku osi X, Y i Z
dla konkretnego punktu obiektu. Kiedy obiekt jest poddawany rotacji dla
pewnej osi, wtedy mówimy o rotacji względem tej osi. Na rysunku 2.8 poka‐
zano rotację kwadratu względem osi Z.
RYSUNEK 2.8.
Rotacja
względem osi Z
RYSUNEK 2.9.
Ikony pomocnicze
rotacji
Skalowanie
Skalowanie powoduje zwiększenie lub zmniejszenie obiektu w przestrzeni
trójwymiarowej. Ta transformacja jest naprawdę prosta i łatwa do wykonania.
Skalowanie obiektu wzdłuż wybranej osi powoduje zmianę jego wielkości
względem wskazanej osi. Na rysunku 2.10 pokazano skalowanie kwadratu
wzdłuż osi X i Y. Z kolei na rysunku 2.11 pokazano wygląd ikon pomocni‐
czych skalowania po wybraniu narzędzia skalowania (skrót klawiszowy R).
RYSUNEK 2.10.
Skalowanie
wzdłuż osi X i Y
RYSUNEK 2.11.
Ikony pomocnicze
skalowania
RYSUNEK 2.12.
Efekt kolejności
stosowania
transformacji
Podsumowanie
Podczas tej lekcji poznałeś obiekty gry w środowisku Unity. Na początek
omówione zostały różnice między systemami 2D i 3D, następnie opisany układ
współrzędnych i przeniesiona na matematykę koncepcja „świata”. Kolejnym
krokiem było rozpoczęcie pracy z obiektami gry, tutaj wykorzystano kilka
58 Lekcja 2. Obiekty gry
Pytania i odpowiedzi
Pytanie: Czy ważne jest, aby poznawać koncepcje zarówno 2D, jak i 3D?
Odpowiedź: Tak. Nawet w grach w pełni trójwymiarowych nadal stosuje się
na poziomie technicznym pewne koncepcje dwuwymiarowe.
Pytanie: Czy od początku powinienem uczyć się, jak używać wszystkich
obiektów gry wbudowanych w Unity?
Odpowiedź: Niekoniecznie. Istnieje tak wiele obiektów gry, że próba poznania
wszystkich od razu może okazać się karkołomna. Lepszym rozwiązaniem
jest poznawanie obiektów gry po kolei, gdy są omawiane w książce.
Pytanie: Jaki jest najlepszy sposób poznania transformacji?
Odpowiedź: Praktyka. Gdy będziesz pracował z transformacjami, wkrótce
ich użycie stanie się oczywiste i naturalne.
Warsztaty
Poświęć nieco czasu i odpowiedz na zamieszczone poniżej pytania, a także
upewnij się, że przyswoiłeś sobie materiał omówiony w tej lekcji.
Quiz
1. Co oznacza litera D w zapisie 2D i 3D?
2. Ile mamy transformacji?
3. Unity nie posiada wbudowanych obiektów i musisz je tworzyć
samodzielnie. Prawda czy fałsz?
4. Jeżeli chcesz „położyć obiekt na boku” w odległości 5 jednostek
w prawo od bieżącego położenia, czy przeprowadzisz wówczas rotację
obiektu, a później jego translację, czy najpierw translację i dopiero
wtedy rotację?
Odpowiedzi
1. Wymiar (ang. dimension).
2. Trzy.
3. Fałsz. Unity zawiera wiele wbudowanych obiektów gotowych do użycia.
4. Najpierw translacja, a dopiero później rotacja.
Ćwiczenie 59
Ćwiczenie
Poświęć chwilę na utrwalenie koncepcji omówionych w tej lekcji. Poekspe‐
rymentuj z translacjami przeprowadzanymi względem zagnieżdżonych obiek‐
tów. Dzięki temu jeszcze lepiej poznasz sposób wprowadzania zmian w układzie
współrzędnych.
1. Utwórz nowy projekt lub scenę.
2. Do projektu dodaj sześcian i umieść go w położeniu (0, 2, –5). Pamiętaj
o skróconej notacji stosowanej w układzie współrzędnych.
Oto poszczególne wartości sześcianu: X: 0, Y: 2 i Z: –5. Wymienione
wartości można bardzo łatwo ustawić w komponencie transformacji
w panelu Inspector.
3. Do sceny dodaj kulę. Zwróć uwagę na wartości X, Y i Z kuli.
4. Zagnieźdź kulę w sześcianie. W tym celu w panelu Hierarchy
przeciągnij kulę na sześcian. Zwróć uwagę na zmianę wartości kuli.
W tym momencie wartości kuli są podawane względem sześcianu.
5. Umieść kulę w położeniu (0, 1, 0). Zauważ, że kula nie zostanie
przesunięta w prawą stronę od początku układu współrzędnych,
ale znajduje się po prawej stronie sześcianu.
6. Poeksperymentuj teraz z różnymi transformacjami. Upewnij się, że
wypróbowujesz je zarówno na sześcianie, jak i na kuli. Zwróć uwagę
na różnice między efektem zastosowania transformacji na obiektach
nadrzędnym i potomnym.
60 Lekcja 2. Obiekty gry
Lekcja 3
Modele, materiały
i tekstury
Podstawy modeli
Bez komponentów graficznych gry wideo nie byłyby aż tak atrakcyjne. W grach
dwuwymiarowych grafika składa się z płaskich obrazów nazywanych sprite’ami.
Twoje zadanie polega wtedy na zmianie położenia X i Y wspomnianych
sprite’ów oraz wielokrotnej ich zamianie, w ten sposób gracz zostanie oszu‐
kany i przekonany, że widzi rzeczywisty ruch i animację. Jednak w grach trój‐
wymiarowych nie jest to takie proste. Aby oszukać oko gracza w świecie obej‐
mującym trzecią oś (głębokość), obiekt nie może być płaski. Ponieważ w grach
wykorzystuje się ogromną liczbę obiektów, bardzo ważne jest zapewnienie
możliwości jak najszybszego przetwarzania danych. Konieczne jest zatem
poznanie siatki. W najprostszej postaci siatka to zbiór połączonych trójkątów.
Łącząc trójkąty, można tworzyć różne obiekty, od prostych do niezwykle skom‐
plikowanych. Połączone trójkąty stanowią trójwymiarową definicję modelu
i mogą być przetwarzane naprawdę bardzo szybko. Nie przejmuj się, środo‐
wisko Unity zajmuje się całą obsługą, a więc nie będziesz zmuszony robić tego
samodzielnie. Dalej w tej lekcji dowiesz się, jak za pomocą trójkątów utworzyć
różne kształty w panelu Scene edytora Unity.
Dlaczego trójkąty?
Być może zadajesz sobie pytanie, dlaczego obiekty 3D w całości składają
się z trójkątów. Odpowiedź jest prosta. Komputer przetwarza grafikę jako
serię punktów nazywanych również wierzchołkami. Im mniej wierzchołków
będzie zawierał obiekt, tym szybciej może być wyświetlony. Trójkąty charak-
teryzują się dwoma własnościami, które czynią z nich doskonały wybór.
Oto pierwsza właściwość: kiedy masz jeden trójkąt, drugi możesz utworzyć
za pomocą tylko jednego dodatkowego wierzchołka. Dlatego też jeden
trójkąt wymaga trzech wierzchołków, dwa trójkąty wymagają tylko czterech
wierzchołków, natomiast trzy trójkąty jedynie pięciu wierzchołków. Z tego
powodu użycie trójkątów jest niezwykle efektywne. A to druga właściwość:
za pomocą wspomnianych wcześniej połączonych trójkątów można wymo-
delować dowolny obiekt 3D. Żaden inny kształt nie oferuje tego poziomu
elastyczności i wydajności.
Wbudowane obiekty 3D
Środowisko Unity jest dostarczane wraz z kilkoma podstawowymi siatkami
(są to obiekty proste), co pozwala na szybkie rozpoczęcie pracy z siatką.
Domyślne siatki są bardzo prostymi kształtami, które mogą służyć w charak‐
terze prostych narzędzi lub być stosowane do tworzenia znacznie bardziej
skomplikowanych obiektów. Na rysunku 3.1 pokazano siatki wbudowane
w Unity. (W poprzednich lekcjach zetknąłeś się już z sześcianem i kulą).
RYSUNEK 3.1.
Siatki domyślnie
wbudowane
w Unity
Importowanie modeli
Posiadanie wbudowanych modeli jest miłe, ale w większości przypadków
opracowywane gry wymagają nieco bardziej złożonych zasobów graficznych.
Na szczęście, środowisko Unity znacznie ułatwia programiście dodawanie
własnych modeli 3D do projektu. Zwykłe umieszczenie w katalogu Assets
64 Lekcja 3. Modele, materiały i tekstury
Wypróbuj samodzielnie
Wypróbuj samodzielnie
RYSUNEK 3.5.
Różne elementy
zasobu modelu
Tekstury
Tekstury to płaskie obrazy nakładane na obiekty 3D. Za pomocą tekstur przy‐
gotowywane modele stają się kolorowe i interesujące. Być może nie potrafisz
sobie wyobrazić, jak obraz dwuwymiarowy można nałożyć na model trój‐
wymiarowy, ale zapewniam, że to całkiem prosty proces, gdy się już go pozna.
Spójrz np. na kolorowe opakowanie puszki z owocami. Po zdjęciu etykiety
pozostanie jedynie blaszane opakowanie. Etykietę można potraktować jako
teksturę. Po wydrukowaniu etykieta jest nakładana na trójwymiarową puszkę
z owocami, w ten sposób otrzymujemy atrakcyjnie wyglądający produkt.
Podobnie jak wszystkie pozostałe zasoby, dodawanie tekstur do projektu Unity
jest łatwe. Należy rozpocząć od utworzenia katalogu dla tekstur, dobrą nazwą
dla katalogu będzie Textures. Następnie tekstury przeznaczone do wykorzy‐
stania w projekcie trzeba przeciągnąć na utworzony przed chwilą katalog.
I to tyle!
To jest rozwinięcie
Wyobrażenie sobie nałożenia tekstury na puszkę nie powinno sprawiać
trudności, ale jak to wygląda w przypadku znacznie bardziej skompliko-
wanych obiektów? Podczas tworzenia złożonych modeli dość często gene-
rowane jest tzw. rozwinięcie (ang. unwrap). Rozwinięcie to rodzaj mapy
dokładnie pokazującej, jak płaska tekstura zostanie nałożona na model.
Kiedy spojrzysz do katalogu Robot Kyle/Textures zaimportowanego wcze-
śniej w tej lekcji, zauważysz teksturę o nazwie Robot_Color. Wprawdzie
wygląda dziwnie, ale przedstawia rozwiniętą teksturę dla tego modelu.
Generowanie rozwinięć, modeli i tekstur jest formą sztuki samą w sobie i tym
nie będziesz się zajmować. Wystarczyć powinna ogólna wiedza na ten temat.
68 Lekcja 3. Modele, materiały i tekstury
Dziwne tekstury
Dalej w tej lekcji będziesz nakładać pewne tekstury na modele. Może się
zdarzyć, że tekstura zostanie nałożona za daleko lub przesunięta w nie-
właściwym kierunku. Trzeba wiedzieć, że to nie jest pomyłka lub błąd. Tego
rodzaju problem występuje, gdy próbujesz zwykłą, prostokątną teksturę
dwuwymiarową nałożyć na model. Sam model „nie wie”, czy dany sposób
nakładania tekstury jest prawidłowy, dlatego też nakłada teksturę zgodnie
ze swoimi możliwościami. Jeżeli chcesz uniknąć opisanego wcześniej pro-
blemu, używaj tekstur specjalnie przygotowanych (czyli rozwiniętych) dla
danego modelu.
Shadery
Tekstura modelu wskazuje, co jest wyświetlane na powierzchni modelu, nato‐
miast shader określa sposób wyświetlenia tej powierzchni. Oto inne wyjaśnienie
działania shadera. Materiał zawiera właściwości i tekstury, a shader ustala,
które właściwości i tekstury mogą przynależeć do danego materiału. W tym
momencie to może wydawać się nonsensowne i nielogiczne, ale gdy będziemy
tworzyć materiały, zaczniesz rozumieć, jak działa shader. Więcej danych
o shaderze znajdziesz dalej w tej lekcji, ponieważ nie można utworzyć shadera
bez materiału. Wiele informacji przedstawionych w punkcie poświęconym
materiałom faktycznie dotyczy shaderów.
Kwestie do przemyślenia
Jeżeli masz trudności w zrozumieniu sposobu działania shadera, przeana-
lizuj następującą sytuację. Wyobraź sobie kawałek drewna — jego kształt
jest nadawany przez siatkę, natomiast kolor i wygląd określa tekstura.
Teraz nasz kawałek drewna umieszczamy w wodzie. Drewno nadal składa
się z tej samej siatki. Dalej ma tę samą postać fizyczną (drewno), ale wygląda
nieco inaczej, jest trochę ciemniejsze i bardziej błyszczące. W omawianym
przykładzie woda jest shaderem. Shader pobiera element, a następnie bez
wprowadzania w nim jakichkolwiek zmian sprawia, że wygląda nieco inaczej.
Materiały
Jak wcześniej wspominałem, materiał składa się z kontenera dla shaderów
i tekstur, które można nałożyć na model. Większość operacji dostosowania
materiału do własnych potrzeb zależy od wybranego shadera, choć wszystkie
shadery charakteryzują się pewnymi wspólnymi funkcjami.
Przygotowanie nowego materiału rozpocznij od utworzenia katalogu Mate-
rials. Następnie kliknij ten katalog prawym przyciskiem myszy i wybierz opcję
Create/Material. Nadaj materiałowi pewną opisową nazwę. Na rysunku 3.6
Tekstury, shadery i materiały 69
RYSUNEK 3.6.
Dwa materiały
z różnymi
shaderami
Powracamy do shaderów
Po ogólnym poznaniu tekstur, materiałów i shaderów warto zobaczyć, jak
wymienione komponenty współpracują. Środowisko Unity zawiera wiele
wbudowanych shaderów, ale w tej książce skoncentrujemy się na jedynie
kilku z rodziny Normal. Tego rodzaju shadery są najprostsze i powinny przy‐
dać się każdemu. W tabeli 3.1 wymieniono wybrane najprostsze shadery oraz
przedstawiono ich ogólny opis.
Po poznaniu kilku wbudowanych shaderów możemy przejść do pewnych
właściwości najczęściej występujących w shaderach, z których będziesz korzy‐
stać. W tabeli 3.2 znajdziesz właściwości wspólne dla shaderów.
Ilość informacji wydaje się duża, ale kiedy trochę popracujesz z kilkoma
podstawowymi teksturami, shaderami i materiałami, przekonasz się, że to
całkiem łatwe.
70 Lekcja 3. Modele, materiały i tekstury
Wypróbuj samodzielnie
Podsumowanie
W tej lekcji omówione zostały modele w środowisku Unity. Na początku dowie‐
działeś się, że modele są tworzone za pomocą kolekcji wierzchołków nazy‐
wanych siatkami. Następnie użyłeś wbudowanych modeli, zaimportowałeś
własne, a także pobrałeś gotowe modele ze sklepu Asset Store. Przeczytałeś
także, jak nadaje się modelom żądany wygląd. Miałeś również możliwość
eksperymentowania z teksturami, shaderami i materiałami. Na końcu utwo‐
rzyłeś teksturowany model przedstawiający ścianę z cegieł.
Pytania i odpowiedzi
Pytanie: Czy mogę tworzyć gry, jeśli nie jestem artystą grafikiem?
Odpowiedź: Oczywiście. Przeszukując bezpłatne dostępne zasoby i sklep
Unity Asset Store, będziesz mógł znaleźć różne elementy graficzne
możliwe do wykorzystania w tworzonych grach.
Pytanie: Czy muszę wiedzieć, jak używać każdego z wbudowanych
shaderów?
Odpowiedź: Niekoniecznie. Wiele shaderów jest przeznaczonych
do stosowania w pewnych konkretnych sytuacjach. Zacznij od opanowania
Warsztaty 73
Warsztaty
Poświęć nieco czasu i odpowiedz na zamieszczone poniżej pytania, a także
upewnij się, że przyswoiłeś sobie materiał omówiony w tej lekcji.
Quiz
1. Kwadraty ze względu na swoją prostotę tworzą siatkę w modelach.
Prawda czy fałsz?
2. W jakich formatach można importować modele 3D do Unity?
3. Ze sklepu Unity Asset Store można pobierać jedynie płatne modele.
Prawda czy fałsz?
4. Wyjaśnij powiązania występujące między teksturami, shaderami
i materiałami.
Odpowiedzi
1. Fałsz. Siatki składają się z trójkątów.
2. Można importować pliki w formatach .fbx, .dae, .3ds, .dxf i .obj.
3. Fałsz. W sklepie Unity Asset Store znajduje się również wiele
bezpłatnych modeli.
4. Materiał zawiera tekstury i shadery. Z kolei shader określa właściwości,
jakie mogą być ustawione dla materiału, i wskazuje sposób
wygenerowania danego materiału.
Ćwiczenie
Poświęć chwilę na utrwalenie koncepcji omówionych w tej lekcji. Poekspe‐
rymentuj z shaderami i zobacz, jaki mają wpływ na wygląd modeli. Dla każ‐
dego modelu użyj tej samej siatki i tekstury, inne będą jedynie shadery.
Utworzony w tym miejscu projekt nosi nazwę Hour3_Exercise i znajduje się
w materiałach przeznaczonych dla bieżącej lekcji.
74 Lekcja 3. Modele, materiały i tekstury
RYSUNEK 3.9.
Właściwości
materiałów
Generowanie terenu
Wszystkie poziomy w grze 3D istnieją jako pewne postaci świata. Światy
mogą być wysoce abstrakcyjne lub wręcz przeciwnie — niezwykle realistyczne.
O grach, w których akcja toczy się głównie „na zewnątrz”, bardzo często mówi
się, że na ich poziomach znajduje się teren. Pojęcie teren oznacza tutaj dowolny
fragment ziemi symulujący miejsce w otaczającym nas świecie. Wysokie góry,
bezkresne płaszczyzny, wilgotne moczary — to są przykłady możliwych tere‐
nów w grze.
W środowisku Unity teren jest płaską siatką, którą można rzeźbić, uzyskując
wiele różnych kształtów. Pomocne może być wyobrażenie sobie terenu jako
piasku w piaskownicy, w którym można kopać, tworząc wzniesienia i doliny.
W Unity jedyną cechą nieobsługiwaną przez prosty teren jest nakładanie się.
Oznacza to, że nie można utworzyć elementów, takich jak jaskinia lub zwi‐
sający brzeg. Jednak, podobnie jak każdy inny obiekt w Unity, teren charak‐
teryzuje się położeniem, rotacją i skalą (choć najczęściej wymienione trans‐
formacje nie są zmieniane).
RYSUNEK 4.1.
Ustawienia
rozdzielczości
Wielkość terenu
Obecnie będziesz pracować z terenem o długości i szerokości wynoszącej
50 jednostek. Ma to na celu ułatwienie zarządzania podczas poznawania
różnych narzędzi. W rzeczywistej grze, aby spełnić jej wymagania, teren
prawdopodobnie będzie musiał być większy. Warto również wspomnieć, że
jeśli wyrzeźbiłeś już mapę wysokości (omówioną w następnym punkcie),
wówczas proporcje terenu (stosunek długości do szerokości) muszą być
takie same jak proporcje wspomnianej mapy.
RYSUNEK 4.2.
Prosta mapa
wysokości
Wypróbuj samodzielnie
Obliczanie wysokości
Na razie mapa wysokości może się wydawać przypadkowa, ale naprawdę
łatwo ją odczytać. Wszystko opiera się na wartości procentowej z 255 oraz
maksymalnej wysokości terenu. Domyślnie maksymalna wysokość terenu
wynosi 600, ale tę wartość łatwo zmienić. Po zastosowaniu wzoru (odcień
szarości) / 255 * (maksymalna wysokość) można będzie łatwo obli-
czyć każdy punkt terenu. Przykładowo kolor czarny ma wartość 0 i każdy
czarny punkt oznacza wysokość wynoszącą 0 jednostek (0 / 255 * 600).
Z kolei kolor biały ma wartość 255 i dlatego też powoduje wygenerowanie
punktów o wysokości 600 jednostek (255 / 255 * 600). Kolor szary
o wartości 125 spowoduje wygenerowanie terenu o wysokości 294 jedno-
stek (125 / 255 * 600).
80 Lekcja 4. Teren
RYSUNEK 4.5.
Narzędzia
do rzeźbienia
terenu
RYSUNEK 4.6.
Dobre wartości
początkowe
właściwości
rzeźbienia terenu
Spłaszczanie terenu
Jeżeli w dowolnym czasie będziesz chciał wyzerować teren, aby z powrotem
stał się płaski, wybierz narzędzie malowania wzniesień i kliknij Flatten.
Korzyścią takiego rozwiązania jest możliwość spłaszczenia terenu do wyso-
kości innej niż domyślna, czyli 0. Jeżeli maksymalna wysokość terenu wynosi
60 i zdecydujesz się na jego spłaszczenie do wysokości 30, zyskasz moż-
liwość podnoszenia terenu o nawet 30 jednostek, a także obniżania go
również o 30 jednostek. To znacznie ułatwia rzeźbienie dolin na płaskim
terenie.
Wypróbuj samodzielnie
Rzeźbienie terenu
Skoro poznałeś narzędzia przeznaczone do rzeźbienia terenu, warto nabyć
nieco praktyki podczas pracy z nimi. W tym ćwiczeniu spróbujesz wyrzeźbić
pewien fragment terenu.
1. Utwórz nowy projekt lub scenę, a następnie dodaj teren. Rozdzielczość
terenu ustaw na 50 na 50 i nadaj mu wysokość 60 jednostek.
2. Spłaszcz teren do wysokości 20. W tym celu wybierz narzędzie
malowania wzniesień, zmień wysokość na 20 i kliknij Flatten.
3. Za pomocą narzędzi przeznaczonych do rzeźbienia spróbuj utworzyć
teren podobny do pokazanego na rysunku 4.7.
Tekstury terenu
Wiesz już, w jaki sposób określić fizyczne wymiary świata 3D w grze. Choć
do krajobrazu dodaliśmy wiele elementów, jednak pozostaje nijaki, a poru‐
szanie się po terenie jest trudne. Najwyższy czas na dodanie pewnego cha‐
rakteru. W tej części lekcji dowiesz się, jak nakładać tekstury na teren i tym
samym zapewnić mu atrakcyjny wygląd.
RYSUNEK 4.8.
Okno dialogowe
Importing
package
Teksturowanie terenu
Procedura teksturowania terenu w Unity jest prosta i działa podobnie jak
rzeźbienie. Najpierw trzeba wczytać teksturę. Na rysunku 4.9 pokazano opcje
narzędzia teksturowania znajdujące się w panelu Inspector. Trzeba zwrócić
84 Lekcja 4. Teren
RYSUNEK 4.9.
Narzędzie
przeznaczone
do teksturowania
terenu
i właściwości
tego narzędzia
RYSUNEK 4.10.
Okno dialogowe
Add Terrain
Texture
Możesz więc przystąpić do malowania i tym samym sprawić, aby teren pre‐
zentował się atrakcyjnie.
Wypróbuj samodzielnie
Podsumowanie
W tej lekcji poznałeś teren w środowisku Unity. Na początku dowiedziałeś
się, czym jest teren oraz w jaki sposób można go dodać do sceny. Następnie
przeszedłeś do rzeźbienia terenu za pomocą zarówno mapy wysokości, jak
i wbudowanych w edytorze Unity narzędzi rzeźbienia. Na koniec zobaczyłeś,
jak można znacznie poprawić wygląd terenu przez nałożenie tekstur w sposób
zapewniających osiągnięcie realistycznego efektu końcowego.
86 Lekcja 4. Teren
Pytania i odpowiedzi
Pytanie: Czy moja gra musi posiadać teren?
Odpowiedź: Niekoniecznie. Akcja wielu gier rozgrywa się wyłącznie
wewnątrz wymodelowanych pomieszczeń lub w abstrakcyjnych
przestrzeniach.
Pytanie: Przygotowany przeze mnie teren nie wygląda zbyt dobrze.
Czy to jest normalne?
Odpowiedź: Osiągnięcie dobrych efektów w posługiwaniu się narzędziami
rzeźbienia wymaga nieco czasu. Przy odrobinie praktyki tworzone przez
Ciebie poziomy gier będą wyglądały znacznie lepiej. Dobrą jakość można
osiągnąć dzięki grze na poziomie testowym, co zostanie omówione
w kolejnej lekcji.
Warsztaty
Poświęć nieco czasu i odpowiedz na zamieszczone poniżej pytania, a także
upewnij się, że przyswoiłeś sobie materiał omówiony w tej lekcji.
Ćwiczenie 87
Quiz
1. Za pomocą obiektu terenu w Unity można tworzyć jaskinie. Prawda
czy fałsz?
2. Jak jest nazywany czarno‐biały obraz zawierający informacje
o wysokości terenu?
3. Rzeźbienie terenu w środowisku Unity przypomina malowanie.
Prawda czy fałsz?
4. W jaki sposób możesz uzyskać dostęp do tekstur terenu oferowanych
przez Unity?
Odpowiedzi
1. Fałsz. Tereny w Unity nie mogą się nakładać.
2. Mapa wysokości.
3. Prawda.
4. Zasoby terenu trzeba zaimportować, wybierając opcję Assets/Import
Package/Terrain Assets.
Ćwiczenie
Warto przećwiczyć rzeźbienie i teksturowanie terenu. Wyrzeźb teren skła‐
dający się z takich elementów jak:
niecka jeziora,
plaża,
góry,
płaskowyże.
Po wyrzeźbieniu wymienionych elementów nałóż tekstury na teren w przed‐
stawiony poniżej sposób. Wszystkie niezbędne tekstury znajdziesz w pakiecie
Terrain Assets.
Plaża powinna mieć nałożoną teksturę Sand i przechodzić
w Grass&Rock.
Płaskowyże powinny być płaskim terenem z nałożoną teksturą Grass.
W miejscach, gdzie teren staje się stromy, tekstura Grass powinna
płynnie przechodzić w Grass&Rock.
W najbardziej stromych miejscach tekstura Grass&Rock powinna
przechodzić w Cliff.
Podczas wykonywania tego ćwiczenia staraj się być maksymalnie kreatywny.
Utwórz świat, z którego będziesz dumny.
88 Lekcja 4. Teren
Lekcja 5
Środowisko
Malowanie drzewami
Dodanie drzew do terenu odbywa się bardzo podobnie jak rzeźbienie i tek‐
sturowanie przedstawione w poprzedniej lekcji. Cały proces jest niezwykle
podobny do malowania. Na początek trzeba wczytać model drzewa, ustawić
jego właściwości, a następnie przystąpić do malowania obszaru, który ma
być pokryty drzewami. Opierając się na wybranych opcjach, Unity rozprasza
drzewa i nieco je różnicuje, aby nadać im naturalny i atrakcyjny wygląd.
Zasoby terenu
Aby wykonywać ćwiczenia przedstawione w tej części lekcji, do projektu
powinieneś zaimportować standardowe zasoby terenu. Jeżeli nie wiesz, jak
to zrobić, odpowiednie informacje znajdziesz w poprzedniej lekcji.
RYSUNEK 5.1.
Narzędzie
Place Trees
Wypróbuj samodzielnie
Ciemne drzewa
Być może zauważyłeś, że pewne drzewa są czarne. Taka sytuacja może się
zdarzyć, gdy małe drzewo zostanie umieszczone blisko większych. Powód
jest prosty: światło oświetlające takie małe drzewo na scenie jest obliczane
jako przechodzące między dużymi drzewami. W efekcie małe drzewo znaj-
duje się w cieniu większych. Rozwiązaniem tego problemu może być użycie
Unity Pro, ponieważ w wersji Pro światło jest obliczane dynamicznie i —
ogólnie rzecz biorąc — jest odtwarzane nieco wierniej. Jeżeli nie masz wersji
Pro, rozwiązaniem jest po prostu usunięcie drzewa i umieszczenie go
w innym miejscu.
Malowanie trawą
Skoro już wiesz, jak umieszczać drzewa w terenie, możemy przejść do tematu
dodawania trawy oraz innej małej roślinności do krajobrazu. W środowisku
Unity trawa oraz inna mała roślinność jest określana mianem Details. Dlatego
też narzędzie przeznaczone do dodawania tego rodzaju roślinności nosi nazwę
Paint Details. W przeciwieństwie do drzew będących modelami 3D, mała roślin‐
ność jest dodawana w postaci billboardów (więcej na ten temat znajdziesz
dalej w tej lekcji). Podobnie jak inne elementy krajobrazu, także drobna roślin‐
ność jest nakładana za pomocą pędzla i operacji malowania. Na rysunku 5.3
pokazano narzędzie Paint Details oraz niektóre z jego właściwości.
Billboardy
W świecie trójwymiarowym billboard to specjalny typ komponentu wizu-
alnego. Pozwala na uzyskanie efektu 3D bez konieczności rzeczywistego
użycia modelu 3D. Modele istnieją we wszystkich trzech wymiarach. Dlatego
też, poruszając się wokół modelu, można zobaczyć jego różne strony. Z kolei
billboard to płaski obraz, który zawsze jest zwrócony w stronę kamery. Gdy
spróbujesz obrócić się wokół billboardu, on również zostanie obrócony,
tak aby był skierowany przodem do kamery. Najczęściej spotykane przy-
kłady użycia billboardów to właśnie trawa, cząsteczki i efekty na ekranie.
Generowanie drzew i trawy 93
RYSUNEK 5.3.
Narzędzie
Paint Details
Dodanie trawy do terenu jest łatwym procesem. Najpierw trzeba dodać tek‐
sturę trawy. W tym celu wykonaj przedstawione poniżej kroki.
1. Kliknij Edit Details w panelu Inspector, a następnie wybierz Add Grass
Texture.
2. W oknie dialogowym Add Grass Texture kliknij małą ikonę kółka
znajdującą się po prawej stronie pola tekstowego Texture (patrz
rysunek 5.4). Wybierz teksturę Grass, a nie Grass (Hill).
RYSUNEK 5.4.
Okno dialogowe
Add Grass Texture
Roślinność a wydajność
Im więcej drzew i trawy umieścisz na scenie, tym więcej mocy procesora
trzeba będzie wykorzystać do wygenerowania danej sceny. Gdy wydajność
ma znaczenie, staraj się zachować niski poziom roślinności. Wprawdzie
dalej w tej lekcji poznasz pewne właściwości pomagające w zachowaniu
wydajności, ale ogólna reguła głosi, aby drzewa i trawę stosować tylko tam,
gdzie jest to naprawdę niezbędne.
Znikająca trawa
Podobnie jak drzewa, także na wygląd trawy wpływ ma odległość dzieląca
obserwatora i trawę. Gdy obserwator jest daleko od drzew, są one gene-
rowane w niskiej jakości. Natomiast trawa po prostu nie jest generowana.
Wokół obserwatora istnieje więc okrąg, po przekroczeniu którego trawa jest
niewidoczna. Wielkość wspomnianego okręgu można określić za pomocą
właściwości przedstawionych dalej w tej lekcji.
Ustawienia terenu
Ostatni przycisk na liście narzędzi dotyczących terenu w panelu Inspector to
narzędzie o nazwie Terrain Settings. Narzędzie to określa ogólny wygląd
i sposób funkcjonowania terenu, tekstur, drzew i mniejszej roślinności. Wszyst‐
kie ustawienia dla terenu pokazano na rysunku 5.5.
Pierwsza grupa ustawień dotyczy ogólnie terenu. Ustawienia te zostały wymie‐
nione w tabeli 5.2.
Oprócz wymienionych wyżej, istnieją jeszcze inne ustawienia, które mają
bezpośredni wpływ na sposób zachowania drzew i mniejszej roślinności
(np. trawy) w terenie. Ustawienia te wymieniono w tabeli 5.3.
Ostatnie ustawienia dotyczą wiatru. Ponieważ w tej lekcji nie miałeś jeszcze
okazji poruszania się po utworzonym świecie (tym zajmiemy się dalej), być
Efekty środowiska 95
RYSUNEK 5.5.
Narzędzie
Terrain Settings
może zastanawiasz się, do czego służą omawiane tutaj ustawienia. Ogólnie rzecz
biorąc, środowisko Unity symuluje lekki wiatr w przygotowanym krajobrazie.
Ten lekki wiatr powoduje przechylanie i kołysanie się trawy oraz ogólnie
ożywia krajobraz. Ustawienia dotyczące wiatru wymieniono w tabeli 5.4.
Efekty środowiska
Potrafisz już rzeźbić teren, dodawać do niego tekstury, a także drzewa i trawę.
Można zatem stwierdzić, że na obecnym etapie teren wygląda znacznie lepiej,
nie jest to już tylko płaski, biały kwadrat. Teraz dowiesz się, jak dodać inne
elementy środowiska, aby gra prezentowała się atrakcyjnie.
96 Lekcja 5. Środowisko
RYSUNEK 5.6.
Komponent
Skybox
4. Uruchom scenę i sprawdź, jak symulacja nieba została dodana
do kamery.
3. Wybierz Sunny1 Skybox. Zwróć uwagę, jak panel Scene się zmienia
i od tego momentu zawiera niebo. Gdyby panel Scene nie uległ zmianie,
włącz ustawienie symulacji nieba, mgły i flar (patrz rysunek 5.7).
RYSUNEK 5.7.
Przełączenie
efektów
środowiska
Mgła
Środowisko Unity pozwala na dodanie mgły do sceny. Mgłę można wykorzy‐
stać do symulacji wielu różnych efektów, np. oparów, rzeczywistej mgły oraz
zanikania obiektów w dalszej odległości. Za pomocą mgły tworzonemu świa‐
tu można nadać nowy i obcy wygląd.
Wypróbuj samodzielnie
Wypróbuj samodzielnie
W tym momencie efekt Lens Flare będzie światłem i zostanie użyty przez
kamerę. To jest możliwe, ponieważ element Main Camera na scenie domyślnie
zawiera komponent Flare Layer. Jeżeli kamera nie posiada wymienionego
komponentu, nie będzie w stanie uzyskać efektu Lens Flare.
Woda
Ostatnim analizowanym efektem środowiska jest woda. W przypadku wody
uzyskany efekt będzie zależał od używanej wersji środowiska Unity, bezpłatnej
lub Pro. Bezpłatna wersja środowiska Unity oferuje dostęp do podstawowego
obiektu wody. Ten obiekt wody jest ogólny, ale możliwy do zaakceptowania.
100 Lekcja 5. Środowisko
Natomiast woda generowana przez wersję Pro wygląda znacznie lepiej. Jeżeli
masz wersję Pro, zdecydowanie powinieneś z niej korzystać podczas gene‐
rowania wody. Jednak książka ta została napisana dla bezpłatnej wersji Unity
i dlatego właśnie tej wersji użyjesz w ćwiczeniu.
W środowisku Unity woda jest zasobem wymagającym zaimportowania. Na sce‐
nie woda będzie płaską płaszczyzną przypominającą ścianę pewnego obszaru,
takiego jak staw lub jezioro. Zwróć uwagę, że woda jest po prostu efektem.
Jeżeli gracz wskoczy do jeziora, to naprawdę wpadnie na dno niecki kryjącej
dane jezioro.
Wypróbuj samodzielnie
Kontroler postaci
Na tym etapie ukończyłeś prace nad terenem. Został wyrzeźbiony, ma nało‐
żone tekstury, zawiera drzewa i trawę, a także ma zdefiniowane niebo, mgłę,
flary i wodę. Najwyższa pora wejść do przygotowanego poziomu i „zagrać”.
Unity oferuje dwa podstawowe kontrolery postaci, które umożliwiają łatwe
wejście na scenę bez konieczności wykonywania zbyt dużej ilości pracy.
W zasadzie umieszczasz kontroler na scenie, a następnie poruszasz się po
niej, jak w większości gier, z perspektywy gracza.
RYSUNEK 5.9.
Kontroler postaci
First Person
Naprawa świata
Teraz możesz wejść do utworzonego świata i zobaczyć go z bliska. To też
najwyższa pora na dopracowanie szczegółów. Być może przekonasz się, że
niektóre obszary są zbyt strome, aby można się było po nich poruszać. Z kolei
na innych obszarach tekstury mogą być nieco przesunięte. Teraz nadeszła
102 Lekcja 5. Środowisko
Importowanie zasobów
W tej lekcji zaimportowałeś całkiem sporo pakietów zasobów. Podczas ich
importowania pozostawiałeś zaznaczone wszystkie opcje w oknie dialo-
gowym Import Package. Z tego powodu każdy zasób pakietu został dodany
do projektu. Takie rozwiązanie prowadzi do znacznego zwiększenia plików
projektu. W rzeczywistych projektach należy importować tylko niezbędne
zasoby i usuwać zaznaczenie niepotrzebnych. Pamiętaj, że jeśli zasób będzie
potrzebny, można go zaimportować w każdej chwili.
Podsumowanie
W tej lekcji poznałeś wiele szczegółów dotyczących środowiska w Unity. Na po‐
czątku dowiedziałeś się, jak dodać drzewa i trawę do sceny. Następnie
przeszedłeś do efektów, takich jak niebo, mgła i Lens Flare. Następnie zająłeś
się zasobami wody w Unity. Lekcję zakończyłeś dodaniem do sceny kontrolera
postaci, co pozwoliło na poruszanie się po utworzonym świecie 3D.
Pytania i odpowiedzi
Pytanie: Czy drzewa i trawa mają duży wpływ na wydajność?
Odpowiedź: To zależy od ilości tych elementów na scenie. Ponadto ważne
znaczenie ma moc obliczeniowa komputera, w którym uruchomiono
edytor Unity. Dobrą regułą jest umieszczanie drzew i trawy na scenie
tylko wtedy, gdy przynosi to pozytywny efekt.
Pytanie: Czy mogę tworzyć własne symulacje nieba?
Odpowiedź: Oczywiście. Takie rozwiązanie powinieneś rozważyć, gdy
tworzysz własny świat lub umieszczasz w nim elementy nieobecne
w dostępnych symulacjach nieba.
Pytanie: Kontroler postaci zawiera wiele właściwości. Czy powinienem
znać je wszystkie?
Odpowiedź: Niekoniecznie. W standardowej postaci tego rodzaju kontroler
jest łatwy w użyciu. Jeżeli chcesz wprowadzić proste zmiany w ruchu,
możesz to zrobić. Jednak większość użytkowników nie będzie tego
potrzebować.
Warsztaty
Poświęć nieco czasu i odpowiedz na zamieszczone poniżej pytania, a także
upewnij się, że przyswoiłeś sobie materiał omówiony w tej lekcji.
Quiz
1. Jak się nazywa ustawienie pozwalające na określenie stopnia kołysania
drzew na wietrze?
2. Jaka jest nazwa efektu, który pozwala na symulację oparów
lub zanikania kolorów w pewnej odległości?
104 Lekcja 5. Środowisko
Odpowiedzi
1. To jest trudne pytanie. Drzewa nie kołyszą się na wietrze, natomiast
trawa już tak. Kontrolujące to ustawienie nosi nazwę Bending
(znajdziesz je w ustawieniach wiatru).
2. To jest mgła.
3. To jest symulacja nieba.
4. To był kontroler First Person.
Ćwiczenie
W tym ćwiczeniu masz szansę ukończyć terem, którego tworzenie rozpocząłeś
na końcu lekcji 4. Tutaj dodasz pozostałe efekty środowiskowe, aby zwięk‐
szyć realizm budowanego świata.
Otwórz projekt lub scenę z terenem opracowanym w lekcji 4. Teren uzupełnij,
dodając niżej wymienione elementy.
Wlej wodę do niecki przygotowanej dla jeziora.
Wokół jeziora umieść nieco rzadkiej trawy, natomiast większą
jej ilość rozmieść na płaskowyżach.
Na trawiastych obszarach umieść palmy, najlepiej w miejscach,
gdzie tekstura trawy łączy się z teksturą piasku.
Do sceny dodaj symulację nieba.
Do sceny dodaj efekt mgły. Ustawienia mgły zmień w taki sposób,
aby wzgórza realistycznie wyglądały na zachmurzone.
Do sceny dodaj światło kierunkowe, a następnie efekt Lens Flare dla
światła. Upewnij się, że wspomniany efekt Lens Flare jest wyrównany
z obrazem słońca, o ile taki został użyty w symulacji nieba.
Do sceny dodaj także kontroler postaci i przetestuj przygotowany
poziom. Sprawdź, czy wszystko zostało prawidłowo rozmieszczone
i wygląda realistycznie.
Lekcja 6
Światła i kamery
Światło
W każdej z form mediów wizualnych postrzeganie roli światła ewoluowało.
Jasne, nieco żółte światło może spowodować, że scena będzie wyglądać na
słoneczną i ciepłą. Jeżeli tę samą scenę oświetlisz słabym, lekko niebieskim
światłem, będzie wyglądała upiornie i niepokojąco. W większości sceny, które
mają wyglądać realistycznie lub dramatycznie, są oświetlone co najmniej
jednym światłem (a najczęściej wieloma). We wcześniejszych lekcjach pra‐
cowałeś już ze światłami w celu oświetlania innych elementów. W tej lekcji
skoncentrujesz się bezpośrednio na pracy ze światłem.
Co to jest światło?
W środowisku Unity światła nie są obiektami, ale raczej komponentami.
Oznacza to, że dodając światło do sceny, umieszczasz na niej obiekt gry wraz
z komponentem Light. Komponent Light może być dowolnego typu świa-
tłem oferowanym przez Unity.
Światło punktowe
Pierwszym typem światła, z którym będziesz pracować, jest światło punk‐
towe. Możesz je potraktować podobnie jak żarówkę — całe światło jest emi‐
towane we wszystkich kierunkach z jednego punktu centralnego. Tego rodzaju
światło jest najczęściej stosowane do oświetlania wnętrz.
W celu dodania światła punktowego do sceny wybierz opcję GameObject/Create
Other/Point Light. Obiekt gry w postaci światła punktowego po umieszczeniu
na scenie może być modyfikowany, podobnie jak każdy inny obiekt. Właści‐
wości światła punktowego zostały wymienione w tabeli 6.1.
Wypalanie
Wypalanie (ang. baking) oznacza proces dodawania światła i cieni do tek-
stur oraz obiektów w trakcie ich tworzenia. Operację wypalenia można
przeprowadzić w Unity lub w edytorze grafiki. Kiedy np. tworzysz teksturę
ściany wraz z ciemnym obszarem oznaczającym cień człowieka, a następ-
nie model człowieka umieścisz obok ściany, otrzymasz złudzenie, że model
rzuca cień na ścianę. Jednak naprawdę cień został „wypalony” w teksturze.
Gdy będziesz korzystał z wypalania, gry będą działały znacznie szybciej,
ponieważ silnik nie będzie musiał obliczać światła i cieni dla każdej ramki.
To naprawdę użyteczne rozwiązanie!
Wypróbuj samodzielnie
Wypróbuj samodzielnie
Światło kierunkowe
Ostatni typ światła, z którym będziesz pracować w tej lekcji, to światło kierun‐
kowe. Tego rodzaju światło jest podobne do reflektora pod tym względem, że
jego strumień można kierować. Jednak w przeciwieństwie do reflektora światło
kierunkowe oświetla całą scenę. Możesz je potraktować jak słońce. Światło kie‐
runkowe wykorzystałeś w poprzednich lekcjach do oświetlenia tworzonego
terenu. Światło kierunkowe równomiernie świeci na scenie.
W celu dodania światła kierunkowego do sceny wybierz opcję GameObject/Create
Other/Directional Light. Ewentualnie, jeśli na scenie znajduje się inne światło,
jego typ można zmienić na Directional. W ten sposób istniejące światło zmieni
się w światło kierunkowe.
110 Lekcja 6. Światła i kamery
Wypróbuj samodzielnie
Aureola
Aureola to świecące okręgi pojawiające się wokół światła, kiedy występują
mgła lub chmury (patrz rysunek 6.2). Aureola się pojawia, ponieważ światło
odbija się od małych cząsteczek znajdujących się wokół źródła światła. W śro‐
dowisku Unity można bardzo łatwo utworzyć aureolę. Każde światło ma pole
wyboru o nazwie Draw Halo. Jeżeli zostanie zaznaczone, dla danego światła
będzie utworzona aureola.
RYSUNEK 6.2.
Aureola wokół
światła
Błąd w Unity
W wersji 4.1 Unity istnieje błąd związany z aureolą. Jeżeli korzystasz z tej
właśnie wersji Unity, będziesz musiał zastosować obejście problemu, aby
uzyskać aureolę wokół światła. Kiedy zaznaczenie pola wyboru Draw Halo
nie powoduje wyświetlenia aureoli, należy dodać komponent Halo. (Jeżeli
aureola się pojawi, nie musisz wykonywać przedstawionej poniżej proce-
dury). W tym celu zaznacz światło i kliknij Component/Effects/Halo. Teraz
wokół światła powinna pojawić się aureola. Na tym etapie można usunąć
już dodany wcześniej komponent Halo. Ponadto tę procedurę trzeba będzie
zastosować tylko jednokrotnie dla sceny. Jeżeli nadal nie widzisz aureoli,
oddal widok, ponieważ aureola nie pojawi się, gdy kamera będzie znajdo-
wała się zbyt blisko.
112 Lekcja 6. Światła i kamery
RYSUNEK 6.3.
Ustawienia
generowania
aureoli
Cookies
Jeżeli kiedykolwiek oświetliłeś ścianę, a następnie umieściłeś rękę między
światłem i ścianą, wtedy zauważyłeś, że pewna część światła została zablo‐
kowana i na ścianie powstał cień rzucany przez rękę. Dzięki cookies ten efekt
można uzyskać także w środowisku Unity. Cookies to specjalne tekstury doda‐
wane do światła w celu wskazania sposobu promieniowania światła. Różnią
się one nieco w światłach punktowym, reflektorze i kierunkowym. W prze‐
ciwieństwie do światła kierunkowego, w przypadku reflektora cookie nie jest
powtarzane. Światło punktowe używa tekstur czarno‐białych, ale muszą być
umieszczone na mapie sześcianu. Wspomniana mapa sześcianu to sześć tek‐
stur umieszczonych w taki sposób, aby uformować pudełko (podobnie jak
w symulacji nieba).
Dodanie cookie do światła jest prostym procesem. W tym celu wystarczy wskazać
teksturę we właściwości Cookie światła. Trudność w uzyskaniu prawidłowo
działającego cookie polega na właściwym, wcześniejszym ustawieniu tekstury.
Aby prawidłowo ustawić teksturę, należy ją zaznaczyć w Unity, a następnie zmie‐
nić jej właściwości w panelu Inspector. Na rysunku 6.4 pokazano prawidłowe
właściwości cookie dla świateł punktowego, reflektora i światła kierunkowego.
Światło 113
RYSUNEK 6.4.
Właściwości
tekstury cookie
dla światła,
odpowiednio,
punktowego,
reflektora i
kierunkowego
Wypróbuj samodzielnie
Kamera
Kamera to przeznaczony dla gracza widok na utworzony świat. Zapewnia
perspektywę oraz kontroluje sposób wyświetlania elementów. Wszystkie gry
w środowisku Unity zawierają przynajmniej jedną kamerę, która jest zawsze
umieszczana na nowo tworzonej scenie. W hierarchii kamera ta zawsze będzie
wyświetlana jako Main Camera. W tej części lekcji poznasz kamerę i dowiesz
się, jak można jej używać w celu osiągnięcia interesujących efektów.
Anatomia kamery
Wszystkie kamery dysponują tym samym zestawem właściwości określających
ich zachowanie. Właściwości kamery zostały wymienione w tabeli 6.2.
Kamery posiadają wiele właściwości, ale wystarczy je ustawić i o nich zapo‐
mnieć. Dla kamer istnieje również kilka dodatkowych komponentów. Przykła‐
dowo GUI Layer pozwala, aby kamera „widziała” elementy graficznego inter‐
fejsu użytkownika (co zostanie omówione dalej w tej książce). Z kolei Flare
Layer umożliwia zobaczenie efektu Lens Flare dodawanego do światła. Nato‐
miast Audio Listener umożliwia kamerze nagrywanie dźwięku. Podczas doda‐
wania kolejnych kamer do sceny trzeba z nich usunąć komponenty Audio Liste-
ner. Na scenie może znajdować się tylko jeden komponent Audio Listener.
Kamera 115
Wiele kamer
Bez użycia wielu kamer w nowoczesnych grach nie uzyskamy wielu efektów.
Na szczęście, na scenie Unity można umieścić dowolną liczbę kamer. W celu
dodania nowej kamery do sceny wybierz opcję GameObject/Create Other/
Camera. Alternatywne rozwiązanie polega na dodaniu komponentu kamery
do obiektu gry znajdującego się już na scenie. Zaznacz więc obiekt, a następnie
w panelu Inspector kliknij przycisk Add Component. Wybór opcji Rendering/
Camera powoduje dodanie komponentu kamery. Pamiętaj, że dodanie kom‐
ponentu kamery do istniejącego obiektu nie spowoduje automatycznego dodania
GUI Layer, Flare Layer lub Audio Listener.
Wypróbuj samodzielnie
Warstwy
Zarządzanie dużą ilością obiektów na scenie bardzo często okazuje się trudne.
Czasami trzeba, aby elementy były widoczne jedynie dla określonych kamer
lub oświetlane tylko przez wskazane światła. Innym razem chcemy, aby kolizje
zachodziły tylko między określonymi typami obiektów. Odpowiedzią edytora
Unity na wymienione problemy są warstwy. Warstwy pozwalają na grupo‐
wanie podobnych obiektów, aby mogły być traktowane w określony sposób.
Domyślnie istnieje 8 wbudowanych warstw i 24 gotowe do zdefiniowania
przez użytkownika.
118 Lekcja 6. Światła i kamery
Wypróbuj samodzielnie
Praca z warstwami
Każdy obiekt gry jest umieszczany na warstwie Default. Oznacza to, że jeśli
obiekt nie ma przypisanej konkretnej warstwy, zostanie umieszczony na
warstwie domyślnej wraz z innymi elementami. Dodanie obiektu do kon‐
kretnej warstwy jest bardzo łatwe i odbywa się w panelu Inspector. Po zazna‐
czeniu obiektu kliknij rozwijane menu Layer w panelu Inspector, a następnie
wskaż nową warstwę dla obiektu (patrz rysunek 6.8). Domyślnie dostępne są
Warstwy 119
Wypróbuj samodzielnie
RYSUNEK 6.8.
Rozwijane menu
Layer
Przeciążenie warstwami
Dodanie warstw może być doskonałym sposobem na osiągnięcie skompli-
kowanych zachowań bez konieczności wykonywania dużej ilości pracy.
Warto jednak pamiętać o jednym ostrzeżeniu: nie twórz warstw dla ele-
mentów, jeśli nie jest to konieczne. Zbyt często programiści tworzą warstwy
podczas dodawania elementów na scenie, sądząc po prostu, że warstwy
mogą się przydać w przyszłości. Tego rodzaju podejście może prowadzić do
organizacyjnego koszmaru, gdy trzeba będzie pamiętać, do czego służą
poszczególne warstwy. Ujmując rzecz najprościej, nowe warstwy twórz
jedynie wtedy, kiedy będą niezbędne. Nie używaj warstw tylko dlatego, że
masz taką możliwość.
Użycie warstw
Istnieje wiele zastosowań warstw. Ich użyteczność jest ograniczona tylko przez
Twoją wyobraźnię. W tej części lekcji zostaną przedstawione trzy najczęściej
spotykane zastosowania warstw.
Pierwszy to możliwość ukrycia warstw w panelu Scene. Za pomocą rozwijanego
menu Layers na pasku narzędziowym panelu Scene (patrz rysunek 6.9) możesz
wybrać warstwy, które będą pojawiały się w panelu Scene. Domyślnie scena
jest skonfigurowana do wyświetlania wszystkich warstw.
Drugim celem stosowania warstw jest ukrycie pewnych obiektów przed ich
oświetleniem. Takie rozwiązanie może okazać się użyteczne, gdy tworzysz
Podsumowanie 121
RYSUNEK 6.10.
Dodanie
nowych warstw
do menedżera
TagManager
Podsumowanie
W tej lekcji poznałeś światło i kamerę. Na początek miałeś okazję pracować
z różnymi typami światła. Dowiedziałeś się, jak dodawać cookies i aureole do
świateł znajdujących się na scenie. Następnym tematem były kamery. Pozna‐
łeś podstawy dotyczące kamer i zobaczyłeś, jak można pracować z wieloma
kamerami na scenie, aby podzielić ekran lub utworzyć efekt PiP. Na końcu
lekcji został poruszony temat warstw.
122 Lekcja 6. Światła i kamery
RYSUNEK 6.11.
Właściwość
Culling Mask
Wypróbuj samodzielnie
Pytania i odpowiedzi
Pytanie: Zauważyłem, że w lekcji pomięto temat mapy światła. Czy to
jest ważny temat?
Odpowiedź: Mapa światła to użyteczna technika optymalizacji wydajności
sceny. To temat znacznie bardziej zaawansowany, a sama technika
nie jest wykorzystywana w projektach tworzonych w tej książce. Mapa
światła może nabrać dla Ciebie znaczenia, gdy przystąpisz do budowania
bardziej zaawansowanych projektów gier.
Pytanie: Skąd mam wiedzieć, czy powinienem użyć kamery
perspektywicznej, czy wyświetlającej obraz dwumiarowy?
Odpowiedź: Jak wspomniano w lekcji, ogólna reguła podczas wyboru kamery
przedstawia się następująco. Kamera perspektywiczna dla gier i efektów
3D, natomiast opcje Ortographic dla gier i efektów 2D.
Warsztaty
Poświęć nieco czasu i odpowiedz na zamieszczone poniżej pytania, a także
upewnij się, że przyswoiłeś sobie materiał omówiony w tej lekcji.
Quiz
1. Jeżeli całą scenę chcesz oświetlić tylko pojedynczym światłem, jakiego
typu światła użyjesz?
2. Ile kamer można umieścić na scenie?
3. Ile może być warstw zdefiniowanych przez użytkownika?
4. Która właściwość określa warstwy ignorowane przez światło
lub kamerę?
Odpowiedzi
1. Światło kierunkowe to jedyny typ światła, który może równomiernie
oświetlać całą scenę.
2. Na scenie można umieścić dowolną liczbę kamer.
3. 24.
4. To jest właściwość Culling Mask.
Ćwiczenie
W tym ćwiczeniu masz szansę pracy z wieloma kamerami i światłami. Masz
tutaj nieco większą swobodę, więc możesz wykazać się kreatywnością.
124 Lekcja 6. Światła i kamery
RYSUNEK 6.12.
Ukończone
ćwiczenie
Lekcja 7
Pierwsza gra
— Amazing Racer
Ukończony projekt
Pamiętaj, aby wykonywać kolejne kroki zaprezentowane w tej
lekcji, bo tylko w ten sposób ukończysz projekt gry. Jeśli
napotkasz problemy, ukończoną wersję gry znajdziesz
w materiałach przeznaczonych dla bieżącej lekcji. Jeśli szukasz
inspiracji, przejrzyj te materiały!
126 Lekcja 7. Pierwsza gra — Amazing Racer
Faza projektowania
Faza projektowania w czasie opracowywania gry to ta, w trakcie której pla‐
nujesz wszystkie najważniejsze funkcje i komponenty gry. Fazę tę możesz
potraktować jak operację układania matryc, za pomocą których sam proces
tworzenia gry stanie się łatwiejszy. Podczas budowania gry całkiem sporo czasu
poświęca się na projektowanie. Ponieważ gra opracowana w tej lekcji jest
niezwykle prosta, więc faza projektowania przebiegnie szybciej. Trzeba koniecz‐
nie skoncentrować się na trzech etapach planowania gry, takich jak koncepcja,
reguły i wymagania.
Koncepcja
Idea gry jest całkiem prosta. Gracz rozpoczyna rozrywkę na początku pew‐
nego obszaru i jego zadaniem jest szybkie dotarcie na drugi koniec obszaru.
Na jego drodze znajdą się wzgórza, drzewa i inne przeszkody. Celem jest
sprawdzenie, jak szybko gracz może dotrzeć do strefy końcowej. Dla pierw‐
szej gry została wybrana taka koncepcja, ponieważ pozwala na wykorzysta‐
nie zdobytej dotąd wiedzy. Nie znasz jeszcze skryptów w środowisku Unity
i dlatego nie możesz dodać zbyt złożonych interakcji. Kolejne gry będą znacz‐
nie bardziej rozbudowane.
Reguły
Każda gra musi mieć zdefiniowany zestaw reguł. Reguły służą dwóm celom.
Pierwszym jest poinformowanie, jak gracz radzi sobie z rozgrywką. A drugi
to ustalenie uprawnień. Ponieważ oprogramowanie jest procesem uprawnień
(patrz uwaga zatytułowana Proces uprawnień), role wskazują dostępne dla
gracza akcje pozwalające na pokonanie wyzwań stawianych w grze. Reguły dla
gry tworzonej w tej lekcji zostały wymienione poniżej.
Nie ma warunku wskazującego na wygraną lub przegraną gracza,
istnieje tylko warunek ukończenia gry. Gra zostanie uznana za
ukończoną, gdy gracz dotrze do obszaru końcowego.
Obszary początkowy i końcowy zawsze będą znajdować się w tym
samym miejscu.
Na planszy będzie znajdowała się woda. Gdy gracz wpadnie do wody,
zostanie przeniesiony z powrotem na początek planszy.
Celem gry jest jak najszybsze dotarcie do punktu końcowego
na planszy. To nie jest jawnie zdefiniowana reguła, a tym samym
nie jest specjalnie wbudowana w grę. Zamiast tego w grze znajdą
się wskazówki podpowiadające graczowi, jaki jest cel gry. Idea polega
na tym, aby na podstawie otrzymywanych sygnałów gracz
wywnioskował, że należy uzyskać jak najkrótszy czas przejścia
od punktu początkowego do końcowego planszy.
Faza projektowania 127
Proces uprawnień
W trakcie tworzenia gier zawsze należy pamiętać o tym, że oprogramo-
wanie jest procesem uprawnień. Oznacza to, że gracz może robić tylko to,
do czego otrzymał wyraźne uprawnienia. Przykładowo gracz chce wspiąć
się na drzewo. Jeżeli programista nie przygotował takiej możliwości, wejście
gracza na drzewo okaże się niemożliwe. Jeżeli nie pozwolisz graczom na
skakanie, nie będą mogli wykonywać skoków. Wszystko to, co gracz może
zrobić w grze, musi być wyraźnie w niej zdefiniowane. Pamiętaj, że nie
możesz przyjmować założenia dotyczącego jakiejkolwiek akcji i musisz
planować absolutnie wszystko!
Terminologia
Poniżej przedstawiono nową terminologię, która jest stosowana w tej lekcji.
Rozpoczęcie gry. To proces, w którym gracz lub jednostka wchodzą
do gry.
Punkt rozpoczęcia gry. To punkt, w którym gracz lub jednostka
rozpoczynają grę. Tego rodzaju punkt może być tylko jeden lub może
być ich wiele. Ponadto punkt rozpoczęcia gry może pozostać statyczny
lub zmieniać położenie na planszy.
Warunek. To forma wyzwalacza. Warunek wygranej to zdarzenie
powodujące, że gracz staje się zwycięzcą (np. po zebraniu wystarczającej
liczby punktów). Z kolei warunek przegranej to zdarzenie powodujące,
że gracz przegrywa (np. traci wszystkie dostępne punkty ruchu).
Kontroler gry. Ten obiekt określa warunki i przebieg gry. Do zadań
kontrolera należy ustalenie, czy gra została wygrana, czy przegrana
(lub po prostu zakończona). Dowolny obiekt może być desygnowany
jako kontroler gry, o ile zawsze będzie znajdował się na scenie. Bardzo
często zdarza się, że na kontrolera gry jest desygnowany obiekt pusty
lub kamera Main Camera.
Wymagania
Innym ważnym krokiem podczas procesu projektowania gry jest określenie
zasobów wymaganych do jej utworzenia. Ogólnie rzecz ujmując, zespół budu‐
jący grę składa się z wielu osób. Niektóre są odpowiedzialne za projektowanie,
inne za programowanie, a jeszcze inne przygotowują grafikę. W trakcie pro‐
cesu powstawania gry każdy członek zespołu wykonuje coś produktywnego.
Jeżeli każdy będzie czekał, aż niezbędny mu komponent zostanie utworzony
przez inną osobę, wtedy praca będzie wielokrotnie przerywana i wznawiana.
Dlatego też wymagane komponenty należy określić wcześniej, aby były gotowe,
zanim staną się potrzebne. Poniżej przedstawiono pełną listę wymagań dla gry
Amazing Racer.
128 Lekcja 7. Pierwsza gra — Amazing Racer
RYSUNEK 7.1.
Ogólny
układ terenu
w tworzonej grze
Amazing Racer
Rzeźbienie terenu
Istnieje wiele sposobów przygotowania terenu. Każdy ma prawdopodobnie
inną wizję pracy. W materiałach znajdziesz mapę wysokości. To gwarantuje,
że gra, którą przygotujesz, będzie zgodna z opisem przedstawionym w książce.
W celu przeprowadzenia operacji rzeźbienia terenu wykonaj wymienione
poniżej kroki.
1. Utwórz nowy projekt w katalogu o nazwie Amazing Racer. Do projektu
dodaj teren.
2. W sekcji Resolution ustawień terenu, w panelu Inspector określ
wymiary terenu na 200 jednostek szerokości, 100 jednostek długości
i 100 jednostek wysokości.
3. W materiałach przeznaczonych dla bieżącej lekcji odszukaj plik
terrain.raw, a następnie zaimportuj go jako mapę wysokości dla terenu
(kliknij Import Raw w sekcji Heightmap ustawień terenu w panelu
Inspector).
4. Utwórz podkatalog Scenes w katalogu Assets, a następnie zapisz bieżącą
scenę pod nazwą Main.
Na tym etapie teren powinien być odpowiednio wyrzeźbiony i odpowiadać
pokazanemu w książce. Jeśli chcesz, możesz w terenie wprowadzić niewielkie
zmiany.
Kontroler postaci
Na tym etapie prac do terenu trzeba dodać kontroler postaci.
1. Zaimportuj standardowe kontrolery postaci, wybierając opcję
Assets/Import Package/Character Controller.
2. Z katalogu Assets/Character Controllers przeciągnij na scenę kontroler
First Person.
3. Kontroler First Person (będzie nosił nazwę Player i miał kolor niebieski)
umieść w położeniu (160, 32, 64). Następnie obróć kontroler o 260
stopni wokół osi Y, aby gracz był zwrócony twarzą w odpowiednim
kierunku.
Po umieszczeniu kontrolera postaci w odpowiednim miejscu na scenie możesz
przystąpić do jej przetestowania. Przejdź po całym terenie i szukaj obszarów,
Gamifikacja 131
Gamifikacja
Na obecnym etapie mamy przygotowany świat, w którym będzie toczyła się
akcja gry. Można więc uruchomić scenę i zacząć zwiedzanie utworzone światy.
Brakuje jeszcze samej gry. W tym momencie dotychczasowy efekt pracy można
uznać za zabawkę. Otrzymałeś scenę, którą można uruchomić i pobawić się nią.
Jednak potrzebujesz gry, która również będzie zabawką, ale ze zdefiniowanymi
regułami i celem. Proces zamiany czegoś na grę nazywany jest gamifikacją
(ang. gamification) i temu zostanie poświęcona ta część lekcji. Jeśli wykony‐
wałeś omawiane dotąd kroki, obecny stan projektu gry będzie podobny do
pokazanego na rysunku 7.2. Kilka kolejnych kroków spowoduje dodanie obiek‐
tów kontrolujących grę, co zapewni możliwość interakcji. Ponadto dodasz
skrypty gry do obiektów oraz połączysz wszystko w jedną całość.
RYSUNEK 7.2.
Obecny stan
tworzonej gry
Amazing Racer
Skrypty
Skrypty to fragmenty kodu definiujące zachowanie obiektów gry. Temat
skryptów w środowisku Unity nie został jeszcze poruszony. Aby gra stała się
interaktywna, konieczne jest użycie skryptów. Skrypty niezbędne dla gry
tworzonej w tej lekcji zostały dostarczone wraz z innymi plikami. Podczas
przygotowywania skryptów włożono sporo wysiłku w ich maksymalne
uproszczenie, co powinno pomóc w zrozumieniu sposobu działania. Dostar-
czone skrypty możesz otworzyć w edytorze tekstów i zobaczyć, do czego
zostały przeznaczone. Dokładniejsze omówienie skryptów znajdziesz
w lekcjach 8. i 9.
RYSUNEK 7.3.
Panel Inspector
dla obiektu
WaterHazard-
Detector
Ostatnim obiektem, który trzeba utworzyć, jest obiekt kontrolujący grę. Tech‐
nicznie rzecz biorąc, obiekt ten nie musi istnieć. W zamian odpowiednie wła‐
ściwości można ustawić w innym obiekcie trwale istniejącym w grze, np.
w kamerze Main Camera. Wspomniany obiekt jednak warto utworzyć, aby
uniknąć przypadkowego usunięcia właściwości. W fazie projektowania obiekt
kontrolujący grę jest bardzo prosty. Znacznie intensywniej będzie używany
nieco później. Poniżej wymieniono kroki prowadzące do utworzenia obiektu
kontrolującego grę.
1. Do sceny dodaj pusty obiekt.
2. W panelu Hierarchy nazwę obiektu gry zmień na GameControl.
Dodanie skryptów
Jak wcześniej wspomniano, skrypty pozwalają na zdefiniowanie zachowania
obiektów gry. W tej części lekcji po prostu zastosujesz skrypty przygotowane
dla tworzonej gry. Teraz nie jest najważniejsze zrozumienie sposobu działania
tych skryptów. Najpierw dodaj je do projektu.
1. W panelu Project przejdź do katalogu Assets i utwórz podkatalog
Scripts.
2. Odszukaj katalog Scripts w materiałach przeznaczonych dla bieżącej
lekcji.
134 Lekcja 7. Pierwsza gra — Amazing Racer
RYSUNEK 7.4.
Panel Inspector
dla obiektu Finish
Połączenie skryptów
Jeżeli zajrzałeś do kodu skryptów, pewnie zauważyłeś, że wszystkie zawierają
miejsca zarezerwowane dla innych obiektów. Dzięki wspomnianym miejscom
zarezerwowanym skrypty mogą się komunikować. W panelu Inspector możesz
zobaczyć, że dla każdego miejsca zarezerwowanego w skrypcie istnieje wła‐
ściwość w komponencie dla danego skryptu. Podobnie jak w przypadku skryp‐
tów, przypisanie obiektów do miejsc zarezerwowanych odbywa się przez
kliknięcie obiektu i przeciągnięcie go na właściwość odpowiadającą miejscu
zarezerwowanemu (patrz rysunek 7.6).
Gamifikacja 135
RYSUNEK 7.5.
Aby zastosować
skrypt, trzeba
przeciągnąć
go na obiekt
RYSUNEK 7.6.
Przypisanie
obiektów gry
do miejsc
zarezerwowanych
Testowanie gry
Wprawdzie gra jest w tym momencie ukończona, ale to jeszcze nie koniec
pracy. Teraz trzeba rozpocząć proces testowania. Testowanie polega na grze
z zamiarem wyszukania wszelkich błędów lub zachowań odmiennych od
oczekiwanych. Najlepiej testowanie gry zlecić innym osobom, które poinfor‐
mują twórców, co im wydaje się sensowne i przynosi radość podczas gry.
Jeżeli wykonywałeś kroki przedstawione w tej lekcji, gra nie powinna zawierać
żadnych błędów. Proces określania tego, co przynosi graczowi radość podczas
gry, jest całkowicie zależny od twórcy gry. Dlatego też ten etap pozostawiam
Tobie. Zagraj w grę i określ to, co Ci się w grze nie podoba. Zanotuj spostrze‐
żenia i odkrycia. Jednak nie koncentruj się jedynie na negatywnych aspek‐
tach gry. Spróbuj również wyszukać te elementy, które sprawiają Ci radość.
Testowanie gry 137
RYSUNEK 7.7.
Usunięcie
zaznaczenia
z pola wyboru
Mouse Look we
właściwościach
kamery
RYSUNEK 7.8.
Zmiana szybkości
poruszania
się gracza
138 Lekcja 7. Pierwsza gra — Amazing Racer
Podsumowanie
W tej lekcji utworzyłeś pierwszą grę w środowisku Unity. Na początku lekcji
poznałeś różne aspekty fazy projektowania gry, czyli koncepcję, reguły i wyma‐
gania. Następnie zbudowałeś świat, w którym toczy się akcja gry, a także doda‐
łeś pewne efekty środowiska. Kolejnym zadaniem było dodanie obiektów gry
wymaganych w celu zapewnienia jej interaktywności. Zastosowałeś skrypty
na wspomnianych obiektach gry, a następnie połączyłeś je. Na końcu przete‐
stowałeś grę i tym samym zyskałeś możliwość poznania aspektów gry zarówno
tych, które Ci się nie podobają, jak i tych, które się podobają.
Pytania i odpowiedzi
Pytanie: Od tych wszystkich informacji rozbolała mnie głowa. Czy robię
coś źle?
Odpowiedź: Oczywiście, nie! Przedstawiony w tej lekcji proces może wydawać
się dziwny czytelnikom, którzy wcześniej się z nim nie spotkali. Kontynuuj
lekturę książki, wykonuj ćwiczenia, a wkrótce wszystko zacznie się
układać w logiczną całość. Najlepsze, co możesz zrobić, to dokładne
zwrócenie uwagi na tworzone za pomocą skryptów połączenia między
obiektami.
Pytanie: W tej lekcji nie poruszono tematu kompilacji i wdrożenia gry.
Dlaczego?
Odpowiedź: Tematy kompilacji i wdrożenia zostaną poruszone dalej w tej
książce. Podczas kompilacji gry trzeba uwzględnić wiele czynników,
a celem tej lekcji było skoncentrowanie się na koncepcjach wymaganych
do utworzenia gry.
Pytanie: Dlaczego nie można zbudować gry bez skryptów?
Odpowiedź: Jak wcześniej wspomniano, skrypty definiują sposób zachowania
obiektów. Bardzo trudno przygotować spójną grę bez pewnej formy
interaktywnego zachowania. Jedynym powodem, dla którego budowałeś
grę w lekcji 7. przed poznaniem skryptów w lekcjach 8. i 9., była
konieczność opanowania pewnych zagadnień przed przejściem do
zupełnie innych.
Warsztaty
Poświęć nieco czasu i odpowiedz na zamieszczone poniżej pytania, a także
upewnij się, że przyswoiłeś sobie materiał omówiony w tej lekcji.
Ćwiczenie 139
Quiz
1. Co to są wymagania gry?
2. Co to jest warunek wygranej w grze?
3. Ile tekstur zaleca się użyć, aby uzyskać naturalny wygląd przejścia
krajobrazu, np. od trawy do skał?
4. Które obiekty są odpowiedzialne za kontrolowanie przebiegu gry?
5. Dlaczego należy przetestować utworzoną grę?
Odpowiedzi
1. Wymagania to lista zasobów niezbędnych do utworzenia danej gry.
2. To jest trudne pytanie! W omawianej grze nie ma warunku
wskazującego na wygraną gracza. Przyjęto założenie, że gracz wygra,
jeśli uzyska lepszy czas niż we wcześniejszej próbie. To nie zostało
jednak wbudowane w grę.
3. Trzy: trawa, trawa wraz ze skałami, skały.
4. Kontroler gry. W utworzonej tutaj grze nosił on nazwę GameControl.
5. W celu wykrycia błędów i określenia, które aspekty gry działają zgodnie
z oczekiwaniami, a które można jeszcze usprawnić.
Ćwiczenie
W procesie tworzenia gier najlepsze jest to, że można je budować wedle wła‐
snego upodobania. Kierowanie się wskazówkami jest przydatne podczas nauki,
ale w ten sposób nie poczujesz satysfakcji płynącej z samodzielnego utworzenia
własnej gry. W przedstawionym tutaj ćwiczeniu zyskujesz możliwość zmody‐
fikowania gry, aby stała się nieco bardziej unikalna. Dokładny sposób modyfi‐
kacji zależy tylko od Ciebie. Poniżej wymieniono jedynie kilka sugestii.
Spróbuj dodać więcej stref zakończenia gry. Zobacz, czy potrafisz
je umieścić w sposób dający graczowi więcej możliwości wyboru.
Zmodyfikuj teren tak, aby zawierał więcej niebezpieczeństw lub
różne ich rodzaje. Jeżeli wszystkie niebezpieczeństwa przygotujesz
w sposób podobny do groźnej wody (łącznie ze skryptem),
będą działały zgodnie z oczekiwaniami.
Spróbuj przygotować więcej punktów początkowych gry. Zmodyfikuj
grę tak, aby różne pułapki przenosiły gracza do odmiennych punktów
początkowych gry.
Zmodyfikuj niebo i tekstury, tworząc w ten sposób inny świat.
Postaraj się, aby rozrywka w nowym świecie była unikalna.
140 Lekcja 7. Pierwsza gra — Amazing Racer
Lekcja 8
Skrypty — część 1.
Przykładowe skrypty
Kilka skryptów i struktur kodu przedstawionych tutaj znajdziesz w materia-
łach przeznaczonych dla bieżącej lekcji. Zajrzyj do dostarczonych skryptów,
aby dowiedzieć się więcej.
Początkujący programiści
Jeżeli nie masz doświadczenia w programowaniu, skrypty mogą wydać Ci
się dziwne i niezrozumiałe. W trakcie bieżącej lekcji staraj się więc skoncen-
trować na strukturze skryptów i na tym, dlaczego zostały utworzone wła-
śnie w taki sposób. Pamiętaj, że programowanie jest czysto logicznym
zadaniem. Jeżeli program nie działa zgodnie z oczekiwaniami, prawdopo-
dobnie nie umieściłeś w nim prawidłowych poleceń. Czasami trzeba po
prostu zmienić sposób myślenia. Z materiałem przedstawionym w tej lekcji
zapoznawaj się powoli i nie zapomnij o ćwiczeniach praktycznych.
142 Lekcja 8. Skrypty — część 1.
Skrypty
Jak wcześniej wspomniano, skrypty pozwalają na zdefiniowanie zachowania.
W Unity skrypty są dołączane do obiektów dokładnie tak samo jak inne kom‐
ponenty, a ponadto zapewniają obiektom interaktywność. Ogólnie rzecz biorąc,
podczas pracy ze skryptami w Unity wykonać trzeba trzy kroki. Oto one.
1. Utworzenie skryptu.
2. Dołączenie skryptu do jednego obiektu gry lub większej ich liczby.
3. Jeżeli skrypt tego wymaga, wypełnienie właściwości wartościami
lub innymi obiektami gry. (Do tego kroku powrócę jeszcze w tej lekcji).
Tworzenie skryptów
Zanim przystąpisz do budowania skryptów, warto za pomocą panelu Project
przygotować dla nich podkatalog Scripts w katalogu Assets. Gdy już będziesz
miał podkatalog przeznaczony dla wszystkich skryptów, po prostu kliknij go
prawym przyciskiem myszy i wybierz opcję Create/C# Script. Po utworzeniu
skryptu trzeba nadać mu nazwę; potem można kontynuować pracę.
Język skryptowy
Środowisko Unity pozwala na tworzenie skryptów w językach C#, Java-
Script i Boo. Wszystkie skrypty przedstawione w tej książce zostały powstały
w języku C#. Wybór języka, w którym pisane są skrypty, należy do Ciebie.
Jeżeli preferujesz inny język programowania niż C#, używaj go do opraco-
wywania skryptów.
Dołączanie skryptu
Aby dołączyć skrypt do obiektu gry, wystarczy kliknąć skrypt w panelu Project,
a następnie przeciągnąć na obiekt (patrz rysunek 8.3). Skrypt można prze‐
ciągnąć na obiekt wyświetlany w panelach Hierarchy, Scene lub Inspector
(oczywiście przy założeniu, że obiekt jest zaznaczony). Po dołączeniu do
obiektu skrypt stanie się komponentem danego obiektu i będzie widoczny
w panelu Inspector.
Skrypty 143
RYSUNEK 8.1.
Zawartość skryptu
wyświetlona
w panelu
Inspector
RYSUNEK 8.2.
Okno edytora
w oprogramowaniu
MonoDevelop
Wypróbuj samodzielnie
Utworzenie skryptu
Poniżej przedstawiono kroki prowadzące do utworzenia skryptu, którego
będziesz używać w tej części lekcji.
1. Utwórz nowy projekt lub scenę. Następnie za pomocą panelu Project
utwórz katalog Scripts.
144 Lekcja 8. Skrypty — część 1.
}
}
4. Zapisz skrypt, wybierając opcję File/Save lub naciskając klawisze Ctrl+S
(Command+S w Macu). Po powrocie do edytora Unity spójrz na panel
Inspector, upewnij się, że skrypt został zmodyfikowany, a następnie
uruchom scenę. Nic się nie zdarzyło. Wprawdzie skrypt został utworzony,
ale nie będzie działał, aż do chwili jego dołączenia do obiektu. Tym
zajmiesz się za chwilę.
MonoDevelop
MonoDevelop to solidne i skomplikowane oprogramowanie dostarczane
wraz z środowiskiem Unity. Nie stanowi jednak fragmentu Unity i dlatego
nie będzie dokładnie omawiane w tej książce. Jedynym elementem Mono-
Develop, który musisz teraz poznać, jest wspomniane wcześniej okno edy-
tora. Jeżeli będziesz musiał dowiedzieć się czegoś więcej o MonoDevelop,
odpowiednie informacje znajdą się w tekście lekcji.
RYSUNEK 8.3.
Kliknięcie
i przeciągnięcie
skryptu
na wybrany
obiekt
RYSUNEK 8.4.
Dane wyjściowe
skryptu
wyświetlone
po uruchomieniu
sceny
Sekcja Using
W pierwszej części skryptu wymienione są biblioteki, które będą używane
przez skrypt. Ta część przedstawia się następująco:
using UnityEngine;
using System.Collections;
Ogólnie rzecz ujmując, nie będziesz modyfikował tej sekcji i powinieneś ją
pozostawić w obecnej postaci.
Sekcja deklaracji
Kolejna część jest nazywana deklaracją klasy. Każdy skrypt zawiera klasę
o takiej samej nazwie jak skrypt. Deklaracja klasy w omawianym skrypcie
przedstawia się następująco:
public class HelloWorldScript : MonoBehaviour { )
Cały kod znajdujący się między nawiasem otwierającym { i zamykającym }
będzie częścią tej klasy, a tym samym skryptu. Tworzony przez Ciebie kod
powinien być umieszczony między wymienionymi nawiasami. Podobnie jak
w deklaracji bibliotek, także omawiany tutaj wiersz rzadko będzie modyfiko‐
wany i najczęściej pozostaje w domyślnej postaci.
Sekcja klasy
Sekcja znajdująca się między nawiasem otwierającym { i zamykającym } jest
uznawana za „treść” klasy. W tym właśnie miejscu tworzysz kod. Domyślnie
w skrypcie znajdują się dwie metody klasy, czyli Start() i Update().
// Poniższej metody użyj do inicjacji.
void Start() {
}
Zmienne 147
Komentarze
Języki programowania zawierają konstrukcje, które pozwalają programistom
na pozostawianie informacji dla innych osób czytających kod źródłowy.
Informacje te są nazywane komentarzami. Treść umieszczona po dwóch
ukośnikach (//) jest właśnie komentarzem. Oznacza to, że komputer pomi-
nie tę treść podczas odczytu kodu. Przykładowe komentarze możesz zoba-
czyć w przedstawionym wcześniej listingu 8.1.
Konsola
Edytor Unity zawiera jeszcze jedno okno, o którym dotąd nie wspomnia-
łem; jest to konsola. Okno konsoli będzie wyświetlało tekst generowany
przez grę. Najczęściej są w nim wyświetlane komunikaty błędów lub dane
wyjściowe skryptów. Przykład okna konsoli pokazano na rysunku 8.5. Jeżeli
konsola nie jest widoczna, możesz uzyskać do niej dostęp za pomocą opcji
Window/Console.
RYSUNEK 8.5.
Okno konsoli
Zmienne
Czasami w skrypcie trzeba użyć tych samych danych więcej niż tylko raz.
W takim przypadku potrzebujesz miejsca zarezerwowanego na dane, które
będzie można ponownie wykorzystać. Tego rodzaju zarezerwowane miejsce
nosi nazwę zmiennej. W przeciwieństwie do tradycyjnej matematyki, zmienne
w języku programowania mogą zawierać nie tylko liczby. Zmienna może prze‐
chowywać słowa, skomplikowane obiekty, a nawet inne skrypty.
148 Lekcja 8. Skrypty — część 1.
Wypróbuj samodzielnie
Tworzenie zmiennej
Każda zmienna ma nazwę i typ, nadawane podczas jej tworzenia. Do utwo‐
rzenia zmiennej stosowana jest poniższa składnia:
<typ zmiennej><nazwa zmiennej>;
Dlatego też utworzenie zmiennej o nazwie num1 i przechowującej
liczbę całkowitą wymaga wydania polecenia:
int num1;
W tabeli 8.1 wymieniono wszystkie podstawowe typy zmiennych oraz typy
danych, które mogą być przez nie przechowywane.
Zasięg zmiennej
Zasięg zmiennej odnosi się do miejsc, w których dana zmienna może być
używana. Jak widziałeś w skryptach, w klasach i metodach stosuje się nawiasy
otwierające i zamykające w celu wskazania należącego do nich kodu. Obszar
znajdujący się między dwoma nawiasami jest często określany mianem bloku.
Zmienne 149
Składnia
Pojęcie składnia odnosi się do reguł w języku programowania. Składnia
określa stosowaną strukturę kodu, aby komputer „wiedział”, jak ma go
odczytywać. Prawdopodobnie zauważyłeś, że w przedstawionych skryptach
wszystkie polecenia kończą się średnikiem. To jest fragment składni języka
C#. Jeżeli zapomnisz o średniku, wtedy skrypt nie będzie działał. Więcej
informacji dotyczących składni C# znajdziesz na stronie http://en.wikipedia.
org/wiki/C_Sharp_syntax.
void Start () {
// To jest "blok lokalny", który pozostaje
// dostępny jedynie w metodzie Start().
int num2;
}
Wypróbuj samodzielnie
Operatory
Wszystkie dane przechowywane w zmiennych pozostaną bezużyteczne, jeśli
nie będzie możliwości uzyskania do nich dostępu lub ich modyfikacji. Operatory
to symbole specjalne pozwalające na modyfikację danych. Możemy wymienić
cztery kategorie operatorów: arytmetyczne, przypisania, równości i logiczne.
Operatory arytmetyczne
Operatory arytmetyczne przeprowadzają pewne standardowe operacje ma‐
tematyczne na zmiennych. Najczęściej są stosowane względem zmiennych
liczbowych, choć istnieje kilka wyjątków. Dostępne operatory arytmetyczne
wymieniono w tabeli 8.2.
Operatory przypisania
Operatory przypisania działają zgodnie ze swoją nazwą — przypisują wartość
zmiennej. Najczęściej używanym operatorem przypisania jest znak równości,
choć istnieją także inne, łączące wiele operacji. Wszystkie operacje przypisania
w C# są przeprowadzane od prawej do lewej strony. Oznacza to, że wartość
znajdująca się po prawej stronie będzie przeniesiona na lewą.
x = 5; // To przypisanie działa, zmienna x otrzymuje wartość 5.
5 = x; // To przypisanie nie działa. Nie można przypisać zmiennej do wartości (tutaj 5).
Operatory przypisania zostały wymienione w tabeli 8.3.
Operatory równości
Celem tego rodzaju operatorów jest porównywanie dwóch wartości. Wyni‐
kiem działania operatora równości zawsze będzie prawda lub fałsz. Dlatego
też jedynym typem zmiennej, który pozwala na przechowywanie wyniku
działania operatora równości, jest Boolean. (Pamiętaj, że zmienna boolowska
może przechowywać jedynie wartości true lub false). Dostępne operatory
równości wymieniono w tabeli 8.4.
Konstrukcje warunkowe 153
Operatory logiczne
Operatory logiczne pozwalają na połączenie dwóch lub więcej wartości boolow‐
skich (true lub false) w pojedynczą wartość boolowską. Szczególnie uży‐
teczne są podczas sprawdzania skomplikowanych warunków. Dostępne ope‐
ratory logiczne zostały wymienione w tabeli 8.5.
Konstrukcje warunkowe
Potęga komputera kryje się w możliwości podejmowania prostych decyzji.
U podstaw wspomnianej potęgi leżą wartości boolowskie true i false. Za
pomocą tych wartości można tworzyć konstrukcje warunkowe i sterować
przebiegiem działania programu. Podczas opracowywania logiki odpowie‐
dzialnej za sterowanie przebiegiem działania programu musisz pamiętać, że
154 Lekcja 8. Skrypty — część 1.
komputer może w danej chwili podejmować tylko jedną, prostą decyzję. Dzięki
zgrupowaniu tego rodzaju decyzji zyskujesz możliwość przygotowania skom‐
plikowanych interakcji.
Konstrukcja if
Podstawowa konstrukcja warunkowa to polecenie if, którego struktura
przedstawia się następująco:
if(<pewien warunek boolowski>)
{
// Dowolna operacja.
}
Strukturę if można odczytać następująco: „jeżeli warunek ma wartość true,
wykonaj wskazaną operację”. Dlatego też, jeśli w konsoli chcesz wyświetlić
komunikat Witaj, świecie!, gdy wartość x jest większa niż 5, możesz użyć
następującej konstrukcji:
if(x > 5)
{
print("Witaj, świecie!");
}
Konstrukcje warunkowe 155
if(x + y) // Nieprawidłowo.
{}
Kod przeznaczony do wykonania, gdy warunek konstrukcji przyjmuje wartość
true, musi się znaleźć w nawiasach klamrowych umieszczonych tuż za pole‐
ceniem if.
Dziwne zachowanie
W konstrukcjach warunkowych używa się specyficznej składni. Jeżeli nie
będziesz z niej korzystał, możesz się spotkać z dziwnym zachowaniem
konstrukcji. Przykładowo w kodzie masz polecenie if i zauważyłeś, że nie
działa zgodnie z oczekiwaniami. Być może kod konstrukcji jest wykonywany
nawet wtedy, kiedy nie powinien. Ewentualnie możesz zauważyć, że nie
jest wykonywany nawet wtedy, kiedy powinien. Warto wiedzieć o dwóch
najczęściej występujących przyczynach wymienionych problemów. Pierwsza
to umieszczenie średnika po warunku if. Jeżeli polecenie if zostanie zapi-
sane ze średnikiem, wtedy znajdujący się po nim kod będzie wykonany
zawsze. Druga to użycie w poleceniu if operatora przypisania (=) zamiast
operatora porównania (==). Popełnienie któregokolwiek z opisanych błędów
powoduje dziwne zachowanie konstrukcji if.
if(x > 5); // Nieprawidłowo.
if(x = 5); // Nieprawidłowo.
Konstrukcja if-else
Polecenie if jest elegancką konstrukcją warunkową, ale co zrobić w sytuacji,
kiedy chcesz zdefiniować dwie odmienne ścieżki działania w programie?
W takim przypadku rozwiązaniem jest użycie konstrukcji if-else. Wymieniona
konstrukcja działa podobnie do omówionej wcześniej if, ale można ją od‐
czytać następująco: „jeżeli warunek ma wartość true, wykonaj wskazaną
operację, w przeciwnym razie wykonaj inną operację”. Konstrukcja if-else
ma następującą strukturę:
if(<pewien warunek boolowski>)
{
// Dowolna operacja.
}
else
{
// Inna dowolna operacja.
}
156 Lekcja 8. Skrypty — część 1.
Jeśli np. w oknie konsoli chcesz wyświetlić komunikat X jest większe niż Y,
gdy wartość zmiennej x jest większa od y lub Y jest większe niż X, gdy
wartość zmiennej x jest mniejsza od y, wtedy możesz użyć poniższej kon‐
strukcji:
if(x > y)
{
print("X jest większe niż Y");
} else {
print("Y jest większe niż X");
}
Konstrukcja if-else if
Czasami trzeba zdefiniować w kodzie większą liczbę ścieżek działania pro‐
gramu. Chcesz np. umożliwić użytkownikowi wybór opcji z grupy dostępnych
opcji (jak w menu). Struktura konstrukcji if-else if jest podobna do dwóch
poprzednio omówionych, ale zawiera większą liczbę warunków.
if(<pewien warunek boolowski>)
{
// Dowolna operacja.
}
else if(<inny warunek boolowski>)
{
// Inna dowolna operacja.
}
else // Ten blok jest opcjonalny w konstrukcji if-else if.
{
// Jeszcze inna dowolna operacja.
}
Kiedy np. w konsoli chcesz wyświetlić ocenę ucznia na podstawie ilości zdo‐
bytych przez niego punktów, wtedy możesz użyć następującej konstrukcji:
if(grade >= 90)
{
print("Otrzymałeś ocenę 5.");
}
else if(grade >= 80)
{
print("Otrzymałeś ocenę 4.");
}
else if(grade >= 70)
{
print("Otrzymałeś ocenę 3.");
}
else if(grade >= 60)
{
print("Otrzymałeś ocenę 2.");
}
Iteracja 157
else
{
print("Otrzymałeś ocenę 1.");
}
Iteracja
Dotychczas dowiedziałeś się, jak pracować ze zmiennymi i podejmować decyzje.
To na pewno będzie użyteczne, gdy trzeba wykonać operację, taką jak dodanie
dwóch liczb. Co zrobić, gdy trzeba dodać wszystkie liczby od 1 do 100? A jeśli
zakres wynosi od 1 do 1000? Zdecydowanie nie chcesz być zmuszony do
wpisywania powtarzającego się i zbędnego kodu. Zamiast tego można wyko‐
rzystać tzw. iterację (inna nazwa to pętla). Mamy dwa podstawowe rodzaje
pętli, z którymi można pracować; są to pętle while i for.
Pętla while
Pętla while stanowi najprostszą postać iteracji. Struktura omawianej pętli jest
podobna do struktury konstrukcji if.
while(<pewien warunek boolowski>)
{
// Dowolna operacja.
}
Jedyna różnica polega na tym, że konstrukcja if wykonuje blok kodu tylko
jednokrotnie, natomiast pętla while wykonuje kod dopóty, dopóki warunek
nie przyjmie wartości false. Dlatego też jeśli chcesz dodać liczby od 1 do 100,
a następnie wyświetlić wynik w konsoli, możesz użyć kodu podobnego do
przedstawionego poniżej.
int sum = 0;
int count = 1;
158 Lekcja 8. Skrypty — część 1.
print(sum);
Jak widać, wartość zmiennej count na początku wynosi 1, a następnie jest
zwiększa o 1 w trakcie każdej iteracji pętli, aż do osiągnięcia wartości 101.
Gdy wartość zmiennej count wyniesie 101, nie będzie dłużej mniejsza lub
równa 100 i nastąpi opuszczenie pętli. Pominięcie wiersza count++ spowo‐
duje działanie pętli w nieskończoność (upewnij się więc, że go dodałeś).
W trakcie każdej iteracji pętli wartość zmiennej count będzie dodana do war‐
tości zmiennej sum. Po opuszczeniu pętli wartość sum zostanie wyświetlona
w konsoli.
Zatem pętla while będzie wykonywała zdefiniowany w niej kod tak długo,
jak długo podany warunek przyjmuje wartość true. Gdy warunek przyjmie
wartość false, pętla zostanie zakończona.
Pętla for
Pętla for opiera się na takiej samej idei jak pętla while, ale posiada nieco inną
strukturę. Jak mogłeś zobaczyć w przedstawionym wcześniej kodzie dla pętli
while, konieczne jest utworzenie zmiennej (np. count), przetestowanie jej
(to warunek pętli) oraz zwiększenie wartości zmiennej. Wymienione działania
to trzy oddzielne operacje zdefiniowane w trzech wierszach kodu. W pętli
for wymienione operacje zostają skondensowane do pojedynczego wiersza:
for(<utworzenie licznika>; <warunek boolowski>; <zwiększenie
licznika>)
{
// Dowolna operacja.
}
Pętla for zawiera trzy specjalne sekcje przeznaczone do jej kontrolowania.
Zwróć uwagę na użycie średników, a nie przecinków między poszczególnymi
sekcjami w nagłówku pętli for. W pierwszej sekcji tworzona jest zmienna,
która będzie używana w charakterze licznika. (Najczęściej otrzymuje ona nazwę
i, to skrót od słowa iterator). Sekcja druga zawiera polecenie warunkowe
pętli. Natomiast w sekcji trzeciej następuje zwiększenie lub zmniejszenie
wartości licznika. Przedstawiony wcześniej przykład oparty na pętli while
można przepisać na postać korzystającą z pętli for. Kod będzie podobny do
poniższego.
int sum = 0;
{
sum += count;
}
print(sum);
Jak możesz zobaczyć, trzy różne polecenia obsługujące pętlę zostały skonden‐
sowane do pojedynczego, co pozwala na oszczędzenie miejsca. Pętla for
naprawdę doskonale sprawdza się w operacjach, takich jak zliczanie.
Podsumowanie
W tej lekcji wykonałeś pierwsze kroki na drodze do programowania gier wideo.
Na początek poznałeś podstawy dotyczące skryptów w środowisku Unity.
Dowiedziałeś się, jak tworzyć skrypty i dołączać je do obiektów. Przeanali‐
zowałeś również podstawową anatomię skryptu. Następnie przeszedłeś do
komponentów logicznych programu. W ten sposób miałeś możliwość pracy
ze zmiennymi, operatorami, konstrukcjami warunkowymi i pętlami.
Pytania i odpowiedzi
Pytanie: Czy utworzenie gry wymaga dużej ilości programowania?
Odpowiedź: Większość gier wymaga użycia pewnych form programowania
w celu zdefiniowania skomplikowanych zachowań. Im bardziej złożone
zachowanie, tym większy poziom skomplikowania kodu, który trzeba
utworzyć. Jeżeli chcesz zająć się opracowywaniem gier, na pewno
powinieneś poznać koncepcje związane z programowaniem. Dotyczy
to również sytuacji, gdy nie jesteś głównym twórcą gry. Możesz mieć
pewność, że tej książce znajdziesz wszystko, co musisz wiedzieć, aby
utworzyć kilka pierwszych prostych gier.
Pytanie: Czy przedstawiony materiał dotyczy tylko skryptów?
Odpowiedź: I tak, i nie. W tej lekcji zaprezentowano podstawy programowania.
One nigdy się nie zmieniają, ale mogą być zastosowane na nowe i unikalne
sposoby. Wiele przedstawionych tutaj koncepcji zostało uproszczonych,
ponieważ programowanie z natury jest skomplikowane. Jeżeli chcesz
dowiedzieć się więcej o programowaniu, powinieneś przeczytać książki
lub artykuły poświęcone temu tematowi.
Warsztaty
Poświęć nieco czasu i odpowiedz na zamieszczone poniżej pytania, a także
upewnij się, że przyswoiłeś sobie materiał omówiony w tej lekcji.
160 Lekcja 8. Skrypty — część 1.
Quiz
1. W jakich trzech językach można programować w środowisku Unity?
2. Kod w metodzie Start() jest wykonywany w każdej klatce. Prawda
czy fałsz?
3. Który typ zmiennych jest domyślnie stosowany w Unity dla liczb
zmiennoprzecinkowych?
4. Wartością zwrotną którego operatora jest reszta z dzielenia?
5. Co to jest konstrukcja warunkowa?
6. Który typ pętli najbardziej nadaje się do przeprowadzania obliczeń?
Odpowiedzi
1. C#, JavaScript i Boo.
2. Fałsz. Kod metody Start() jest wykonywany po uruchomieniu sceny.
Natomiast kod metody Update() jest wykonywany w każdej klatce.
3. To typ float.
4. Operator modulo.
5. To jest struktura kodu pozwalająca komputerowi na wybór ścieżki
działania na podstawie prostych decyzji.
6. Pętla for.
Ćwiczenie
Bardzo często użyteczne jest postrzeganie struktur kodu jako bloków budul‐
cowych. Pojedyncze elementy są proste, ale łącząc je, można tworzyć skom‐
plikowane struktury. W poniższych punktach znajdziesz kilka wyzwań pro‐
gramistycznych. Wiedzę zdobytą w tej lekcji wykorzystaj więc do opracowania
rozwiązań dla przedstawionych problemów. Każde rozwiązaniem umieść
w oddzielnym skrypcie, a następnie dołącz skrypty do obiektu Main Camera
i upewnij się, że prawidłowo działają. Rozwiązania poniższych ćwiczeń znaj‐
dziesz w materiałach przeznaczonych dla bieżącej lekcji.
1. Opracuj skrypt, który będzie dodawał wszystkie liczby całkowite
z zakresu od 2 do 499. Suma powinna zostać wyświetlona w konsoli.
2. Opracuj skrypt, który w konsoli wyświetli wszystkie liczby od 1 do
100. Jednak dane wyjściowe nie powinny zawierać liczb będących
wielokrotnością 3 lub 5. Zamiast nich powinien zostać wyświetlony
komunikat Programowanie jest wspaniałe!. (Podpowiedź: liczba
jest wielokrotnością innej, jeśli wynikiem operatora modulo jest 0).
3. W ciągu Fibonacciego kolejną liczbę można obliczyć przez dodanie
dwóch poprzednich. Początek sekwencji ciągu jest następujący:
0, 1, 1, 2, 3, 5… Napisz skrypt, który utworzy sekwencję składającą się
z 20 pierwszych liczb ciągu Fibonacciego i wyświetli je w konsoli.
Lekcja 9
Skrypty — część 2.
Przykładowe skrypty
Kilka skryptów i struktur kodu przedstawionych w tej lekcji
znajdziesz w materiałach przeznaczonych dla bieżącej lekcji.
Zajrzyj do dostarczonych skryptów, aby dowiedzieć się więcej
na ich temat.
162 Lekcja 9. Skrypty — część 2.
Metody
Metody (często nazywane funkcjami) to moduły kodu, które mogą być wywo‐
ływane i używane niezależnie od innych. Każda metoda służy do wykonania
pojedynczego zadania. Bardzo często poszczególne metody można łączyć
w celu osiągnięcia bardziej skomplikowanych celów. Znasz już dwie używane
dotąd metody, czyli Start() i Update(). Każda z nich służy do jednego kon‐
kretnego celu. W metodzie Start() znajduje się cały kod wykonywany dla
obiektu podczas uruchamiania sceny. Z kolei metoda Update() zawiera kod
wykonywany w trakcie każdej klatki uruchomionej sceny.
Anatomia metody
Zanim rozpoczniesz pracę z metodami, warto poznać tworzące ją poszczególne
elementy. Poniżej przedstawiona została ogólna struktura metody.
<typ wartości zwrotnej><nazwa metody>(<parametry>)
{
<Wewnątrz bloku metody>
}
Nazwa metody
Każda metoda musi mieć unikalną nazwę. Wprawdzie konkretne reguły doty‐
czące prawidłowych nazw metod są określane przez dany język, ale poniżej
wymieniono ogólne zasady dotyczące nazewnictwa metod.
Nazwa metody powinna być opisowa. Najlepiej, jeśli wskazuje akcję
i zawiera czasownik.
Nazwa metody nie może zawierać spacji, są niedozwolone.
W nazwie metody należy unikać znaków specjalnych, takich jak !, @,
*, %, $ itd. W różnych językach programowania może być dozwolone
stosowanie odmiennych zestawów znaków. Jeżeli jednak nie będziesz
używać żadnych znaków specjalnych, wyeliminujesz ryzyko
wystąpienia problemu związanego z nazwami metod.
Nazwy metod są ważne, ponieważ zarówno je identyfikują, jak i wskazują
sposób ich użycia.
Lista parametrów
Podobnie jak metoda może przekazać zmienną z powrotem do wywołującego
ją kodu, tak samo wspomniany kod może przekazać zmienne metodzie. W takim
przypadku zmienne są nazywane parametrami. Zmienne przekazywane meto‐
dzie są wymienione w sekcji listy parametrów metody. Poniżej przedstawiono
przykład metody o nazwie Attack(), która pobiera zmienną o nazwie enemyID
będącą liczbą całkowitą:
void Attack(int enemyID)
{}
Jak możesz zobaczyć, podczas wskazywania parametru konieczne jest podanie
zarówno typu zmiennej, jak i jej nazwy. Wiele parametrów należy rozdzielić
przecinkami.
Blok metody
W tym bloku jest umieszczany rzeczywisty kod metody. W trakcie każdego
wywołania metody zdefiniowany w niej kod będzie wykonany w całości.
Wypróbuj samodzielnie
Tworzenie metody
Skoro poznałeś elementy składające się na metodę, jej utworzenie jest już
całkiem łatwym zadaniem. Zanim przystąpisz do tworzenia metod, najpierw
poświęć chwilę i odpowiedz sobie na następujące pytania.
164 Lekcja 9. Skrypty — część 2.
Upraszczanie
W powyższym przykładzie w ostatecznej wersji metody przeprowadzana
jest prosta operacja odejmowania. Takie uproszczenie zostało zastosowane
celowo dla potrzeb dydaktycznych. W bardziej rzeczywistych sytuacjach
istnieje wiele różnych sposobów wykonania omówionego powyżej zadania.
Informacje o zdrowiu gracza mogą być przechowywane w zmiennej nale-
żącej do skryptu. Dzięki temu nie trzeba będzie ich odczytywać. Kolejną
możliwością jest użycie skomplikowanego algorytmu w metodzie Take-
DamageFromFireball(), w którym liczba odejmowanych punktów będzie
zmniejszana o pewną wartość zależącą od aktualnej osłony posiadanej
przez gracza, uników wykonywanych przez gracza lub zdolności magicz-
nych. Jeżeli przedstawiane tutaj przykłady wydają Ci się głupie, pamiętaj,
że ich celem jest przedstawienie różnych aspektów omawianego tematu.
Użycie metod
Po utworzeniu metody można z niej korzystać. Korzystanie z metody jest
najczęściej określane mianem wywołania. W celu wywołania metody trzeba
wpisać jej nazwę, nawiasy i wymagane parametry. Dlatego też, jeśli próbujesz
użyć metody DowolnaMetoda(), stosujesz następujące wywołanie:
DowolnaMetoda();
Jeżeli DowolnaMetoda() wymaga parametru w postaci liczby całkowitej, wtedy
wywołanie ma postać:
// Wywołanie metody wraz z wartością 5.
DowolnaMetoda(5);
Wypróbuj samodzielnie
Wywoływanie metod
Powróćmy jeszcze na chwilę do metody TakeDamageFromFireball()
omawianej przed chwilą. W tym ćwiczeniu będziesz wywoływać różne
formy metod. Rozwiązanie ćwiczenia znajdziesz w materiałach przezna-
czonych dla bieżącej lekcji.
1. Utwórz nowy projekt lub scenę. W materiałach przeznaczonych dla
bieżącej lekcji odszukaj skrypt FireBallScript i zaimportuj go do projektu.
Alternatywne rozwiązanie polega na utworzeniu skryptu C# o nazwie
FileBallScript i umieszczeniu w nim trzech przedstawionych wcześniej
wersji metody TakeDamageFromFireball().
2. W metodzie Start() wywołaj pierwszą wersję TakeDamageFrom
Fireball(), wydając następujące polecenie:
int x = TakeDamageFromFireball();
print ("Liczba punktów zdrowia gracza: " + x);
3. Dołącz skrypt do obiektu Main Camera i uruchom scenę. Zanotuj dane
wyjściowe wyświetlone w konsoli. Następnie w metodzie Start()
wywołaj drugą wersję TakeDamageFromFireball(), wydając poniższe
polecenie (umieść je poniżej pierwszego wywołania, nie musisz nic
usuwać):
int y = TakeDamageFromFireball(25);
print ("Liczba punktów zdrowia gracza: " + y);
4. Ponownie uruchom scenę i zanotuj dane wyjściowe wyświetlone
w konsoli. Wreszcie w metodzie Start() wywołaj trzecią wersję
TakeDamageFromFireball(), wydając polecenie:
int z = TakeDamageFromFireball(30, 50);
print ("Liczba punktów zdrowia gracza: " + z);
5. Uruchom scenę i zanotuj ostateczne dane wyjściowe wyświetlone
w konsoli. Zwróć uwagę, że wszystkie trzy metody zachowują się nieco
odmiennie. Zobacz, w jaki sposób je wywoływałeś.
Dane wejściowe 167
Dane wejściowe
Bez danych wejściowych gracza gra wideo byłaby zwykłym wideo. Dane wej‐
ściowe gracza mogą być bardzo różne, np. fizyczne w postaci padów, dżojsti‐
ków, klawiatury i myszy. Dostępne są także inne kontrolery, takie jak względnie
nowe ekrany dotykowe znajdujące się w nowoczesnych urządzeniach mobil‐
nych. Ponadto mamy również urządzenia reagujące na ruch, np. Wii Remote,
PlayStation Move i Microsoft Kinect. Rzadziej spotykane są dane wejściowe
w postaci dźwięku, przykładowo gracz wydaje polecenia głosowe grze. W tej
części lekcji dowiesz się, jak tworzyć kod pozwalający graczowi na interakcję
z grą za pomocą urządzeń fizycznych.
RYSUNEK 9.1.
Menedżer Input
Manager
niem wymienionej metody jest odczyt nazwy osi i zwrot tej nazwy w postaci
ciągu tekstowego. Jeśli zatem chcesz pobrać wartość osi poziomej, musisz
wydać poniższe polecenie:
float hVal = Input.GetAxis("Horizontal");
Jeśli w przypadku osi poziomej gracz naciśnie klawisz kursora w lewo (lub A),
wartością zwrotną GetAxis() jest liczba ujemna. Z kolei naciśnięcie klawisza
kursora w prawo (lub D) spowoduje, że omawiana metoda zwróci wartość
dodatnią.
Wypróbuj samodzielnie
if(hVal != 0)
print("Ruch w kierunku poziomym: " + hVal);
if(vVal != 0)
print("Ruch w kierunku pionowym: " + vVal);
3. Zapisz skrypt i uruchom scenę. Zwróć uwagę na to, co się stanie, gdy
naciśniesz klawisze kursora. Następnie wypróbuj klawisze W, A, S i D.
RYSUNEK 9.2.
Automatycznie
rozwijana lista
w edytorze
oprogramowania
MonoDevelop
Wypróbuj samodzielnie
Wypróbuj samodzielnie
Uzyskanie dostępu
do komponentów lokalnych
Jak mogłeś zobaczyć wielokrotnie w panelu Inspector, obiekty składają się
z wielu komponentów. Po uruchomieniu sceny interakcja z tymi komponen‐
tami jest możliwa za pomocą skryptów. Komponenty różnią się nieco między
sobą, ale ogólna składnia edycji komponentu jest następująca: nazwa kompo‐
nentu, kropka, a następnie nazwa właściwości, którą chcesz zmienić. Jeśli np.
chcesz zmienić typ w komponencie światła, możesz wydać poniższe polecenie:
light.type = LightType.Directional;
Pokazana składnia powoduje zmianę typu właściwości komponentu światła
na kierunkowe. Zwróć uwagę, że w panelu Inspector nazwa komponentu
światła i typ właściwości zaczynają się od dużej litery, natomiast w kodzie są
zapisywane małą. Pamiętaj, że kiedy próbujesz uzyskać dostęp do określonego
elementu (np. „to światło”), musisz używać małych liter.
Komponent, z którym najczęściej będziesz pracował, to transformacja. Dzięki
edycji właściwości wymienionego komponentu obiekty mogą poruszać się po
scenie. Nie zapominaj, że transformacja obiektu składa się z translacji (poło‐
żenie), rotacji i skali. Wprawdzie można je modyfikować bezpośrednio, ale
znacznie łatwiejszym rozwiązaniem będzie użycie pewnych wbudowanych
opcji: metod Translate() i Rotate() oraz zmiennej localScale.
// Przesunięcie obiektu wzdłuż dodatniej osi x. Zapis ‘0f’ oznacza 0 jako liczbę typu float.
// W ten sposób środowisko Unity odczytuje liczby zmiennoprzecinkowe.
transform.Translate(.05f, 0f, 0f);
Uzyskanie dostępu
do innych obiektów
Wielokrotnie zdarza się, że skrypt powinien mieć możliwość wyszukania
i przeprowadzenia operacji na innych obiektach i komponentach. To jest po
prostu kwestia znalezienia obiektu i wywołania odpowiedniego komponentu.
Mamy do dyspozycji kilka prostych sposobów na wyszukiwanie obiektów, które
nie są lokalne dla skryptu lub obiektu, do jakiego został dołączony skrypt.
Uzyskanie dostępu do innych obiektów 173
Wypróbuj samodzielnie
Transformacja obiektu
Zobaczysz teraz, jak działa przedstawiony wcześniej kod. Zastosujesz go
dla obiektu znajdującego się na scenie.
1. Utwórz nowy projekt lub scenę. Do sceny dodaj sześcian i umieść go
w położeniu (0, –1, 0).
2. Utwórz nowy skrypt o nazwie CubeScript i dołącz go do sześcianu.
Następnie w edytorze MonoDevelop wprowadź do metody Update()
przedstawiony poniżej kod.
transform.Translate(.05f, 0f, 0f);
transform.Rotate(0f, 0f, 1f);
transform.localScale = new Vector3(1.5f, 1.5f, 1.5f);
3. Zapisz skrypt i uruchom scenę. Zwróć uwagę, jak efekty działania
metod Translate() i Rotate() kumulują się, natomiast zmiennej
localScale nie — wartość zmiennej nie rośnie nieustannie.
RYSUNEK 9.3.
Nowa właściwość
Object You Want
w panelu
Inspector
174 Lekcja 9. Skrypty — część 2.
Innym sposobem na wyszukanie obiektu gry jest użycie metody Find(). Aby
wyszukać obiekt w ten sposób, trzeba znać jego nazwę. Wspomniana nazwa
obiektu jest wyświetlana w panelu Hierarchy. Jeżeli przyjmiemy założenie,
że szukany jest obiekt o nazwie Cube, odpowiedni kod może przedstawiać się
następująco.
// Ten wiersz jest tylko w celu zapewnienia punktu odniesienia.
public class SomeClassScript : MonoBehaviour {
RYSUNEK 9.4.
Dodawanie
nowego tagu
RYSUNEK 9.5.
Wybór tagu
Zapewnienie efektywności
W poprzednich przykładach docelowy obiekt gry był przechowywany
w zmiennej klasy (nazywanej często zmienną składową). Kod odpowie-
dzialny za wyszukiwanie obiektu docelowego był umieszczony w metodzie
Start(). Zawsze możesz utworzyć zmienną i odszukać cel w metodzie
Update() lub innej, wybranej wedle potrzeb, ale powinieneś unikać takiego
rozwiązania. Nieustanne wyszukiwanie obiektu jest nieefektywne i może
zmniejszyć wydajność gry. Pamiętaj, że wydajność ma znaczenie. Ciągłe
wykonywanie tych samych zadań jest błędem.
Wypróbuj samodzielnie
void Update() {
target.transform.Translate(.05f, 0f, 0f);
target.transform.Rotate(0f, 0f, 1f);
target.transform.localScale = new Vector3(1.5f, 1.5f, 1.5f);
}
3. Zapisz skrypt i uruchom scenę. Zwróć uwagę, jak sześcian porusza się
po scenie nawet mimo faktu, że skrypt został dołączony do kamery
Main Camera.
Podsumowanie
W tej lekcji zagłębiłeś się w temat skryptów w środowisku Unity. Dowiedziałeś
się, czym są metody oraz poznałeś kilka sposobów ich tworzenia. Następnie
popracowałeś z danymi wejściowymi użytkownika pochodzącymi z klawia‐
tury i myszy. Kolejnym poruszonym tematem była modyfikacja komponentów
obiektu z poziomu kodu. Lekcja została zakończona informacjami, jak za
pomocą skryptów wyszukać i prowadzić interakcję z innymi obiektami gry.
Pytania i odpowiedzi
Pytanie: Jak wiele metod powinienem tworzyć?
Odpowiedź: Metoda powinna być pojedynczą, zwięzłą funkcją. Metod
nie może być zbyt mało, ponieważ wtedy poszczególne metody będą
wykonywać więcej niż tylko jedno zadanie. Z drugiej strony, metoda
nie może być zbyt mała, ponieważ to wypacza cel jej tworzenia.
Jeżeli każdy proces ma swoją metodę, wtedy wszystko jest w porządku.
Warsztaty 177
Warsztaty
Poświęć nieco czasu i odpowiedz na zamieszczone poniżej pytania, a także
upewnij się, że przyswoiłeś sobie materiał omówiony w tej lekcji.
Quiz
1. Metodę można określić także mianem funkcji. Prawda czy fałsz?
2. Nie wszystkie metody mają typ wartości zwrotnej. Prawda czy fałsz?
3. Dlaczego błędem jest mapowanie interakcji użytkownika na
określone przyciski lub klawisze?
4. W części lekcji dotyczącej komponentów lokalnych i docelowych
pojawiło się ćwiczenie w ramce. W ramach wspomnianego ćwiczenia
sześcian był przesuwany wzdłuż dodatniej osi X oraz obracany wokół
osi Z. Skutkiem było poruszanie się sześcianu po dużym okręgu.
Dlaczego?
Odpowiedzi
1. Prawda.
2. Fałsz. Każda metoda ma typ wartości zwrotnej. Jeżeli metoda nie
zwraca żadnej wartości, wtedy typem jej wartości zwrotnej jest void.
3. Gracz będzie musiał poświęcić czas na zmianę mapowania kontrolek
i dopasować je do własnych preferencji. Po zastosowaniu mapowania
na ogólne osie gracz może z łatwością zmienić przyciski mapujące
wspomniane osie.
4. Transformacje są stosowane względem lokalnego układu
współrzędnych — przypomnij sobie to z lekcji 2. Dlatego też sześcian
porusza się wzdłuż dodatniej osi X. Jednak zmianie ulega kierunek
zwrócenia tej osi do kamery.
178 Lekcja 9. Skrypty — część 2.
Ćwiczenie
Dobrym pomysłem jest połączenie materiału przedstawionego w poszcze‐
gólnych lekcjach, aby w bardziej rzeczywisty sposób zobaczyć, jakie interakcje
zachodzą między omawianymi koncepcjami. W tym ćwiczeniu utworzysz
skrypt pozwalający graczowi na kierunkową kontrolę nad obiektem gry.
Rozwiązanie ćwiczenia znajdziesz w materiałach przeznaczonych dla bieżącej
lekcji.
1. Utwórz nowy projekt lub scenę. Do sceny dodaj sześcian i umieść go
w położeniu (0, 0, –5). Ponadto do sceny dodaj światło kierunkowe.
2. Utwórz katalog o nazwie Scripts, a następnie w nim skrypt
CubeControlScript. Kolejnym krokiem jest dołączenie skryptu
do sześcianu.
W skrypcie spróbuj zaimplementować wymienioną poniżej funkcjonalność.
Jeżeli w którymkolwiek momencie napotkasz trudności, zajrzyj do materiałów
przeznaczonych dla bieżącej lekcji.
Kiedy gracz naciśnie klawisz kursora w lewo lub w prawo, sześcian
powinien zostać przesunięty wzdłuż osi X o wartość, odpowiednio,
ujemną lub dodatnią. Z kolei naciśnięcie przez gracza klawisza
kursora w dół lub w górę powinno spowodować przesunięcie
sześcianu wzdłuż osi Y o wartość, odpowiednio, ujemną lub
dodatnią.
Kiedy gracz przesunie mysz wzdłuż osi Y, sześcian powinien zostać
obrócony wokół osi X. Natomiast przesunięcie myszą wzdłuż osi X
powinno spowodować rotację sześcianu wokół osi Y.
Kiedy gracz naciśnie klawisz M, sześcian powinien zostać
powiększony. Z kolei naciśnięcia klawisza N powinno zmniejszyć
sześcian.
Lekcja 10
Kolizje
Bryły sztywne
Aby obiekty mogły wykorzystać zalety wbudowanego w Unity silnika fizycz‐
nego, muszą zawierać komponent o nazwie Rigidbody. Dodanie tego kompo‐
nentu powoduje, że obiekt zachowuje się jak rzeczywista jednostka. W celu
dodania omawianego komponentu należy po prostu zaznaczyć obiekt, a następ‐
nie wybrać opcję Component/Physics/Rigidbody. Jak pokazano na rysunku 10.1,
komponent nowo dodany do obiektu będzie widoczny w panelu Inspector.
RYSUNEK 10.1.
Komponent
Rigidbody
Wypróbuj samodzielnie
Kolizje
Skoro wiesz, jak poruszać obiektami, najwyższy czas zdefiniować możliwość
kolizji z innymi obiektami. Aby obiekt mógł wykrywać kolizje, musi mieć dodany
komponent o nazwie Collider. Komponent ten definiuje granicę obiektu i może
wykryć jej przekroczenie przez inny obiekt.
Komponent Collider
Obiekty geometryczne, takie jak kula, kapsuła i sześcian, mają w trakcie two‐
rzenia dodawany komponent Collider. Jeżeli obiekt nie posiada wymienionego
komponentu, zawsze można go dodać, wybierając opcję Component/Physics,
a następnie odpowiedni komponent Collider zależny od kształtu obiektu. Na
rysunku 10.2 pokazano komponenty Collider dostępne dla różnych kształtów
obiektów.
RYSUNEK 10.2.
Dostępne
komponenty
Collider
Wypróbuj samodzielnie
Materiały fizyczne
Dla komponentów Collider można zastosować materiały fizyczne i tym samym
nadać obiektowi różne właściwości fizyczne. Przykładowo materiał w postaci
gumy może umożliwić obiektowi odbijanie się, natomiast materiał w postaci
lodu spowoduje, że obiekt stanie się śliski. Istnieje również możliwość two‐
rzenia własnych, specyficznych materiałów.
Aby zaimportować materiały standardowo dostarczane z środowiskiem Unity,
wybierz opcję Assets/Import Package/Physic Materials. W oknie dialogowym
importu pozostaw zaznaczone wszystkie opcje i kliknij przycisk Import. W ten
sposób w projekcie pojawi się katalog Standard Assets zawierający materiały
Wyzwalacze 185
RYSUNEK 10.3.
Właściwości
materiału
fizycznego
Wyzwalacze
Dotychczas miałeś okazję poznać komponenty Collider oparte na fizyce, czyli
reagujące na położenie i obrót obiektu zgodnie z założeniami wbudowanego
w Unity silnika fizycznego. Jeżeli powrócisz do lekcji 7., w której tworzyliśmy
grę Amazing Racer, prawdopodobnie przypomnisz sobie użycie innego typu
komponentu Collider. Czy pamiętasz, w jaki sposób gra wykrywała wejście
gracza do niebezpiecznej wody lub strefy zakończenia gry? Użyliśmy wów‐
czas komponentu Collider opartego na wyzwalaczu. Wyzwalacz wykrywa
kolizję dokładnie tak samo jak zwykły komponent Collider, ale nie podejmuje
wtedy żadnych szczególnych działań. Zamiast tego wywołuje trzy charakte‐
rystyczne metody pozwalające programiście na obsługę danego zderzenia.
Oto one.
void OnTriggerEnter(Collider other) // Wywoływana, gdy obiekt wchodzi
// do wyzwalacza.
void OnTriggerStay(Collider other) // Wywoływana, gdy obiekt pozostaje
// w wyzwalaczu.
void OnTriggerExit(Collider other) // Wywoływana, gdy obiekt opuszcza
// wyzwalacz.
Za pomocą trzech wymienionych metod można zdefiniować, co się stanie,
gdy obiekt wchodzi do komponentu Collider, pozostaje w nim lub go opuszcza.
Jeśli np. po przekroczeniu krawędzi sześcianu w oknie konsoli ma zostać
wyświetlony komunikat, do sześcianu należy dodać wyzwalacz. Następnie do
sześcianu trzeba dodać skrypt zawierający poniższy kod.
186 Lekcja 10. Kolizje
Raycasting
Raycasing to proces wysłania wyimaginowanej linii (promienia światła)
i sprawdzenia, dokąd dotrze. Wyobraź sobie np. patrzenie przez teleskop. Twoja
linia wzroku jest promieniem, a to, co możesz zobaczyć na końcu, to miejsce,
do którego dociera promień. Twórcy gier wykorzystują raycasting praktycznie
nieustannie do zadań, takich jak celowanie, określanie linii wzroku, określanie
odległości itd. Unity oferuje wiele metod obsługi raycastingu. Dwie najczęściej
stosowane zostaną tutaj opisane. Pierwsza metoda obsługi raycastingu przed‐
stawia się następująco:
bool Raycast(Vector3 origin, Vector3 direction, float distance,
LayerMask mask) ;
Jak widzisz, metoda pobiera całkiem sporo parametrów. Zwróć także uwagę
na użycie zmiennej typu Vector3. Zmienna typu Vector3 pozwala na prze‐
chowywanie trzech wartości float. Stanowi więc doskonały sposób podania
współrzędnych X, Y i Z bez konieczności użycia trzech oddzielnych parametrów.
Parametr origin określa punkt początkowy promienia. Parametr direction
wskazuje kierunek poruszania promienia. Parametr distance określa, jak
daleko promień będzie się poruszał. Ostatni parametr mask wskazuje war‐
stwę, do której ma dotrzeć promień. Istnieje możliwość pominięcia parame‐
trów distance i mask. Jeżeli się na to zdecydujesz, promień będzie poruszał
się w nieskończoność i trafiał w obiekty wszystkich typów.
Jak wcześniej wspomniano, mamy wiele zastosowań dla promieni. Jeśli np.
chcesz ustalić, czy coś znajduje się przed kamerą, możesz do niej dołączyć
skrypt zawierający następujący kod.
188 Lekcja 10. Kolizje
Wypróbuj samodzielnie
Praca z wyzwalaczami
W tym ćwiczeniu będziesz miał możliwość przygotowania interaktywnej
sceny wraz z funkcjonującym wyzwalaczem. Pełny projekt zawierający to
ćwiczenie nosi nazwę Hour10_TriggerExercise i znajdziesz go w materiałach
przeznaczonych dla bieżącej lekcji.
1. Utwórz nowy projekt lub scenę. Do sceny dodaj światło kierunkowe.
Następnie dodaj sześcian i kulę. Sześcian umieść w położeniu (–1, 1, –5),
natomiast kulę w położeniu (1, 1, –5).
2. Utwórz dwa skrypty o nazwach TriggerScript i MovementScript. Pierwszy
z wymienionych dołącz do sześcianu, natomiast drugi — do kuli.
3. W komponencie Collider dla sześcianu zaznacz pole wyboru Is Trigger.
Do kuli dodaj komponent Rigidbody, a następnie usuń zaznaczenie
opcji Use Gravity.
4. W metodzie Update() skryptu MovementScript umieść przedstawiony
poniżej kod.
float mX = Input.GetAxis("Mouse X") / 10;
float mY = Input.GetAxis("Mouse Y") / 10;
transform.Translate(mX, mY, 0);
5. W skrypcie TriggerScript umieść przedstawiony poniżej kod. Upewnij
się, że dodajesz go do klasy, ale nie wewnątrz jakiejkolwiek istniejącej
metody.
void OnTriggerEnter(Collider other)
{
print(other.gameObject.name + " wszedł do sześcianu.");
}
void OnTriggerStay(Collider other)
{
print(other.gameObject.name + " nadal pozostaje
w sześcianie.");
}
void OnTriggerExit(Collider other)
{
print(other.gameObject.name + " opuścił sześcian.");
}
6. Uruchom scenę. Zwróć uwagę, jak myszą można poruszać kulę.
Doprowadź do zderzenia kuli z sześcianem i obserwuj komunikaty
wyświetlane w oknie konsoli. Zauważ, że wprawdzie oba obiekty
fizycznie nie stykają się, ale nadal między nimi zachodzi interakcja.
void Update() {
// Wyrzucenie promienia od położenia kamery w kierunku do przodu.
if (Physics.Raycast(transform.position, transform.forward, 10))
print("Przed kamerą coś się znajduje!");
}
Podsumowanie 189
Podsumowanie
W tej lekcji dowiedziałeś się wiele o interakcjach między obiektami, czyli
zderzeniach. Na początku poznałeś podstawy oferowanych przez środowisko
Unity możliwości w zakresie fizyki i komponent Rigidbody. Następnie prze‐
szedłeś do różnego rodzaju komponentów Collider i kolizji między obiektami.
Później zająłeś się wyzwalaczami i dowiedziałeś się, że kolizja to nieco więcej
niż tylko podskakiwanie obiektów. Na końcu został poruszony temat wyszu‐
kiwania obiektów za pomocą raycastingu.
Pytania i odpowiedzi
Pytanie: Czy do wszystkich obiektów powinienem dodawać komponent
Rigidbody?
Odpowiedź: Rigidbody to użyteczny komponent przeznaczony do obsługi
funkcji fizycznych. Dlatego też dodawanie go do każdego obiektu może
spowodować występowanie dziwnych efektów ubocznych oraz zmniejszyć
wydajność. Dobrą zasadą jest dodawanie komponentów tylko wtedy,
gdy są niezbędne, a nie na wyrost.
Pytanie: Istnieje wiele rodzajów komponentów Collider, o których nie
wspomniano w tekście. Dlaczego?
Odpowiedź: Większość komponentów Collider działa w dokładnie taki sam
sposób jak omówione w lekcji lub w sposób wykraczający poza temat
lekcji, dlatego też zostały pominięte. W tej książce znajdziesz wszystkie
informacje, jakie są potrzebne do tworzenia gier zapewniających dobrą
zabawę.
190 Lekcja 10. Kolizje
Wypróbuj samodzielnie
Warsztaty
Poświęć nieco czasu i odpowiedz na zamieszczone poniżej pytania, a także
upewnij się, że przyswoiłeś sobie materiał omówiony w tej lekcji.
Ćwiczenie 191
Quiz
1. Jaki komponent jest wymagany dla obiektu, jeśli obiekt ma obsługiwać
pewne właściwości fizyczne, takie jak spadanie?
2. Do obiektu może być dodany tylko jeden komponent Collider. Prawda
czy fałsz?
3. Aby wyzwalacz działał, obiekt wyzwalacza również musi mieć dodany
komponent Collider. Prawda czy fałsz?
4. Do jakich zadań przydaje się raycasting w Unity?
Odpowiedzi
1. To komponent Rigidbody.
2. Fałsz. Obiekt może mieć dodanych wiele różnych komponentów
Collider.
3. Fałsz. Aby wyzwalacz zadziałał, obiekt musi mieć dodany komponent
Rigidbody.
4. Do ustalenia, co obiekt może „zobaczyć”, do wyszukiwania obiektów,
a także do określania odległości między obiektami.
Ćwiczenie
W tym ćwiczeniu utworzysz interaktywną aplikację wykorzystującą ruch
i wyzwalacze. Ćwiczenie wymaga kreatywnego znalezienia rozwiązania, ponie‐
waż nie jest ono tutaj przedstawione. Jeżeli napotkasz problemy, pełny projekt
zawierający to ćwiczenie (Hour10_Exercise) znajdziesz w materiałach przezna‐
czonych dla bieżącej lekcji.
1. Utwórz nowy projekt lub scenę. Do sceny dodaj światło kierunkowe
oraz sześcian, który musisz umieścić w położeniu (–1.5, 0, –5).
Przeskaluj sześcian (0.1, 2, 2) i nadaj mu nazwę LTrigger.
2. Powiel sześcian (w panelu Hierarchy prawym przyciskiem myszy
kliknij sześcian, a następnie wybierz opcję Duplicate). Kopii sześcianu
nadaj nazwę RTrigger i umieść ją w położeniu (1.5, 0, –5).
3. Do sceny dodaj kulę i umieść ją w położeniu (0, 0, –5). Do kuli dodaj
komponent Rigidbody i usuń zaznaczenie przy właściwości Use Gravity.
4. Utwórz skrypt o nazwie TriggerScript i dołącz go do obu sześcianów.
Następnie utwórz skrypt MotionScript i dołącz go do kuli.
Teraz najzabawniejsza część zadania. W aplikacji zaimplementuj wymienioną
poniżej funkcjonalność.
Gracz powinien mieć możliwość przesuwania kuli za pomocą
klawiszy kursora.
192 Lekcja 10. Kolizje
Ukończony projekt
Aby ukończyć projekt gry, musisz wykonać kolejne kroki
zaprezentowane w lekcji. Jeżeli napotkasz problemy, ukoń-
czoną wersję gry znajdziesz w materiałach przeznaczonych
dla bieżącej lekcji. Przejrzyj te materiały, jeśli szukasz inspiracji!
194 Lekcja 11. Druga gra — Chaos Ball
Faza projektowania
Elementy fazy projektowania zostały omówione w lekcji 7., w której powstała
pierwsza gra, zatytułowana Amazing Racer. Teraz od razu przystąpisz do ich
zdefiniowania.
Koncepcja
Budowana w tej lekcji gra przypomina nieco gry zatytułowane Pinball i Breakout.
Gracz będzie znajdował się na arenie. Każdy z czterech narożników areny
jest w innym kolorze, a po arenie poruszają się cztery kule o kolorach odpo‐
wiadających zastosowanym w rogach. Na arenie, poza czterema kolorowymi
kulami, znajduje się też kilka innych białych kul nazywanych chaos ball. Zada‐
niem białych kul jest tylko przeszkadzanie graczowi i sprawienie, aby gra stała
się wymagająca. Białe kule są mniejsze od czterech kolorowych i poruszają się
szybciej. Gracz dysponuje płaską paletką, którą będzie próbował umieścić
kolorowe kule we właściwych narożnikach.
Reguły
Reguły określają sposób prowadzenia gry, a ponadto mają wpływ na pewne
właściwości obiektów. Poniżej wymieniono reguły dla gry Chaos Ball.
Gracz wygrywa, gdy wszystkie cztery kolorowe kule znajdą się
w odpowiednich rogach. Nie ma warunku określającego przegraną.
Uderzenie właściwego narożnika powoduje, że kula zostaje
zatrzymana.
Wszystkie obiekty w grze mają doskonałe właściwości odbijania się
(przy zderzeniu nie tracą impetu).
Żadna kula nie może opuścić areny.
Szybkość kul zarówno kolorowych, jak i białych jest wybierana losowo.
Wymagania
Wymagania dla tworzonej gry są proste. To nie będzie gra z rozbudowaną
grafiką, natomiast zdecydowanie oparta na skryptach i interakcjach. Wyma‐
gania dla gry Chaos Ball przedstawiają się następująco.
Fragment ogrodzonego murem terenu, który będzie służył
w charakterze areny.
Na teren i obiekty gry będą nałożone tekstury dostarczane
standardowo z środowiskiem Unity.
Kilka kul zarówno kolorowych, jak i białych. Wspomniane kule zostaną
wygenerowane w Unity.
Arena 195
Arena
Pierwszym krokiem jest utworzenie areny, na której będzie toczyła się akcja
gry. W tym miejscu użyto pojęcia arena, aby wskazać, że teren jest całkiem
mały i otoczony murem. Ani gracz, ani żadna z kul nie powinny opuszczać
areny. Jak widać na rysunku 11.1, arena jest dość prosta.
RYSUNEK 11.1.
Arena
dla tworzonej gry
Utworzenie areny
Jak wcześniej wspomniano, utworzenie areny będzie prostym procesem, co
wynika z jej konstrukcji. Aby przygotować arenę, wykonaj wymienione poniżej
kroki.
1. Utwórz nowy projekt i nadaj mu nazwę ChaosBall. Tym razem w oknie
dialogowym Create New Project zaznacz pola wyboru Character
Controler.unityPackage i Terrain Assets.unityPackage (patrz rysunek 11.2).
Następnie do projektu dodaj teren.
2. Wymiary terenu to 50 na 50 (pamiętaj, aby użyć sekcji Resolution
w ustawieniach terenu wyświetlanych w panelu Inspector). Do sceny
dodaj światło kierunkowe i usuń obiekt Main Camera.
196 Lekcja 11. Druga gra — Chaos Ball
RYSUNEK 11.2.
Okno dialogowe
Create New Project
Konsolidacja obiektów
Być może zastanawiasz się, dlaczego utworzyłeś mur tylko dla jednej strony,
choć powinieneś dla wszystkich. Idea polega na tym, aby uniknąć zbędnego
powielania żmudnej pracy. Bardzo często zdarza się, że jeśli kilka wyma-
ganych obiektów przedstawia się podobnie, wystarczy utworzyć jeden
i kilkakrotnie go powielić. W omawianym przykładzie przygotujesz poje-
dynczą ścianę muru wraz z wymaganymi materiałami i właściwościami,
a następnie po prostu trzykrotnie ją skopiujesz. Takie samo rozwiązanie
zostanie użyte dla narożników, kul białych i kolorowych. W ten sposób
powinieneś się przekonać, jak odrobina planowania może pozwolić na
zaoszczędzenie dużej ilości czasu.
Teksturowanie
Na obecnym etapie prac arena prezentuje się nędznie i nijako. Wszystko jest
w kolorze białym, a otaczający ją mur składa się z tylko jednej ściany. Kolej‐
nym krokiem jest więc dodanie pewnych tekstur i ożywienie areny. Potrze‐
bujesz przede wszystkim tekstur dla dwóch obiektów: podłoża i muru. Podczas
wykonywania tego kroku możesz śmiało poeksperymentować z teksturowa‐
niem, być może uzyskasz niezwykle interesujące efekty!
1. Za pomocą panelu Project w katalogu Assets utwórz nowy podkatalog
o nazwie Materials. Do katalogu dodaj nowy materiał (prawym
przyciskiem myszy kliknij katalog Materials, a następnie wybierz opcję
Create/Material). Nowemu materiałowi nadaj nazwę WallMaterial.
2. Jak pokazano na rysunku 11.3, właściwości Tilling wzdłuż osi X ustaw
wartość 10.
Arena 197
RYSUNEK 11.3.
Dodanie tekstury
do definiowanego
materiału
Materiał zapewniający
rewelacyjne odbijanie się obiektu
Dążymy do tego, aby obiekty odbijały się od ścian muru bez utraty pędu. Dla‐
tego też konieczne jest przygotowanie materiału zapewniającego rewelacyjne
odbijanie się obiektu. Jak pewnie sobie przypominasz, Unity oferuje pewien
zestaw materiałów fizycznych. Jednak znajdujący się wśród nich materiał
odbijania okazuje się niewystarczająco dobry do naszych potrzeb. Trzeba więc
utworzyć nowy materiał, wykonując wymienione poniżej kroki.
198 Lekcja 11. Druga gra — Chaos Ball
RYSUNEK 11.4.
Dodanie tekstury
do terenu
RYSUNEK 11.5.
Ustawienia materiału
SuperBouncyMaterial
Elementy gry
W tej części lekcji utworzysz różne obiekty gry, które będą niezbędne do
prowadzenia rozgrywki. Podobnie jak w przypadku muru otaczającego arenę,
najłatwiej zbudować jeden obiekt, a następnie powielać go wedle potrzeb.
Gracz
Gracz w tej grze będzie zmodyfikowanym kontrolerem postaci First Person.
Podczas tworzenia projektu należy zaznaczyć opcję importu pakietu kon‐
trolera postaci. Kliknij kontroler postaci First Person, przeciągnij go na scenę,
a następnie umieść w położeniu (46, 1, 4) i zastosuj rotację (0, 315, 0).
Przede wszystkim trzeba przesunąć kamerę w górę i odsunąć od kontrolera.
W ten sposób gracz będzie miał lepsze pole widzenia podczas gry. Wykonaj
zatem wymienione poniżej kroki.
1. W panelu Inspector rozwiń kontroler First Person (kliknij strzałkę
wyświetlaną obok jego nazwy) i odszukaj Main Camera. Nie będziesz
mieć wątpliwości, że znalazłeś właściwą, ponieważ jest oznaczona
kolorem niebieskim.
2. Po zaznaczeniu kamery kontrolera umieść ją w położeniu (0, 5, ‐3.5)
i zastosuj rotację (43, 0, 0). Kamera powinna być teraz z tyłu ponad
kontrolerem i nieco obrócona w dół.
Kolejnym zadaniem jest dodanie paletki do sceny. Paletka to płaska powierzch‐
nia używana przez gracza do odbijania kul. W celu dodania paletki wykonaj
poniższe kroki.
1. Dodaj sześcian do sceny, zmień jego nazwę na Bumper i przeskaluj
(3.5, 3, 1).
2. Kliknij utworzony wcześniej materiał fizyczny i przeciągnij na paletkę.
200 Lekcja 11. Druga gra — Chaos Ball
RYSUNEK 11.6.
Ustawienia
materiału
ChaosBallMaterial
RYSUNEK 11.7.
Wybór tagu
Chaos
W tym momencie kula jest ukończona, ale jeszcze nic się nie dzieje. Konieczne
jest opracowanie skryptu pozwalającego na przesuwanie kuli po całej arenie.
Utworzymy skrypt o nazwie VelocityScript i dołączymy go do kuli chaos ball.
Pełny kod skryptu przedstawiono w listingu 11.1.
Kolorowe kule
Wprawdzie kula chaos ball jest żółta i to niewątpliwie kolor, ale określenie
kolorowe kule dotyczy niezbędnych do wygrania czterech kul w różnych kolo‐
rach: czerwonym, pomarańczowym, niebieskim i zielonym. Podobnie jak
w przypadku chaos ball, można przygotować tylko jedną kulę, a następnie
powielić ją, tym samym ułatwiając sobie pracę.
Aby utworzyć pierwszą kulę, wykonaj wymienione poniżej kroki.
1. Dodaj kulę do sceny. Zmień jej nazwę na Blue i umieść ją w pobliżu
środka areny. Upewnij się tylko, że wartość jej położenia dla osi Y
wynosi 2.
2. Utwórz nowy materiał o nazwie BlueMaterial i ustaw mu kolor niebieski,
dokładnie w ten sam sposób, jak to zrobiłeś dla kuli chaos ball (patrz
rysunek 11.6). Następnie utwórz materiały RedMaterial, GreenMaterial
oraz OrangeMaterial i ustaw im odpowiednie kolory (czerwony, zielony
i pomarańczowy). Kliknij materiał BlueMaterial i przeciągnij na kulę.
3. Kliknij materiał SuperBouncyMaterial i przeciągnij go na kulę.
4. Do kuli dodaj komponent Rigidbody. Właściwości Angular Drag ustaw
wartość 0 i usuń zaznaczenie przy Use Gravity. We właściwości
Constraints zamroź położenie Y.
5. Podczas pracy nad kulą chaos ball utworzyłeś tag o nazwie Blue. Teraz
zmień tag kuli na wspomniany Blue. Procedura zmiany jest taka sama
jak w przypadku chaos ball (patrz rysunek 11.7).
6. Do kuli dołącz skrypt VelocityScript. W panelu Inspector odszukaj
komponent Velocity Script (Script) i zmień wartość jego właściwości
Max na 25 (patrz rysunek 11.8). Ta zmiana spowoduje, że kolorowa
kula będzie na początku poruszała się znacznie wolniej niż chaos ball.
RYSUNEK 11.8.
Zmiana
właściwości Max
Obiekty kontrolne 203
Obiekty kontrolne
Po przygotowaniu wszystkich niezbędnych elementów możemy przystąpić do
gamifikacji. Tym razem zamienimy je w dostarczającą rozrywki grę. W tym
celu konieczne jest utworzenie czterech narożników, skryptów oraz kontrolera
gry. Dopiero wtedy będziemy mieli gotową grę.
Cele
Każdy z czterech narożników jest w kolorze odpowiadającym jednej z kolo‐
rowych kul. Gdy kula znajdzie się w danym narożniku, wtedy gra sprawdzi
wartość przypisanego jej tagu. Gdy wartości tagu i kolor narożnika są takie
same, wtedy mamy dopasowanie. Po znalezieniu dopasowania dla kuli zosta‐
nie włączona właściwość Kinematic (jak pamiętasz, powoduje unierucho‐
mienie obiektu), a cel zostanie uznany za osiągnięty. Podobnie jak w przypadku
obiektów kul, także teraz można utworzyć jeden cel, a następnie powielić go
wymaganą ilość razy.
Aby utworzyć pierwszy cel, wykonaj wymienione poniżej kroki.
1. Utwórz pusty obiekt gry (wybierz opcję GameObject/Create Empty),
zmień mu nazwę na BlueGoal, przypisz tag o nazwie Blue i następnie
umieść obiekt w położeniu (1.6, 2, 1.6).
2. Do obiektu dodaj komponent Box Collider i ustaw jego właściwość
Is Trigger. Wielkość dodanego komponentu zmień na (1.5, 1.5, 1.5).
3. Dodaj światło do obiektu (wybierz opcję Component/Rendering/Light).
Światło powinno być punktowe, w kolorze odpowiadającym
oczekiwanemu przez dany narożnik kolorowi kuli (patrz rysunek 11.9).
Intensywność światła ustaw na 3.
204 Lekcja 11. Druga gra — Chaos Ball
RYSUNEK 11.9.
Zdefiniowany
narożnik
w kolorze
niebieskim
Zmienna prywatna
Jak zapewne zauważyłeś, skrypt GoalScript zawiera zmienną prywatną
o nazwie solved i metodę publiczną IsSolved(). Wartością zwrotną
metody jest zmienna. Być może zastanawiasz się, dlaczego wykonano
dodatkową pracę, aby zmienna była publiczna. Ma to na celu uniemoż-
liwienie wszelkim innym obiektom lub skryptom przypadkowego ozna-
czenia celu jako osiągniętego. Ponieważ żaden inny element nie może
uzyskać dostępu do zmiennej solved poza samym obiektem celu, nie ma
niebezpieczeństwa przypadkowej zmiany wartości wymienionej zmiennej.
Z kolei metoda IsSolved() istnieje jedynie po to, aby poinformować
obiekt kontrolny gry o osiągnięciu danego celu.
Kontroler gry
Ostatni element niezbędny do zakończenia budowy gry to kontroler gry. Kon‐
troler będzie odpowiedzialny za sprawdzanie wszystkich celów w każdej klatce
i określanie, kiedy zostaną osiągnięte. Dla gry tworzonej w tej lekcji kontroler
jest bardzo prosty. W celu jego utworzenia wykonaj wymienione poniżej kroki.
1. Do sceny dodaj pusty obiekt gry. Przenieś go w dowolne miejsce i zmień
nazwę na GameControler.
2. Utwórz skrypt o nazwie GameControlScript i umieść w nim kod
przedstawiony w listingu 11.3. Gotowy skrypt dołącz do kontrolera gry.
206 Lekcja 11. Druga gra — Chaos Ball
void OnGUI()
{
if(isGameOver)
{
GUI.Box(new Rect(Screen.width / 2 - 100,
Screen.height / 2 - 50, 200, 75), "Koniec gry");
GUI.Label(new Rect(Screen.width / 2 - 30,
Screen.height / 2 - 25, 60, 50), "Dobra
robota!");
}
}
}
RYSUNEK 11.10.
Dodanie celów
do kontrolera gry
Usprawnienie gry
Wprawdzie ukończyłeś pracę nad grą Chaos Ball, ale niewątpliwie nie jest
ona doskonała. Wiele pominiętych funkcji mogłoby znacznie poprawić gry‐
walność. Wspomniane funkcje zostały pominięte, aby umożliwić Ci ekspe‐
rymenty z grą i wprowadzanie w niej usprawnień. Można więc stwierdzić, że
Chaos Ball to jedynie ukończony prototyp. Jest to działająca wersja gry, choć
wymagająca wykończenia. Dlatego też zachęcam do ponownej lektury roz‐
działu i wyszukania aspektów gry, które można poprawić. Najlepiej postaw
się w roli gracza i spróbuj odpowiedzieć na poniższe pytania.
Czy gra jest zbyt łatwa, czy może zbyt trudna?
Co może ułatwić lub utrudnić rozgrywkę?
Co może spowodować, że gra zachwyci graczy?
Które fragmenty gry są zabawne, a które nużące?
W przedstawionym na końcu rozdziału ćwiczeniu będziesz miał możliwość
poprawienia gry i dodania do niej nowych funkcji. Jeżeli otrzymasz jakikolwiek
błąd, oznacza to, że prawdopodobnie pominąłeś któryś z kroków. Upewnij się,
że dokładnie sprawdziłeś wszystko, co powinno pomóc w rozwiązaniu ewen‐
tualnych błędów.
208 Lekcja 11. Druga gra — Chaos Ball
Podsumowanie
W tej lekcji opracowałeś grę zatytułowaną Chaos Ball. Na początek wykonałeś
fazę projektowania. Określiłeś koncepcję, reguły i wymagania. Następnie
przystąpiłeś do tworzenia areny. Przy tej okazji dowiedziałeś się, że można
utworzyć jeden obiekt, a następnie wielokrotnie powielać go, w ten sposób
oszczędzając czas. Później przeszedłeś do tworzenia gracza, kul chaos ball
i kolorowych, (narożników) celów, a także kontrolera gry. Na końcu zyskałeś
możliwość zagrania w grę oraz wyszukania aspektów wartych usprawnienia.
Pytania i odpowiedzi
Pytanie: Dlaczego do wykrywania kolizji kul wykorzystujemy wartość
Continuous właściwości Collision Detection? Byłem przekonany,
że jej użycie powoduje spadek wydajności gry.
Odpowiedź: Nieustanne wykrywanie zderzeń faktycznie może zmniejszyć
wydajność gry. W omawianej grze jest jednak niezbędne. Ponieważ
kula chaos ball jest mała i bardzo szybka, istnieje więc niebezpieczeństwo,
że czasami mogłaby „przejść” przez ściany.
Pytanie: Osiągnięcie celu jest określane na podstawie wartości tagu kuli.
Czy ten sam cel można uzyskać na podstawie jedynie nazwy kuli?
Odpowiedź: Oczywiście! W omawianej grze tagi zostały użyte, by uprościć
aplikację. Dzięki zastosowaniu tagów i edytorów skrypty mogły
pozostać uogólnione. W ten sposób skrypt jest utworzony tylko raz,
a wykorzystywany aż czterokrotnie.
Warsztaty
Poświęć nieco czasu i odpowiedz na zamieszczone poniżej pytania, a także
upewnij się, że przyswoiłeś sobie materiał omówiony w tej lekcji.
Quiz
1. W grze został użyty dostępny w środowisku Unity materiał fizyczny
zapewniający odbijanie się obiektu. Prawda czy fałsz?
2. Jak gracz może przegrać w utworzonej tutaj grze?
3. Które osie pozycji obiektów kul zostały zamrożone?
4. Osiągnięcie celu jest sprawdzane w metodzie OnTriggerEnter().
W wymienionej metodzie sprawdzamy, czy obiekt jest oczekiwaną
kulą. Prawda czy fałsz?
5. Dlaczego w grze pominięto pewne podstawowe funkcje?
Ćwiczenie 209
Odpowiedzi
1. Fałsz. Na potrzeby gry utworzyliśmy nowy materiał fizyczny
zapewniający wręcz rewelacyjne odbijanie się obiektów.
2. To jest podchwytliwe pytanie. Gracz nie może przegrać.
3. To jest oś Y.
4. Prawda.
5. Aby dać czytelnikowi szansę na ich implementację.
Ćwiczenie
W procesie tworzenia gier najlepsze jest to, że można je kreować wedle wła‐
snego upodobania. Kierowanie się wskazówkami jest przydatne podczas nauki,
ale w ten sposób nie osiągniesz satysfakcji, takiej jak z samodzielnego utwo‐
rzenia własnej gry. W przedstawionym tutaj ćwiczeniu zyskujesz możliwość
zmodyfikowania gry, aby stała się nieco bardziej unikalna. Dokładny sposób
modyfikacji zależy tylko od Ciebie. Poniżej wymieniono jedynie kilka sugestii.
Spróbuj dodać przycisk pozwalający graczowi na ponowne
rozpoczęcie gry po jej zakończeniu. (Elementy graficznego interfejsu
użytkownika nie zostały jeszcze omówione, ale ta funkcja istnieje
w ostatnio utworzonej grze. Przekonaj się, czy potrafisz dodać
wspomniany przycisk).
Spróbuj dodać licznik, aby gracz wiedział, ile czasu potrzebował
na zakończenie gry.
Spróbuj dodać większe zróżnicowanie dla kuli chaos ball.
Spróbuj dodać kolejny cel, który wymaga wszystkich kul chaos ball.
Spróbuj zmienić wielkość lub kształt paletki gracza. Spróbuj
utworzyć paletkę w wielu różnych kształtach.
210 Lekcja 11. Druga gra — Chaos Ball
Lekcja 12
Prefabrykaty
Podstawy prefabrykatów
Jak wcześniej wspomniano, prefabrykat jest specjalnego typu zasobem skła‐
dającym się z obiektów gry. W przeciwieństwie do prostego zagnieżdżania
obiektów w panelu Hierarchy, prefabrykaty są wyświetlane w panelu Project
i mogą być wielokrotnie używane w różnych scenach. W ten sposób zysku‐
jesz możliwość tworzenia skomplikowanych obiektów, np. wroga, a następnie
zbudowania armii na jego podstawie. Prefabrykaty można również budować
w kodzie. Dzięki temu w trakcie działania gry można wygenerować niemalże
nieskończoną liczbę obiektów. Warto w tym miejscu dodać, że dowolny
obiekt gry lub kolekcja obiektów gry mogą się znaleźć w prefabrykacie. Możli‐
wości są niemal nieograniczone!
Kwestie do przemyślenia
Jeżeli masz trudności ze zrozumieniem wagi prefabrykatów, rozważ nastę-
pującą sytuację. W poprzedniej lekcji opracowaliśmy grę zatytułowaną
Chaos Ball. Podczas tworzenia gry przygotowaliśmy jedną kulę typu chaos
ball, a następnie czterokrotnie ją powieliliśmy. Co zrobić, jeśli potrzebujemy
więcej kul chaos ball tworzonych w trakcie działania gry? Nie możemy ich
wówczas zbudować, a już na pewno nie bez użycia prefabrykatów. A co
zrobić w sytuacji, gdy w grze wykorzystywany jest wróg w postaci orka?
Ponownie można przygotować pojedynczy obiekt wroga, a następnie
wielokrotnie go powielić. Co czynić w sytuacji, gdy ork ma się pojawić
w innej scenie? Wówczas trzeba ponownie odtworzyć orka w nowej scenie.
Jeśli jednak ork będzie prefabrykatem, wtedy stanowi część projektu i może
być stosowany w dowolnej liczbie scen. Prefabrykaty to bardzo ważny
aspekt tworzenia gier w środowisku Unity.
Struktura prefabrykatu
Niezależnie od tego, czy o tym wiedziałeś, czy nie, miałeś już okazję pracować
z prefabrykatami. Oferowany przez Unity kontroler postaci jest prefabrykatem.
W celu utworzenia obiektu prefabrykatu na scenie trzeba jedynie go kliknąć
i przeciągnąć na odpowiednie miejsce w panelach Scene lub Hierarchy (patrz
rysunek 12.1).
RYSUNEK 12.1.
Dodanie
egzemplarza
prefabrykatu
do sceny
RYSUNEK 12.2.
W panelu
Hierarchy
egzemplarze
prefabrykatów
są wyświetlane
w kolorze
niebieskim
RYSUNEK 12.3.
Wyświetlenie
zawartości
prefabrykatu
w panelu Project
Praca z prefabrykatami
Wykorzystanie wbudowanych w Unity prefabrykatów jest użyteczną możli‐
wością, ale często trzeba przygotować własne. Utworzenie prefabrykatu to
proces składający się z dwóch kroków. Pierwszy to zbudowanie zasobu pre‐
fabrykatu. Drugim krokiem jest wypełnienie zasobu pewną zawartością.
Tworzenie prefabrykatu jest naprawdę łatwe. Podobnie jak w przypadku
wszelkich innych zasobów, na początku za pomocą panelu Project w katalogu
Assets utwórz podkatalog przeznaczony dla prefabrykatu. Następnie prawym
przyciskiem myszy kliknij nowy katalog i wybierz opcję Create/Prefab (patrz
rysunek 12.4). W katalogu pojawi się nowy prefabrykat, któremu można
nadać dowolną nazwę. Ponieważ prefabrykat jest pusty, pojawia się jako pusty
biały sześcian.
Praca z prefabrykatami 215
RYSUNEK 12.4.
Tworzenie
nowego
prefabrykatu
Wypróbuj samodzielnie
Tworzenie prefabrykatu
Zbudujesz teraz zasób prefabrykatu i umieścisz w nim skomplikowany
obiekt gry. Przygotowany tutaj zasób prefabrykatu wykorzystasz później
w tej lekcji, a więc nie usuwaj go.
1. Utwórz nowy projekt lub scenę. Do sceny dodaj sześcian i kulę.
2. Sześcian umieść w położeniu (0, 0, 0) i przeskaluj (0.5, 0.2, 0.5).
Następnie do sześcianu dodaj komponent Rigidbody. Kulę umieść
w położeniu (0, 1.2, 0) i przeskaluj (0.5, 0.5, 0.5). Do kuli dodaj
komponent światła punktowego.
3. W panelu Hierarchy kliknij kulę i przeciągnij na sześcian. W ten sposób
kula zostanie zagnieżdżona w sześcianie (patrz rysunek 12.5).
Dodanie do sceny
egzemplarza prefabrykatu
Zasób prefabrykatu po utworzeniu można wielokrotnie dodawać do sceny
lub do dowolnej liczby scen w projekcie. Aby egzemplarz prefabrykatu dodać
do sceny, trzeba jedynie kliknąć prefabrykat w panelu Project, a następnie
przeciągnąć w odpowiednie miejsce w panelu Scene. Poszczególne egzem‐
plarze można bardzo łatwo umieszczać na innych obiektach. W ten sposób
pozycjonowanie nowych egzemplarzy staje się niezwykle proste.
Praca z prefabrykatami 217
Wypróbuj samodzielnie
Dziedziczenie
Pojęcie dziedziczenia używane w kontekście prefabrykatów oznacza połącze‐
nie egzemplarzy prefabrykatu z rzeczywistym zasobem prefabrykatu. Jeżeli
więc zmienisz zasób prefabrykatu, automatycznie zmienione zostaną również
wszystkie obiekty prefabrykatu. To jest niezwykle użyteczna cecha. Bardzo
często zdarza się następująca sytuacja: po umieszczeniu ogromnej liczby
obiektów prefabrykatów na scenie okazuje się, że wszystkie wymagają kosme‐
tycznych zmian. W takim przypadku bez zastosowania dziedziczenia każdy
ze wspomnianych obiektów musiałby zostać zmodyfikowany oddzielnie.
Istnieją dwa sposoby modyfikacji zasobu prefabrykatu. Pierwszy polega na
wprowadzeniu zmian w panelu Project. Zwykłe zaznaczenie zasobu prefabry‐
katu w panelu Project powoduje wyświetlenie w panelu Inspector jego kompo‐
nentów i właściwości. Jeżeli trzeba zmodyfikować element potomny, można
218 Lekcja 12. Prefabrykaty
Wypróbuj samodzielnie
Uaktualnianie prefabrykatu
Dotychczas utworzyłeś prefabrykat, a następnie umieściłeś na scenie
kilka jego egzemplarzy. Teraz masz możliwość uaktualnienia prefabrykatu
i zobaczenia, jak zmiana wpłynie na zasoby już znajdujące się na scenie.
W tym ćwiczeniu wykorzystasz scenę utworzoną w poprzednim ćwiczeniu.
Jeżeli nie wykonałeś poprzedniego ćwiczenia, musisz to zrobić, zanim przy-
stąpisz do wykonywania bieżącego.
1. Otwórz utworzoną poprzednio scenę z lampami.
2. W panelu Project zaznacz prefabrykat Lamp i wyświetl jego zawartość,
klikając strzałkę znajdującą się po prawej stronie. Zaznacz komponent
potomny Sphere. W panelu Inspector zmień kolor światła
na pomarańczowy (patrz rysunek 12.8). Zauważ, że automatycznie
zostaną zmienione prefabrykaty umieszczone na scenie.
Zerwanie połączenia
z zasobem prefabrykatu
Czasami trzeba zerwać połączenie między egzemplarzem prefabrykatu i zaso‐
bem prefabrykatu. Taka sytuacja występuje, gdy potrzebujesz egzemplarza
prefabrykatu, ale nie chcesz, aby ulegał zmianie w przypadku jakiejkolwiek
modyfikacji prefabrykatu. Zerwanie połączenia z zasobem prefabrykatu nie
powoduje w żaden sposób zmiany egzemplarza. Nadal zachowuje on wszyst‐
kie obiekty, komponenty i właściwości. Jedyna różnica polega na tym, że nie
jest dłużej egzemplarzem prefabrykatu, a tym samym nie korzysta z dziedzi‐
czenia.
Aby zerwać połączenie między egzemplarzem prefabrykatu i zasobem pre‐
fabrykatu, najpierw zaznacz obiekt w panelu Hierarchy. Po zaznaczeniu wybierz
opcję GameObject/Break Prefab Instance. Zauważysz, że obiekt nie ulegnie
zmianie, ale jego nazwa będzie wyświetlona w kolorze czarnym, a nie niebie‐
skim. Po zerwaniu połączenia z zasobem prefabrykatu wspomnianego połą‐
czenia nie można ponownie nawiązać.
220 Lekcja 12. Prefabrykaty
Podsumowanie
W tej lekcji zająłeś się prefabrykatami w środowisku Unity. Na początku
poznałeś podstawy dotyczące prefabrykatów: koncepcję, terminologię i struk‐
turę. Następnie przeszedłeś do tworzenia własnych prefabrykatów. Dowie‐
działeś się, jak je budować, dodawać do sceny, modyfikować oraz zrywać
połączenie egzemplarza prefabrykatu z zasobem prefabrykatu. Na końcu
zobaczyłeś, jak za pomocą kodu można utworzyć egzemplarze obiektów
prefabrykatów.
Pytania i odpowiedzi 221
Pytania i odpowiedzi
Pytanie: Prefabrykat przypomina klasę w programowaniu zorientowanym
obiektowo (OOP). Czy to trafne skojarzenie?
Odpowiedź: Tak, istnieje wiele podobieństw między prefabrykatami i klasami.
Obie wymienione konstrukcje służą jako matryce. Obiekty obu konstrukcji
powstają w trakcie procesu tworzenia egzemplarza. Ponadto są połączone
z oryginałem.
Pytanie: Ile obiektów prefabrykatów może istnieć na scenie?
Odpowiedź: Dowolna ilość. Musisz jednak mieć świadomość, że po
przekroczeniu pewnej liczby obiektów wydajność gry może spaść.
Raz utworzony egzemplarz istnieje aż do chwili usunięcia, dlatego
też utworzenie 10000 egzemplarzy oznacza 10000 prefabrykatów
znajdujących się na scenie.
Warsztaty
Poświęć nieco czasu i odpowiedz na zamieszczone poniżej pytania, a także
upewnij się, że przyswoiłeś sobie materiał omówiony w tej lekcji.
Quiz
1. Jakim wyrażeniem określamy utworzenie obiektu na podstawie
zasobu prefabrykatu?
2. Jakie są dwa sposoby modyfikacji zasobu prefabrykatu?
3. Co to jest dziedziczenie?
4. Na ile sposobów można używać metody Instantiate()?
Odpowiedzi
1. Tworzenie egzemplarza.
2. Zasób prefabrykatu można zmodyfikować w panelu Project. Inny
sposób polega na modyfikacji egzemplarza prefabrykatu w panelu
Scene, a następnie jego przeciągnięciu na zasób prefabrykatu w panelu
Project.
3. To jest połączenie między zasobem prefabrykatu i jego egzemplarzami.
W praktyce oznacza, że zmiana zasobu prefabrykatu pociąga za sobą
również zmianę poszczególnych egzemplarzy.
4. Dwa. Pierwszy to podanie jedynie nazwy prefabrykatu, natomiast
drugi to podanie również danych położenia i rotacji.
222 Lekcja 12. Prefabrykaty
Ćwiczenie
W tym ćwiczeniu ponownie wykorzystasz prefabrykat utworzony wcześniej
w tej lekcji. Tym razem utworzysz egzemplarze prefabrykatów za pomocą kodu.
Mam nadzieję, że będziesz się dobrze bawić. Ukończony projekt ćwiczenia
znajdziesz w katalogu Hour12_Exercise w materiałach przeznaczonych dla
bieżącej lekcji.
1. W projekcie zawierającym prefabrykat Lamp utwórz nową scenę.
Następnie w panelu Project kliknij prefabrykat Lamp i umieść go
w położeniu (–1, 1, –5).
2. Do sceny dodaj pusty obiekt gry. Zmień jego nazwę na SpawnPoint
i umieść w położeniu (1, 1, –5). Do sceny dodaj płaszczyznę, umieść
ją w położeniu (0, 0, –4) i zastosuj rotację (270, 0, 0).
3. Do projektu dodaj skrypt o nazwie PrefabGenerator i dołącz go
do obiektu SpawnPoint. Pełny kod skryptu został przedstawiony
w listingu 12.1.
if(Input.GetKeyDown(KeyCode.Space))
Instantiate(prefab, transform.position,
transform.rotation);
}
}
Podstawy GUI
Jak wcześniej wspomniano, graficzny interfejs użytkownika (najczęściej okre‐
ślany mianem GUI) to warstwa specjalna znajdująca się między graczem
a rzeczywistą grą. Rolą GUI jest wyświetlanie użytkownikowi ważnych infor‐
macji i czasami odczyt danych wprowadzanych przez tegoż użytkownika.
W środowisku Unity system GUI składa się z wielu kontrolek opracowywanych
w kodzie. Kontrolki te umożliwiają utworzenie elementów, takich jak etykiety,
przyciski, pola tekstowe i suwaki. Dokładniejsze omówienie kontrolek znaj‐
dziesz dalej w tej lekcji.
Projektowanie GUI
Ogólnie rzecz biorąc, GUI należy zaprojektować wcześniej. Dokładnie trzeba
przemyśleć, w którym miejscu oraz jak mają być wyświetlane dane na
ekranie. Zbyt duża ilość informacji pokazywanych na ekranie powoduje jego
zaśmiecenie i zmniejsza czytelność danych. Z kolei zbyt mała ilość infor-
macji sprawia, że gracz staje się zdezorientowany lub niepewny. Zawsze
staraj się znaleźć odpowiedni sposób konsolidacji informacji lub podania ich
w łatwiejszej formie. Gracze podziękują Ci za to.
Tworzenie GUI
Ponieważ GUI jest tworzony w kodzie, może być dodany do dowolnego
skryptu dołączonego do dowolnego obiektu. Jeżeli nie zachowasz ostroż-
ności, możliwość ta powoduje problem natury organizacyjnej. Umiesz-
czenie fragmentów kodu GUI w wielu skryptach znacznie utrudnia później
wyszukanie niezbędnych danych. Co więcej, trudniejsze staje się wyszu-
kiwanie i usuwanie błędów. Ponadto umieszczenie fragmentów kodu
tworzącego GUI w wielu obiektach utrudnia zdefiniowanie obowiązków
danego obiektu w zakresie odpowiedzialności za GUI. Dobrym rozwiązaniem
jest umieszczenie całego kodu GUI w jednym miejscu, w specjalnie zbu-
dowanym obiekcie. Gdy cały kod związany z GUI znajdzie się w jednym
miejscu, praca nad grą stanie się nieco łatwiejsza.
Jak widać, metoda OnGUI() nie pobiera parametrów i nie zwraca żadnych
danych. Podobnie jak Update(), omawiana tutaj metoda jest wywoływana
w każdej klatce i wyświetla komponenty GUI na ekranie. Jak zobaczysz dalej
w tej lekcji, kontrolki GUI składają się z pojedynczych wierszy kodu umiesz‐
czonych wewnątrz metody OnGUI().
Wypróbuj samodzielnie
Tworzenie GUI
Teraz wyświetlisz na ekranie proste kontrolki GUI. W tym ćwiczeniu na
ekranie pojawi się etykieta z prostym komunikatem. Nie zagłębiaj się
zbytnio w kod tworzący etykietę, ponieważ dokładnie zostanie omówiony
dalej w tej lekcji. Zamiast tego upewnij się, że kontrolka GUI została pra-
widłowo wyświetlona na ekranie. W ten sposób będziesz przygotowany
do dalszej pracy.
1. Utwórz nowy projekt lub scenę. Utwórz nowy skrypt o nazwie
BasicGUIScript i dołącz go do obiektu Main Camera.
2. Wewnątrz klasy, ale poza dowolną metodą, umieść poniższy kod (jeśli
potrzebujesz pomocy, zajrzyj do plików dołączonych do książki).
void OnGUI()
{
GUI.Label(new Rect(0, 0, 80, 20), "Hello World");
}
3. Uruchom scenę. Zwróć uwagę, że komunikat Hello World został
wyświetlony na ekranie (patrz rysunek 13.1).
Kontrolki GUI
W tej części lekcji będziesz pracować z najczęściej używanymi, wbudowanymi
w Unity kontrolkami GUI. Większość kontrolek jest tworzona i działa w podobny
sposób. Zanim jednak przejdziesz do określonych kontrolek, powinieneś poznać
zmienną typu Rect. Zmienna tego typu służy komponentom do podawania
położenia na ekranie. Jak wcześniej wspomniano w książce, elementy GUI
działają jedynie ze współrzędnymi 2D. Dlatego też dokładne położenie i wiel‐
kość dowolnego elementu GUI można podać za pomocą zmiennej typu Rect.
W tej lekcji wielokrotnie spotkasz się z następującym kodem:
228 Lekcja 13. Graficzny interfejs użytkownika
Wyśrodkowanie kontrolki
Bardzo często trzeba umieścić kontrolkę dokładnie na środku ekranu.
Prawdopodobnie zauważyłeś, że utworzenie Rect na środku ekranu
w rzeczywistości przesuwa strukturę nieco niżej oraz w prawą stronę.
Wynika to z faktu, że lewy górny narożnik struktury Rect znajduje się
dokładnie na środku ekranu, a pozostała część prostokąta jest nieco prze-
sunięta. Umieszczenie kontrolki dokładnie na środku ekranu wymaga prze-
prowadzenia nieco większej ilości obliczeń. Strukturę trzeba umieścić na
środku ekranu i odjąć połowę jej szerokości i wysokości. W ten sposób
środek struktury będzie znajdował się dokładnie na środku ekranu. Dlatego
też w celu umieszczenia na środku ekranu struktury Rect o wymiarach 100
jednostek długości i 50 jednostek wysokości należy użyć poniższego kodu:
new Rect(Screen,width / 2 – 50, Screen.height / 2 – 25, 100, 50)
Na początku może to wydawać się zawiłe, ale po kilkakrotnym użyciu tego
rodzaju kod stanie się zrozumiały.
Etykieta
Kontrolka etykiety zalicza się do najprostszych. Jej zadanie polega na wyświe‐
tleniu danych w postaci ciągu tekstowego. Kod tworzący etykietę przedstawia
się następująco:
Kontrolki GUI 229
Pole
Kontrolka pola jest podobna do etykiety. Jedyna różnica polega na tym, że
pole zawiera ciemne tło wyświetlane wokół etykiety. Pole jest użyteczne jako
tło dla różnych innych kontrolek. Składnia tworzenia pola przedstawia się
następująco:
GUI.Box(new Rect(<x>, <y>, <w>, <h>), <Dowolny ciąg tekstowy>);
Jeśli na środku w górnej części ekranu chcesz wyświetlić pole wraz z komu‐
nikatem Box Label, powinieneś użyć poniższego polecenia:
GUI.Box(new Rect(Screen.width / 2 - 50, 0, 100, 50), "Box Label");
Jeśli w tym samym położeniu ma się pojawić puste pole bez etykiety, wtedy
polecenie przedstawia się następująco:
GUI.Box(new Rect(Screen.width / 2 - 50, 0, 100, 50), "");
Na rysunku 13.2 pokazano pole utworzone przy użyciu wcześniej przedsta‐
wionego polecenia.
RYSUNEK 13.2.
Kontrolka Box
na ekranie
Przycisk
Przycisk to prosta kontrolka działająca w połączeniu z poleceniem warunko‐
wym. Przycisk może mieć wartość false (nie został naciśnięty) lub true (został
naciśnięty). Ponadto kontrolkę przycisku można nacisnąć tylko raz. Przytrzy‐
mywanie przycisku nie da żadnego dodatkowego efektu. Składnia przycisku
przedstawia się następująco:
if(GUI.Button(new Rect(<x>, <y>, <w>, <h>), <Dowolny ciąg tekstowy>))
{
// Działanie przycisku po jego naciśnięciu.
}
230 Lekcja 13. Graficzny interfejs użytkownika
RYSUNEK 13.3.
Kontrolka
przycisku
Przycisk powtarzający
Przycisk powtarzający jest niemal identyczny ze zwykłym, ale może być naci‐
śnięty i przytrzymany. Jeżeli chcesz utworzyć przycisk zwiększający wartość
pewnej zmiennej przez cały czas, w trakcie którego przycisk jest przytrzy‐
mywany, możesz użyć poniższego kodu:
if(GUI.RepeatButton(new Rect(0, 0, 80, 20), "Increase"))
{
someValue += 1;
}
Warto dodać, że zmienna someValue jest tutaj tylko przykładem.
Pole wyboru
Pole wyboru to kontrolka, którą można określić mianem przycisku zachowu-
jącego informacje o stanie. Oznacza to, że przyciski zachowują stan wskazujący
na kliknięcie lub brak kliknięcia (przypomina to przełącznik). Kod tworzący
pole wyboru jest taki sam jak dla innych przycisków, ale pobiera parametr
boolowski i zwraca wartość boolowską. Pobierany parametr pozwala na
ustalenie, czy pole wyboru jest aktualnie zaznaczone. Z kolei wartość boolow‐
ska informuje o kliknięciu. Składnia pola wyboru przedstawia się następująco:
<wartość boolowska> = GUI.Toggle(new Rect(<x>, <y>, <w>, <h>),
<wartość boolowska>, <Dowolny Ciąg tekstowy>);
Kontrolki GUI 231
void OnGUI()
{
toggleState = GUI.Toggle(new Rect(5, 5, 80, 30), toggleState,
"My Toggle");
}
Utworzone przez ten kod pole wyboru pokazano na rysunku 13.4.
RYSUNEK 13.4.
Pole wyboru
wyświetlone
na ekranie
Pasek narzędziowy
Pasek narzędziowy to rząd przycisków. Liczba przycisków zależy tylko od
Ciebie. Podobnie jak w przypadku zwykłego paska narzędziowego, w danej
chwili może być wybrany tylko jeden przycisk. Do monitorowania aktualnie
wybranego przycisku jest wykorzystywana zmienna w postaci liczby całko‐
witej. Kolejną nowością w pasku narzędziowym jest użycie tablicy ciągów
tekstowych. Liczba elementów znajdujących się w tablicy określa liczbę przy‐
cisków wyświetlanych na pasku narzędziowym. Składnia przeznaczona do
tworzenia kontrolki paska narzędziowego przedstawia się następująco:
<Some int> = GUI.Toolbar(new Rect(<x>, <y>, <w>, <h>), <liczba
całkowita>, <tablica>);
Jeżeli więc chcesz utworzyć pasek narzędziowy zawierający trzy przyciski, takie
jak Easy, Medium i Hard, możesz użyć poniższego fragmentu kodu.
int buttonInt = 0;
string[] list = {"Easy", "Medium", "Hard"};
void OnGUI()
{
buttonInt = GUI.Toolbar(new Rect(5, 5, 200, 30), buttonInt,
list);
}
232 Lekcja 13. Graficzny interfejs użytkownika
Wypróbuj samodzielnie
Paski narzędziowe
Poświęć chwilę na poznanie pasków narzędziowych w środowisku Unity.
1. Utwórz nowy projekt lub scenę. Utwórz skrypt o nazwie GUIScript
i dołącz do obiektu Main Camera.
2. Do skryptu dodaj przedstawiony wcześniej kod paska narzędziowego.
Upewnij się, że umieściłeś kod wewnątrz klasy, ale poza jakąkolwiek
istniejącą w niej metodą.
3. Uruchom scenę. Powinieneś zobaczyć trzy przyciski (patrz rysunek 13.5).
Spróbuj je klikać i zobacz, jakie będzie działanie przycisków.
Pole tekstowe
Kontrolka pola tekstowego umożliwia użytkownikowi wprowadzanie tekstu
na scenie. Kontrolka jest wyświetlana jako pole, które może być zaznaczone
i pozwala na wprowadzanie w nim tekstu. Istnieje również możliwość umiesz‐
czenia ciągu tekstowego w polu. Podobnie jak w przypadku poprzednich
kontrolek, konieczne jest przekazanie ciągu tekstowego oraz zaakceptowanie
ciągu tekstowego z pola tekstowego, aby monitorować interakcję użytkownika.
Składnia tworzenia kontrolki pola tekstowego przedstawia się następująco:
<Some String> = GUI.TextField(new Rect(<x>, <y>, <w>, <h>),
<Dowolny ciąg tekstowy>);
W celu utworzenia pola tekstowego wyświetlającego komunikat Enter Text
Here należy użyć poniższego fragmentu kodu.
string textString = "Enter Text Here";
void OnGUI()
{
textString = GUI.TextField(new Rect(5, 5, 100, 30), textString);
}
Kontrolki GUI 233
RYSUNEK 13.6.
Kontrolka pola
tekstowego
Obszar tekstu
Obszar tekstu przypomina pole tekstowe, ale może składać się z wielu wierszy.
Składnia przeznaczona do utworzenia obszaru tekstu przedstawia się nastę‐
pująco:
<Some String> = GUI.TextArea(new Rect(<x>, <y>, <w>, <h>),
<Dowolny ciąg tekstowy>);
Musisz zwrócić uwagę na jedno: ponieważ obszar tekstowy może zawierać
wiele wierszy, istnieje niebezpieczeństwo, że użytkownik wprowadzi dużą liczbę
wierszy przekraczającą wysokość obszaru.
Suwaki
Suwaki to kontrolki pozwalające użytkownikowi na wybór między zakresami
wartości przez „przesunięcie” gałki suwaka. W środowisku Unity dostępne
są dwa rodzaje suwaków: poziome i pionowe. Suwak, poza zmienną typu Rect
wskazującą położenie, wymaga jeszcze trzech parametrów. Pierwszy z nich
jest typu float i wskazuje wartość bieżącą suwaka. Drugi i trzeci to parametry
określające minimalną i maksymalną wartość suwaka. Wartość zwrotna jest
typu float i wskazuje wartość bieżącą suwaka. Składnia dla obu rodzajów
suwaków przedstawia się następująco:
<Value> = GUI.HorizontalSlider(new Rect(<x>, <y>, <w>, <h>), <Value>,
<Min>, <Max>);
<Value> = GUI.VerticalSlider(new Rect(<x>, <y>, <w>, <h>), <Value>,
<Min>, <Max>);
W celu utworzenia dwóch suwaków o zakresie od 0 do 100 możesz użyć nastę‐
pującego fragmentu kodu.
float hValue = 0;
float vValue = 0;
void OnGUI()
234 Lekcja 13. Graficzny interfejs użytkownika
{
vValue = GUI.VerticalSlider(new Rect(5, 5, 20, 150), vValue, 0,
100);
hValue = GUI.HorizontalSlider(new Rect(30, 30, 150, 20), hValue,
0, 100);
}
Dwie kontrolki suwaków utworzone przez przedstawiony powyżej fragment
kodu pokazano na rysunku 13.7.
RYSUNEK 13.7.
Kontrolki
suwaków
Dostosowanie kontrolki
do własnych potrzeb
Graficzny interfejs użytkownika jest bardzo ważnym elementem każdej gry.
Wbudowany w Unity system GUI oferuje potężne możliwości, ale czasami
trzeba przygotować własny GUI z określonym sposobem działania. Na szczę‐
ście, dostosowanie kontrolek GUI do własnych potrzeb to bardzo prosty proces.
Kontrolki można zmieniać za pomocą stylów GUI i skórek.
Style GUI
Styl GUI to coś, co po dodaniu do kontrolki określa jej wygląd. Style wbudo‐
wane w Unity przypominają kaskadowe arkusze stylów (CSS) używane na
stronach internetowych i pozwalają na zmianę koloru tekstu, tekstur tła,
czcionek i innych aspektów.
Każda kontrolka GUI ma zastosowany domyślny styl GUI. Nazwy kontrolki
i stylu są dokładnie takie same. Przykładowo w kontrolce button zastosowano
styl o nazwie button. Wymieniona cecha staje się interesująca, ponieważ styl
jednej kontrolki można zastosować w kontrolce innego typu. Jeżeli zastosujesz
styl przycisku w kontrolce pola wyboru, otrzymasz kontrolkę wyglądającą jak
przycisk, ale działającą jak pole wyboru. Do wszystkich omówionych wcze‐
śniej kontrolek można dostarczyć parametr dodatkowy. Parametr ten określa
styl i może być obiektem GUIStyle lub nazwą stylu.
Dostosowanie kontrolki do własnych potrzeb 235
Wypróbuj samodzielnie
void OnGUI()
{
value = GUI.Toggle(new Rect(5, 5, 100, 100), value,
"toggle", "button");
}
3. Uruchom scenę i zobacz, że pole wyboru wygląda jak przycisk. Zobacz,
co się stanie po jego kliknięciu. Poeksperymentuj z innymi kontrolkami
i stylami. Pamiętaj, że styl kontrolki ma taką samą nazwę jak kontrolka.
Skórki GUI
Style GUI określają wygląd kontrolki po wygenerowaniu. Takie rozwiązanie
sprawdza się, jeśli zarządzasz niewielką liczbą kontrolek. Gdy chcesz przygoto‐
wać całe GUI definiujące „wygląd i działanie” różnych kontrolek, wtedy obsługa
wszystkich stylów może stać się trudna. Z pomocą przychodzą wówczas skórki
236 Lekcja 13. Graficzny interfejs użytkownika
RYSUNEK 13.8.
Właściwość Style
void OnGUI()
{
GUI.skin = skin;
// Miejsce na kod GUI.
}
Dostosowanie kontrolki do własnych potrzeb 237
Wypróbuj samodzielnie
void OnGUI()
{
if(GUI.Button(new Rect(5, 5, 100, 30), "Hello World",
style);
}
3. W edytorze Unity przejdź do panelu Inspector, a następnie rozwiń
właściwości Style i Normal. Teraz zmień kolor we właściwości Text
Color na pomarańczowy (patrz rysunek 13.9). Uruchom scenę i zobacz,
jak wygląda etykieta.
Skomplikowane style
Podczas eksperymentowania ze stylami możesz zauważyć, że niektóre funk-
cje nie powodują żadnego efektu. Ponadto można dostrzec, że zastosowa-
nie stylu na kontrolce przycisku (lub jakiejkolwiek innej) powoduje zmianę
jej wyglądu na etykietę. To wszystko wynika z ogromnego skomplikowania
stylów. Przykładowo wygląd przycisku jest nadawany za pomocą grafiki.
Jeżeli więc nie zdefiniujesz grafiki w tworzonym przez siebie stylu, wtedy
przycisk nie będzie wyglądał jak przycisk. To samo ma zastosowanie do
kliknięcia przycisku: tutaj potrzebna jest kolejna grafika przedstawiająca
naciśnięty przycisk. Dlatego też, jeśli planujesz przygotowanie własnych
stylów dla kontrolek, musisz poświęcić nieco czasu na opracowanie odpo-
wiednich zasobów, aby kontrolki prezentowały się zgodnie z oczekiwaniami.
Wypróbuj samodzielnie
void OnGUI()
{
GUI.skin = skin;
if(GUI.Button(new Rect(5, 5, 100, 30), "Hello World"))
{}
}
3. W edytorze Unity utwórz skórkę GUI (prawym przyciskiem myszy kliknij
katalog Assets i wybierz opcję Create/GUI Skin). Nowej skórce nadaj
nazwę NewSkin. Rozwiń właściwość Button, następnie Active i zmień
kolor właściwości Text Color na czerwony (patrz rysunek 13.10).
Podsumowanie
W tej lekcji dowiedziałeś się sporo o graficznym interfejsie użytkownika
w środowisku Unity. Na początku poznałeś podstawy GUI, a także sposoby
jego projektowania i tworzenia. Następnie przeszedłeś do kwestii położenia
kontrolek GUI na ekranie. Poznałeś wiele najczęściej używanych kontrolek GUI
i miałeś okazje je wypróbować. Na końcu lekcji poruszony został temat stylów
i skórek GUI.
Pytania i odpowiedzi
Pytanie: Czy każda gra wymaga GUI?
Odpowiedź: Zwykle doskonale przemyślane GUI jest zaletą gry. Bardzo rzadko
zdarza się, że gra w ogóle jest pozbawiona GUI. Mając to na uwadze,
zawsze warto przygotować choć skromny graficzny interfejs
użytkownika. Zdecydowanie nie warto przytłoczyć graczy zbyt
rozbudowanym GUI.
240 Lekcja 13. Graficzny interfejs użytkownika
Warsztaty
Poświęć nieco czasu i odpowiedz na zamieszczone poniżej pytania, a także
upewnij się, że przyswoiłeś sobie materiał omówiony w tej lekcji.
Quiz
1. Co oznacza skrót GUI?
2. Jakiego typu zmienna przechowuje położenie X i Y, a także szerokość
i wysokość?
3. Co mamy na myśli, mówiąc, że pole wyboru to przycisk zachowujący
informacje o stanie?
4. Jaka jest różnica między stylem GUI a skórką GUI?
Odpowiedzi
1. To graficzny interfejs użytkownika (ang. Graphical User Interface).
2. To jest typ Rect.
3. Pole wyboru zachowuje informacje o stanie, czyli „wie”, czy zostało
kliknięte.
4. Styl pozwala na określenie wyglądu pojedynczej kontrolki. Natomiast
skórka to kolekcja stylów i jest używana w celu nadania całemu
systemowi GUI spójnego wyglądu i działania.
Ćwiczenie
W tym ćwiczeniu zaprojektujesz własny system GUI. Aby zapewnić Ci moż‐
liwość wykazania się kreatywnością, możesz utworzyć dowolne GUI. W mate‐
riałach przeznaczonych dla bieżącej lekcji znajduje się projekt ukończonego
ćwiczenia (Hour13_Exercise), ale użyto w nim jedynie domyślnych stylów
kontrolek. Twoim zadaniem jest nadanie im unikalnego stylu. Sam projekt to
prosty program. Sprawdź, czy potrafisz samodzielnie wykonać to ćwiczenie.
Jeżeli napotkasz jakiekolwiek trudności, zajrzyj do dostarczonego przykładu.
Ćwiczenie 241
Kontroler postaci
Dotychczas widziałeś już wiele sposobów interakcji z obiektami na scenie.
Poznałeś możliwości w zakresie przesuwania ich za pomocą skryptów, a także
fizyczne interakcje z użyciem brył sztywnych. Są to akceptowalne sposoby
obsługi ruchu w grze. Jeśli jednak szukasz sposobu na opracowanie bardziej
realistycznej i spójnej rozgrywki, potrzebujesz nieco bardziej zaawansowanego
rozwiązania. Niezbędny jest kontroler postaci (często nazywany po prostu kon-
trolerem). Kontroler postaci to specjalizowany komponent, który pozwala na
uzyskanie dużej kontroli nad obiektem gry bez konieczności użycia fizyki brył
sztywnych. Kontroler postaci umożliwia poruszanie obiektem po scenie, może
być ograniczany przez ściany i strome wzniesienia, nie wymaga popychania
obiektów przez np. inne obiekty. Sercem kontrolera postaci jest komponent
Capsule Collider wyposażony w dodatkowe funkcje, które zostaną omówione
dalej w tej lekcji.
RYSUNEK 14.1.
Komunikat
wyświetlany
podczas
dodawania
kontrolera
do obiektu
już zawierającego
komponent Collider
Skrypty dla kontrolerów postaci 245
Wypróbuj samodzielnie
RYSUNEK 14.2.
Komponent
kontrolera postaci
CharacterController controller;
void Start () {
controller = GetComponent<CharacterController>();
}
Powyższy fragment kodu tworzy zmienną CharacterController. Następnie
w metodzie Start() odszukiwane jest odniesienie do kontrolera i zapisywane
w zmiennej. Od tego miejsca kontroler postaci można wykorzystywać w kodzie.
Zmienne dotyczące kontrolera postaci zostały opisane w tabeli 14.2.
Kontrolowanie poślizgu
Ruch odbywający się za pomocą kontrolera postaci może zawierać pewien
poślizg. Oznacza to, że obiekt nie zatrzymuje się natychmiast po naciśnięciu
klawisza. Zamiast tego zwalnia przez pewien okres czasu. Zwiększenie lub
zmniejszenie poślizgu obiektu można zmienić, modyfikując właściwość
Gravity dla osi danych wejściowych w menedżerze InputManager (patrz
rysunek 14.3). W celu przejścia do tego menedżera wybierz opcję menu
Edit/Project Settings/Input.
Skrypty dla kontrolerów postaci 249
RYSUNEK 14.3.
Ustawienia
grawitacji
w InputManager
Kolizje
Kontroler postaci automatycznie zajmuje się obsługą kolizji w trakcie ruchu,
ale czasami będziesz chciał zachować nad tym znacznie dokładniejszą kon‐
trolę. Dlatego też po wykryciu kolizji kontroler wywołuje metodę OnControl
lerColliderHit(). Za pomocą wymienionej metody można opracowywać
własne skutki kolizji, np. popchnięcie obiektu. W celu wykrycia kolizji należy
w skrypcie umieścić poniższy fragment kodu.
void OnControllerColliderHit(ControllerColliderHit hit) {
// Miejsce na kod obsługi kolizji.
}
Po dodaniu tej metody do kodu możesz w niej umieścić dowolny kod przezna‐
czony do obsługi kolizji. Parametr hit będzie zawierał informacje o obiekcie,
który wszedł w kolizję z kontrolerem. Przykład praktycznego wykorzystania
omawianej metody zostanie przedstawiony dalej w tej lekcji.
Konfiguracja podstawowa
Zanim faktycznie przystąpisz do tworzenia skryptów własnego kontrolera
postaci, konieczne jest przygotowanie sceny i wypróbowanie różnych aspek‐
tów. Scena będzie wyjątkowo prosta: składa się z ziemi, pojedynczej platformy
i poruszanej postaci.
1. Utwórz nowy projekt lub scenę. Do sceny dodaj światło kierunkowe,
dwa sześciany i kapsułę.
2. Ponieważ tworzona jest scena dwuwymiarowa, kamera musi być
ustawiona inaczej. Po zaznaczeniu kamery przejdź do panelu Inspector
i zmień opcję właściwości Projection na Orthographic, natomiast
wartość właściwości Size ustaw na 8 (patrz rysunek 14.4). Położenie
kamery powinno wynosić (0, 2.4, –10).
RYSUNEK 14.4.
Właściwości
kamery
void Start () {
controller = GetComponent<CharacterController>();
}
252 Lekcja 14. Sterowanie postaciami
Obsługa ruchu
Po przygotowaniu sceny trzeba dodać do kapsuły najbardziej podstawową funk‐
cję, czyli obsługę ruchu. Aby poruszyć obiektem, konieczne jest obliczenie
wektora przesunięcia i wywołanie metody Move(). Dobrym rozwiązaniem
(choć nie jest to wymagane) będzie przechowywanie szybkości ruchu w zmien‐
nej, aby można było ją łatwo zmieniać. Dane dotyczące ruchu powinny być
przechowywane w zmiennej typu Vector3. W tym momencie nie jest to wyma‐
gane, ale stanie się niezbędne później, gdy zaczniemy wykorzystywać oś Y.
public float speed = 5.0f;
Vector3 movement = Vector3.zero;
void Update () {
movement.x = Input.GetAxis("Horizontal") * speed;
controller.Move(movement * Time.deltaTime);
}
W powyższym fragmencie kodu zdefiniowano zmienną speed, która będzie
używana do kontrolowania szybkości poruszania się obiektu. Następnie zdefi‐
niowano zmienną typu Vector3 o nazwie movement przeznaczoną do prze‐
chowywania między poszczególnymi klatkami danych ruchu. W metodzie
Update() zmienna movement otrzymuje wartość pobraną z poziomej osi ruchu
(klawisze kursorów w lewo i w prawo lub klawisze A i S) pomnożoną przez
wartość zmiennej speed. Zwróć uwagę na brak podanych wartości dla osi Y
lub Z. Ponieważ tworzymy dwuwymiarowy kontroler postaci, nie istnieje ruch
wzdłuż osi Z, a oś Y jest obsługiwana inaczej. Następnie wywoływana jest
metoda Move(), a wartość zmiennej movement pomnożona przez Time.del
Tworzenie kontrolera postaci 253
Grawitacja
Kolejną funkcją, którą dodamy do kontrolera postaci, jest obsługa grawitacji.
Istnieją dwa sposoby obsługi grawitacji: można wykorzystać wartość wbu‐
dowaną lub wskazać inną. Zastosowanie wartości wbudowanej w Unity powo‐
duje, że wszystkie elementy spadają z taką samą szybkością. Być może będziesz
chciał zastosować inną wartość, jeśli postać ma spadać nieco inaczej, np. jak
ze spadochronem. Do obsługi grawitacji można wykorzystać przedstawiony
poniżej fragment kodu.
movement.x = Input.GetAxis("Horizontal") * speed;
if(controller.isGrounded == false)
movement.y += Physics.gravity.y * Time.deltaTime;
controller.Move(movement * Time.deltaTime);
Pierwszy i ostatni wiersz kodu zostały omówione w poprzedniej sekcji, pozo‐
stawiono je tutaj jedynie w charakterze punktów odniesienia. Ponieważ gra‐
witacja nie zawsze musi być zastosowana, konstrukcja warunkowa if służy
do ustalenia, czy postać nie jest uziemiona. Jeżeli ustalono, że postać aktualnie
nie znajduje się na ziemi, w wektorze ruchu zostaje uwzględniony komponent Y
bieżącej grawitacji sceny. W ten sposób po wywołaniu metody Move() obiekt
porusza się w lewą i prawą stronę, a także podlega grawitacji.
Uruchom scenę i zobacz, jak działa. Kapsuła natychmiast spada i zatrzymuje
się na ziemi. Jeżeli zepchniesz ją z platformy, kapsuła wypadnie ze sceny.
Skoki
Gra platformowa nie będzie dostarczała zbyt wielkiej rozrywki, jeśli gracz nie
otrzyma możliwości wykonywania skoków pomiędzy kolejnymi platformami.
Obsługa skoków jest bardziej skomplikowana niż obsługa poruszania i spada‐
nia. Konieczne jest monitorowanie, jak wysoko postać może skoczyć. Trzeba
się również upewnić, że postać może skoczyć tylko raz w danej chwili, ponieważ
w przeciwnym razie będzie latać.
public float jumpSpeed = 8.0f;
void Update() {
254 Lekcja 14. Sterowanie postaciami
controller.Move(movement * Time.deltaTime);
}
Ponownie przedstawiony fragment kodu zawiera większą ilość kodu niż intere‐
sująca nas w tym momencie. Nadmiarowy kod służy w charakterze punktów
odniesienia. Na początku mamy definicję zmiennej typu float o nazwie jump
Speed określającej maksymalną wysokość skoku. Następnie w metodzie
Update() konstrukcja warunkowa if została użyta do upewnienia się, że
postać może skakać tylko po naciśnięciu klawisza i jeśli aktualnie znajduje
się na ziemi.
Uruchom scenę i wypróbuj ją. Sprawdź, czy możesz kapsułą wykonać skok
na drugą platformę. Zobacz, jaką masz kontrolę na kapsułą, gdy znajduje się
w powietrzu. To jest celowy wybór projektowy i może być zmieniony w przy‐
szłych projektach.
Popychanie obiektów
Ostatnią funkcją do dodania jest możliwość popychania obiektów na scenie.
Wymaga to użycia wspomnianej wcześniej metody OnControllerCollider
Hit(). Kod dla funkcji popychania obiektów przedstawia się następująco.
public float pushPower = 2.0f;
CharacterController controller;
void Start () {
controller = GetComponent<CharacterController>();
}
void Update() {
if(controller.isGrounded == false)
movement.y += Physics.gravity.y * Time.deltaTime;
controller.Move(movement * Time.deltaTime);
}
Podsumowanie
W tej lekcji zapoznałeś się z oferowanymi przez środowisko Unity kontrolerami
postaci. Na początku poznałeś podstawy dotyczące kontrolerów postaci oraz
właściwości komponentu kontrolera. Następnie przeszedłeś do pracy z kon‐
trolerem postaci za pomocą skryptu. Poznałeś oferowane przez kontroler
postaci różne zmienne, metody i obsługę kolizji. Na końcu opracowałeś własny
kontroler postaci przeznaczony specjalnie dla dwuwymiarowych gier plat‐
formowych.
Pytania i odpowiedzi
Pytanie: Ile mamy typów kontrolerów postaci?
Odpowiedź: Istnieje tylko jeden komponent kontrolera postaci. Jednak
liczba sposobów, na jakie można go wykorzystać, jest praktycznie
nieograniczona. Kontroler postaci jest tworzony tak, aby umożliwić
jego dostosowanie do własnych potrzeb i sytuacji.
Pytanie: Co jest lepsze, komponent Rigidbody czy kontroler postaci?
Odpowiedź: To jest bardzo ważne pytanie. Odpowiedź zależy od tego,
co chcesz osiągnąć. Jeżeli planujesz wykorzystanie oferowanych przez
środowisko Unity możliwości w zakresie fizyki, wtedy zdecyduj się
na komponent Rigidbody. Jeśli natomiast chcesz opracować dokładne
zachowanie dla postaci, wybierz kontroler postaci.
Warsztaty
Poświęć nieco czasu i odpowiedz na zamieszczone poniżej pytania, a także
upewnij się, że przyswoiłeś sobie materiał omówiony w tej lekcji.
Quiz
1. Jak się nazywa komponent Collider dostarczany przez kontroler postaci?
2. Która właściwość określa, jak daleko komponent Collider może
spenetrować kontroler postaci, zanim nastąpi wykrycie kolizji?
3. Jaki typ zmiennej zawiera informacje o kierunku kolizji?
4. Która metoda powoduje przesunięcie kontrolera i pozwala na ruch
wzdłuż osi Y, np. podczas skoku?
Ćwiczenie 257
Odpowiedzi
1. To jest Capsule Collider.
2. Właściwość Skin Width.
3. Zmienna typu CollisionFlags.
4. Metoda Move().
Ćwiczenie
Ćwiczenie dotyczy przede wszystkim tworzenia skryptu. Twoje zadanie polega
na zmianie skryptu kontrolera opracowanego w tej lekcji i dodanie wymienio‐
nych poniżej funkcji. Jak zwykle, jeżeli napotkasz trudności i będziesz potrze‐
bował pomocy, ukończony projekt (Hour14_Exercise) znajdziesz w materiałach
przeznaczonych dla bieżącej lekcji.
Zmodyfikuj kontroler w taki sposób, aby gracze mieli możliwość
zmiany kierunku ruchu tylko wtedy, gdy postać znajduje się
na ziemi. W obecnej postaci skryptu gracz może zmienić kierunek
postaci nawet wtedy, kiedy znajduje się ona w powietrzu.
Dodaj możliwość biegu (szybszy ruch) po przytrzymaniu klawisza
Shift.
Dodaj możliwość podwojenia skoku. Podwójny skok mamy wtedy,
gdy gracz skoczy i następnie skoczy ponownie (tylko raz), znajdując
się jeszcze w powietrzu.
258 Lekcja 14. Sterowanie postaciami
Lekcja 15
Trzecia gra
— Captain Blaster
Ukończony projekt
Aby ukończyć projekt gry, musisz wykonać kolejne kroki
zaprezentowane w lekcji. Jeżeli napotkasz problemy, ukoń-
czoną wersję gry znajdziesz w materiałach przeznaczonych dla
bieżącej lekcji. Przejrzyj te materiały, jeśli szukasz inspiracji!
260 Lekcja 15. Trzecia gra — Captain Blaster
Faza projektowania
Elementy fazy projektowania zostały omówione w lekcji 7., w której tworzyłeś
pierwszą grę zatytułowaną Amazing Racer. Teraz od razu przystąpisz do ich
zdefiniowania.
Koncepcja
Jak wcześniej wspomniano, Captain Blaster to dwuwymiarowa strzelanka
z przewijanym tłem. Gracz porusza się po scenie, niszczy meteory i ma za
zadanie po prostu przeżyć. Miłą cechą dwuwymiarowych gier z przewijanym
tłem jest fakt, że gracz w ogóle nie musi się poruszać. Przewijane tło po pro‐
stu symuluje poruszanie się gracza do przodu. W ten sposób maleją wyma‐
gania w zakresie umiejętności gracza, a twórca gry może się skoncentrować
na przygotowaniu większego wyzwania dla gracza, np. w postaci różnorod‐
nych wrogów.
Reguły
Reguły określają sposób prowadzenia gry, a ponadto mają wpływ na pewne
właściwości obiektów. Poniżej wymieniono reguły dla gry Captain Blaster.
Gra toczy się dopóty, dopóki gracz nie zderzy się z meteorem.
Nie ma warunku koniecznego do wygrania gry.
Gracz może strzelać pociskami, niszcząc w ten sposób meteory.
Za każdy zniszczony meteor gracz otrzymuje 1 punkt.
Gracz może wystrzelić dwa pociski w ciągu sekundy.
Pole manewru gracza jest ograniczone wymiarami ekranu.
Nowe meteory pojawiają się nieustannie, aż do chwili, gdy gracz
zostanie zniszczony.
Wymagania
Wymagania dla tworzonej gry są proste.
Tekstura tła przedstawiająca kosmos.
Model statku i odpowiednia tekstura dla niego.
Model meteoru i odpowiednia tekstura dla niego.
Kontroler gry; zostanie utworzony w Unity.
Materiał fizyczny pozwalający na odbijanie; zostanie utworzony
w Unity.
Interaktywne skrypty; zostaną przygotowane w edytorze
oprogramowania MonoDevelop.
Świat 261
Świat
Ponieważ akcja gry toczy się w przestrzeni kosmicznej, świat gry jest więc dość
łatwy do zaimplementowania. Idea polega na tym, że gra jest dwuwymiarowa
i poszczególne fragmenty tła będą przesuwane pionowo, wywołując u gracza
wrażenie, iż porusza się do przodu. W rzeczywistości postać sterowana przez
gracza będzie statyczna. Zanim przejdziesz do przewijania tła, najpierw trzeba
przygotować projekt. Pracę rozpocznij więc od wykonania poniższych kroków.
1. Utwórz nowy projekt w katalogu o nazwie Captain Blaster. Do sceny
dodaj światło kierunkowe.
2. Utwórz katalog Scenes i zapisz scenę pod nazwą Main.
3. W panelu Game zmień proporcje ekranu na 5:4 (patrz rysunek 15.1).
RYSUNEK 15.1.
Ustawienie
proporcji
ekranu gry
Kamera
Po prawidłowym przygotowaniu sceny możesz przejść do kamery. W tworzo‐
nej tutaj grze wykorzystasz kamerę typu Orthographic. Tego rodzaju kamera
nie uwzględnia perspektywy i doskonale sprawdza się w grach 2D. Aby przygo‐
tować kamerę Main Camera, wykonaj poniższe kroki.
1. Umieść kamerę w położeniu (0, 0, –10) bez rotacji.
2. We właściwości Projection kamery wybierz opcję Orthographic.
3. We właściwości Size wpisz wartość 6 (patrz rysunek 15.2).
Tło
Prawidłowe przygotowanie przewijanego tła może nastręczać trudności. Mamy
dwa obiekty tła poruszające się w dół sceny. Gdy dolny obiekt wypadnie poza
ekran, wtedy ponownie umieszczamy go na górze ekranu. Nieustannie wykorzy‐
stujemy dwa wspomniane obiekty, a gracz nigdy nie będzie o tym wiedział.
W celu przygotowania przewijanego tła wykonaj wymienione poniżej kroki.
262 Lekcja 15. Trzecia gra — Captain Blaster
RYSUNEK 15.2.
Właściwości
kamery
Main Camera
Płynne przewijanie
W przygotowanym wcześniej przewijanym tle prawdopodobnie zauwa-
żyłeś niewielką linię. Powstała ona, ponieważ obraz użyty w charakterze
tła nie został specjalnie przygotowany do kafelkowania. Linia nie jest aż
tak bardzo widoczna, a akcja w grze odwróci uwagę od tej drobnej wady.
Jeżeli w przyszłości będziesz chciał przygotować znacznie doskonalsze
przewijane tło, powinieneś użyć obrazu specjalnie przeznaczonego do
kafelkowania.
Elementy gry
W budowanej grze potrzebować będziesz trzech podstawowych elementów,
czyli gracza, meteoru i pocisku. Interakcje zachodzące między wymienionymi
elementami również są bardzo proste. Gracz wystrzeliwuje pociski. Pociski
niszczą meteory. Natomiast meteory niszczą gracza. Ponieważ gracz może
wystrzelić ogromną liczbę pocisków, a ponadto na ekranie może pojawić się
ogromna liczba meteorów, potrzebujesz sposobu na usuwanie tych elementów
z ekranu. W grze musi więc istnieć wyzwalacz, który spowoduje usunięcie
pocisków i meteorów trafianych przez pociski.
Gracz
Element gracza symbolizuje statek kosmiczny. Modele zarówno statku kosmicz‐
nego, jak i meteorów zostały opracowane przez Duane’a Mayberry’ego (http://
www.duanesmind.co.uk/) i znajdują się w materiałach przeznaczonych dla bie‐
żącej lekcji. W celu utworzenia gracza wykonaj wymienione poniżej kroki.
1. Utwórz nowy katalog o nazwie Meshes. W materiałach przeznaczonych
dla bieżącej lekcji odszukaj katalog o nazwie Space Shooter i przeciągnij
go na nowo utworzony katalog Meshes (w celu zaimportowania statku
kosmicznego).
2. W katalogu Meshes powinien teraz znajdować się podkatalog Space
Shooter. Odszukaj plik Space_Shooter.fbx i zmień w edytorze
współczynnik skalowania na 0.09 (patrz rysunek 15.3). Upewnij się,
że nacisnąłeś przycisk Apply na dole panelu Inspector.
3. W panelu Project kliknij Space_Shooter.fbx i przeciągnij na panel
Scene. Pojazd jest odwrócony w niewłaściwym kierunku. Umieść go
w położeniu (0, –4, –5) i zastosuj rotację (270, 0, 0).
4. W katalogu Space Shooter odszukaj podkatalog Textures, a następnie
kliknij 1K_Body-TXTR.jpg i przeciągnij ma model statku kosmicznego
wyświetlany w panelu Scene.
5. Do statku kosmicznego dodaj komponent Capsule Collider. Zaznacz
właściwość Is Trigger. Właściwości Radius przypisz wartość 0.62,
właściwości Height — wartość 1.71, natomiast z rozwijanego menu
Direction wybierz opcję Z-Axis (patrz rysunek 15.4).
264 Lekcja 15. Trzecia gra — Captain Blaster
RYSUNEK 15.3.
Model statku
kosmicznego
RYSUNEK 15.4.
Ustawienia
komponentu
Capsule Collider
statku
kosmicznego
Meteory
Kroki prowadzące do przygotowania meteorów są podobne do wykonanych
podczas tworzenia statku kosmicznego. Jedyna różnica polega na tym, że meteor
będzie prefabrykatem, aby można go było później wielokrotnie używać.
1. Odszukaj katalog Meteor1 i przeciągnij na utworzony wcześniej katalog
Meshes.
2. W katalogu Meteor1 znajdź plik Meteor1.fbx, a następnie w panelu
Inspector zmień współczynnik skalowania na 0.5. Upewnij się,
że kliknąłeś przycisk Apply w panelu Inspector.
Świat 265
Pociski
W budowanej tutaj grze pociski są proste. Ponieważ poruszają się bardzo
szybko, nie wymagają żadnych szczegółów. Poniżej wymieniono kroki nie‐
zbędne do przygotowania pocisku.
1. Do sceny dodaj kapsułę. Umieść ją w położeniu (0, 0, 0) i przeskaluj
(0.1, 0.1, 0.1). Następnie do kapsuły dodaj komponent Rigidbody
i usuń zaznaczenie właściwości Use Gravity.
2. Jeżeli wcześniej tego nie zrobiłeś, utwórz katalog Materials, a następnie
w nim nowy materiał o nazwie BulletMaterial. W materiale zdefiniuj
jasnozielony kolor. Materiał dołącz do pocisku.
3. Utwórz nowy prefabrykat o nazwie Bullet. Kliknij kapsułę i przeciągnij
na nowy prefabrykat. Teraz możesz już usunąć kapsułę ze sceny.
To był ostatni z podstawowych elementów gry. Do przygotowania pozostały
już tylko wyzwalacze, które uniemożliwią pociskom i meteorom podróżowa‐
nie w nieskończoność.
Wyzwalacze
Wyzwalacze to po prostu dwa sześciany, które zostaną umieszczone nad i pod
ekranem. Ich zadaniem jest przechwytywanie wszelkich zabłąkanych pocisków
i meteorów.
1. Do sceny dodaj sześcian i zmień mu nazwę na Trigger. Następnie
umieść go w położeniu (0, –9, –5) i przeskaluj (15, 1, 1).
2. W panelu Inspector upewnij się, że zaznaczyłeś właściwość Is Trigger
komponentu Box Collider.
3. Powiel wyzwalacz i umieść w położeniu (0, 9, –5).
266 Lekcja 15. Trzecia gra — Captain Blaster
W ten sposób wszystkie elementy gry znajdują się na swoich miejscach i można
przystąpić do przekształcenia sceny na grę.
Obiekty kontrolne
Przygotowanie działającej gry wymaga użycia komponentów różnych skryptów.
Gracz musi mieć możliwość poruszania się i wystrzeliwania pocisków. Z kolei
pociski i meteory muszą poruszać się automatycznie. Obiekt budujący meteory
będzie tworzył je w różnych miejscach. Wyzwalacze posłużą do usuwania
niepotrzebnych elementów, a obiekt kontrolera gry będzie nadzorował całą
rozgrywkę.
Kontroler gry
W budowanej tutaj grze kontroler gry jest prosty i dlatego zajmiesz się nim na
początku. Utwórz pusty obiekt gry i nadaj mu nazwę GameControl. Następnie
utwórz nowy skrypt o nazwie GameControlScript i dołącz go do kontrolera
gry. Zawartość skryptu zastąp przedstawionym poniżej kodem.
using UnityEngine;
using System.Collections;
void Start () {}
void Update () {}
void OnGUI()
{
if(isRunning == true)
{
GUI.Label(new Rect(5, 5, 100, 30), "Punkty: " +
playerScore);
}
Obiekty kontrolne 267
else
{
GUI.Label(new Rect(Screen.width / 2 - 100,
Screen.height / 2 - 50, 200,
100), "Koniec gry. Liczba zdobytych punktów: " +
playerScore);
}
}
}
W powyższym kodzie widać, że kontroler gry jest odpowiedzialny za wygene‐
rowanie GUI, obsługę punktacji i ustalenie, czy gra nadal się toczy. Kontroler
gry zawiera dwie funkcje publiczne: PlayerDied() i AddScore(). Pierwsza
z nich jest wywoływana przez gracza, gdy zostanie uderzony przez meteor.
Z kolei druga jest wywoływana przez pocisk, gdy uderzy on w meteor. W zależ‐
ności od stanu gry na ekranie jest wyświetlane odpowiednie GUI.
Skrypt meteoru
Meteory pojawiają się na górze ekranu, a następnie spadają w kierunku gracza.
Utwórz nowy skrypt o nazwie MeteorScript. W katalogu Prefabs zaznacz pre‐
fabrykat Meteor. W panelu Inspector odszukaj przycisk Add Component (patrz
rysunek 15.5) i kliknij Add Component/Scripts/Meteor Script.
RYSUNEK 15.5.
Przycisk Add
Component
using UnityEngine;
using System.Collections;
void Start () {
rotation = Random.Range(-40, 40);
}
void Update () {
transform.Translate(0f, speed * Time.deltaTime, 0f);
transform.Rotate(0f, rotation * Time.deltaTime, 0f);
}
}
Skrypt przeznaczony do obsługi meteoru jest bardzo prosty. Zawiera zmienne
przechowujące szybkość (speed) i rotację (rotation). Zastosowano rotację,
aby poszczególne meteory nieco się różniły od siebie. W metodzie Start()
następuje losowe wybranie wartości rotacji z zakresu od –40 do 40. Z kolei
w metodzie Update() meteor jest przesuwany w dół ekranu i obracany wokół
osi Y o wartość przechowywaną w zmiennej rotation. Zwróć uwagę, że meteor
nie jest odpowiedzialny za określanie, czy doszło do kolizji.
Tworzenie meteorów
Na razie meteory są jedynie prefabrykatami nieumieszczonymi na scenie.
Potrzebujesz obiektu odpowiedzialnego za umieszczanie meteorów na scenie
w ustalonych odstępach czasu. Utwórz więc nowy, pusty obiekt gry. Zmień jego
nazwę na MeteorSpawn i umieść w położeniu (0, 7, –5). Teraz utwórz nowy
skrypt o nazwie MeteorSpawnScript i dołącz do obiektu MeteorSpawn. Zawar‐
tość skryptu meteoru zastąp przedstawionym poniżej kodem.
using UnityEngine;
using System.Collections;
// Prefabrykat meteoru.
public GameObject meteor;
void Start () {}
void Update () {
Obiekty kontrolne 269
spawnThreshold -= spawnDecrement;
if(spawnThreshold < 2)
{
spawnThreshold = 2;
}
}
}
}
Pod wieloma względami działanie skryptu jest interesujące. Na początku po‐
wstają dwie zmienne przeznaczone do zarządzania licznikiem czasu. Ponadto
zdefiniowana jest zmienna typu GameObject przeznaczona do przechowywania
prefabrykatu meteoru. W metodzie Update() skrypt tworzy losową liczbę
z zakresu od 0 do spawnThreshold (na początek to 100). Jeżeli losowo wybrana
liczba jest równa lub mniejsza niż 1, następuje utworzenie meteoru. Jak możesz
zobaczyć, każdy tworzony meteor ma tę samą wartość dla współrzędnych Y i Z,
natomiast współrzędna X jest przesunięta o wartość z zakresu od -6 do 6.
W ten sposób meteor jest tworzony w różnych punktach ekranu, a nie zawsze
w tym samym. Wreszcie wartość spawnThreshold jest zmniejszana o spawnDe
crement. Jeżeli wartość spawnThreshold spadnie poniżej 2, wtedy warto‐
ścią będzie 2. Takie rozwiązanie powoduje, że wraz z upływem czasu meteory
spadają coraz szybciej. Ponieważ zmniejszył się całkowity zakres, na podstawie
którego jest losowo generowana liczba, wzrasta prawdopodobieństwo wylo‐
sowania liczby mniejszej lub równej 1. W efekcie meteory pojawiają się coraz
szybciej.
W edytorze Unity kliknij prefabrykat Meteor w panelu Project i przeciągnij go
na właściwość Meteor komponentu Meteor Spawn Script obiektu MeteorSpawn.
Po uruchomieniu sceny zobaczysz meteory spadające na ekranie, na początku
bardzo wolno.
Skrypt wyzwalacza
Skoro meteory pojawiają się wszędzie, dobrym pomysłem będzie ich usuwanie.
Utwórz więc nowy skrypt o nazwie TriggerScript i dołącz do umieszczonych
na górze i dole ekranu przygotowanych wcześniej obiektów wyzwalaczy.
Następnie w skrypcie umieść przedstawiony poniżej kod. Upewnij się, że kod
znajduje się w klasie, ale nie w jakiejkolwiek z istniejących w niej metod.
270 Lekcja 15. Trzecia gra — Captain Blaster
Skrypt gracza
Na tym etapie prac meteory spadają, ale gracz nie może ich usuwać. Trzeba więc
opracować skrypt kontrolny dla gracza. Utwórz nowy skrypt o nazwie Player-
Script i dołącz go do obiektu statku kosmicznego. Zawartość skryptu zastąp
przedstawionym poniżej kodem.
using UnityEngine;
using System.Collections;
// Prefabrykat pocisku.
public GameObject bullet;
// Skrypt kontrolny.
public GameControlScript control;
void Start () {}
void Update () {
// Monitorowanie czasu dla wystrzeliwania pocisków.
elapsedTime += Time.deltaTime;
RYSUNEK 15.6.
Połączenie
skryptu gracza
Skrypt pocisku
Ostatni fragment interaktywności, który musisz utworzyć, pozwala na poru‐
szanie się pocisków i obsługę ich kolizji. Utwórz nowy skrypt o nazwie Bullet-
Script i dodaj go do prefabrykatu pocisku. Zawartość skryptu pocisku zastąp
przedstawionym poniżej kodem.
using UnityEngine;
using System.Collections;
void Start () {
// Ponieważ obiekt kontrolny gry jest już utworzony,
// trzeba go odszukać w trakcie trwania gry.
Usprawnienie gry 273
control = GameObject.Find("GameControl").
GetComponent<GameControlScript>();
}
void Update () {
// Ruch w górę.
transform.Translate(0f, speed * Time.deltaTime, 0f);
}
Usprawnienie gry
Podobnie jak wcześniejsze gry, także i tę można jeszcze usprawnić. Wiele kom‐
ponentów celowo pozostawiono w najprostszej postaci. Zagraj kilkakrotnie
i zobacz, jak przebiega akcja gry. Które aspekty gry zapewniają rozrywkę,
a które nie są już tak ciekawe? Czy istnieją jakiekolwiek oczywiste sposoby
pozwalające na zepsucie gry? W grze gracz może bardzo łatwo oszukiwać i zdo‐
być dużą ilość punktów. Czy jesteś w stanie odkryć, w jaki sposób?
274 Lekcja 15. Trzecia gra — Captain Blaster
Podsumowanie
W tej lekcji opracowałeś grę zatytułowaną Captain Blaster. Na początku zapro‐
jektowałeś elementy gry. Następnie przystąpiłeś do tworzenia świata, w któ‐
rym toczy się akcja gry. Przygotowałeś animowane w pionie tło gry. Później
zająłeś się budową różnych elementów gry, a także zapewniłeś jej interak‐
tywność za pomocą skryptów i obiektów kontrolnych. Na końcu przeanalizo‐
wałeś grę i spróbowałeś znaleźć obszary, na których można ją usprawnić.
Pytania i odpowiedzi
Pytanie: Czy meteory mają powstawać w tak długich odstępach czasu?
Odpowiedź: Gra została zaprojektowana w taki sposób, aby wraz z upływem
czasu meteory powstawały coraz szybciej. Jeżeli według Ciebie powstają
zbyt wolno, możesz zmienić wartość graniczną (spawnThreshold).
Pytanie: Czy kapitan Blaster (ang. Captain Blaster) naprawdę ma stopień
kapitana, czy to tylko nazwa?
Odpowiedź: Trudno powiedzieć, to są jedynie spekulacje. Jednego możesz
być pewien: porucznikom nie pozwala się na kierowanie statkami
kosmicznymi!
Pytanie: Dlaczego pociski można wystrzeliwać jedynie co pół sekundy?
Odpowiedź: Tylko ze względu na zachowanie równowagi. Jeżeli gracz będzie
mógł strzelać zbyt często, gra nie będzie stanowiła wyzwania.
Warsztaty 275
Warsztaty
Poświęć nieco czasu i odpowiedz na zamieszczone poniżej pytania, a także
upewnij się, że przyswoiłeś sobie materiał omówiony w tej lekcji.
Quiz
1. Jaki jest warunek, którego spełnienie oznacza wygraną w grze?
2. Na jakiej zasadzie działa przewijanie tła?
3. Które obiekty mają komponent Rigidbody? Które obiekty mają
komponent typu Collider?
4. Meteor jest odpowiedzialny za wykrywanie kolizji z obiektem
kierowanym przez gracza. Prawda czy fałsz?
5. W jaki prosty sposób gracz może oszukiwać w opracowanej tutaj grze?
Odpowiedzi
1. To jest trudne pytanie. Gracz nie może odnieść zwycięstwa w grze.
Jednak gracz, który uzyska największą liczbę punktów, może być
uznany za „zwycięzcę”.
2. Dwa sześciany wraz z teksturami zostały ułożone jeden na drugim.
Następnie pojawiają się kolejno przed kamerą i powodują złudzenie
animacji tła w nieskończoność.
3. Pociski i meteory zawierają komponent Rigidbody. Natomiast pociski,
meteory, gracz i wyzwalacze mają komponenty Collider.
4. Fałsz.
5. Wyszukanie takiego sposobu należy do Ciebie. To pytanie miało Ci
jedynie przypomnieć o wyszukaniu sposobu, jeśli o tym zapomniałeś.
276 Lekcja 15. Trzecia gra — Captain Blaster
Ćwiczenie
To ćwiczenie będzie nieco dziwne w porównaniu do innych, dotąd przedsta‐
wianych. W trakcie procesu dopracowywania gry najczęściej pozwala się na
jej przetestowanie osobom, które nie uczestniczyły w pracach nad grą. W ten
sposób osoby zupełnie nieznające gry mogą szczerze podzielić się swoimi spo‐
strzeżeniami. Są to niezwykle cenne informacje. Ćwiczenie polega na tym, aby
grę dać do przetestowania innym osobom. Postaraj się zróżnicować grupę
testujących grę. O ile to możliwe, wybierz osoby grające i niegrające w gry.
Spróbuj wyszukać graczy będących i niebędących fanami tego gatunku gier.
Otrzymane informacje pogrupuj na funkcje dobre, niewłaściwe i możliwe do
usprawnienia. Ponadto sprawdź, czy istnieją jakiekolwiek najczęściej ocze‐
kiwane funkcje, które nie są jeszcze zaimplementowane w grze. Na końcu
zobacz, czy będziesz w stanie zaimplementować oczekiwane funkcje lub popra‐
wić istniejące na podstawie informacji otrzymanych od osób testujących grę.
Lekcja 16
Systemy cząsteczek
Systemy cząsteczek
System cząsteczek to właściwie obiekt lub komponent emitujący inne obiekty,
najczęściej określane mianem cząsteczek. Cząsteczki mogą być szybkie, wolne,
bezkształtne, kształtne, małe lub wielkie. Definicja jest bardzo ogólna, ponie‐
waż po zastosowaniu odpowiednich ustawień systemy cząsteczek pozwalają
na osiągnięcie naprawdę różnorodnych efektów. Mogą utworzyć strumień
ognia pozostawiany przez samolot odrzutowy, smugi na kłębach dymu,
świetliki, deszcz, mgłę lub cokolwiek innego, co tylko sobie wyobrazisz. Wymie‐
nione efekty są najczęściej nazywane efektami systemu cząsteczek.
Cząsteczki
Cząsteczka to pojedynczy element emitowany przez system cząsteczek. Ponie‐
waż w danej chwili generowana jest ogromna liczba cząsteczek, bardzo ważne
jest, aby były maksymalnie efektywne. Dlatego też większość cząsteczek to
po prostu dwuwymiarowe billboardy. Pamiętaj, że billboard to płaski obraz
zawsze zwrócony przodem do kamery. W ten sposób otrzymujemy złudzenie
efektu trójwymiarowego.
Wypróbuj samodzielnie
Własne cząsteczki
Domyślnie cząsteczki w Unity są małymi, białymi kulami przechodzącymi
do przezroczystości. To jest naprawdę użyteczna podstawowa cząsteczka,
ale nic więcej Ci nie zaoferuje. Czasami potrzeba czegoś konkretnego, np.
do utworzenia ognia. Jeżeli chcesz, możesz opracować własne cząsteczki na
podstawie dowolnego obrazu 2D i tym samym przygotować efekt dokład-
nie spełniający określone wymagania.
RYSUNEK 16.2.
Kontrolki efektów
systemu
cząsteczek
280 Lekcja 16. Systemy cząsteczek
Efekt cząsteczek
W celu utworzenia skomplikowanych i atrakcyjniejszych wizualnie efektów
konieczne jest użycie wielu współdziałających systemów cząsteczek, np.
dymu i ognia. Gdy wiele systemów cząsteczek współpracuje, mówimy
o efekcie cząsteczek. W Unity utworzenie efektu cząsteczek polega na
zagnieżdżeniu systemów cząsteczek. Jeden system cząsteczek może być
elementem potomnym innego lub oba mogą być elementami potomnymi
zupełnie innego obiektu. W wyniku tego efekt cząsteczek w Unity jest
traktowany jak jeden system, a wspomniane wcześniej kontrolki efektu czą-
steczek sterują całym efektem jako całością.
Krótkie wprowadzenie
Część modułów ma właściwości, których nazwy są oczywiste (np. właści-
wości Length i Width w Rectangle) lub zostały już wcześniej omówione.
W celu zachowania prostoty i uniknięcia nadmiernego rozbudowania tej
lekcji omówione wcześniej właściwości pominięto. Jeżeli więc widzisz na
ekranie więcej właściwości niż przedstawiono w tekście, nie przejmuj się,
ponieważ to jest celowe.
Moduł domyślny
Moduł domyślny jest po prostu oznaczony jako Particle System. W tym module
znajdują się wszelkie informacje wymagane przez każdy system cząsteczek.
Właściwości modułu domyślnego zostały wymienione w tabeli 16.1.
Moduły systemu cząsteczek 281
RYSUNEK 16.3.
Wyświetlenie
wszystkich
modułów
Moduł Emission
Moduł Emission jest używany do określenia częstotliwości emisji cząsteczek.
Za pomocą tego modułu można wskazać, czy cząsteczki są strumieniowane
ze stałą częstotliwością, falami, czy w sposób pośredni. Właściwości modułu
Emission wymieniono w tabeli 16.2.
Moduł Shape
Jak sama nazwa wskazuje, moduł Shape pozwala na określenie kształtu for‐
mowanego przez wyemitowane cząsteczki. Dostępne są opcje Sphere (kula),
Hemisphere (półkula), Cone (stożek), Box (sześcian) i Mesh (siatka). Ponadto
każdy kształt ma pewien zestaw właściwości pozwalających na dokładniej‐
sze zdefiniowanie. Właściwości to np. promień dla kuli i stożka. Ponieważ
przeznaczenie tych właściwości jest oczywiste, nie zostały tutaj omówione.
282 Lekcja 16. Systemy cząsteczek
RYSUNEK 16.4.
Moduł Emission
RYSUNEK 16.5.
Edytor gradientu
Moduł Collision
Moduł Collision umożliwia zdefiniowanie kolizji cząsteczek. Jest to bardzo
użyteczne dla wszelkiego rodzaju efektów kolizji, np. ognia odbijającego się
od ściany lub deszczu uderzającego w ziemię. Kolizje można skonfigurować
286 Lekcja 16. Systemy cząsteczek
Wypróbuj samodzielnie
Moduł Renderer
Moduł Renderer określa sposób, w jaki rzeczywiście zostaną wyświetlone czą‐
steczki. W tym miejscu możesz wskazać teksturę używaną przez cząsteczki oraz
inne ich właściwości dotyczące wyświetlania. Właściwości modułu Renderer
zostały wymienione w tabeli 16.10.
Edytor krzywych
Kilka wartości w różnych wymienionych wcześniej modułach ma możliwość
ustawienia opcji typu Constant (stała) lub Curve (krzywa). Opcji Constant nie
trzeba wyjaśniać — przypisujesz wartość, która pozostaje później niezmieniona.
Co zrobić w sytuacji, gdy chcesz, aby wartość uległa zmianie po pewnym
okresie czasu? Tutaj z pomocą przychodzi nowy system krzywych. Z pomocą
tej funkcji zyskujesz bardzo dokładną kontrolę nad zachowaniem wartości.
Edytor krzywych znajduje się na dole panelu Inspector (patrz rysunek 16.8).
RYSUNEK 16.8.
Edytor krzywych
Podsumowanie
W tej lekcji przedstawiono wprowadzenie do systemów cząsteczek w środo‐
wisku Unity. Poznałeś podstawy zarówno cząsteczek, jak i systemów cząsteczek.
Następnie przeszedłeś do omówienia wielu modułów tworzących system
cząsteczek w Unity. Na końcu zająłeś się edytorem krzywych w Unity.
Pytania i odpowiedzi 291
Wypróbuj samodzielnie
Pytania i odpowiedzi
Pytanie: Czy system cząsteczek jest nieefektywny?
Odpowiedź: Tak może się zdarzyć. Wszystko zależy od wybranych ustawień.
Najlepiej korzystać z systemu cząsteczek tylko wtedy, jeśli poprawia
wartość gry. System cząsteczek może być atrakcyjny wizualnie, ale nie
należy przesadzać z jego użyciem.
Warsztaty
Poświęć nieco czasu i odpowiedz na zamieszczone poniżej pytania, a także
upewnij się, że przyswoiłeś sobie materiał omówiony w tej lekcji.
292 Lekcja 16. Systemy cząsteczek
Quiz
1. Jak się nazywa dwuwymiarowy obraz, który zawsze jest zwrócony
przodem do kamery?
2. Jak się nazywa nowy system cząsteczek w Unity?
3. Który moduł określa sposób wyświetlania cząsteczek?
4. Edytor krzywych jest używany do tworzenia krzywych, które powodują
zmianę wartości na przestrzeni czasu. Prawda czy fałsz?
Odpowiedzi
1. To billboard.
2. System cząsteczek Shuriken.
3. Moduł Renderer.
4. Prawda.
Ćwiczenie
W tym ćwiczeniu poeksperymentujesz z pewnymi istniejącymi efektami czą‐
steczek oraz spróbujesz utworzyć własny. Przede wszystkim zwróć uwagę, że
efekty cząsteczek w Unity zostały zbudowane za pomocą starszego systemu.
Oznacza to, że nie mają tych samych modułów lub ustawień, które omówiono
w lekcji. To nie stanowi żadnego problemu, a jednocześnie jest użyteczne do
porównania sposobu pracy starego i nowego systemu cząsteczek. Ponieważ
to ćwiczenie pozwala na eksperymenty zarówno z istniejącymi efektami, jak
i utworzenie własnych, nie istnieje więc jedno prawidłowe „rozwiązanie”.
Kieruj się wymienionymi poniżej krokami i użyj wyobraźni.
1. Zaimportuj pakiet efektów cząsteczek, wybierając opcję menu
Assets/Import Package/Particles. Upewnij się, że pozostawiłeś
zaznaczone wszystkie opcje, a następnie kliknij przycisk Import.
2. Odszukaj katalog Fire, który powinien znajdować się w nowo
utworzonej strukturze katalogów Standard Assets/Particles. Kliknij
prefabrykaty Fire i Flame, a następnie przeciągnij je na scenę.
Poeksperymentuj z położeniem i ustawieniami tych efektów.
3. Kontynuuj eksperymenty z pozostałymi efektami cząsteczek. (Wypróbuj
efekty Dust i Water).
4. Skoro zobaczyłeś, jakie możliwości daje system cząsteczek, spróbuj
samodzielnie utworzyć efekt. Wypróbuj różne moduły i staraj się
opracować ciekawy efekt cząsteczek.
Lekcja 17
Animacje
Systemy animacji
W środowisku Unity mogą zostać użyte dwa systemy anima-
cji. W tej lekcji zajmiemy się starszym z nim. Postacie będą
kontrolowane na bardzo szczegółowym poziomie. Jednak już
w kolejnej lekcji przejdziemy do nowego systemu animacji
Mecanim i rozpoczniemy pracę z nowym i oferującym potężne
możliwości kontrolerem Animator.
294 Lekcja 17. Animacje
Podstawy animacji
Animacja składa się z zestawu klatek statycznych. W grach dwuwymiarowych
oznacza to użycie wielu sekwencyjnych obrazów, które bardzo szybko się
zmieniają. Wynikiem jest powstanie efektu poruszającego się obiektu. Efekt
można porównać do staroświeckiej książki, w której bardzo szybko przerzuca
się kartki, a na każdej z nich narysowana jest jedna klatka animacji. W świecie
3D animacja jest zupełnie inna. W grach trójwymiarowych do przedstawienia
elementów gry używane są modele. Nie można po prostu przechodzić między
kolejnymi modelami, licząc na powstanie iluzji ruchu. Konieczne jest rzeczywi‐
ste poruszanie częściami modelu, a to wymaga odpowiedniego przygotowania
modelu (ang. rigging) i animacji.
Przygotowanie modelu
Animacja modelu bez odpowiedniego przygotowania jest niemożliwa (lub
niezwykle trudna). Bez riggingu modelu komputer „nie wie”, które fragmenty
modelu mogą się poruszać oraz jak mają się poruszać. Mógłbyś w tym miejscu
zapytać, czym dokładnie jest rigging? Przypomnij sobie szkielet człowieka
(patrz rysunek 17.1), rigging wskazuje te części modelu, które są sztywne
i często nazywane kośćmi. Ponadto określa, które części mogą się zginać —
te części są nazywane złączeniami.
RYSUNEK 17.1.
Szkielet
przedstawiony
jako rigging
Przygotowanie modelu do animacji 295
Animacja
Model po odpowiednim przygotowaniu (rigging) można wykorzystać w ani‐
macji. Pod względem technicznym animację można określić jako serię instrukcji
dla riggingu — podnieś prawą dłoń, opuść prawą dłoń, podnieś prawą dłoń,
pomachaj nią itd. Instrukcje można odegrać, tak jak w filmie. Istnieje nawet
możliwość ich wstrzymania, przejścia przez nie lub odtworzenia wstecz. Co
więcej, prawidłowe przygotowanie modelu powoduje, że zmiana akcji jest
niezwykle prosta i sprowadza się do zmiany w animacji. Czasami animacje
mogą być dostarczane wraz instrukcjami przenoszącymi cały model w prze‐
strzeni 3D. Najlepsze jest to, że jeśli masz dwa zupełnie różne modele wypo‐
sażone w ten sam rigging, tę samą animację możesz zastosować dla obu modeli.
Dlatego też ork, człowiek, olbrzym i wilkołak mogą wykonać tę samą animację
przedstawiającą taniec.
Poszukiwani artyści 3D
Prawda dotycząca animacji jest następująca: większość pracy będzie wyko-
nywana poza programami, takimi jak Unity. Ogólnie rzecz biorąc, mode-
lowanie, teksturowanie, rigging i animacje są przygotowywane przez pro-
fesjonalistów nazywanych artystami 3D w programach, takich jak Blender,
Maya, 3D Studio Max lub innych przeznaczonych do tworzenia 3D. Opra-
cowanie wymienionych zasobów wymaga znacznych umiejętności i prak-
tyki. Dlatego też ich tworzenie nie jest omawiane w tej książce. Tu poka-
zano, jak pobrać gotowe zasoby 3D i wykorzystać je w Unity do
opracowania interaktywnej aplikacji. Pamiętaj, że budowanie gry nie
sprowadza się jedynie do połączenia razem jej wszystkich elementów.
Możesz sprawić, że gra działa, ale dopiero dzięki artyście nabierze odpo-
wiedniego wyglądu.
RYSUNEK 17.2.
Pasek
wyszukiwania
w sklepie Unity
Asset Store
Szukasz bezpłatnego modelu o nazwie 3dsmax Bip Warrior Anim Free; gdy go
znajdziesz, kliknij przycisk Import (patrz rysunek 17.3). Po wyświetleniu okna
dialogowego Import Package sprawdź, czy pozostawiłeś zaznaczenie wszyst‐
kich opcji, i kliknij przycisk Import.
W panelu Project powinieneś zobaczyć nowy katalog o nazwie 3dsmax Bip
Warrior Anim Free. Poświęć chwilę na przejrzenie jego zawartości, ponieważ
będziesz z niej korzystać w tej lekcji.
Demo
Model żołnierza jest dostarczany wraz ze sceną demonstracyjną. Znajdziesz
ją w podkatalogu Scenes katalogu 3dsmax Bip Warrior Anim Free. Otwo-
rzenie wspomnianej sceny pozwoli na przetestowanie modelu z różnymi
przygotowanymi dla niego animacjami.
Przygotowanie modelu do animacji 297
RYSUNEK 17.3.
Model wymagany
w tej lekcji
Model
Używany w tej lekcji model znajduje się w podkatalogu Models nowo utwo‐
rzonego katalogu 3dsmax Bip Warrior Anim Free. Nazwa modelu to Soldier_f_0.
Odszukaj ten model i zaznacz go. Jak pokazano na rysunku 17.4, w panelu
Inspector powinieneś zobaczyć trzy podstawowe karty: Model, Rig i Animations.
RYSUNEK 17.4.
Panel Inspector
dla modelu
RYSUNEK 17.5.
Ustawienia
w karcie Rig
RYSUNEK 17.6.
Ustawienia
animacji
RYSUNEK 17.7.
Obiekty potomne
w modelu
Zasoby animacji
Kolejnym krokiem jest przejrzenie zasobów animacji i upewnienie się, że
zostały skonfigurowane w oczekiwany przez Ciebie sposób. W katalogu 3dsmax
Bip Warrior Anim Free odszukaj podkatalog Animations. Podkatalog będzie
zawierał cztery dostępne animacje: Death, Idle0, Idle1 i Idle2. Wybór dowolnego
z zasobów animacji pozwoli na modyfikację jego właściwości Wrap Mode
i wyświetlenie podglądu. Jednak zanim wyświetlisz podgląd animacji, konieczne
jest dostarczenie modelu. Na rysunku 17.8 pokazano wygląd okna Preview
przed wskazaniem modelu.
Stosowanie animacji 299
RYSUNEK 17.8
Wygląd okna
Preview,
gdy model
nie został
wskazany
RYSUNEK 17.9.
Dodanie modelu
do okna podglądu
Teraz możesz już nacisnąć przycisk Play w oknie Preview, aby wyświetlić
podgląd animacji wybranego modelu. Poświęć chwilę i wyświetl podgląd
wszystkich czterech animacji dostarczonych wraz z modelem. Nie przejmuj
się teraz właściwością Wrap Mode, jej dokładne omówienie znajdziesz dalej
w tej lekcji.
Stosowanie animacji
Jak przekonałeś się wcześniej w tej lekcji, model żołnierza ma dołączony
komponent Animation. Komponent działa jak zbiór różnych animacji, które
można stosować na modelu po uruchomieniu aplikacji. Właściwości kompo‐
nentu Animation zostały wymienione w tabeli 17.1.
300 Lekcja 17. Animacje
Wypróbuj samodzielnie
Dodawanie animacji
Jak wcześniej wspomniano, animację można zastosować na modelu przez jej
przeciągnięcie na właściwość Animations komponentu Animation (patrz rysu‐
nek 17.10).
Skrypty i animacje 301
RYSUNEK 17.10.
Dodanie animacji
do modelu
Skrypty i animacje
Wprawdzie miło mieć model odtwarzający zapętloną animację postaci pozo‐
stającej w stanie bezczynności, ale to może stać się nieco nudne. Niemal na
pewno będziesz chciał, aby modele robiły coś więcej, a nie tylko odtwarzały
zapętloną animację. Jak wcześniej wspomniano, do właściwości Animations
komponentu Animation można dodać wiele animacji. Jednak nie przedstawiono
jeszcze sposobu przełączania między animacjami po uruchomieniu sceny.
302 Lekcja 17. Animacje
Wypróbuj samodzielnie
Animacja modelu
W tym ćwiczeniu użyjesz sceny utworzonej w poprzednim zatytułowanym
„Dodanie żołnierza do sceny”. Jeżeli jej jeszcze nie masz, musisz wrócić do
poprzedniego ćwiczenia i je wykonać. Tutaj zajmiesz się animacją modelu
żołnierza. Po zakończeniu pracy nad sceną zapisz ją, ponieważ użyjesz jej
dalej w tej lekcji.
1. Otwórz poprzednio utworzoną scenę.
2. Przeciągnij wszystkie animacje na właściwość Animations komponentu
Animation. Przeciągnij animację Idle0 na właściwość Animations
komponentu Animation.
3. Uruchom scenę. Zwróć uwagę, że animacja Idle0 jest odtwarzana dla
żołnierza. Zatrzymaj scenę, powróć do edytora i następnie na modelu
wypróbuj pozostałe animacje. Zobacz, jaki efekt powoduje każda z nich.
Zauważ również, że animacja Death nie jest zapętlona i zatrzymuje się
po odtworzeniu.
Wypróbuj samodzielnie
Podsumowanie
W tej lekcji zająłeś się animacjami w Unity. Na początku przedstawiono pod‐
stawy dotyczące animacji. Następnie przeszedłeś do samych animacji i riggingu.
Kolejnym etapem było zaimportowanie ze sklepu Unity Asset Store modelu
wraz ze zdefiniowanymi dla niego animacjami. Dowiedziałeś się, jak zastoso‐
wać animacje na modelu oraz zobaczyłeś odtwarzane animacje po urucho‐
mieniu sceny. Na koniec poruszony został temat zmiany odtwarzanej animacji
za pomocą skryptu.
Pytania i odpowiedzi
Pytanie: Czy animacje można łączyć?
Odpowiedź: Oczywiście. Zostanie to omówione w kolejnej lekcji poświęconej
nowemu w Unity systemowi Mecanim.
304 Lekcja 17. Animacje
Wypróbuj samodzielnie
Zmiana animacji
W tym ćwiczeniu za pomocą skryptu zmienisz animację modelu, gdy scena
jest uruchomiona. Wspomniana zmiana animacji modelu odbywa się
w metodzie Start(). W ćwiczeniu użyjesz sceny utworzonej we wcześniej-
szym zatytułowanym „Dodanie żołnierza do sceny”.
1. Otwórz poprzednio utworzoną scenę. Upewnij się, że idle0 to domyślna
animacja żołnierza. Opcjami wybranymi we właściwości Animations
komponentu Animation powinny być zdefiniowane cztery animacje
używane w tej lekcji.
2. Utwórz nowy skrypt o nazwie SoldierScript i dołącz go do modelu
żołnierza znajdującego się na scenie. Kod metody Start() skryptu
powinien przedstawiać się tak.
void Start() {
transform.animation.Play("idle1");
}
3. Uruchom scenę i zauważ, że model ma zapętloną animację idle1.
Zatrzymaj scenę i powróć do skryptu. Zmień animację z idle1 na idle2
i ponownie uruchom scenę. To samo zrób dla animacji death. Przetestuj
różne animacje i sprawdź, jak się zachowują.
Warsztaty
Poświęć nieco czasu i odpowiedz na zamieszczone poniżej pytania, a także
upewnij się, że przyswoiłeś sobie materiał omówiony w tej lekcji.
Ćwiczenie 305
Quiz
1. Jakim mianem jest określany „szkielet” modelu?
2. Które opcje właściwości Wrap Mode pozwalają na odtwarzanie
do przodu i wstecz zapętlonej animacji?
3. Właściwość Animations komponentu Animation zawiera wszystkie
dostępne animacje dla modelu. Prawda czy fałsz?
4. Animacje są odtwarzane za pomocą metody transform.animation.
Play(). Prawda czy fałsz?
Odpowiedzi
1. Rig lub rigging.
2. Opcja Ping Pong.
3. Fałsz. Właściwość Animations wskazuje animację domyślną, natomiast
Animation wskazuje zbiór animacji.
4. Prawda.
Ćwiczenie
W tym ćwiczeniu utworzysz skrypt przeznaczony do zmiany animacji „w locie”
za pomocą klawiszy numerycznych. Ukończony projekt ćwiczenia znajdziesz
w katalogu Hour17_Exercise w materiałach przeznaczonych dla bieżącej lekcji.
W ćwiczeniu wykorzystasz scenę utworzoną wcześniej w innym ćwiczeniu
zatytułowanym „Dodanie żołnierza do sceny”.
1. Otwórz wcześniej utworzoną scenę. Upewnij się, że idle0 to domyślna
animacja dla żołnierza. Opcjami wybranymi we właściwości Animations
komponentu Animation powinny być wszystkie cztery używane
dotąd animacje.
2. Utwórz nowy skrypt o nazwie SoldierScript i dołącz go do modelu
żołnierza znajdującego się na scenie. Kod metody Start() skryptu
powinien przedstawiać się tak, jak poniżej.
void Start() {
if(Input.GetKeyDown(KeyCode.Alpha1))
transform.animation.Play("idle0");
else if(Input.GetKeyDown(KeyCode.Alpha2))
transform.animation.Play("idle1");
else if(Input.GetKeyDown(KeyCode.Alpha3))
transform.animation.Play("idle2");
else if(Input.GetKeyDown(KeyCode.Alpha4))
transform.animation.Play("death");
}
306 Lekcja 17. Animacje
Wypróbuj samodzielnie
Z powodu skomplikowania animatorów lekcję tę można
potraktować jako jedną dużą ramkę typu „Wypróbuj samo-
dzielnie”. Oznacza to, że powinieneś wykonywać wszystkie
kroki, gdy są przedstawiane w tekście. Dzięki temu zyskasz
pewność, że tworzony projekt będzie gotowy, gdy wszystko
zacznie się zazębiać. W tej książce znajduje się kilka lekcji,
które można po prostu przeczytać. Ta na pewno nie zalicza
się do jednej z nich.
308 Lekcja 18. Animator
Rigging modeli
Jak sobie przypominasz z poprzedniej lekcji, modele i animacje muszą mieć
dokładnie ten sam rigging, aby wszytko działało zgodnie z oczekiwaniami.
Oznacza to, że dostosowanie animacji z jednego modelu do działania w innym
jest bardzo trudne. W nowym systemie Mecanim ponowny rigging modelu
można przeprowadzić bezpośrednio w edytorze Unity bez konieczności użycia
jakichkolwiek narzędzi przeznaczonych do modelowania 3D. Wskutek tego
dowolna animacja przygotowana dla modelu Mecanim może działać z dowol‐
nym modelem, którego ponowny rigging przeprowadzono w Unity. Animatorzy
mogą teraz tworzyć ogromne biblioteki animacji, które następnie można zasto‐
sować do ogromnej liczby modeli przy użyciu wielu różnych riggingów.
Rigging modeli jest przeprowadzany w panelu Inspector. W tej części lekcji
wykorzystasz model o nazwie Jack opracowany przez utalentowanego artystę
Matta Muzziego (http://www.mattmuzzy.com/). Model znajdziesz w katalogu
Jack w materiałach przeznaczonych dla bieżącej lekcji. Wprawdzie w standar‐
dowo dostarczanym modelu Jack rigging został już przygotowany, ale ponow‐
nie przeprowadzisz go w Unity, aby dostosować model do pracy z zasobem
animatora. W celu zaimportowania i konfiguracji modelu wykonaj wymienione
poniżej kroki.
1. W edytorze Unity utwórz katalog o nazwie Models, a następnie
z materiałów przeznaczonych dla bieżącej lekcji przeciągnij katalog Jack.
2. W katalogu Jack odszukaj model o nazwie Jack1 i zaznacz go. W panelu
Inspector kliknij kartę Animations i usuń zaznaczenie właściwości
Import Animation. Kliknij przycisk Apply.
3. W karcie Rig zmień typ animacji na Humanoid. To spowoduje
pojawienie się właściwości o nazwie Avatar Definition. Właściwość
jest przeznaczona do przeprowadzenia mapowania riggingu. Spójrz
na rysunek 18.1, upewnij się, że tak samo ustawiłeś właściwości,
a następnie kliknij przycisk Apply.
Podstawy zasobu Animator 309
RYSUNEK 18.1.
Ustawienia
riggingu
RYSUNEK 18.2.
Model Jack
w pozycji T
RYSUNEK 18.3.
Model
z prawidłowym
riggingiem
RYSUNEK 18.4.
Model
z nieprawidłowym
riggingiem
Podstawy zasobu Animator 311
RYSUNEK 18.5.
Wymuszenie
użycia pozycji T
Przygotowanie animacji
W tej lekcji będziesz używać zestawu animacji Mecanim, które są dostarczane
w środowisku Unity w demo, które jest przeznaczone dla zestawu Mecanim.
Jednak w celu zaoszczędzenia czasu pliki animacji znajdują się w katalogu
Animations w materiałach przeznaczonych dla bieżącej lekcji. Jeżeli spojrzysz
na zawartość wymienionego katalogu, zobaczysz, że animacjami są w rzeczy‐
wistości pliki w formacie .fbx. Wynika to z faktu umieszczania animacji w ich
domyślnych modelach. Nie przejmuj się tym, masz możliwość modyfikacji
i wyodrębnienia ich z poziomu edytora Unity.
Każda animacja musi być specjalnie skonfigurowana pod kątem sposobu, w jaki
zamierzasz ją wykorzystać. Przykładowo musisz się upewnić, że prawidłowo
zapętliłeś animację ruchu, aby przejścia nie zawierały żadnych widocznych
łączeń. W tej części lekcji przeanalizujesz poszczególne rodzaje aplikacji i przy‐
gotujesz je. Pracę zacznij od przeciągnięcia katalogu Animations na edytor
Unity. Istnieją trzy animacje, z którymi będziesz pracować; są to Idle, Walk-
Forward i WalkForwardTurns. Ponadto każda z wymienionych animacji może
być skonfigurowana w unikalny sposób.
RYSUNEK 18.6.
Właściwości
animacji Idle
RYSUNEK 18.7.
Odszukanie
animacji
w modelu
Podstawy zasobu Animator 313
RYSUNEK 18.8.
Ustawienia
animacji
WalkForward
314 Lekcja 18. Animator
RYSUNEK 18.9.
Ustawienia
animacji
WalkForward
RYSUNEK 18.10.
Dodanie klipu
animacji
Podstawy zasobu Animator 315
RYSUNEK 18.11.
Ustawienia
skrętu w prawo
RYSUNEK 18.12.
Lustrzane odbicie
animacji
316 Lekcja 18. Animator
Utworzenie animatora
W środowisku Unity animator jest zasobem. Oznacza to, że stanowi część pro‐
jektu i znajduje się poza jakąkolwiek sceną. Takie rozwiązanie ma na celu
umożliwienie wielokrotnego użycia animatora. W celu dodania animatora do
projektu przejdź do panelu Projekt, prawym przyciskiem myszy kliknij katalog
projektu i wybierz opcję Create/Animator Controller.
Wypróbuj samodzielnie
Konfiguracja sceny
W tym ćwiczeniu skonfigurujesz scenę i przygotujesz pozostałe materiały
wykorzystywane w trakcie bieżącej lekcji. Zapisz utworzoną tutaj scenę,
ponieważ będzie jeszcze potrzebna.
1. Jeżeli jeszcze tego nie zrobiłeś, utwórz nowy projekt i wykonaj omówione
wcześniej kroki mające na celu przygotowanie modelu i animacji.
2. Na scenę przeciągnij model Jack1 i umieść go w położeniu (0, 0, –5).
Do sceny dodaj światło kierunkowe.
3. Na scenie zaznacz model Jack1. W katalogu Jack odszukaj teksturę
Jack Diffuse1.psd i przeciągnij ją na model Jack1 znajdujący się na
scenie. Zagnieźdź kamerę Main Camera w modelu Jack1 (w panelu
Hierarchy przeciągnij Main Camera na model). Kamerę umieść
w położeniu (0, 1.5, –1.5) i zastosuj rotację (20, 0, 0).
4. Utwórz nowy katalog o nazwie Animators. Prawym przyciskiem myszy
kliknij nowy katalog i wybierz opcję Create/Animator Controller.
Animatorowi nadaj nazwę PlayerAnimator. Mając zaznaczony na
scenie model Jack1, przeciągnij animator na właściwość Controller
komponentu Animator w panelu Inspector (patrz rysunek 18.13).
5. Do sceny dodaj płaszczyznę, umieść ją w położeniu (0, 0, –5) i przeskaluj
(50, 1, 50). Odszukaj plik Checker.tga w materiałach przeznaczonych
dla lekcji i zaimportuj go do projektu. Teksturę nałóż na płaszczyznę.
6. Uruchom scenę i upewnij się, że wszystko wygląda prawidłowo. Zwróć
uwagę, że na obecnym etapie nic nie jest animowane.
Utworzenie animatora 317
Panel Animator
Dwukrotne kliknięcie animatora spowoduje wyświetlenie panelu Animator.
Panel ten to w istocie elastyczny diagram pozwalający na wizualne tworzenie
ścieżek animacji i ich łączenie. To naprawdę użyteczna funkcja nowego sys‐
temu Mecanim. Na rysunku 18.14 pokazano nieskomplikowany panel Ani‐
mator. Dla nowego animatora ma on niezwykle prostą postać — istnieje tylko
warstwa bazowa, nie ma żadnych parametrów lub informacji o stanie. Dokład‐
niejsze omówienie panelu Animator znajdziesz dalej w tej lekcji.
Animacja Idle
Pierwszą animacją, którą nałożysz na model Jack, jest Idle. Zauważ, że gdy cały
długi proces konfiguracji zostanie zakończony, dodawanie animacji jest już
proste. Trzeba odszukać klip animacji Idle — powinien być przechowywany
wewnątrz pliku Idles.fbx (patrz rysunek 18.7) — a następnie przeciągnąć go
na animator w panelu Animator (patrz rysunek 18.15).
Po uruchomieniu sceny zobaczysz, jak model Jack odtwarza zapętloną ani‐
mację Idle.
318 Lekcja 18. Animator
RYSUNEK 18.14.
Panel Animator
RYSUNEK 18.15.
Nałożenie
animacji Idle
Parametry
Parametry animatora przypominają zmienne. Parametr można zdefiniować
w panelu Animator, a następnie odwoływać się do niego w skryptach. Wspo‐
mniane parametry pozwalają na kontrolowanie mieszania i łączenia animacji.
Utworzenie animatora 319
Wypróbuj samodzielnie
Dodawanie parametrów
W tym ćwiczeniu dodasz dwa parametry. Wykorzystasz tutaj projekt i scenę,
nad którymi pracujesz w bieżącej lekcji.
1. Upewnij się, że wykonałeś wszystkie przedstawione dotąd w lekcji kroki.
2. W panelu Animator kliknij przycisk + (plus), tworząc tym samym
nowy parametr. Wybierz typ Float i nadaj mu nazwę Speed (patrz
rysunek 18.16).
RYSUNEK 18.17.
Tworzenie
i nadawanie
nazwy nowemu
stanowi
RYSUNEK 18.18.
Dodanie
Motion Field
Przejścia
Ostatnią modyfikacją do wprowadzenia w animatorze jest wskazanie sposobu
przejścia między animacjami Idle i Walking. Konieczne jest zdefiniowanie
maksymalnie dwóch przejść. Jedno jest przeznaczone dla przejścia od ani‐
macji Idle do Walking, natomiast drugie dla przejścia w przeciwną stronę.
W celu przygotowania przejść wykonaj przedstawione poniżej kroki.
Utworzenie animatora 321
RYSUNEK 18.19.
Zmiana wartości
minimalnej
i dodanie animacji
do drzewa
RYSUNEK 18.20.
Nawigacja
w panelu
Animator
RYSUNEK 18.21.
Modyfikacja
ustawień przejścia
Obsługa animacji
za pomocą skryptów
Teraz po przygotowaniu całości, czyli modelu, riggingu, animacji, animatora,
przejść i drzewa Blend Tree, wreszcie można sprawić, że całość stanie się inte‐
raktywna. Na szczęście, rzeczywiste komponenty skryptu są proste. Większość
najtrudniejszej pracy została już wykonana w edytorze. Na tym etapie potrze‐
bujesz sposobu operowania utworzonymi wcześniej parametrami umożliwia‐
jącymi modelowi poruszanie się. Ponieważ zdefiniowane parametry są typu
float, konieczne jest wywołanie następującej metody animatora:
SetFloat(<nazwa>, <wartość>);
I to tyle. Kiedy uruchomisz scenę po dodaniu skryptu, możesz zauważyć coś
dziwnego. Model Jack jest animowany nie tylko w stanie bezczynności, ruchu
i obrotu, ale również przesuwa się. Wynika to z dwóch czynników. Po pierwsze,
wybrane animacje mają wbudowany ruch. To zostało zdefiniowane przez
animatory spoza Unity. Jeżeli tego zabraknie, musisz samodzielnie progra‐
mować ruch. Po drugie, animator domyślny pozwala animacji na przesunięcie
modelu. To może być zmienione we właściwości Apply Root Motion kompo‐
nentu Animator (patrz rysunek 18.22).
RYSUNEK 18.22.
Właściwość Apply
Root Motion
Podsumowanie
W tej lekcji zająłeś się utworzeniem animatora w Unity. Na początek dowie‐
działeś się, czym w ogóle jest animator. Następnie omówione zostały kroki
wymagane do przygotowania modelu (rigging) i animacji do użycia w nowym
Pytania i odpowiedzi 323
Wypróbuj samodzielnie
Ostatnie poprawki
W tym ćwiczeniu wykorzystasz projekt, nad którym pracowałeś w tej lekcji.
Teraz dodasz skrypt pozwalający na prawidłowe działanie całości.
1. Utwórz nowy katalog o nazwie Scripts i dodaj do niego nowy skrypt.
Skryptowi nadaj nazwę AnimationControlScript i dołącz go do modelu
Jack1 znajdującego się na scenie.
2. W skrypcie umieść przedstawiony poniżej kod.
Animator anim;
void Start () {
// Pobranie odniesienia do animatora.
anim = GetComponent<Animator>();
}
void Update () {
anim.SetFloat("Speed", Input.GetAxis("Vertical"));
anim.SetFloat("Direction", Input.GetAxis("Horizontal"));
}
3. Uruchom scenę i zobacz, że animacje są kontrolowane za pomocą osi
pionowej i poziomej.
Pytania i odpowiedzi
Pytanie: W lekcji przedstawiono wiele kroków do wykonania. Czy nowy
system Mecanim naprawdę jest lepszy od starego?
Odpowiedź: Ilość pracy wykonanej w tej lekcji może wydawać się zniechęcająca.
Musisz mieć świadomość, że po poznaniu systemu Mecanim przedstawione
tutaj kroki stają się bardzo proste. Co więcej, bez systemu Mecanim
animacje musiały być przygotowywane dla konkretnego riggingu.
W poprzednio stosowanym systemie nie można było ponownie
przeprowadzić riggingu, co umożliwia Mecanim.
Warsztaty
Poświęć nieco czasu i odpowiedz na zamieszczone poniżej pytania, a także
upewnij się, że przyswoiłeś sobie materiał omówiony w tej lekcji.
324 Lekcja 18. Animator
Quiz
1. Jaką pozycję musi przyjąć model, aby był prawidłowo mapowany
w edytorze riggingu?
2. Jaką nazwę noszą zmienne istniejące w animatorze?
3. Która metoda jest używana do ustawienia w skrypcie parametrów
typu float?
Odpowiedzi
1. Pozycja T.
2. To parametry.
3. To metoda SetParam(<nazwa>, <wartość>).
Ćwiczenie
Przygotowanie solidnego i oferującego wysoką jakość systemu animacji
wymaga ogromnej ilości informacji. W tej lekcji poznałeś jeden ze sposobów
oraz jedną grupę ustawień pozwalających na osiągnięcie celu. Dostępnych jest
wiele innych zasobów, a nauka ma kapitalne znaczenie dla osiągnięcia suk‐
cesu. Twoim ćwiczeniem po tej lekcji jest kontynuacja poznawania systemu
Mecanim. Przejrzyj dokumentację dostarczoną przez Unity — znajdziesz ją na
stronie http://docs.unity3d.com/Manual/MecanimAnimationSystem.html. Jeżeli
chcesz poświęcić nieco czasu na poznanie systemu Mecanim, Unity dostarcza
doskonałe demo poświęcone temu systemowi — znajdziesz je na stronie
http://www.youtube.com/watch?v=Xx21y9eJq1U.
Lekcja 19
Czwarta gra
— Gauntlet Runner
Ukończony projekt
Musisz wykonać kolejne kroki zaprezentowane w lekcji, aby
w ten sposób ukończyć projekt gry. Jeżeli napotkasz problemy,
ukończoną wersję gry znajdziesz w materiałach przeznaczo-
nych dla bieżącej lekcji. Przejrzyj wspomniane materiały, jeśli
szukasz inspiracji!
326 Lekcja 19. Czwarta gra — Gauntlet Runner
Faza projektowania
Elementy fazy projektowania zostały omówione w lekcji 7., w której tworzyłeś
pierwszą grę zatytułowaną Amazing Racer. Teraz od razu przystąpisz do ich
zdefiniowania.
Koncepcja
W tej grze gracz wciela się w postać robota poruszającego się po niebezpiecz‐
nej drodze i usiłującego zdobyć dodatkową energię pozwalającą na przedłu‐
żenie czasu gry. Robot musi unikać spowalniających go przeszkód. Jeżeli gracz
nie zdoła zdobyć dodatkowej energii przed upływem czasu, gra kończy się.
Reguły
Reguły określają sposób prowadzenia gry, a ponadto mają wpływ na pewne
właściwości obiektów. Poniżej wymieniono reguły dla gry Gauntlet Runner.
Gracz może poruszać się w lewo i w prawo oraz skakać. Postać
sterowana przez gracza porusza się ze stałą szybkością i nie może
wykonać ruchu w żaden inny sposób.
Zderzenie z przeszkodą powoduje zwolnienie gracza o 50%
przez 1 sekundę.
Zdobycie energii przez gracza powoduje wydłużenie czasu gry
o 1,5 sekundy.
Gracz jest ograniczony krawędziami ekranu.
Gracz przegrywa, gdy upłynie czas, zanim zdoła zyskać dodatkową
energię. Nie ma warunku wskazującego na wygraną.
Wymagania
Wymagania dla tworzonej gry są proste.
Tekstura dla drogi.
Model postaci sterowanej przez gracza.
Model energii i przeszkody; zostaną utworzone w Unity.
Kontroler gry; zostanie utworzony w Unity.
Efekt cząsteczek występujący po zyskaniu energii. Ten efekt zostanie
utworzony w Unity.
Interaktywne skrypty; zostaną przygotowane w edytorze
oprogramowania MonoDevelop.
Świat 327
Świat
Świat w tworzonej tutaj grze jest całkiem prosty i składa się z trzech sześcia‐
nów ułożonych w taki sposób, aby przypominały drogę. Cała konstrukcja jest
dość łatwa, pozostałe komponenty gry będą stanowiły wyzwanie i zapewnią
rozrywkę.
Scena
Zanim skonfigurujesz podłoże i jego funkcjonalność, najpierw musisz przy‐
gotować scenę. W celu przygotowania sceny wykonaj poniższe kroki.
1. Utwórz nowy projekt o nazwie Gauntlet Runner. Następnie utwórz
nowy katalog o nazwie Scenes i pod nazwą Main zapisz w nim aktualną
scenę.
2. Do sceny dodaj światło kierunkowe.
3. Umieść kamerę Main Camera w położeniu (0, 3, –10.7) i zastosuj
rotację (33, 0, 0). Zapisz scenę.
W budowanej tutaj grze kamera pozostanie nieruchoma nad obszarem gry.
Pozostałe elementy gry będą poruszały się pod kamerą.
Droga
W budowanej grze droga, po której porusza się gracz, będzie przewijana.
Jednak w przeciwieństwie do przewijania tła w grze Captain Blaster, tutaj
w rzeczywistości nic nie będziemy przewijać. To zostanie dokładnie wyjaśnione
w następnym punkcie. Teraz musisz zrozumieć, że konieczne jest utworzenie
tylko jednego obiektu drogi, aby przewijanie działało. Sama droga składa się
z trzech podstawowych sześcianów oraz prostej tekstury. W celu utworzenia
podłoża wykonaj wymienione poniżej kroki.
1. Do sceny dodaj sześcian. Nadaj mu nazwę Ground, umieść w położeniu
(0, 0, 15.5) i przeskaluj (10, 0.5, 50). Następnie dodaj do sceny drugi
sześcian, nadaj mu nazwę Wall, umieść w położeniu (–5.5, 0.7, 15.5)
i przeskaluj (1, 1, 50). Powiel sześcian Wall i umieść go w położeniu
(5.5, 0.7, 15.5).
2. W projekcie utwórz dwa nowe katalogi o nazwach Textures i Materials.
W materiałach przeznaczonych dla bieżącej lekcji odszukaj plik
Checker.tga i przeciągnij go na katalog Textures. Z kolei w katalogu
Materials utwórz nowy materiał o nazwie GroundMaterial.
3. Jako teksturę materiału GroundMaterial wskaż zaimportowany
wcześniej plik Checker.tga. Zmodyfikuj właściwość Main Color
materiału, aby nadać mu nieco czerwonawy odcień. Przygotowany
materiał zastosuj na podłożu i ścianach.
I to tyle. Przygotowana droga jest całkiem prosta.
328 Lekcja 19. Czwarta gra — Gauntlet Runner
Przewijanie drogi
W poprzedniej grze zobaczyłeś, że przewijane tło można przygotować przez
utworzenie dwóch egzemplarzy tła i następnie przenoszenie ich kolejno do
przodu. W tej grze zastosujesz nieco sprytniejsze rozwiązanie. Każdy materiał
ma zestaw właściwości pozwalających na zdefiniowanie wartości przesunięcia
tekstury. Właściwości znajdziesz w panelu Inspector po zaznaczeniu materiału.
Twoim celem jest modyfikacja za pomocą skryptów wartości przesunięcia tek‐
stury. Jeżeli tekstura ma być powtarzana (a tak jest ustawione domyślnie),
będzie zapętlona w nieskończoność, praktycznie niezauważalnie. Jeżeli zosta‐
nie to zrobione prawidłowo, efektem jest płynne przewijanie obiektu bez
wykonywania przez niego jakiegokolwiek rzeczywistego ruchu. Aby uzyskać
tego rodzaju efekt, wykonaj poniższe kroki.
1. Utwórz nowy katalog o nazwie Scripts. W katalogu utwórz skrypt
o nazwie GroundScript. Skrypt dołącz do obiektów podłoża i ścian.
2. W skrypcie umieść przedstawiony poniżej fragment kodu, zastępując
istniejącą w nim implementację metody Update().
float speed = .5f;
void Update () {
float offset = Time.time * speed;
renderer.material.mainTextureOffset = new Vector2(0,
-offset);
}
Elementy gry
Po przygotowaniu przewijanego świata nadeszła pora na utworzenie pozosta‐
łych elementów gry. Potrzebujesz czterech podstawowych elementów, takich
jak obiekt sterowany przez gracza, dodatkowa energia, przeszkody i strefa
wyzwalacza. Strefa wyzwalacza będzie używana do usunięcia wszelkich ele‐
Elementy gry 329
RYSUNEK 19.1.
Przygotowana
droga
w budowanej
grze
Dodatkowa energia
Obiekt dodatkowej energii w grze ma postać prostej kuli wraz z dodanymi
pewnymi efektami. W tym miejscu utworzysz kulę, umieścisz w odpowiednim
miejscu, a następnie przygotujesz na jej podstawie prefabrykat. W celu utwo‐
rzenia obiektu dodatkowej energii wykonaj poniższe kroki.
1. Do sceny dodaj kulę, umieść ją w położeniu (0, 1, 42). Następnie do kuli
dodaj komponent Rigidbody i usuń zaznaczenie opcji Use Gravity.
2. Utwórz nowy materiał o nazwie PowerupMaterial i nadaj mu kolor
żółty. Materiał nałóż na kulę.
3. Do kuli dodaj światło punktowe (wybierz opcję
Component/Rendering/Light). Kolor światła ustaw na żółty. Do kuli
dodaj system cząsteczek (wybierz opcję Component/Effects/Particle
System). Kolor początkowy cząsteczki ustaw na żółty, a jej czas życia
na 2.5.
4. Utwórz nowy katalog o nazwie Prefabs. W tym katalogu utwórz nowy
prefabrykat i nadaj mu nazwę Powerup. W panelu Hierarchy kliknij
kulę i przeciągnij ją na prefabrykat. Teraz możesz już usunąć kulę ze
sceny.
Zwróć uwagę, że przypisanie położenia obiektowi przed jego umieszczeniem
w prefabrykacie pozwala po prostu na utworzenie egzemplarza prefabrykatu,
który pojawi się we wskazanym położeniu. Dlatego też nie jest potrzebny
punkt początkowy dla obiektu. Na rysunku 19.2 pokazano ukończony prefa‐
brykat dodatkowej energii.
330 Lekcja 19. Czwarta gra — Gauntlet Runner
RYSUNEK 19.2.
Ukończony
prefabrykat
dodatkowej
energii
Przeszkody
W budowanej tutaj grze przeszkody są przedstawione w postaci małych
czarnych sześcianów. Gracz ma możliwość ominięcia przeszkody lub jej
przeskoczenia. W celu utworzenia elementu przeszkody wykonaj poniższe
kroki.
1. Do sceny dodaj sześcian, umieść go w położeniu (0, 0.4, 42) i przeskaluj
(1, 0.2, 1). Następnie do sześcianu dodaj komponent Rigidbody i usuń
zaznaczenie opcji Use Gravity.
2. Utwórz nowy materiał o nazwie ObstacleMaterial. Materiałowi przypisz
kolor czarny i nałóż na sześcian.
3. Utwórz nowy prefabrykat o nazwie Obstacle. W panelu Hierarchy
kliknij sześcian, a następnie przeciągnij go na nowy prefabrykat. Teraz
możesz już usunąć sześcian ze sceny.
Strefa wyzwalacza
Podobnie jak w poprzednich grach, także w tej skonfigurujesz strefę wyzwala‐
cza odpowiedzialną za usuwanie wszelkich obiektów gry, które miną gracza.
W celu utworzenia strefy wyzwalacza wykonaj przedstawione poniżej kroki.
1. Do sceny dodaj sześcian, zmień mu nazwę na TriggerZone, umieść
w położeniu (0, 1, –20) i przeskaluj (10, 1, 1).
2. W komponencie Box Collider strefy wyzwalacza zaznacz właściwość
Is Trigger.
Elementy gry 331
Obiekt gracza
W tworzonej tutaj grze obiekt gracza wymaga wykonania dość sporej ilości
pracy. Zastosowane zostaną dwie nowe animacje, których jeszcze nie miałeś
okazji poznać, czyli Run (bieg) i Jump (skok). Na początek model gracza trzeba
przygotować, by można było użyć systemu Mecanim.
1. W materiałach przeznaczonych dla bieżącej lekcji odszukaj katalog
o nazwie Robot Kyle. To jest model bezpłatnie dostarczany wraz z Unity.
Aby zaoszczędzić czas potrzebny na wyszukanie modelu w sklepie
Unity Asset Store, został umieszczony w wymienionych materiałach.
Katalog Robot Kyle przeciągnij na panel Project w Unity i tym samym
zaimportuj do projektu.
2. W podkatalogu Model katalogu Robot Kyle odszukaj plik Robot Kyle.fbx.
Następnie przejdź do panelu Inspector, kliknij kartę Animations i usuń
zaznaczenie opcji Import Animation. Kliknij przycisk Apply.
3. W karcie Rig zmień typ animacji na Humanoid i kliknij przycisk Apply.
Na tym etapie powinieneś zobaczyć znak „ptaszka” wyświetlony obok przy‐
cisku Configure… (patrz rysunek 19.3). Jeżeli „ptaszek” nie jest wyświetlany,
kliknij przycisk Configure… i przeprowadź konfigurację riggingu. Opis procedury
konfiguracji riggingu znajdziesz w lekcji 18., choć konfiguracja nie powinna
być potrzebna.
RYSUNEK 19.3.
Ustawienia
riggingu
RYSUNEK 19.4.
Właściwości
animacji Jump
RYSUNEK 19.5.
Właściwości
animacji Run
RYSUNEK 19.6.
Dodanie klipu
animacji Run
334 Lekcja 19. Czwarta gra — Gauntlet Runner
RYSUNEK 19.7.
Dodanie
parametru
Jumping
RYSUNEK 19.8.
Właściwości
przejścia
ze stanu Run
RYSUNEK 19.9.
Właściwości
przejścia
ze stanu Jump
Obiekt gracza jest już skonfigurowany i gotowy do użycia w grze. Kiedy uru‐
chomisz scenę, powinieneś zobaczyć, że robot biegnie po przewijanym podłożu
w postaci przygotowanej wcześniej drogi. Efekt jest taki, jakby robot biegł do
przodu.
Obiekty kontrolne
Najwyższa pora dodać obiekty kontrolne i zapewnić interaktywność tworzo‐
nej grze. Ponieważ położenie prefabrykatów dodatkowej energii i przeszkód
jest już zdefiniowane, nie ma konieczności określania punktu tworzenia
wymienionych elementów. Dlatego też większość kodu zostanie umieszczona
w obiekcie kontrolnym gry.
void Update () {
if(isGameOver)
return;
totalTimeElapsed += Time.deltaTime;
timeRemaining -= Time.deltaTime;
if(timeRemaining <= 0)
isGameOver = true;
}
objectSpeed = minSpeed;
ground.SlowDown();
wall1.SlowDown();
wall2.SlowDown();
void SpeedWorldUp()
{
objectSpeed = maxSpeed;
ground.SpeedUp();
wall1.SpeedUp();
wall2.SpeedUp();
}
{
timeRemaining += timeExtension;
}
void OnGUI()
{
if(!isGameOver)
{
GUI.Box(new Rect(Screen.width / 2 - 50, Screen.height - 100,
100, 50),
"Pozostały czas");
GUI.Label(new Rect(Screen.width / 2 - 10, Screen.height - 80,
20, 40),
((int)timeRemaining).ToString());
}
else
{
GUI.Box(new Rect(Screen.width / 2 - 60, Screen.height / 2 -
100, 120, 50),
"Koniec gry");
GUI.Label(new Rect(Screen.width / 2 - 55, Screen.height / 2 -
80, 90, 40),
"Całkowity czas: " + (int)totalTimeElapsed);
}
}
Pamiętaj o jednym z założeń gry: wszystko zwalnia, gdy gracz zderzy się
z przeszkodą. Dlatego też elementy muszą pobierać z obiektu kontrolnego
gry ich aktualną szybkość. Na początku skryptu zdefiniowano trzy zmienne
określające aktualną, minimalną i maksymalną szybkość poruszania się obiektu.
Konieczne jest również monitorowanie podłoża i ścian, aby zwolnić szybkość
ich przewijania, gdy będzie trzeba. Pozostałe zmienne są przeznaczone do
przechowywania informacji o czasie gry i stanie.
Metoda Update() monitoruje czas. Do wartości zmiennej totalTimeElapsed
dodaje czas, jaki upłynął od ostatniej klatki (Time.deltaTime). Ponadto
sprawdza, czy gra się zakończyła, co następuje po spadku do zera pozostałego
czasu. Jeżeli gra jest zakończona, następuje ustawienie zmiennej isGameOver.
Metody SlowWorldDown() i SpeedWorldUp() działają w połączeniu. Gdy gracz
zderzy się z przeszkodą, następuje wywołanie metody SlowWorldDown().
Zadaniem tej metody jest spowolnienie wszystkich obiektów znajdujących się
na scenie. Następnie wywoływana jest metoda Invoke(). Działanie tej metody
można określić następująco: wywołaj wskazaną metodę w ciągu x sekund.
Nazwa metody do wywołania jest ujęta w cudzysłów, natomiast liczba sekund
opóźnienia w wywołaniu jest podana jako drugi parametr Invoke(). Praw‐
dopodobnie zauważyłeś wywołanie CancelInvoke() na początku metody
SlowWorldDown(). Powoduje ono anulowanie oczekiwania na wywołanie
metody SpeedWorldUp(), ponieważ gracz zderzył się z kolejną przeszkodą.
W kodzie przedstawionym powyżej po upływie jednej sekundy następuje
338 Lekcja 19. Czwarta gra — Gauntlet Runner
float strafeSpeed = 2;
bool jumping = false;
void Start () {
anim = GetComponent<Animator>();
}
void Update () {
transform.Translate(Input.GetAxis("Horizontal") * Time.deltaTime
* strafeSpeed, 0f,
0f);
if(transform.position.x > 3)
transform.position = new Vector3(3, transform.position.y,
transform.position.z);
else if(transform.position.x < -3)
transform.position = new Vector3(-3, transform.position.y,
transform.position.z);
if (anim.GetCurrentAnimatorStateInfo(0).IsName("Base
Layer.Jump"))
{
anim.SetBool("Jumping", false);
jumping = true;
}
else
{
jumping = false;
if(Input.GetButtonDown("Jump"))
Obiekty kontrolne 339
anim.SetBool("Jumping", true);
}
}
Skrypty obiektów
dodatkowej energii i przeszkód
Skrypty przeznaczone dla obiektów dodatkowej energii i przeszkód są iden‐
tyczne. W rzeczywistości to jest pojedynczy skrypt. Oczywiście można utworzyć
oddzielne skrypty, aby tym samym ułatwić sobie wprowadzanie w przyszłości
340 Lekcja 19. Czwarta gra — Gauntlet Runner
różnych zmian dla poszczególnych obiektów. Utwórz więc dwa skrypty o na‐
zwach PowerupScript i ObstacleScript. Skrypt PowerupScript dodaj do
prefabrykatu dodatkowej energii. W tym celu zaznacz prefabrykat w panelu
Inspector i wybierz opcję Add Component/Scripts/Powerup Script. To samo
zrób ze skryptem ObstacleScript dla prefabrykatu przeszkody. W obu skryp‐
tach umieść przedstawiony poniżej kod.
public GameControlScript control;
void Update () {
transform.Translate(0, 0, control.objectSpeed);
}
Powyższy kod jest bardzo prosty. Zawiera miejsce zarezerwowane dla skryptu
kontrolnego gry. W trakcie każdego wywołania metody Update() obiekt zosta‐
nie przesunięty z szybkością pobraną z obiektu kontrolnego gry. W ten sposób
obiekt kontrolny wpływa na szybkość każdego obiektu gry znajdującego się na
scenie.
Skrypt SpawnScript
Omawiany tutaj skrypt jest odpowiedzialny za tworzenie obiektów na scenie.
Ponieważ informacje o położeniu początkowym obiektów znajdują się w pre‐
fabrykatach, skrypt należy dołączyć do obiektu kontrolnego gry. Utwórz nowy
skrypt o nazwie SpawnScript i dołącz go do obiektu GameControl. Następnie
w skrypcie umieść przedstawiony poniżej kod.
GameControlScript control;
float timeElapsed = 0;
float spawnCycle = .5f;
bool spawnPowerup = true;
void Start () {
control = GetComponent<GameControlScript>();
}
void Update () {
timeElapsed += Time.deltaTime;
if(timeElapsed > spawnCycle)
{
GameObject temp;
if(spawnPowerup)
{
temp = (GameObject)Instantiate(powerup);
temp.GetComponent<PowerupScript>().control = control;
Vector3 pos = temp.transform.position;
Obiekty kontrolne 341
timeElapsed -= spawnCycle;
spawnPowerup = !spawnPowerup;
}
}
Na początku skryptu znajduje się odniesienie do skryptu obiektu kontrolnego.
Ponadto mamy odniesienia do obiektów dodatkowej energii i przeszkód. Kolejne
zmienne są przeznaczone do przechowywania informacji o czasie i kolejności
tworzenia obiektów. Obiekty dodatkowej energii i przeszkód są budowane
w ustalonej kolejności, dlatego konieczne jest użycie zmiennej do monitoro‐
wania procesu tworzenia.
W metodzie Update() następuje zwiększenie czasu gry oraz sprawdzenie, czy
nadeszła chwila na utworzenie nowego obiektu. Gdy nadszedł czas budowania
obiektu, skrypt sprawdza, który powinien być to obiekt. Do wyboru jest dodat‐
kowa energia i przeszkoda. Następnie odniesienie do skryptu obiektu kon‐
trolnego gry jest przekazywane do skryptu nowego obiektu. W ten sposób
obiekt dodatkowej energii lub przeszkody „wiedzą”, gdzie znaleźć skrypt
obiektu kontrolnego gry. Utworzony obiekt jest losowo umieszczany po lewej
lub prawej stronie. Na końcu metoda Update() zmniejsza ilość dostępnego
czasu i zmienia typ obiektu, który będzie tworzony następnym razem.
RYSUNEK 19.10.
Przeciąganie
obiektów
na przygotowane
dla nich
właściwości
RYSUNEK 19.11.
Dodanie obiektu
kontrolnego gry
do skryptu gracza
Usprawnienie gry 343
Usprawnienie gry
Podobnie jak wcześniejsze gry, także i ta nie będzie w pełni gotowa przed
dokładnym przetestowaniem i dopracowaniem. Teraz jest odpowiedni moment
na zagranie i przekonanie się, które aspekty Ci się podobają, a które nie. Pamię‐
taj o zapisywaniu funkcji, o których sądzisz, że mogą wzbogacić grę i popra‐
wić jej grywalność. Warto również notować informacje o elementach, które
uprzykrzają rozgrywkę. Dokładnie notuj spostrzeżenia, przydadzą się podczas
pracy nad kolejnymi wersjami gry. Spróbuj zachęcić przyjaciół do zagrania
w zbudowaną tutaj grę i zbierz ich wrażenia. To wszystko pomoże w uczynieniu
gry unikalną i poprawieniu jej grywalności.
Podsumowanie
W tej lekcji utworzyłeś grę zatytułowaną Gauntlet Runner. Na początku zająłeś
się zaprojektowaniem poszczególnych elementów gry. Następnie przystąpiłeś
do utworzenia drogi i jej przewijania za pomocą sztuczki z użyciem tekstury.
Później utworzyłeś różne elementy gry. Dalej rozpocząłeś przygotowanie
poszczególnych obiektów kontrolnych i skryptów. Na końcu przetestowałeś
grę i przystąpiłeś do zbierania opinii na jej temat.
Pytania i odpowiedzi
Pytanie: Ruch obiektów i podłoża nie jest idealnie dopasowany.
Czy to normalne?
Odpowiedź: W omawianym przykładzie tak. Aby zapewnić doskonałą
synchronizację wymienionych elementów, trzeba dokładnie przetestować
grę i wprowadzić niezbędne poprawki. Na poprawie synchronizacji
możesz się skupić w trakcie usprawniania gry.
Pytanie: Animacja skaczącej postaci wygląda nieco dziwnie.
Czy to normalne?
Odpowiedź: Ponownie w omawianym przykładzie tak. Animacje wykorzystane
w tej lekcji zostały dostarczone przez Unity i przygotowane dla wersji
demo systemu Mecanim. Dlatego też w grze zostały użyte w sposób,
do którego ich nie przystosowano. (Dostarczone animacje opracowano
w celu kontroli ruchu gracza). Dlatego też mogą wyglądać nieco dziwnie.
Czasami tworzenie gry oznacza konieczność zrobienia tego,
na co pozwalają dostarczone narzędzia.
Warsztaty
Poświęć nieco czasu i odpowiedz na zamieszczone poniżej pytania, a także
upewnij się, że przyswoiłeś sobie materiał omówiony w tej lekcji.
344 Lekcja 19. Czwarta gra — Gauntlet Runner
Quiz
1. Czy gracz może przegrać w zbudowanej tutaj grze?
2. Na jakiej zasadzie działa przewijanie drogi?
3. Jakie dwa stany utworzone zostały w animatorze?
4. Jak obiekt kontrolny gry wpływa na szybkość wszystkich obiektów
znajdujących się na scenie?
Odpowiedzi
1. Gdy upłynie czas gry, gracz przegrywa.
2. Sama droga pozostaje nieruchoma. Zamiast niej przewijamy teksturę
w obiekcie. Efektem jest złudzenie, jakby droga poruszało się.
3. Run i Jump.
4. Każdy obiekt znajdujący się na scenie ma odniesienie do skryptu obiektu
kontrolnego gry. Skrypt zawiera dane dotyczące szybkości, z jaką mają
się poruszać obiekty. Podczas każdego uaktualnienia obiektu szybkość
zostaje pobrana ze skryptu obiektu kontrolnego.
Ćwiczenie
Teraz możesz przystąpić do podjęcia próby implementacji zmian, które zano‐
towałeś podczas testowania gry. Zrób, co możesz, by gra stała się unikalna.
Powinieneś określić pewne słabe punkty gry, a także jej mocne strony, które
warto jeszcze bardziej wzmocnić. Oto kilka podpowiedzi zmian wartych
rozważenia.
Spróbuj wprowadzić nowe obiekty dodające czas gry oraz przeszkody.
Spróbuj jeszcze lepiej dobrać szybkość obiektu, aby udoskonalić
dopasowanie jej do przewijanej drogi.
Spróbuj zwiększyć lub zmniejszyć trudność gry przez zmianę
częstotliwości pojawiania się obiektów dodających czas gry i przeszkód.
Ponadto poeksperymentuj z wartością dodawanego czasu oraz
stopniem spowolnienia całości po zderzeniu z przeszkodą. Możesz
np. zmodyfikować stopień spowolnienia całości, a nawet ustalić tę
wartość odmiennie dla poszczególnych obiektów.
Nadaj nowy wygląd obiektom dodającym czas gry i przeszkodom.
Poeksperymentuj z teksturami i efektami cząsteczek, aby obiekty
przedstawiały się rewelacyjnie.
Lekcja 20
Dźwięk
Podstawy dźwięku
Ogromną część dowolnego doświadczenia stanowią związane z nim dźwięki.
Rozważ tworzenie przerażającego filmu i dodanie do niego ścieżki dźwiękowej
ze śmiechem. W ten sposób to, co powinno być przerażające, staje się zabawne.
Podobnie jest w przypadku gier wideo. Zwykle gracze nie zdają sobie sprawy,
że dźwięk ma ogromny wpływ na ogólną grywalność. Dźwięk może sygnali‐
zować rozwiązanie zagadki przez gracza, odgłosy towarzyszące bitwie dodają
realizmu grze symulującej wojnę itd. Za pomocą środowiska Unity można
bardzo łatwo zaimplementować zadziwiające efekty dźwiękowe.
Składniki dźwięku
Uzyskanie dźwięku na scenie wymaga trzech rzeczy: komponentu Audio
Listener, źródła dźwięku oraz klipu audio. Audio Listener to najprostszy kom‐
ponent systemu audio. Jedynym zadaniem wymienionego komponentu jest
„nasłuchiwanie” zdarzeń zachodzących na scenie. Można go porównać do ucha
człowieka. Domyślnie każda scena zawiera komponent Audio Listener dołą‐
czony do kamery Main Camera (patrz rysunek 20.1). Omawiany komponent
nie zawiera żadnych właściwości, a ponadto nie trzeba nic robić, aby zaczął
funkcjonować. Najczęściej spotykaną praktyką jest dodawanie komponentu
Audio Listener do obiektu gry przedstawiającego gracza. Warto w tym miejscu
pamiętać o jednym: jeżeli zamierzasz dodać Audio Listener do innego obiektu
gry, wtedy omawiany komponent trzeba usunąć z kamery Main Camera, ponie‐
waż na scenie może znajdować się tylko jeden komponent Audio Listener.
RYSUNEK 20.1.
Komponent
Audio Listener
Źródła dźwięku 347
Komponent Audio Listener nasłuchuje dźwięku, ale jego faktyczną emisją zaj‐
muje się źródło dźwięku. Źródło jest komponentem, który można umieścić na
dowolnym obiekcie sceny (nawet zawierającym komponent Audio Listener).
Istnieje wiele właściwości i ustawień związanych ze źródłem dźwięku, które
zostaną przedstawione dalej w tej lekcji.
Ostatnim elementem wymaganym do funkcjonowania dźwięku jest klip audio.
Jak sama nazwa wskazuje, klip audio to plik dźwiękowy rzeczywiście odtwa‐
rzany przez źródło dźwięku. Każdy klip zawiera pewne właściwości, które
można ustawić i wpłynąć na sposób jego odtwarzania przez Unity. W Unity
obsługiwane są następujące formaty audio: .aif, .wav, .mp3 i .ogg. Po połącze‐
niu wszystkich trzech wymienionych elementów na scenie można odtwarzać
dźwięki.
Dźwięk 2D i 3D
W przypadku dźwięku można rozważać dwie koncepcje: dźwięk 2D i 3D.
Klipy audio 2D to najprostsze rodzaje dźwięku. Są odtwarzane z taką samą
(maksymalną) głośnością niezależnie od bliskości komponentu Audio Listener
od źródła dźwięku na scenie. Dźwięk 2D najlepiej sprawdza się w przypadku
menu, ostrzeżeń, ścieżki dźwiękowej lub innych rodzajów dźwięku, które
zawsze muszą być słyszane w dokładnie taki sam sposób. Największa zaleta
dźwięku 2D stała się jednocześnie jego największą wadą. Rozważ sytuację,
w której każdy dźwięk w grze jest odtwarzany z dokładnie taką samą głośnością,
niezależnie od wszystkiego. To mogłoby szybko wyrwać się spod kontroli.
Rozwiązaniem problemów z dźwiękiem 2D jest dźwięk 3D. Tego rodzaju klipy
audio mają tzw. funkcję roll off, która określa głośność dźwięku na podstawie
odległości komponentu Audio Listener od źródła dźwięku. W zaawansowa‐
nych systemach audio, takich jak istniejący w Unity, dźwięki 3D mogą nawet
zawierać symulowany efekt Dopplera (więcej na ten temat znajdziesz dalej
w tej lekcji). Jeśli chcesz uzyskać realistyczny dźwięk na scenie pełnej różnych
źródeł dźwięku, powinieneś się zdecydować na użycie dźwięku 3D.
Wymiary różnych klipów audio są ustalane przy użyciu indywidualnych usta‐
wień pliku dźwiękowego.
Źródła dźwięku
Jak wcześniej wspomniano, źródło dźwięku to komponent, który rzeczywiście
odtwarza klip audio na scenie. Na sposób odtworzenia klipu audio 3D na scenie
wpływ ma odległość między źródłem dźwięku i komponentem Audio Listener.
Aby do obiektu gry dodać źródło audio, należy zaznaczyć dany obiekt, a następ‐
nie wybrać opcję Component/Audio/Audio Source.
Komponent Audio Source ma wiele właściwości pozwalających na uzyskanie
dokładnej kontroli nad sposobem odtwarzania dźwięków na scenie. Różne
właściwości komponentu Audio Source wymieniono w tabeli 20.1.
348 Lekcja 20. Dźwięk
Priorytet dźwięku
Każdy system ma ograniczoną liczbę kanałów audio. Liczba nie jest stała
i zależy od wielu czynników, takich jak sprzęt i system operacyjny. Dlatego
też w większości systemów audio stosowane są priorytety. Po zastoso-
waniu priorytetów dźwięki odtwarzane są w kolejności ich otrzymywania,
aż do wykorzystania wszystkich dostępnych kanałów. Gdy wszystkie kanały
są w użyciu, dźwięki o niższym priorytecie są wypychane przez dźwięki
o wyższym priorytecie. Musisz koniecznie pamiętać, że w środowisku Unity
niższa wartość priorytetu oznacza wyższy priorytet dźwięku!
Wypróbuj samodzielnie
Testowanie dźwięku
W tym ćwiczeniu przetestujesz dźwięk w Unity i upewnisz się, że wszystko
działa zgodnie z oczekiwaniami. Koniecznie zapisz utworzoną tutaj scenę,
ponieważ będziesz z niej korzystać dalej w tej lekcji.
1. Utwórz nowy projekt lub scenę. Odszukaj katalog Sounds w materiałach
dla bieżącej lekcji i przeciągnij go na katalog Assets w panelu Project
wyświetlanym w edytorze Unity.
2. Do sceny dodaj sześcian i umieść go w położeniu (0, 0, 0). Następnie
do sześcianu dodaj źródło dźwięku, czyli komponent Audio Source
(w tym celu wybierz opcję Component/Audio/Audio Source). W nowo
zaimportowanym katalogu Sounds odszukaj plik looper.ogg i przeciągnij
go na właściwość Audio Clip źródła dźwięku w sześcianie (patrz
rysunek 20.2).
RYSUNEK 20.3.
Włączenie
dźwięków
na scenie
Wypróbuj samodzielnie
Dźwięk 3D
Jak wcześniej wspomniano, domyślnie wszystkie klipy audio są traktowane
jako dźwięk 3D. Oznacza to, że cały dźwięk podlega efektom audio 3D, takim
jak efekty oparte na odległości od źródła dźwięku i ruchu. Wspomniane efekty
można modyfikować za pomocą właściwości 3D komponentu Audio Source
(patrz rysunek 20.4).
Różne właściwości dźwięku 3D zostały wymienione w tabeli 20.2.
Źródła dźwięku 351
RYSUNEK 20.4.
Ustawienia
dźwięku 3D
Dźwięk 2D
Czasami trzeba odtworzyć dźwięk z pełną głośnością niezależnie od położenia
na scenie. Najczęstszym przykładem jest tutaj muzyka grająca w tle. Aby przejść
z klipu 3D na 2D, zaznacz po prostu plik dźwiękowy, a następnie usuń zazna‐
czenie 3D Sound w panelu Inspector (patrz rysunek 20.5).
Po ustawieniu klipu audio jako 2D dla danego źródła dźwięku zastosowanie
będą miały jedynie właściwości 2D Sound Settings. Istnieje tylko jedna właści‐
wość dla dźwięku 2D: Pan. Jest to egzemplarz kontrolujący sposób odtwarzania
dźwięku. Wartość 0 wymienionej właściwości oznacza równomierne odtwa‐
rzanie dźwięku w obu głośnikach w środowisku stereo (lewym i prawym).
Wartość -1 oznacza odtworzenie dźwięku tylko po lewej stronie, natomiast
1 powoduje odtworzenie dźwięku tylko po prawej stronie.
Wypróbuj samodzielnie
Testowanie dźwięku 2D
W tym ćwiczeniu wypróbujesz dźwięk 2D na scenie. Wykorzystasz tutaj
scenę przygotowaną w dwóch poprzednich ćwiczeniach.
1. Otwórz scenę przygotowaną i używaną w poprzednich ćwiczeniach.
2. W katalogu Sounds odszukaj plik looper.ogg i zaznacz go. W panelu
Inspector usuń zaznaczenie właściwości 3D Sound. Kliknij przycisk
Apply.
3. Po włączeniu dźwięków na scenie poruszaj się po niej. Zwróć uwagę,
że Twoje położenie nie ma żadnego wpływu na odtwarzany dźwięk.
352 Lekcja 20. Dźwięk
RYSUNEK 20.5.
Ustawienie klipu
audio jako 2D
Rozpoczęcie i zatrzymanie
odtwarzania dźwięku
Najprostszą funkcją będzie rozpoczęcie lub zatrzymanie odtwarzania klipu
audio. Operacje te są kontrolowane przez dwie metody o nazwach Start()
i Stop(). Poniżej przedstawiono sposób użycia tych metod.
audio.Start(); // Rozpoczęcie odtwarzania klipu.
audio.Stop(); // Zatrzymanie odtwarzania klipu.
Powyższy kod spowoduje odtworzenie klipu wskazywanego przez właściwość
Audio Clip komponentu Audio Source. Istnieje możliwość rozpoczęcia odtwa‐
rzania klipu z pewnym opóźnieniem. W tym celu należy użyć metody Play
Delayed(), która pobiera pojedynczy parametr wyrażający w sekundach czas
oczekiwania przed rozpoczęciem odtwarzania klipu. Metoda PlayDelayed()
przedstawia się następująco:
audio.PlayDelayed(<czas wyrażony w sekundach>);
Istnieje możliwość sprawdzenia w kodzie aktualnie odtwarzanego klipu za
pomocą zmiennej isPlaying będącej częścią obiektu audio. Aby uzyskać
dostęp do tej zmiennej i tym samym sprawdzić, czy klip jest odtwarzany, można
użyć poniższego fragmentu kodu.
if(audio.isPlaying)
{
// Dźwięk jest odtwarzany.
}
Jak sama nazwa wskazuje, zmienna przyjmuje wartość true, jeśli dźwięk jest
aktualnie odtwarzany. W przeciwnym razie ma wartość false.
Niewymienione właściwości
Wszystkie właściwości źródła dźwięku wymienione w panelu Inspector są
dostępne także za pomocą skryptów. Przykładowo dostęp do właściwości
Loop odbywa się w kodzie za pomocą zmiennej audio.loop. Jak wcześniej
wspomniano, wszystkie właściwości są używane w połączeniu z obiektem
audio. Przekonaj się, ile z nich potrafisz znaleźć!
354 Lekcja 20. Dźwięk
Wypróbuj samodzielnie
audio.clip = newClip;
audio.Play();
W podobny sposób możesz łatwo utworzyć kolekcję klipów audio i przełączać
się między nimi.
Podsumowanie
W tej lekcji zająłeś się dźwiękiem w środowisku Unity. Na początek poznałeś
podstawy dźwięku i komponenty wymagane do jego odtwarzania. Następnie
przeszedłeś do źródła dźwięku w postaci komponentu Audio Source. Dowie‐
działeś się, jak przetestować dźwięk w panelu Scene, a także jak używać klipów
audio 2D i 3D. Na końcu lekcji poruszony został temat obsługi dźwięku za
pomocą skryptów.
Pytania i odpowiedzi
Pytanie: Ile średnio kanałów audio znajduje się w systemie?
Odpowiedź: Ilość kanałów audio zależy od konkretnego systemu.
Warto wiedzieć, że słuchawki, ogólnie rzecz biorąc, mają dwa kanały.
To oczywiście nie oznacza, że słuchawki mogą odtworzyć tylko dwa
dźwięki. Oznacza to, że dwa dźwięki mogą być odtworzone, zanim system
będzie musiał zacząć łączyć dźwięki i tym samym nieco obniżyć ich
jakość.
Warsztaty
Poświęć nieco czasu i odpowiedz na zamieszczone poniżej pytania, a także
upewnij się, że przyswoiłeś sobie materiał omówiony w tej lekcji.
Quiz
1. Jakie elementy są niezbędne do odtwarzania dźwięku w Unity?
2. Dźwięk 3D jest odtwarzany z tą samą głośnością niezależnie
od odległości od źródła dźwięku, w jakiej słuchacz się znajduje.
Prawda czy fałsz?
3. Która metoda pozwala na odtworzenie klipu audio po pewnym
opóźnieniu?
Odpowiedzi
1. Komponent Audio Listener, źródło dźwięku i klip audio.
2. Fałsz. Dźwięk 2D jest odtwarzany z taką samą głośnością niezależnie
od odległości od źródła dźwięku.
3. To metoda PlayDelayed().
356 Lekcja 20. Dźwięk
Ćwiczenie
W tym ćwiczeniu utworzysz prostą tablicę dźwięków pozwalającą na odtwa‐
rzanie jednego z trzech dostępnych dźwięków. Będziesz miał możliwość roz‐
poczęcia i zakończenia odtwarzania dźwięku, a także włączenia i wyłączenia
jego zapętlenia. Ukończony projekt znajdziesz w katalogu Hour20_Exercise
w materiałach przeznaczonych dla bieżącej lekcji.
1. Utwórz nowy projekt lub scenę. Do sceny dodaj sześcian i umieść
go w położeniu (0, 0, –10), a następnie dodaj do sześcianu źródło
dźwięku. Upewnij się, że usunąłeś zaznaczenie właściwości Play On
Wake. W materiałach przeznaczonych dla bieżącej lekcji odszukaj
katalog Sounds i przeciągnij go na katalog Assets projektu.
2. Utwórz nowy katalog o nazwie Scripts, w nim skrypt AudioScript
i dołącz go do sześcianu. Następnie w skrypcie umieść przedstawiony
poniżej kod.
public AudioClip clip1;
public AudioClip clip2;
public AudioClip clip3;
void Start()
{
audio.clip = clip1;
}
void Update () {
if(Input.GetButtonDown("Jump"))
{
if(audio.isPlaying)
audio.Stop();
else
audio.Play();
}
if(Input.GetKeyDown(KeyCode.L))
audio.loop = !audio.loop; // Włączenie lub wyłączenie zapętlenia.
if(Input.GetKeyDown(KeyCode.Alpha1))
{
audio.Stop();
audio.clip = clip1;
audio.Play();
}
else if(Input.GetKeyDown(KeyCode.Alpha2))
{
audio.Stop();
audio.clip = clip2;
audio.Play();
}
else if(Input.GetKeyDown(KeyCode.Alpha3))
Ćwiczenie 357
{
audio.Stop();
audio.clip = clip3;
audio.Play();
}
}
3. W edytorze Unity zaznacz sześcian na scenie. Z katalogu Sound pliki
looper.ogg, quick_laser.ogg i xxplosion.ogg przeciągnij na właściwości,
odpowiednio, Clip1, Clip2 i Clip3 skryptu AudioScript.
4. Uruchom scenę. Zwróć uwagę, że poszczególne klipy audio możesz
zmieniać za pomocą klawiszy od 1 do 3. Rozpoczęcie i zakończenie
odtwarzania dźwięku następuje przez naciśnięcie spacji. Z kolei
klawisz L pozwala na zapętlenie odtwarzanego dźwięku.
358 Lekcja 20. Dźwięk
Lekcja 21
Programowanie
na platformach mobilnych
Wymagania
Materiał przedstawiony w tej lekcji dotyczy urządzeń mobil-
nych. Jeżeli nie dysponujesz tego rodzaju urządzeniem dzia-
łającym pod kontrolą systemu iOS lub Android, nie będziesz
mógł wykonać zaprezentowanych tutaj ćwiczeń. Jednak nie
przejmuj się tym i pamiętaj, że mimo wszystko lektura tej lek-
cji ma sens, a Ty nadal możesz opracowywać gry dla urządzeń
mobilnych. Jedyne ograniczenie to brak możliwości zagrania.
360 Lekcja 21. Programowanie na platformach mobilnych
Przygotowanie do programowania
na platformach mobilnych
Środowisko Unity niezwykle ułatwia tworzenie gier dla urządzeń mobilnych.
W wersji Unity 4.1 wtyczka przeznaczona dla platform mobilnych jest bez‐
płatna! Na pewno będziesz szczęśliwy, gdy dowiesz się, że programowanie
dla platformy mobilnej jest identyczne z tworzeniem projektów dla innych
platform. Oznacza to możliwość opracowania gry raz, a następnie przysto‐
sowania jej dla wielu różnych platform. Nie ma więc żadnego powodu, aby
unikać tworzenia gier dla większości platform. Taki poziom niezależności od
platformy jest bezprecedensowy. Zanim jednak rozpoczniesz pracę z urzą‐
dzeniami mobilnymi w Unity, powinieneś przygotować do tego komputer.
Konfiguracja środowiska
Zanim uruchomisz Unity w celu opracowania gry, najpierw musisz przygo‐
tować środowisko pracy. Konkretne kroki zależą od urządzenia mobilnego
i dlatego też poniżej przedstawiono jedynie ogólną procedurę.
1. Zainstaluj SDK (ang. Software Development Kit) dla urządzenia,
dla którego będziesz tworzyć oprogramowanie.
2. Upewnij się, że komputer rozpoznaje urządzenie i potrafi z nim
współpracować (to bardzo ważne, jeśli grę chcesz przetestować
w rzeczywistym urządzeniu).
3. Wskaż środowisku Unity, gdzie znaleźć SDK (dotyczy jedynie systemu
Android).
Jeżeli wymienione powyżej kroki wydają się niezrozumiałe, nie przejmuj się.
W internecie znajdziesz wiele artykułów, w których dokładnie omówiono
konfigurację Unity i urządzeń mobilnych. Najlepszym miejscem do rozpoczęcia
poszukiwań odpowiednich informacji jest dokumentacja Unity, znajdziesz ją
pod adresem http://docs.unity3d.com/.
Przygotowanie do programowania na platformach mobilnych 361
RYSUNEK 21.1.
Wyłączone
wyświetlanie
dokumentacji
dotyczącej
urządzeń
mobilnych
RYSUNEK 21.2.
Włączone
wyświetlanie
dokumentacji
dotyczącej
urządzeń
mobilnych
362 Lekcja 21. Programowanie na platformach mobilnych
RYSUNEK 21.3.
Różne sklepy
oferujące aplikacje
mobilne
Wypróbuj samodzielnie
Przyśpieszeniomierz
Większość nowoczesnych urządzeń mobilnych ma wbudowany przyśpiesze‐
niomierz, którego zadaniem jest przekazywanie informacji o fizycznym poło‐
żeniu urządzenia. Dzięki tym informacjom wiadomo, czy urządzenie się poru‐
sza, jest pochylone, czy też leży płasko. Zmiany są wykrywane we wszystkich
trzech osiach. Na rysunku 21.4 pokazano osie przyśpieszeniomierza urzą‐
dzenia mobilnego oraz ich orientację. Na pokazanym rysunku widzimy tzw.
orientację pionową.
364 Lekcja 21. Programowanie na platformach mobilnych
RYSUNEK 21.4.
Osie przyśpiesze-
niomierza
Użycie przyśpieszeniomierza
Odczyt danych przyśpieszeniomierza z poziomu skryptu odbywa się dokładnie
tak samo jak innych danych wejściowych użytkownika. Całość sprowadza się
do odczytu zmiennej typu Vector3 o nazwie acceleration, która należy do
obiektu Input. Poniżej przedstawiono fragment kodu pozwalający na odczyt
danych dla osi X, Y i Z.
Input.acceleration.x;
Input.acceleration.y;
Input.acceleration.z;
Za pomocą tak pobranych wartości można sterować obiektami gry.
Rozbieżność osi
Podczas użycia danych przyśpieszeniomierza w połączeniu z aplikacją Unity
Remote można zauważyć, że osie nie są dokładnie dopasowane, o czym
wspomniano we wcześniejszej części lekcji (patrz podrozdział „Przyśpie-
szeniomierz”). Wynika to z faktu, że osie w Unity Remote są oparte na
orientacji gry w wybranych proporcjach ekranu. Aplikacja Unity Remote
automatycznie użyje orientacji poziomej (dłuższa krawędź urządzenia jest
równoległa do podłoża) i odpowiednio przekształci dane osi za Ciebie. Dla-
tego też, gdy używasz Unity Remote, oś X przebiega wzdłuż dłuższej
krawędzi urządzenia, natomiast oś Y wzdłuż krótszej. To może wydawać się
dziwne, ale istnieje spore prawdopodobieństwo, że urządzenia z urucho-
mioną grą będziesz używać w taki właśnie sposób. Dzięki temu oszczę-
dzasz sobie nieco pracy.
Wypróbuj samodzielnie
Podsumowanie
W tej lekcji dowiedziałeś się, jak wykorzystać środowisko Unity do opraco‐
wywania gier na platformy mobilne. Na początku przedstawiono ogólne
wskazówki dotyczące konfiguracji środowiska pracy do tworzenia gier dla
Podsumowanie 367
Wypróbuj samodzielnie
Śledzenie dotknięć
W tym ćwiczeniu będziesz śledzić dotknięcia palcem i dotyczące ich dane
wyświetlać na ekranie. Oczywiście możliwość wykonania tego ćwiczenia
wymaga posiadania podłączonego i odpowiednio skonfigurowanego urzą-
dzenia mobilnego, wyposażonego w ekran dotykowy z obsługą jedno-
cześnie wielu dotknięć.
1. Utwórz nowy projekt lub scenę.
2. Utwórz nowy skrypt o nazwie TouchScript i dołącz go do kamery
Main Camera. W skrypcie umieść przedstawiony poniżej kod.
void OnGUI()
{
foreach(Touch touch in Input.touches)
{
string message = "";
message += "ID: " + touch.fingerId + "\n";
message += "Phase: " + touch.phase.ToString() + "\n";
message += "TapCount: " + touch.tapCount + "\n";
message += "Pos X: " + touch.position.x + "\n";
message += "Pos Y: " + touch.position.y + "\n";
Pytania i odpowiedzi
Pytanie: Czy mogę grę utworzyć tylko jeden raz, a następnie wdrożyć ją na
wszystkich najważniejszych platformach, w tym także mobilnych?
Odpowiedź: Oczywiście! Musisz jedynie pamiętać, że urządzenia mobilne
nie mają aż tak dużej mocy obliczeniowej jak urządzenia stacjonarne.
Dlatego też, jeśli w grze przeprowadzana jest ogromna ilość obliczeń
lub zastosowano zbyt wiele efektów, wtedy po jej uruchomieniu
w urządzeniu mobilnym mogą pojawić się pewne problemy związane
z wydajnością. Jeżeli grę chcesz wydać także na platformach mobilnych,
upewnij się, że działa na nich efektywnie.
Pytanie: Jakie są różnice między urządzeniami działającymi pod kontrolą
systemów iOS i Android?
Odpowiedź: Z perspektywy środowiska Unity nie istnieje zbyt wiele różnic
między dwoma wymienionymi systemami operacyjnymi. Oba są
traktowane jako przeznaczone dla urządzeń mobilnych. Musisz mieć
jednak świadomość istnienia pewnych różnic w sprzęcie, które mogą
mieć wpływ na gry.
Warsztaty
Poświęć nieco czasu i odpowiedz na zamieszczone poniżej pytania, a także
upewnij się, że przyswoiłeś sobie materiał omówiony w tej lekcji.
Quiz
1. Podaj nazwę narzędzia pozwalającego na przekazywanie na bieżąco
danych wejściowych urządzenia do edytora Unity, w którym
uruchomiono scenę.
2. Ilu osi przyśpieszeniomierza można realnie używać w danej chwili?
3. Ile dotknięć może być jednocześnie obsłużonych przez urządzenie
mobilne?
Odpowiedzi
1. Aplikacja Unity Remote.
2. Dwie osie. Na trzecią zawsze będzie miała wpływ grawitacja. Dokładna
oś zależy od orientacji urządzenia.
3. To całkowicie zależy od urządzenia. Jeżeli urządzenie mobilne
nie zawiera ekranu dotykowego obsługującego jednocześnie wiele
dotknięć (multi‐touch), wtedy to będzie tylko jeden dotyk.
W przypadku ekranu typu multi‐touch to może być wiele dotknięć.
370 Lekcja 21. Programowanie na platformach mobilnych
Ćwiczenie
W tym ćwiczeniu będziesz poruszać obiektami po scenie za pomocą danych
wejściowych pochodzących z urządzenia mobilnego. Oczywiście możliwość
wykonania tego ćwiczenia wymaga posiadania podłączonego i odpowiednio
skonfigurowanego urządzenia mobilnego wyposażonego w ekran dotykowy
z obsługą jednocześnie wielu dotknięć. Jeżeli nie posiadasz takiego urządzenia,
nadal możesz przeczytać tekst ćwiczenia i poznać ogólne idee. Ukończony
projekt znajdziesz w katalogu Hour21_Exercise w materiałach przeznaczonych
dla bieżącej lekcji.
1. Utwórz nowy projekt lub scenę. Do sceny dodaj światło kierunkowe.
2. Do sceny dodaj trzy sześciany, nadaj im nazwy Cube1, Cube2 i Cube3
oraz umieść w położeniach, odpowiednio, (–3, 1, –5), (0, 1, –5) i (3, 1, –5).
3. Utwórz nowy katalog o nazwie Scripts, w nim nowy skrypt o nazwie
InputScript i dołącz go do wszystkich trzech sześcianów.
4. W metodzie Update() skryptu umieść przedstawiony poniżej kod.
foreach(Touch touch in Input.touches)
{
if(touch.fingerId == 0 && gameObject.name == "Cube1")
transform.Translate(touch.deltaPosition.x * .05F,
touch.deltaPosition.y * .05F, 0F);
if(touch.fingerId == 1 && gameObject.name == "Cube2")
transform.Translate(touch.deltaPosition.x * .05F,
touch.deltaPosition.y * .05F, 0F);
if(touch.fingerId == 2 && gameObject.name == "Cube3")
transform.Translate(touch.deltaPosition.x * .05F,
touch.deltaPosition.y * .05F, 0F);
}
5. Uruchom scenę i dotknij ekranu trzema palcami. Zwróć uwagę,
że masz możliwość niezależnego przesuwania trzech sześcianów.
Zauważ także, że podniesienie jednego palca z ekranu nie powoduje
utraty możliwości przesuwania pozostałych sześcianów.
Lekcja 22
Kolejne wersje gier
Ukończone gry
Każda z ukończonych gier w wersji przyjaznej dla urządzeń
mobilnych znajduje się w materiałach przeznaczonych do
bieżącej lekcji.
372 Lekcja 22. Kolejne wersje gier
Amazing Racer
Pierwszą zbudowaną w tej książce grę prawdopodobnie najtrudniej będzie
przekonwertować na urządzenia mobilne. Powód jest prosty: istnieją trzy
formy unikalnych danych wejściowych, takie jak poruszanie się, rozglądanie
i skoki. Dane potrzebne do poruszania graczem można łatwo odczytać z przy‐
śpieszeniomierza. Jednak dane potrzebne do rozglądania się i skoków trzeba
pobrać z ekranu dotykowego. Dlatego też potrzebny będzie pewien sposób
na rozróżnianie danych wejściowych dotyczących rozglądania się i skoków.
CharacterController control;
void Start () {
control = GetComponent<CharacterController>();
}
{
// Obrót.
if(touch.position.x > Screen.width / 2)
{
transform.Rotate(0f, touch.deltaPosition.x, 0f);
}
}
}
3. Podłącz urządzenie mobilne do komputera i uruchom aplikację Unity
Remote. Trzymając urządzenie w orientacji poziomej, uruchom scenę.
Zwróć uwagę na możliwość poruszania się przez pochylanie
urządzenia. Spróbuj przeciągnąć palcem po prawej stronie ekranu.
Teraz zobacz, jak dotknięcie po prawej stronie ekranu pozwala na
rozejrzenie się.
Po dodaniu możliwości poziomego rozglądania się przystąp do implementacji
pionowego rozglądania. Komponent rozglądania się w pionie dodasz bezpo‐
średnio do kamery kontrolera First Person. Wykorzystasz takie samo rozwią‐
zanie jak w przypadku rozglądania się w poziomie. Implementacja wymaga
wykonania przedstawionych poniżej kroków.
1. W katalogu Scripts utwórz nowy skrypt o nazwie MobileLookScript.
Dołącz skrypt do kamery Main Camera, która jest zagnieżdżona
w obiekcie gry Player (patrz rysunek 22.1).
RYSUNEK 22.1.
Dodanie
do kamery
kontrolera skryptu
implementującego
funkcję
rozglądania się
Skoki
Ostatnią funkcją, którą chcemy dodać do gry Amazing Racer, jest możliwość
wykonywania skoków. Jak wcześniej wspomniano, gra została utworzona
z wykorzystaniem kontrolera First Person. Dlatego też dodawana teraz funkcja
obsługi skoków nie będzie działała w dokładnie taki sam sposób. Najlepszym
rozwiązaniem jest modyfikacja kodu kontrolera w celu obsługi danych wej‐
ściowych skoku. Jednak ze względu na związany z tym poziom skompliko‐
wania musisz się zdecydować na dodanie nowego kodu.
Skok będzie wykonywany po dotknięciu lewej strony ekranu. W omawianym
rozwiązaniu kod sprawdza, czy nastąpiło jakiekolwiek dotknięcie po lewej
stronie ekranu. Jeżeli tak, postać kierowana przez gracza skoczy w górę. Imple‐
mentacja rozwiązania wymaga przedstawionych poniżej kroków.
1. Nie będziesz tworzyć nowego skryptu. Użyjesz MobileInputScript,
który utworzyłeś wcześniej.
2. W metodzie Update() umieść przedstawiony poniżej fragment kodu.
W metodzie powinien już znajdować się pewien kod. Pozostawiono
go tutaj, aby zapewnić Ci punkt odniesienia.
foreach(Touch touch in Input.touches) // Punkt odniesienia.
{
// Obsługa skoków.
if(touch.position.x < Screen.width - Screen.width / 2 &&
touch.phase == TouchPhase.Began)
{
control.Move(new Vector3(0f, jump, 0f));
}
Jakość gry
Po uruchomieniu gry w urządzeniu mobilnym możesz zauważyć brak kon-
troli jakości. Mechanika skoku jest rwana, natomiast ruch i rozglądanie
się są nieco szarpane. W omawianym przykładzie to normalne i nie jest
skutkiem żadnego problemu z urządzeniem mobilnym. Nowe funkcje
zostały dodane na podstawie już istniejących. Nie wszystkie rozwiązania
można łatwo integrować. Ruch, skoki i rozglądanie się można wygładzić
i dopracować, ale to wymaga znacznie większej ilości czasu. Pamiętaj, że
nadal czekają trzy gry do konwersji. Przedstawione tutaj gry wykorzystaj
więc w charakterze drogowskazu pokazującego, co można osiągnąć za
pomocą urządzeń mobilnych. Prezentowane tutaj informacje są wska-
zówkami dla podstaw implementacji rozwiązań.
Chaos Ball
Druga utworzona w tej książce gra zatytułowana Chaos Ball jest nieco prostsza
do konwersji. Także w tej grze do poruszania obiektem gracza wykorzystasz
dane pochodzące z przyśpieszeniomierza. Do rozglądania się można użyć
dotknięcia ekranu. Ponieważ nie są wymagane żadne inne dane wejściowe,
nie ma konieczności dzielenia ekranu lub wykorzystywania dotyku do innych
celów. Przedstawione tutaj skrypty wyglądają podobnie do zaprezentowa‐
nych w poprzedniej grze i działają na podobnej zasadzie. Aby przeprowadzić
konwersję gry, wykonaj przedstawione poniżej kroki.
1. W Unity otwórz projekt gry Chaos Ball. Wyłącz komponent Mouse
Look (Script) w kamerze Main Camera obiektu gry w postaci kontrolera
First Person (patrz rysunek 22.2).
2. Do katalogu Scripts dodaj nowy skrypt o nazwie MouseInputScript.
Skrypt dołącz do obiektu gry w postaci kontrolera First Person.
Następnie w skrypcie umieść poniższy kod.
public float speed = 15;
void Update () {
float x = Input.acceleration.x * Time.deltaTime * speed;
float z = -Input.acceleration.z * Time.deltaTime * speed;
Captain Blaster
Gra Captain Blaster jest unikalna wśród gier, które utworzyłeś do tej chwili:
została potraktowana jako gra dwuwymiarowa i jest zorientowana pionowo.
Oznacza to, że nie musisz się przejmować osią Z. Jednak musisz się upewnić,
że gra została skonfigurowana do działania w orientacji pionowej. Jak sobie
przypominasz, orientacja pionowa to taka, gdy trzymasz urządzenie mobilne
pionowo, aby jego krótsza krawędź znajdowała się równolegle do podłoża,
natomiast dłuższa prostopadle do podłoża.
Aby umożliwić Unity działanie w orientacji pionowej, konieczne jest wpro‐
wadzenie pewnych zmian w edytorze Unity. Przede wszystkim należy wskazać
chęć działania w orientacji pionowej. Wykonaj więc wymienione poniżej kroki.
1. W Unity otwórz projekt gry Captain Blaster.
2. Wybierz opcję File/Build Settings, co spowoduje wyświetlenie okna
dialogowego Build Settings. Nie przejmuj się na razie zawartością tego
okna, powrócisz do niego w kolejnej lekcji. W menu widocznym po
lewej stronie zaznacz Android lub iOS, w zależności od używanego
urządzenia, a następnie kliknij przycisk Switch Platform. Teraz kliknij
X w prawym górnym rogu okna dialogowego (patrz rysunek 22.3),
a zamkniesz je. Jeżeli używasz Maca, podobny przycisk znajdziesz
w lewym górnym rogu okna dialogowego.
RYSUNEK 22.3.
Przełączanie
platformy
378 Lekcja 22. Kolejne wersje gier
RYSUNEK 22.4.
Zmiana
rozdzielczości
sceny
Błędy konsoli
W trakcie przedstawionego powyżej procesu możesz zauważyć w konsoli
wiele błędów wyświetlanych w kolorze czerwonym. Na tym etapie możesz
je bezpiecznie zignorować. Błędy te są generowane podczas konwersji
tekstur i modeli na scenie. Po uruchomieniu sceny błędy znikną i wszystko
będzie działało zgodnie z oczekiwaniami.
Gauntlet Runner
Ostatnia utworzona w tej książce gra zatytułowana Gauntlet Runner jest
najłatwiejsza do konwersji na postać przyjazną dla urządzeń mobilnych. Cała
praca sprowadza się do wprowadzenia zmian w kodzie, które już zastoso‐
wano w przypadku gry Captain Blaster. Ponieważ to jest nudne, zdecyduj się
na implementację innego systemu poruszania się gracza.
Tym razem gracz będzie poruszał się w lewo i prawo przez przeciągnięcie
palcem w odpowiednią stronę. Aby skoczyć, gracz musi „machnąć” palcem
w górę. Obie akcje są oparte na zmiennej deltaPositioin wewnątrz zmiennej
typu Touch. Żeby zaimplementować nowy system poruszania się gracza, wyko‐
naj przedstawione poniżej kroki.
1. W Unity otwórz projekt gry Gauntlet Runner.
2. W katalogu Scripts odszukaj skrypt PlayerScript i otwórz go. Następnie
zmodyfikuj kod metody Update() do następującej postaci.
transform.Translate(Input.GetAxis("Horizontal") * Time.deltaTime
* strafeSpeed, 0f, 0f);
if(transform.position.x > 3)
transform.position = new Vector3(3, transform.position.y,
transform.position.z);
else if(transform.position.x < -3)
transform.position = new Vector3(-3, transform.position.y,
transform.position.z);
380 Lekcja 22. Kolejne wersje gier
if (anim.GetCurrentAnimatorStateInfo(0).IsName("Base
Layer.Jump"))
{
anim.SetBool("Jumping", false);
jumping = true;
}
else
{
jumping = false;
if(Input.GetButtonDown("Jump"))
{
anim.SetBool("Jumping", true);
}
Podsumowanie
W tej lekcji poprzednio utworzone w książce gry przystosowałeś do użycia
w urządzeniach mobilnych. Na początku zająłeś się grą Amazing Racer, do której
dodałeś możliwość ruchu, skakania i rozglądania się. Następnie przystąpiłeś
do modyfikacji gry Chaos Ball, w której wykorzystałeś dane pochodzące
z przyśpieszeniomierza i ekranu dotykowego. W Captainie Blasterze wprowa‐
dziłeś zmianę orientacji gry w urządzeniach mobilnych. Ponadto dane przy‐
śpieszeniomierza i dotknięcia ekranu użyte zostały do obsługi ruchu i strze‐
Pytania i odpowiedzi 381
Pytania i odpowiedzi
Pytanie: Wydaje się, że konwersja niektórych gier nie wyszła zbyt dobrze.
Czy to normalne?
Odpowiedź: Tak. Bardzo często zdarza się, że jeśli od samego początku gra nie
została opracowana z uwzględnieniem urządzeń mobilnych, jej późniejsza
konwersja staje się trudna. Komputery i konsole do gier oferują znacznie
więcej możliwości w zakresie sterowania, niż ma to miejsce w urządzeniach
mobilnych. Podczas projektowania gry zawsze zastanów się, czy
w przyszłości będziesz przygotowywać jej wersję dla urządzeń mobilnych.
Warsztaty
Poświęć nieco czasu i odpowiedz na zamieszczone poniżej pytania, a także
upewnij się, że przyswoiłeś sobie materiał omówiony w tej lekcji.
Quiz
1. W jaki sposób w grze Amazing Racer rozwiązałeś kwestię użycia
ekranu do obsługi zarówno skoków, jak i rozglądania się?
2. Jaki był największy problem podczas użycia translacji do poruszania
obiektem gracza w grze Chaos Ball?
3. Gra Captain Blaster została zmodyfikowana do działania w orientacji
poziomej. Prawda czy fałsz?
4. Co oznacza pojęcie „machnięcia” w grze Gauntlet Runner?
Odpowiedzi
1. Połowę ekranu wykorzystano do pobierania danych wejściowych
skoku, natomiast drugą połowę do obsługi rozglądania się.
2. Gracz ma możliwość przejścia przez ściany i wypadnięcia z planszy gry.
3. Fałsz. Gra została zmodyfikowana do działania w orientacji pionowej.
4. Machnięcie występuje, gdy gracz bardzo szybko przesunie w górę
palcem po ekranie.
382 Lekcja 22. Kolejne wersje gier
Ćwiczenie
W tej lekcji dużo pracowałeś nad sposobami sterowania postacią gracza
w czterech różnych grach. Podczas pracy nad grami mogą pojawiać się poważne
problemy na tym polu. Często zdarza się zmiana sposobu pobierania danych
wejściowych lub kontrolek, aby tym samym poprawić wrażenia odnoszone
przez gracza. Każdą poważną zmianę trzeba dokładnie przetestować i spraw‐
dzić, jaki ma wpływ na grę. Ćwiczeniem w tej lekcji jest ponowna gra we
wszystkie cztery gry tutaj omówione. Tym razem skoncentruj się jednak na
sterowaniu postacią gracza w urządzeniu mobilnym. Podobnie jak wcześniej,
rób notatki dotyczące tego, co lubisz i co Ci się nie podoba. Kiedy zakończysz
testy gier, porównaj nowe notatki z tymi, które sporządziłeś po utworzeniu
pierwotnych wersji gier (mam nadzieję, że je zachowałeś). Zobacz, jakie
zmiany możesz wprowadzić, aby poprawić wrażenia odnoszone podczas gry
w urządzeniu mobilnym. Spróbuj zaimplementować niektóre ze wspomnianych
zmian.
Lekcja 23
Dopracowanie i wdrożenie
Zarządzanie scenami
Dotychczas w środowisku Unity wszystko robiłeś na pojedynczej scenie. Wpraw‐
dzie w ten sposób niewątpliwie można przygotować ogromne i skompliko‐
wane gry, ale — ogólnie rzecz biorąc — znacznie łatwiejsze będzie podzielenie
gry na wiele mniejszych scen. Idea sceny polega na utworzeniu samowystar‐
czalnej kolekcji obiektów gry. Dlatego też podczas przejścia między scenami
wszystkie istniejące obiekty gry są niszczone, a tworzone nowe obiekty gry.
Istnieje możliwość zmiany tego zachowania, o czym dowiesz się dalej w tej
lekcji.
Wypróbuj samodzielnie
Przełączanie scen
Po zdefiniowaniu kolejności scen przełączanie między nimi jest już łatwym
zadaniem. Do zmiany scen służy metoda LoadLevel(), która jest częścią obiektu
Application. Metoda pobiera pojedynczy parametr w postaci liczby całkowitej
wskazującej indeks sceny lub ciągu tekstowego określającego nazwę sceny.
386 Lekcja 23. Dopracowanie i wdrożenie
Wypróbuj samodzielnie
Zachowywanie obiektów
Łatwym sposobem zachowania danych między scenami jest po prostu pozo‐
stawienie obiektów wraz z danymi. Jeśli np. masz obiekt gracza wraz ze skryp‐
tami obsługującymi liczbę dostępnych „żyć” (a przecież ładniej brzmiałoby
„żywotów”), zdobyte zasoby, punktację itd., wówczas najłatwiejszym sposo‐
bem zachowania tej ogromnej ilości danych będzie przeniesienie obiektu do
kolejnej sceny i upewnienie się, że nie zostanie zniszczony. Można to zrobić
dość łatwo za pomocą metody o nazwie DontDestroyOnLoad(). Metoda pobiera
pojedynczy parametr będący obiektem gry, który ma zostać zachowany. Dlatego
też, jeśli chcesz zachować obiekt przechowywany w zmiennej Brick, możesz
użyć poniższego wywołania:
DontDestroyOnLoad(Brick);
Ponieważ metoda pobiera parametr w postaci obiektu gry, innym doskonałym
sposobem użycia omawianej metody dla obiektów jest wykorzystanie słowa
kluczowego this. Jeżeli obiekt ma zachować sam siebie, w metodzie Start()
skryptu dołączonego do obiektu umieść poniższe wywołanie:
DontDestroyOnLoad(this);
Teraz po przejściu do innej sceny zachowane obiekty będą na Ciebie czekały.
Zachowywanie danych
Czasami zachodzi konieczność zapisu danych w pliku w celu ich późniejszego
użycia. Zapisywane mogą być informacje dotyczące punktów zdobytych przez
gracza, ustawienia konfiguracyjne, przedmioty zdobyte w grze itd. Istnieje wiele
skomplikowanych i oferujących użyteczne możliwości sposobów zapisu danych,
ale proste rozwiązanie jest oparte na PlayerPrefs. Jest to obiekt, w którym
zapisuje się proste dane w pliku lokalnym znajdujących się w systemie. Następ‐
nie za pomocą obiektu PlayerPrefs można odczytać dane z pliku.
Zapis danych w obiekcie PlayerPrefs to prosta operacja sprowadzająca się
do podania nazwy dla danych oraz samych danych. Konkretna metoda zależy
od typu zapisywanych danych. Przykładowo w celu zapisania liczby całkowitej
należy wywołać metodę SetInt(). Z kolei pobranie liczby całkowitej odbywa
388 Lekcja 23. Dopracowanie i wdrożenie
Wypróbuj samodzielnie
Zachowywanie obiektów
W tym ćwiczeniu zachowasz sześcian podczas przejścia do następnej sceny.
Do wykonania tego ćwiczenia potrzebny jest projekt z poprzedniego. Jeżeli
nie wykonałeś poprzedniego ćwiczenia, musisz to zrobić teraz. Zapisz pro-
jektu, ponieważ będziesz jeszcze z niego korzystać w tej lekcji.
1. Wczytaj wcześniej utworzony projekt. Upewnij się, że Scene1
to aktualnie wczytana scena. Zwróć uwagę na istnienie sześcianu
we wcześniej utworzonej scenie.
2. W katalogu Scripts utwórz nowy skrypt o nazwie DontDestroyScript.
Następnie skrypt dołącz do sześcianu, a metodę Start() zastąp
jej poniższą wersją.
void Start ()
{
DontDestroyOnLoad(this);
}
3. Zapisz i uruchom scenę. Zwróć uwagę, że podczas przechodzenia
między scenami sześcian pozostaje, jest trwale przechowywany.
Zapisz projekt.
się za pomocą metody GetInt(). Dlatego też kod przeznaczony do zapisu liczby
10 w obiekcie PlayerPrefs, a następnie pobrania tej wartości z powrotem
przedstawia się następująco.
PlayerPrefs.SetInt("score", 10);
PlayerPrefs.GetInt("score");
Podobne metody istnieją dla ciągów tekstowych (SetString()) i liczb
zmiennoprzecinkowych (SetFloat()). Za pomocą wymienionych metod można
bardzo łatwo zapisywać w pliku dowolne proste dane.
Wypróbuj samodzielnie
void OnGUI()
{
Zachowywanie danych i obiektów 389
void Start()
{
playerName = PlayerPrefs.GetString("name");
}
void OnGUI()
{
GUI.Label(new Rect(5, 120, 50, 30), playerName);
}
3. Zapisz Scene2 i ponownie wczytaj Scene1. Uruchom scenę. W polu
tekstowym podaj imię i naciśnij przycisk Zapisz. Następnie wciśnij
przycisk Wczytaj Scene2 w celu wczytania sceny drugiej. Zwróć uwagę,
że podane przez Ciebie imię jest wyświetlone na ekranie. Dane zostały
zapisane w PlayerPrefs, a następnie wczytane z wymienionego
obiektu w innej scenie.
Bezpieczeństwo danych
Wprawdzie użycie obiektu PlayerPrefs do zapisu danych gry jest bardzo
łatwe, ale jednocześnie nie zapewnia bezpieczeństwa danych. Dane są prze-
chowywane w niezabezpieczonym pliku znajdującym się na dysku urządze-
nia użytkownika. Dlatego też gracz może bardzo łatwo otworzyć ten plik
i zmodyfikować znajdujące się w nim dane. W ten sposób użytkownik ma
możliwość zdobycia w nieuczciwy sposób korzyści lub przewagi w grze
bądź też może uszkodzić grę. Musisz więc pamiętać, że zgodnie z nazwą
obiektu jest on przeznaczony do przechowywania preferencji gracza. Moż-
liwość zapisu innych danych to jedynie użyteczny dodatek. Zapewnienie
prawdziwego bezpieczeństwa danych to trudne zadanie i to zagadnienie
zdecydowanie wykracza poza zakres tematyczny książki. Obiekt Player-
Prefs jest odpowiedni do zadań przedstawianych w tej lekcji, ale w przy-
szłych projektach powinieneś zastosować znacznie bardziej skomplikowane
i bezpieczne rozwiązanie w zakresie zachowywania danych gracza.
390 Lekcja 23. Dopracowanie i wdrożenie
RYSUNEK 23.2.
Ustawienia
niezależne
od platformy
RYSUNEK 23.3.
Pasek wyboru
platformy
Wiele ustawień znajdujących się w tej grupie wymaga dużej wiedzy o platfor‐
mie, dla której tworzona jest gra. Dlatego też nie powinieneś zmieniać tych
ustawień, o ile dokładnie nie znasz sposobu działania danej platformy. Pozo‐
stałe ustawienia są całkiem proste i mogą być zmienione, gdy chcesz osiągnąć
konkretny efekt. Przykładowo grupa ustawień dotyczących rozdzielczości i pre‐
zentacji pozwala na zmianę wymiarów okna gry. Dla produktów tworzonych
na platformy stacjonarne istnieje możliwość przygotowania gry uruchamianej
w oknie lub na pełnym ekranie, a ponadto obsługiwanych jest wiele różnych
proporcji ekranu. Przez włączenie lub wyłączenie danej proporcji ekranu
pozwalasz lub nie pozwalasz graczowi na wybór pewnych rozdzielczości ekranu
podczas gry.
Ustawienia dotyczące ikony są uzupełniane automatycznie po podaniu pliku
ikony dla właściwości Default Icon w grupie ustawień niezależnych od plat‐
formy. Możesz dostrzec, że na podstawie dostarczonej ikony wygenerowane
zostają ikony różnej wielkości. Dlatego tak ważne jest dostarczanie obrazów
o prawidłowych wymiarach. W kolejnej grupie ustawień można zdefiniować
winietę dla programu. Winieta jest obrazem dodawanym w oknie dialogowym
Player Settings i wyświetlanym graczowi podczas uruchamiania gry.
Kompilacja gry
Przyjąłem założenie, że zakończyłeś opracowywanie pierwszej gry. Wykonałeś
wszystkie niezbędne zadania i przetestowałeś grę w edytorze. Przejrzałeś
nawet ustawienia Player Settings i ustawiłeś je zgodnie z wymaganiami gry.
Nadeszła więc pora na jej kompilację. Istnieją dwa okna dialogowe z ustawienia‐
mi ważnymi podczas kompilacji gry. Pierwsze okno to Build Settings, w którym
392 Lekcja 23. Dopracowanie i wdrożenie
RYSUNEK 23.4.
Okno dialogowe
Build Settings
RYSUNEK 23.5.
Okno dialogowe
Game Settings
394 Lekcja 23. Dopracowanie i wdrożenie
Tytuł gry jest wyświetlany na pasku tytułowym. Ponadto w górnej części okna
pojawia się winietka podana wcześniej w oknie dialogowym Player Settings.
Pierwsza karta o nazwie Graphics pozwala na wybór rozdzielczości gry. Lista
dostępnych rozdzielczości zależy od proporcji ekranu włączonych lub wyłą‐
czonych wcześniej w oknie dialogowym Player Settings. Gracz ma także moż‐
liwość uruchomienia gry w oknie lub na pełnym ekranie, a także wybór jakości
wyświetlanej grafiki.
Po przejściu do drugiej karty zatytułowanej Input (patrz rysunek 23.6) gracz
może przypisać wybranym przez siebie klawiszom różne osie danych wej‐
ściowych.
RYSUNEK 23.6.
Ustawienia
w karcie Input
Mówiłem Ci!
Być może pamiętasz, jak wcześniej w książce pisałem, że zawsze należy sta-
rać się, aby dane wejściowe gracza były pobierane na podstawie osi danych
wejściowych, a nie określonych klawiszy. Teraz już wiesz dlaczego. Jeżeli
w kodzie będą szukane dane pochodzące z określonych klawiszy, a nie osi,
wtedy gracz nie będzie miał wyboru i musi używać zdefiniowanego przez
Ciebie sposobu sterowania grą. Jeżeli nie widzisz w tym żadnego problemu,
przypomnij sobie, że wiele osób (np. niepełnosprawnych) może korzystać
z niestandardowych urządzeń danych wejściowych. Jeśli uniemożliwisz im
zmianę sposobu sterowania grą, być może w ogóle uniemożliwisz im grę.
Wykorzystanie osi zamiast na stałe określonych klawiszy wymaga tylko
niewielkiej ilości dodatkowej pracy, a dla gracza może stanowić ogromną
różnicę: pokocha lub znienawidzi Twoją grę.
Podsumowanie
W tej lekcji zająłeś się dopracowaniem i kompilacją gry w Unity. Na początku
dowiedziałeś się, jak zmieniać sceny w Unity za pomocą metody LoadLevel().
Następnie zobaczyłeś, jak zachowywać w grze obiekty i dane. Później prze‐
szedłeś do różnych ustawień gracza. Na końcu poznałeś procedurę kom‐
pilacji gry.
Pytania i odpowiedzi
Pytanie: Wiele ustawień wydaje się ważnych. Dlaczego nie zostały
omówione w tej lekcji?
Odpowiedź: Szczerze mówiąc, większość tych ustawień jest Ci niepotrzebna.
Nie są ważne, dopóki… nie staną się ważne. Większość ustawień dotyczy
poszczególnych platform i ich omówienie wykracza poza zakres
tematyczny książki. Zamiast poświęcać czas na lekturę wielu stron
poświęconych ustawieniom, których prawdopodobnie nigdy nie użyjesz,
pozostawiono Ci możliwość wyszukania informacji o nich, gdy staną
się potrzebne.
Warsztaty
Poświęć nieco czasu i odpowiedz na zamieszczone poniżej pytania, a także
upewnij się, że przyswoiłeś sobie materiał omówiony w tej lekcji.
Quiz
1. W jaki sposób można określić indeksy poszczególnych scen w grze?
2. Dane mogą być zachowywane za pomocą obiektu PlayerPrefs.
Prawda czy fałsz?
3. Jakie wymiary powinna mieć ikona dla gry?
4. Ustawienia w karcie Input w oknie dialogowym Game Settings
pozwalają graczowi na określenie sposobu sterowania grą. Prawda
czy fałsz?
Odpowiedzi
1. Po dodaniu scen do listy Scenes w oknie dialogowym Build Settings
poszczególnym scenom są przypisywane wartości indeksu.
2. Prawda.
3. Ikona gry powinna być kwadratem o boku, którego wielkość będzie
potęgą liczby 2, np. 8x8, 16x16, 32x32 itd.
396 Lekcja 23. Dopracowanie i wdrożenie
Ćwiczenie
W tym ćwiczeniu skompilujesz grę dla biurowego systemu operacyjnego i poeks‐
perymentujesz z różnymi funkcjami. Ćwiczenie nie jest zbyt obszerne, więk‐
szość czasu poświęcisz na wypróbowanie różnych ustawień i obserwację ich
wpływu na grę. Ponieważ to jest jedynie przykład kompilacji gry, w mate‐
riałach przeznaczonych dla tej lekcji nie znajdziesz ukończonego projektu.
1. Wybierz dowolny z wcześniej utworzonych projektów lub zbuduj
nowy.
2. Przejdź do okna dialogowego Player Settings i skonfiguruj je wedle
własnych potrzeb.
3. Przejdź do okna dialogowego Build Settings i upewnij się, że dodałeś
sceny do listy Scenes. Wybierz platformę PC, Mac & Linux Standalone,
a następnie skompiluj grę.
4. Odszukaj wygenerowany plik gry, a następnie uruchom ją.
Poeksperymentuj z różnymi ustawieniami gry i zobacz, jaki mają
wpływ na jej przebieg.
Lekcja 24
Zakończenie
Osiągnięcia
Kiedy z czymś pracujesz przez dłuższy czas, może się zdarzyć, że zapomnisz
o wszystkim, czego się po drodze nauczyłeś. Warto więc spojrzeć na umie‐
jętności posiadane na początku procesu nauki i porównać je z późniejszymi.
Odkrycie poczynionego postępu znacznie poprawia motywację, a ponadto
przynosi satysfakcję. Spójrz teraz na pewne liczby.
19 lekcji nauki
Przede wszystkim odbyłeś 19 lekcji, w trakcie których intensywnie poznawałeś
różne aspekty tworzenia gier w środowisku Unity 4. Oto wybrane zagadnie‐
nia, które poznałeś w czasie wspomnianych lekcji.
Dowiedziałeś się, jak używać edytora Unity oraz wielu jego paneli
i okien dialogowych.
Poznałeś obiekty gry i transformacje. Dowiedziałeś się, jakie mamy
dwu‐ i trójwymiarowe układy współrzędnych, a także jakie różnice
dzielą układ współrzędnych lokalnych i świata. Stałeś się ekspertem
w zakresie użycia podstawowych kształtów geometrycznych wbudo‐
wanych w Unity.
Poznałeś modele. Zobaczyłeś, że modele składają się z tekstur i shade‐
rów zastosowanych w materiałach, które następnie są nakładane na
siatki. Dowiedziałeś się, że siatki składają się z trójkątów, które z kolei
składają się z punktów w przestrzeni 3D.
Dowiedziałeś się, jak utworzyć teren w Unity. Rzeźbiłeś unikalne krajo‐
brazy i wykorzystywałeś narzędzia potrzebne do wykreowania wyma‐
rzonego świata (ile osób może to powiedzieć?). Przygotowywane
światy usprawniałeś efektami świetlnymi i środowiskowymi.
Dowiedziałeś się wiele o kamerach i światłach.
Zobaczyłeś, jak programować w Unity. Jeżeli nigdy wcześniej nie mia‐
łeś okazji programować, to rozpoczęcie programowania w Unity jest
naprawdę dużym osiągnięciem. Świetna robota!
Poznałeś kolizje, materiały fizyczne i technikę raycastingu. Innymi
słowy, wykonałeś pierwszy krok do interakcji obiektów z uwzględ‐
nieniem fizyki.
Dowiedziałeś się wiele o prefabrykatach i tworzeniu egzemplarzy
obiektów.
Zobaczyłeś, jak opracować graficzny interfejs użytkownika (GUI) za
pomocą wbudowanych w środowisko Unity kontrolek GUI. Wiesz już
nawet, co oznacza GUI.
Osiągnięcia 399
4 pełne gry
W trakcie lekcji przedstawionych w książce utworzyłeś 4 gry zatytułowane:
Amazing Racer, Chaos Ball, Captain Blaster i Gauntlet Runner. Zaprojektowałeś
każdą z tych gier. Opracowałeś koncepcje, zdefiniowałeś reguły i wymagania,
a następnie przystąpiłeś do przygotowania wszystkich elementów gier. Każdy
obiekt, gracz, świat, kula, meteor i wszystko inne zostało przez Ciebie umiesz‐
czone w grze. Ponadto utworzyłeś wszystkie skrypty i zapewniłeś interak‐
tywność każdej gry. Co najważniejsze, przetestowałeś wszystkie opracowane
gry, określiłeś ich mocne i słabe strony. W gry grałeś samodzielnie, a także
pozwalałeś pobawić się innym. Zastanawiałeś się, jak można je usprawnić,
a nawet spróbowałeś poprawić je samodzielnie. Warto spojrzeć na koncepcje
wykorzystane w grach. Oto one.
400 Lekcja 24. Zakończenie
58 scen
W trakcie kolejnych lekcji utworzyłeś 58 różnych scen. Zatrzymajmy się na
chwilę przy tej liczbie. Oznacza to, podczas lektury książki pracowałeś nad
co najmniej 58 różnymi koncepcjami. W ten sposób zdobyłeś całkiem spore
doświadczenie.
W tym momencie prawdopodobnie domyśliłeś się powodów, dla których
powstała ta lekcja. Pokonałeś długą drogę i powinieneś być dumny z własnych
dokonań. Skorzystałeś z ogromnej części silnika gier Unity. Zdobyta dotąd
wiedza będzie stanowiła dla Ciebie solidne podstawy w trakcie dalszego pozna‐
wania Unity.
Co dalej?
Ukończenie lektury tej książki na pewno nie oznacza końca Twojej edukacji
w zakresie tworzenia gier. Tak naprawdę można stwierdzić, że nikt nie zakoń‐
czył edukacji w przemyśle, który zmienia się tak szybko. Mając to na uwadze,
mogę pokusić się o udzielenie Ci kilku rad, dzięki którym będziesz mógł kon‐
tynuować wysiłki.
Co dalej? 401
Buduj gry
Mówię to całkiem serio, buduj kolejne gry. W poprzednim zdaniu nie ma prze‐
sady. Jeżeli jesteś osobą, która próbuje jeszcze dokładniej poznać silnik gier
Unity, znaleźć pracę w przemyśle związanym z grami lub masz taką pracę,
ale chcesz zdobyć lepszą, wtedy po prostu buduj kolejne gry. Błędem najczę‐
ściej popełnianym przez osoby stawiające pierwsze kroki w przemyśle two‐
rzenia gier (lub innego oprogramowania) jest przekonanie, że wiedza wystar‐
czy do zdobycia pracy lub rozwinięcia umiejętności. Nie można się bardziej
mylić. Doświadczenie ma tutaj ogromne znaczenie. Dlatego powinieneś two‐
rzyć kolejne gry i nie muszą być one rozbudowane. Rozpocznij od budowania
wielu mniejszych gier, podobnych do utworzonych w tej książce. Próba przej‐
ścia od razu do skomplikowanej gry może prowadzić do frustracji i rozcza‐
rowania. Niezależnie od tego, co postanowisz, koniecznie twórz kolejne gry
(czy nie wspomniałem już o tym?).
Współpracuj z innymi
Istnieje wiele lokalnych i internetowych grup zajmujących się opracowywa‐
niem gier dla przyjemności lub w celach zarobkowych. Dołącz do tych grup.
Grupa naprawdę dużo zyska, przyjmując w swoje szeregi osobę z tak dużym
doświadczeniem z zakresu środowiska Unity. Pamiętaj, że dotychczas utwo‐
rzyłeś już cztery gry. Co więcej, współpraca z innymi osobami dostarczy Ci wiele
informacji o dynamice grupy. Ponadto współpracując z innymi, będziesz miał
możliwość rozwinięcia własnych umiejętności i jednocześnie zwiększy się
poziom skomplikowania gier, jakie możesz zbudować. Spróbuj znaleźć artystów
grafików i muzyków, aby zapewnić tworzonym grom jeszcze lepszy poziom
multimediów. Przekonasz się, że praca w zespole jest najlepszym sposobem na
poznanie swoich mocnych i słabych stron. To może być doskonały sprawdzian
własnych umiejętności i jednocześnie wzmocnienie zaufania między poszcze‐
gólnymi członkami grupy.
Pisz o tym
Pisanie o grach i wysiłkach ponoszonych podczas ich tworzenia może być praw‐
dziwym dobrodziejstwem pomagającym w osobistym rozwoju. Niezależnie
od tego, czy zaczniesz pisać blog, czy jedynie sporządzać prywatne notatki,
poczynione obserwacje niewątpliwe okażą się przydatne zarówno teraz,
jak i w przyszłości. Ponadto pisanie może być doskonałym sposobem na rozwi‐
nięcie umiejętności własnych oraz współpracy z innymi. Dzieląc się swoimi
ideami i pomysłami, możesz liczyć na odzew innych osób i uczyć się dzięki
otrzymywanym od nich informacjom.
402 Lekcja 24. Zakończenie
Dostępne zasoby
W internecie dostępnych jest wiele zasobów, które pomogą Ci w poszerzaniu
wiedzy z zakresu zarówno silnika gier Unity, jak i ogólnie tworzenia gier. Do
dyspozycji masz przede wszystkim dokumentację Unity. Ten podręcznik jest
oficjalnym źródłem informacji o wszystkim, co dotyczy Unity. Trzeba koniecz‐
nie wiedzieć, że witryna dokumentacji (http://docs.unity3d.com/) zawiera
omówienie Unity z technicznego punktu widzenia. Nie traktuj tej witryny jako
typowego narzędzia do nauki, to jest przede wszystkim podręcznik.
Unity oferuje także doskonały wybór samouczków w witrynie domowej Unity
(http://unity3d.com/learn). Znajdziesz tam wiele materiałów wideo, projektów
oraz innych zasobów, dzięki którym będziesz mógł rozwijać własne umie‐
jętności.
Jeżeli okaże się, że masz pytanie i nie możesz na nie znaleźć odpowiedzi w obu
wymienionych zasobach, wtedy pomocna może okazać się społeczność Unity.
Fora społeczności znajdziesz pod adresem http://forum.unity3d.com/. W tym
miejscu prowadzone są ogólne dyskusje i zadawane pytania. Istnieje również
witryna http://answers.unity3d.com, w której można zadawać szczegółowe
pytania dotyczące Unity i otrzymywać odpowiedzi od profesjonalistów zajmu‐
jących się Unity.
Poza oficjalnymi zasobami Unity istnieje jeszcze wiele witryn poświęconych
tworzeniu gier. Dwie najpopularniejsze to http://www.gamasutra.com/ i http://
www.gamedev.net/page/index.html. Obie witryny mają ogromne społeczności,
a ponadto regularnie są w nich publikowane artykuły. Tematyka artykułów
nie jest ograniczona jedynie do Unity, a tym samym wymienione witryny
stanowią doskonałe źródła bezstronnych informacji.
Podsumowanie
W tej lekcji przypomniałeś sobie to wszystko, co dotąd zrobiłeś. Ponadto spoj‐
rzałeś w przyszłość. Na początku przeanalizowałeś wszystkie dokonania, jakie
udało Ci się osiągnąć w trakcie wcześniejszych lekcji. Następnie dowiedziałeś
się, jak możesz kontynuować rozwijanie własnych umiejętności. Na końcu
przedstawione zostały pewne dostępne w internecie zasoby dotyczące Unity.
Pytania i odpowiedzi
Pytanie: Po bieżącej lekcji raczej nie potrafię pomóc innym, ale mam
wrażenie, że powinienem tworzyć gry. Czy mam rację?
Odpowiedź: Tak. Jestem przekonany, że wielokrotnie o tym wspominałem.
Nie jestem w stanie wystarczająco dobitnie podkreślić wagi rozwijania
własnych umiejętności dzięki praktyce i kreatywności.
Warsztaty 403
Warsztaty
Poświęć nieco czasu i odpowiedz na zamieszczone poniżej pytania, a także
upewnij się, że przyswoiłeś sobie materiał omówiony w tej lekcji.
Quiz
1. W której grze 3D zadaniem gracza było zbieranie elementów?
2. Czy powinieneś być dumny z dotychczasowych osiągnięć?
3. Jaki jest najlepszy sposób na dalsze rozwijanie umiejętności w zakresie
tworzenia gier?
4. Ile jest dostępnych witryn społeczności Unity?
Odpowiedzi
1. Gauntlet Runner.
2. Oczywiście.
3. Możesz tworzyć kolejne gry!
4. Dwie: fora Unity i Unity Answers.
Ćwiczenie
Tematem przewodnim tej lekcji była retrospekcja i utrwalenie zdobytej dotąd
wiedzy. Ostatnie ćwiczenie w tej książce podąża tą samą drogą. W przemyśle
gier komputerowych bardzo często opracowuje się analizę. Celem jest przy‐
gotowanie artykułu o utworzonej grze, a intencją artykułu jest jego przeczy‐
tanie przez inne osoby. W tego rodzaju artykule analizujesz elementy procesu,
zarówno te, które się sprawdziły, jak i te, które zawiodły. Informujesz innych
o pokonanych przeszkodach, aby nie musieli wpadać w te same pułapki.
W tym ćwiczeniu Twoje zadanie polega na przygotowaniu analizy dotyczą‐
cej jednej z gier, którą utworzyłeś. Niekoniecznie ktokolwiek musi przeczytać
ten tekst, najważniejsze jest tutaj jego napisanie. Poświęć nieco czasu na przygo‐
towanie analizy, ponieważ być może będziesz ją jeszcze wielokrotnie czytał.
Możesz być zadziwiony aspektami, które uznałeś za trudne, lub tymi, które
uznałeś za zabawne.
Po przygotowaniu analizy wydrukuj ją (o ile nie została napisana ręcznie)
i umieść w tej książce. Gdy później powrócisz do książki, koniecznie przeczytaj
również własną analizę.
404 Lekcja 24. Zakończenie
Skorowidz
A D
anatomia dane
kamery, 114 wejściowe, 167, 169
metody, 162 wejściowe myszy, 170
skryptu, 145 wejściowe z ekranu dotykowego, 366
animacja wyjściowe skryptu, 145
Idle, 311, 317 dodawanie
Jump, 332 animacji, 300
modelu, 294, 302 celów, 207
ruchu, 320 cookie, 112, 113
Run, 333 efektu Lens Flare, 99
WalkForward, 313 egzemplarza prefabrykatu, 216
WalkForwardTurn, 314 elementów, 129
animacje, 293, 295 karty, 33
przygotowanie, 311 klipu, 333
przygotowanie modelu, 294, 295 klipu animacji, 314
zasoby, 298 kontrolera postaci, 101, 244
zmiana, 304 mgły, 98
animator, 307, 316 Motion Field, 320
aplikacja Unity Remote, 362 obiektów kontrolujących, 131
aplikacje mobilne, 362 parametru Jumping, 334
arena, 195, 199 parametrów, 319
aureola, 111 płaszczyzny, 288
reflektora, 109
scen, 385
B skryptów, 133
bezpieczeństwo danych, 389 symulacji nieba, 97
billboardy, 92 światła kierunkowego, 110
blok światła punktowego, 108
lokalny, 150 tagów, 174
metody, 163 tekstury, 197, 198
błąd, 111 terenu, 76
błędy konsoli, 378 trawy, 93
bryły sztywne, 180, 181 warstw, 121
budowanie świata gry, 128 wody, 100
żołnierza, 300
dodatkowa energia, 329
C dokumentacja, 361
dołączanie skryptu, 142
cookies, 112
dopasowywanie
cząsteczki, 278, 279
komponentów Collider, 183
czcionki, 239
stylów, 235
406 Skorowidz
dopracowanie gra
gry, 383 Amazing Racer, 125, 372, 400
szczegółów, 101 Captain Blaster, 259, 377, 400
dostęp do Chaos Ball, 193, 375, 400
komponentów lokalnych, 172 Gauntlet Runner, 325, 379, 400
obiektów, 172 gracz, 199, 263, 270, 331
dostępne zasoby, 402 graficzny interfejs użytkownika, 225
dostosowywanie grawitacja, 249, 253
gier, 371 GUI, Graphical User Interface, 225
kontrolki, 234
droga, 327
drzewa, 90
H
drzewo Blend Tree, 319 horyzont, 96
dziedziczenie, 213, 217
dźwięk, 345
2D, 347, 351 I
3D, 350 ignorowanie
w panelu Scene, 350 kamer, 122
światła, 122
E ikony
pomocnicze sceny, 39, 41
edytor, 29 rotacji, 55
edytor krzywych, 290 translacji, 53
efekt transformacji, 42
cząsteczek, 280 implementacja
Lens Flare, 99, 100 ruchu, 378
efekty środowiska, 95 strzelania, 379
efektywność, 175 importowanie
egzemplarz, 212 klipów audio, 348
ekran dotykowy, 366 modeli, 63
elementy zasobów, 102
gry, 199, 263, 328 zasobów terenu, 83
zasobu modelu, 67 instalacja Unity, 26
etykieta, 228 interfejs, 31
iteracja, 157
F
fabryka, 164
J
faza projektowania, 126, 194, 260, 326 język C#, 149
formaty map wysokości, 80 język skryptowy, 142
funkcja PiP, 116
K
G
kamera, 114, 261
gamifikacja, 131 katalog
generowanie Assets, 33
drzew, 90 Materials, 74
terenu, 76 Scenes, 36
trawy, 90 Scripts, 133
Water, 100
Skorowidz 407
metoda narzędzie
OnControllerColliderHit(), 250 Hand, 42
OnGUI(), 235, 368 Place Trees, 90, 91
SimpleMove(), 248 Terrain Settings, 94
Start(), 148 nasłuchiwanie dźwięku, 347
Translate(), 376 nazwa metody, 162
Update(), 148, 370, 379 niebo, 96
metody wbudowane, 148
mgła, 98
model, 62–66, 297
O
Jack, 309 obiekt
Robot Kyle, 66 Finish, 133
żołnierza, 296 GameControl, 135
moduł PlayerPrefs, 388, 389
Collision, 285 WaterHazardDetector, 133
Color by Speed, 284 obiekty
Color over Lifetime, 284 3D, 63
domyślny, 280 gracza, 331
Emission, 281, 283 gry, 47, 50
External Forces, 285 kontrolne, 131, 203, 342
Force over Lifetime, 284 potomne, 298
Limit Velocity over Lifetime, 283 wbudowane, 51
Renderer, 289 zagnieżdżone, 57
Rotation by Speed, 285 obliczanie wysokości, 79
Rotation over Lifetime, 285 obsługa
Shape, 281 animacji, 322
Size by Speed, 285 danych wejściowych, 168
Size over Lifetime, 284 ruchu, 252
Sub Emitter, 288 obszar tekstu, 233
Texture Sheet, 288 odczyt
Velocity over Lifetime, 283 danych wejściowych, 169
moduły systemu cząsteczek, 280 naciśnięcia klawisza, 170
modyfikacja ruchu myszą, 171
komponentów obiektu, 175 oddalanie, 44
zmiennej, 150 odszukanie animacji w modelu, 312
MonoDevelop, 144 odtwarzanie dźwięku, 353, 354
okno
N Add Tree, 91
Build Settings, 385, 392
nakładanie Create New Project, 196
animacji Idle, 318 Game Settings, 393
mapy wysokości, 78 Import Heightmap, 79
materiałów, 71 konsoli, 147
shaderów, 71 Project, 29
tekstur, 71 opcja
narzędzia Add Layer…, 119
do rzeźbienia terenu, 80 Add Tab, 32
rotacji, 55 Add Tree, 91
transformacji, 41, 53, 54 Console, 147
Create Other, 51
Skorowidz 409
projektu, 30
T promieni, 190
tagi, 175 skryptów, 142
tekstura, 66–68 stanu, 319
tekstura Robot_Color, 67 systemu cząsteczek, 279
teksturowanie, 196 systemu kamer, 118
tekstury terenu, 83 światła, 110
teren, 75 tekstur terenu, 86
dodanie drzew, 90 wielu egzemplarzy prefabrykatu, 217
dodanie tekstury, 198 własnego stylu, 237
dodanie trawy, 93 własnego terenu, 129
dodawanie do projektu, 76 zmiennej, 148
malowanie teksturą, 85 typ wartości zwrotnej, 162
narzędzia, 80 typy zmiennych
rzeźbienie mapy wysokości, 77 bool, 149
spłaszczanie, 81 char, 149
tekstury, 83 double, 149
ustawienia, 94, 95 float, 149
testowanie int, 149
dźwięku, 349, 351 string, 149
gry, 136
konfiguracji urządzenia, 363 U
tło, 261
uaktualnianie prefabrykatu, 218
transformacja, 51–57, 173, 176
układ współrzędnych
translacja, 52, 56
2D, 47, 49
trawy, 90, 92
3D, 48, 49
trójkąty, 62
lokalny, 50
tryb
początek, 49
dźwięku, 38
składnia, 49
Flythrough, 43
świata, 50
generowania, 38
Unity Free, 26
wyświetlania, 38
Unity Pro, 26
tryby właściwości Wrap Mode, 302
uruchamianie gry, 40
tworzenie
urządzenia mobilne, 371
animatora, 316
usprawnianie gry, 207, 273, 343
areny, 195
ustawienia
drzew, 90
animacji, 298
efektu PiP, 119
animacji WalkForward, 313, 314
egzemplarza, 213
dla platform, 390
egzemplarza prefabrykatu, 220
dźwięku 3D, 351
gier, 401
grawitacji, 249
GUI, 226, 227
komponentu Capsule Collider, 264
jeziora, 100
niezależne, 390
kontrolera postaci, 250
obiektów, 96
materiałów, 74
riggingu, 309, 331
meteorów, 268
rozdzielczości, 77
metody, 163
skrętu, 315
obiektów gry, 52
terenu, 94, 95
płaskowyżów, 81
Unity Player, 390
prefabrykatu, 215
wiatru, 96
412 Skorowidz