You are on page 1of 410

Spis treści

O autorze . ..............................................................................................................................19
Wprowadzenie . ..................................................................................................................21

LEKCJA 1. Wprowadzenie do Unity ............................................................ 25


Instalacja Unity . .................................................................................................................26
Pobieranie i instalacja Unity . ........................................................................................26
Poznajemy edytor Unity .................................................................................................29
Okno dialogowe Project . .................................................................................................29
Interfejs Unity . ....................................................................................................................31
Panel Project . .......................................................................................................................32
Panel Hierarchy . .................................................................................................................34
Panel Inspector . ..................................................................................................................35
Panel Scene ...........................................................................................................................37
Panel Game . ..........................................................................................................................39
Wyróżnienie — pasek narzędziowy . .........................................................................41
Poruszanie się po panelu Scene w Unity .................................................................42
Narzędzie Hand . .................................................................................................................42
Tryb Flythrough . ................................................................................................................43
Podsumowanie . ..................................................................................................................43
Pytania i odpowiedzi ........................................................................................................45
Warsztaty . .............................................................................................................................45
Quiz ...........................................................................................................................................45
Odpowiedzi . .........................................................................................................................45
Ćwiczenie . .............................................................................................................................46

LEKCJA 2. Obiekty gry ................................................................................ 47


Wymiary i układy współrzędnych .............................................................................48
Umieszczenie litery D w nazwie 3D . ..........................................................................48
Użycie układów współrzędnych . ................................................................................48
Współrzędne świata kontra lokalne . .........................................................................50
Obiekty gry . ..........................................................................................................................50
Transformacje . ...................................................................................................................51
Translacja . ............................................................................................................................52
Rotacja .....................................................................................................................................54
Skalowanie . ..........................................................................................................................55
6 Spis treści

Ryzyko związane z transformacjami . ........................................................................55


Transformacja a obiekty zagnieżdżone . ...................................................................57
Podsumowanie . ..................................................................................................................57
Pytania i odpowiedzi ........................................................................................................58
Warsztaty . .............................................................................................................................58
Quiz ...........................................................................................................................................58
Odpowiedzi . .........................................................................................................................58
Ćwiczenie . .............................................................................................................................59

LEKCJA 3. Modele, materiały i tekstury ...................................................... 61


Podstawy modeli . ..............................................................................................................62
Wbudowane obiekty 3D . ................................................................................................63
Importowanie modeli . .....................................................................................................63
Modele i sklep Asset Store . ............................................................................................65
Tekstury, shadery i materiały ......................................................................................66
Tekstury .................................................................................................................................67
Shadery ...................................................................................................................................68
Materiały ................................................................................................................................68
Powracamy do shaderów . ..............................................................................................69
Podsumowanie . ..................................................................................................................72
Pytania i odpowiedzi ........................................................................................................72
Warsztaty . .............................................................................................................................73
Quiz ...........................................................................................................................................73
Odpowiedzi . .........................................................................................................................73
Ćwiczenie . .............................................................................................................................73

LEKCJA 4. Teren ......................................................................................... 75


Generowanie terenu .........................................................................................................76
Dodanie terenu do projektu . .........................................................................................76
Rzeźbienie mapy wysokości . ........................................................................................77
Narzędzia do rzeźbienia terenu oferowane przez Unity ..................................80
Tekstury terenu . ................................................................................................................83
Importowanie zasobów terenu . ..................................................................................83
Teksturowanie terenu . ....................................................................................................83
Podsumowanie . ..................................................................................................................85
Pytania i odpowiedzi ........................................................................................................86
Warsztaty . .............................................................................................................................86
Quiz ...........................................................................................................................................87
Odpowiedzi . .........................................................................................................................87
Ćwiczenie . .............................................................................................................................87
Spis treści 7

LEKCJA 5. Środowisko . .............................................................................. 89


Generowanie drzew i trawy ..........................................................................................90
Malowanie drzewami . .....................................................................................................90
Malowanie trawą . ..............................................................................................................92
Ustawienia terenu . ............................................................................................................94
Efekty środowiska . ...........................................................................................................95
Symulacja nieba i horyzontu . .......................................................................................96
Mgła ..........................................................................................................................................98
Efekt Lens Flare . .................................................................................................................99
Woda ........................................................................................................................................99
Kontroler postaci ............................................................................................................101
Dodanie kontrolera postaci . .......................................................................................101
Naprawa świata ................................................................................................................101
Podsumowanie .................................................................................................................103
Pytania i odpowiedzi .....................................................................................................103
Warsztaty . ..........................................................................................................................103
Quiz ........................................................................................................................................103
Odpowiedzi ........................................................................................................................104
Ćwiczenie . ..........................................................................................................................104

LEKCJA 6. Światła i kamery ...................................................................... 105


Światło . ...............................................................................................................................106
Światło punktowe ...........................................................................................................106
Światło kierunkowe .......................................................................................................109
Tworzenie światła z dowolnego obiektu . .............................................................110
Aureola .................................................................................................................................111
Cookies .................................................................................................................................112
Kamera . ...............................................................................................................................114
Anatomia kamery ............................................................................................................114
Wiele kamer .......................................................................................................................116
Podział ekranu oraz funkcja PiP . ..............................................................................116
Warstwy . ............................................................................................................................117
Praca z warstwami ..........................................................................................................118
Użycie warstw ...................................................................................................................120
Podsumowanie .................................................................................................................121
Pytania i odpowiedzi .....................................................................................................123
Warsztaty . ..........................................................................................................................123
Quiz ........................................................................................................................................123
Odpowiedzi ........................................................................................................................123
Ćwiczenie . ..........................................................................................................................123
8 Spis treści

LEKCJA 7. Pierwsza gra — Amazing Racer . .............................................. 125


Faza projektowania ........................................................................................................126
Koncepcja ............................................................................................................................126
Reguły ...................................................................................................................................126
Wymagania ........................................................................................................................127
Budowanie świata gry ..................................................................................................128
Rzeźbienie terenu ............................................................................................................129
Dodanie elementów do środowiska . ......................................................................129
Kontroler postaci .............................................................................................................130
Gamifikacja .........................................................................................................................131
Dodanie obiektów kontrolujących grę . .................................................................131
Dodanie skryptów ...........................................................................................................133
Połączenie skryptów ......................................................................................................134
Testowanie gry .................................................................................................................136
Podsumowanie .................................................................................................................138
Pytania i odpowiedzi .....................................................................................................138
Warsztaty . ..........................................................................................................................138
Quiz ........................................................................................................................................139
Odpowiedzi ........................................................................................................................139
Ćwiczenie . ..........................................................................................................................139

LEKCJA 8. Skrypty — część 1. ................................................................... 141


Skrypty . ...............................................................................................................................142
Tworzenie skryptów ......................................................................................................142
Dołączanie skryptu .........................................................................................................142
Anatomia prostego skryptu . ......................................................................................145
Zmienne . .............................................................................................................................147
Tworzenie zmiennej .......................................................................................................148
Zasięg zmiennej ................................................................................................................148
Zmienne publiczne i prywatne . ................................................................................150
Operatory . ..........................................................................................................................151
Operatory arytmetyczne ..............................................................................................151
Operatory przypisania ..................................................................................................152
Operatory równości .......................................................................................................152
Operatory logiczne ..........................................................................................................153
Konstrukcje warunkowe .............................................................................................153
Konstrukcja if ....................................................................................................................154
Konstrukcja if‐else ..........................................................................................................155
Konstrukcja if‐else if ......................................................................................................156
Spis treści 9

Iteracja . ...............................................................................................................................157
Pętla while ..........................................................................................................................157
Pętla for ...............................................................................................................................158
Podsumowanie .................................................................................................................159
Pytania i odpowiedzi .....................................................................................................159
Warsztaty . ..........................................................................................................................159
Quiz ........................................................................................................................................160
Odpowiedzi ........................................................................................................................160
Ćwiczenie . ..........................................................................................................................160

LEKCJA 9. Skrypty — część 2. ................................................................... 161


Metody . ...............................................................................................................................162
Anatomia metody ............................................................................................................162
Tworzenie metody ..........................................................................................................163
Dane wejściowe ...............................................................................................................167
Podstawy danych wejściowych . ...............................................................................167
Skrypty przeznaczone do obsługi danych wejściowych . ...............................168
Dane wejściowe z określonych klawiszy . .............................................................169
Dane wejściowe myszy .................................................................................................170
Uzyskanie dostępu do komponentów lokalnych . .............................................172
Uzyskanie dostępu do innych obiektów . ..............................................................172
Wyszukanie innych obiektów . ..................................................................................173
Modyfikacja komponentów obiektu . ......................................................................175
Podsumowanie .................................................................................................................176
Pytania i odpowiedzi .....................................................................................................176
Warsztaty . ..........................................................................................................................177
Quiz ........................................................................................................................................177
Odpowiedzi ........................................................................................................................177
Ćwiczenie . ..........................................................................................................................178

LEKCJA 10. Kolizje ...................................................................................... 179


Bryły sztywne ...................................................................................................................180
Kolizje . .................................................................................................................................182
Komponent Collider .......................................................................................................182
Materiały fizyczne ...........................................................................................................184
Wyzwalacze .......................................................................................................................185
Raycasting ..........................................................................................................................187
Podsumowanie .................................................................................................................189
Pytania i odpowiedzi .....................................................................................................189
10 Spis treści

Warsztaty . ..........................................................................................................................190
Quiz ........................................................................................................................................191
Odpowiedzi ........................................................................................................................191
Ćwiczenie . ..........................................................................................................................191

LEKCJA 11. Druga gra — Chaos Ball ........................................................... 193


Faza projektowania ........................................................................................................194
Koncepcja ............................................................................................................................194
Reguły ...................................................................................................................................194
Wymagania ........................................................................................................................194
Arena . ...................................................................................................................................195
Utworzenie areny ............................................................................................................195
Teksturowanie ..................................................................................................................196
Materiał zapewniający rewelacyjne odbijanie się obiektu . ..........................197
Zakończenie prac nad areną . .....................................................................................199
Elementy gry .....................................................................................................................199
Gracz .....................................................................................................................................199
Kula chaos ball ..................................................................................................................200
Kolorowe kule ...................................................................................................................202
Obiekty kontrolne ...........................................................................................................203
Cele ........................................................................................................................................203
Kontroler gry .....................................................................................................................205
Usprawnienie gry ............................................................................................................207
Podsumowanie .................................................................................................................208
Pytania i odpowiedzi .....................................................................................................208
Warsztaty . ..........................................................................................................................208
Quiz ........................................................................................................................................208
Odpowiedzi ........................................................................................................................209
Ćwiczenie . ..........................................................................................................................209

LEKCJA 12. Prefabrykaty ............................................................................. 211


Podstawy prefabrykatów ............................................................................................212
Terminologia związana z prefabrykatami . ..........................................................212
Struktura prefabrykatu .................................................................................................213
Praca z prefabrykatami ................................................................................................214
Dodanie do sceny egzemplarza prefabrykatu . ...................................................216
Dziedziczenie .....................................................................................................................217
Zerwanie połączenia z zasobem prefabrykatu . .................................................219
Tworzenie egzemplarza prefabrykatu w kodzie ...............................................220
Podsumowanie .................................................................................................................220
Spis treści 11

Pytania i odpowiedzi .....................................................................................................221


Warsztaty . ..........................................................................................................................221
Quiz ........................................................................................................................................221
Odpowiedzi ........................................................................................................................221
Ćwiczenie . ..........................................................................................................................222

LEKCJA 13. Graficzny interfejs użytkownika ............................................... 225


Podstawy GUI ....................................................................................................................226
Kontrolki GUI ....................................................................................................................227
Etykieta ................................................................................................................................228
Pole ........................................................................................................................................229
Przycisk ...............................................................................................................................229
Przycisk powtarzający ...................................................................................................230
Pole wyboru .......................................................................................................................230
Pasek narzędziowy .........................................................................................................231
Pole tekstowe ....................................................................................................................232
Obszar tekstu .....................................................................................................................233
Suwaki ..................................................................................................................................233
Dostosowanie kontrolki do własnych potrzeb . .................................................234
Style GUI ..............................................................................................................................234
Skórki GUI ...........................................................................................................................235
Podsumowanie .................................................................................................................239
Pytania i odpowiedzi .....................................................................................................239
Warsztaty . ..........................................................................................................................240
Quiz ........................................................................................................................................240
Odpowiedzi ........................................................................................................................240
Ćwiczenie . ..........................................................................................................................240

LEKCJA 14. Sterowanie postaciami ............................................................. 243


Kontroler postaci ............................................................................................................244
Dodanie kontrolera postaci . .......................................................................................244
Właściwości kontrolera postaci . ..............................................................................245
Skrypty dla kontrolerów postaci . ............................................................................245
Praca z kontrolerem za pomocą skryptów . .........................................................246
Zmienna typu CollisionFlags . .....................................................................................249
Kolizje ...................................................................................................................................250
Tworzenie kontrolera postaci . ..................................................................................250
Konfiguracja podstawowa ...........................................................................................251
Obsługa ruchu ...................................................................................................................252
Grawitacja ...........................................................................................................................253
12 Spis treści

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

LEKCJA 15. Trzecia gra — Captain Blaster .................................................. 259


Faza projektowania ........................................................................................................260
Koncepcja ............................................................................................................................260
Reguły ...................................................................................................................................260
Wymagania ........................................................................................................................260
Świat . ....................................................................................................................................261
Kamera .................................................................................................................................261
Tło ..........................................................................................................................................261
Elementy gry .....................................................................................................................263
Gracz .....................................................................................................................................263
Meteory ................................................................................................................................264
Pociski ..................................................................................................................................265
Wyzwalacze .......................................................................................................................265
Obiekty kontrolne ...........................................................................................................266
Kontroler gry .....................................................................................................................266
Skrypt meteoru .................................................................................................................267
Tworzenie meteorów ....................................................................................................268
Skrypt wyzwalacza .........................................................................................................269
Skrypt gracza .....................................................................................................................270
Skrypt pocisku ..................................................................................................................272
Usprawnienie gry ............................................................................................................273
Podsumowanie .................................................................................................................274
Pytania i odpowiedzi .....................................................................................................274
Warsztaty . ..........................................................................................................................275
Quiz ........................................................................................................................................275
Odpowiedzi ........................................................................................................................275
Ćwiczenie . ..........................................................................................................................276
Spis treści 13

LEKCJA 16. Systemy cząsteczek . ................................................................ 277


Systemy cząsteczek ........................................................................................................278
Cząsteczki ...........................................................................................................................278
Systemy cząsteczek w Unity . .....................................................................................278
Kontrolki systemu cząsteczek . ..................................................................................278
Moduły systemu cząsteczek .......................................................................................280
Moduł domyślny ..............................................................................................................280
Moduł Emission ................................................................................................................281
Moduł Shape ......................................................................................................................281
Moduł Velocity over Lifetime . ...................................................................................283
Moduł Limit Velocity over Lifetime . .......................................................................283
Moduł Force over Lifetime ..........................................................................................284
Moduł Color over Lifetime ...........................................................................................284
Moduł Color by Speed ....................................................................................................284
Moduł Size over Lifetime ..............................................................................................284
Moduł Size by Speed .......................................................................................................285
Moduł Rotation over Lifetime . ..................................................................................285
Moduł Rotation by Speed .............................................................................................285
Moduł External Forces ..................................................................................................285
Moduł Collision .................................................................................................................285
Moduł Sub Emitter ..........................................................................................................288
Moduł Texture Sheet ......................................................................................................288
Moduł Renderer ...............................................................................................................289
Edytor krzywych .............................................................................................................290
Podsumowanie .................................................................................................................290
Pytania i odpowiedzi .....................................................................................................291
Warsztaty . ..........................................................................................................................291
Quiz ........................................................................................................................................292
Odpowiedzi ........................................................................................................................292
Ćwiczenie . ..........................................................................................................................292

LEKCJA 17. Animacje .................................................................................. 293


Podstawy animacji ..........................................................................................................294
Przygotowanie modelu .................................................................................................294
Animacja ..............................................................................................................................295
Przygotowanie modelu do animacji . ......................................................................295
Model ....................................................................................................................................297
Zasoby animacji ................................................................................................................298
14 Spis treści

Stosowanie animacji ......................................................................................................299


Dodawanie animacji .......................................................................................................300
Właściwość Wrap Mode ...............................................................................................301
Skrypty i animacje ..........................................................................................................301
Podsumowanie .................................................................................................................303
Pytania i odpowiedzi .....................................................................................................303
Warsztaty . ..........................................................................................................................304
Quiz ........................................................................................................................................305
Odpowiedzi ........................................................................................................................305
Ćwiczenie . ..........................................................................................................................305

LEKCJA 18. Animator ................................................................................. 307


Podstawy zasobu Animator . ......................................................................................308
Rigging modeli ..................................................................................................................308
Czerwony rigging śmierci . ..........................................................................................309
Przygotowanie animacji ...............................................................................................311
Utworzenie animatora ..................................................................................................316
Panel Animator .................................................................................................................317
Animacja Idle .....................................................................................................................317
Parametry ...........................................................................................................................318
Stan i tzw. drzewo Blend Tree . .................................................................................319
Przejścia ..............................................................................................................................320
Obsługa animacji za pomocą skryptów . ...............................................................322
Podsumowanie .................................................................................................................322
Pytania i odpowiedzi .....................................................................................................323
Warsztaty . ..........................................................................................................................323
Quiz ........................................................................................................................................324
Odpowiedzi ........................................................................................................................324
Ćwiczenie . ..........................................................................................................................324

LEKCJA 19. Czwarta gra — Gauntlet Runner .............................................. 325


Faza projektowania ........................................................................................................326
Koncepcja ............................................................................................................................326
Reguły ...................................................................................................................................326
Wymagania ........................................................................................................................326
Świat . ....................................................................................................................................327
Scena .....................................................................................................................................327
Droga ....................................................................................................................................327
Przewijanie drogi ............................................................................................................328
Spis treści 15

Elementy gry .....................................................................................................................328


Dodatkowa energia .........................................................................................................329
Przeszkody .........................................................................................................................330
Strefa wyzwalacza ...........................................................................................................330
Obiekt gracza .....................................................................................................................331
Obiekty kontrolne ...........................................................................................................335
Skrypt strefy wyzwalacza . ..........................................................................................335
Skrypt obiektu kontrolnego gry . ..............................................................................335
Skrypt obiektu gracza ....................................................................................................338
Skrypty obiektów dodatkowej energii i przeszkód . ........................................339
Skrypt SpawnScript ........................................................................................................340
Zebranie wszystkiego w całość . ...............................................................................341
Usprawnienie gry ............................................................................................................343
Podsumowanie .................................................................................................................343
Pytania i odpowiedzi .....................................................................................................343
Warsztaty . ..........................................................................................................................343
Quiz ........................................................................................................................................344
Odpowiedzi ........................................................................................................................344
Ćwiczenie . ..........................................................................................................................344

LEKCJA 20. Dźwięk ..................................................................................... 345


Podstawy dźwięku ..........................................................................................................346
Składniki dźwięku ...........................................................................................................346
Dźwięk 2D i 3D .................................................................................................................347
Źródła dźwięku ................................................................................................................347
Import klipów audio ......................................................................................................348
Testowanie dźwięku w panelu Scene . ...................................................................350
Dźwięk 3D ...........................................................................................................................350
Dźwięk 2D ...........................................................................................................................351
Użycie dźwięku za pomocą skryptów . ...................................................................352
Rozpoczęcie i zatrzymanie odtwarzania dźwięku . ...........................................353
Zmiana klipu audio .........................................................................................................354
Podsumowanie .................................................................................................................355
Pytania i odpowiedzi .....................................................................................................355
Warsztaty . ..........................................................................................................................355
Quiz ........................................................................................................................................355
Odpowiedzi ........................................................................................................................355
Ćwiczenie . ..........................................................................................................................356
16 Spis treści

LEKCJA 21. Programowanie na platformach mobilnych . ........................... 359


Przygotowanie do programowania na platformach mobilnych .................360
Konfiguracja środowiska ..............................................................................................360
Aplikacja Unity Remote .................................................................................................362
Przyśpieszeniomierz .....................................................................................................363
Programowanie dla przyśpieszeniomierza . ........................................................364
Użycie przyśpieszeniomierza .....................................................................................365
Dane wejściowe pochodzące z ekranu dotykowego . .......................................366
Podsumowanie .................................................................................................................366
Pytania i odpowiedzi .....................................................................................................369
Warsztaty . ..........................................................................................................................369
Quiz ........................................................................................................................................369
Odpowiedzi ........................................................................................................................369
Ćwiczenie . ..........................................................................................................................370

LEKCJA 22. Kolejne wersje gier ................................................................... 371


Amazing Racer ..................................................................................................................372
Poruszanie i rozglądanie się . .....................................................................................372
Skoki ......................................................................................................................................374
Chaos Ball . .........................................................................................................................375
Captain Blaster .................................................................................................................377
Gauntlet Runner ..............................................................................................................379
Podsumowanie .................................................................................................................380
Pytania i odpowiedzi .....................................................................................................381
Warsztaty . ..........................................................................................................................381
Quiz ........................................................................................................................................381
Odpowiedzi ........................................................................................................................381
Ćwiczenie . ..........................................................................................................................382

LEKCJA 23. Dopracowanie i wdrożenie ...................................................... 383


Zarządzanie scenami .....................................................................................................384
Ustalanie kolejności scen .............................................................................................384
Przełączanie scen ............................................................................................................385
Zachowywanie danych i obiektów . .........................................................................387
Zachowywanie obiektów .............................................................................................387
Zachowywanie danych ..................................................................................................387
Ustawienia Unity Player ..............................................................................................390
Ustawienia niezależne od platformy . .....................................................................390
Ustawienia dla poszczególnych platform . ............................................................390
Spis treści 17

Kompilacja gry ..................................................................................................................391


Okno Build Settings ........................................................................................................392
Okno Game Settings ........................................................................................................393
Podsumowanie .................................................................................................................395
Pytania i odpowiedzi .....................................................................................................395
Warsztaty . ..........................................................................................................................395
Quiz ........................................................................................................................................395
Odpowiedzi ........................................................................................................................395
Ćwiczenie . ..........................................................................................................................396

LEKCJA 24. Zakończenie ............................................................................. 397


Osiągnięcia .........................................................................................................................398
19 lekcji nauki ...................................................................................................................398
4 pełne gry ..........................................................................................................................399
58 scen .................................................................................................................................400
Co dalej? . ............................................................................................................................400
Buduj gry .............................................................................................................................401
Współpracuj z innymi ....................................................................................................401
Pisz o tym ............................................................................................................................401
Dostępne zasoby ..............................................................................................................402
Podsumowanie .................................................................................................................402
Pytania i odpowiedzi .....................................................................................................402
Warsztaty . ..........................................................................................................................403
Quiz ........................................................................................................................................403
Odpowiedzi ........................................................................................................................403
Ćwiczenie . ..........................................................................................................................403

Skorowidz . .............................................................................. 405


18 Spis treści
O autorze
Mike Geig jest zarówno doświadczonym nauczycielem, jak i twórcą gier
komputerowych, a obie profesje udaje mu się z powodzeniem łączyć. Obecnie
prowadzi zajęcia z tworzenia i projektowania gier na Stark State College oraz
w Cleveland Institute of Art. Zajmuje się również tworzeniem screencastów
dla Unity Technologies i jest członkiem sekcji Unity Learn. Przygotowany przez
niego kurs wideo zatytułowany Game Development Essentials with Unity 4
LiveLessons stał się najważniejszą pozycją dla osób, które chcą poznać środo‐
wisko Unity. Wymienionym kursem Mike wzbudził ogólny entuzjazm i otrzy‐
mał ponad milion „Lubię to!” w portalu społecznościowym Facebook.
20 O autorze
Wprowadzenie
Silnik Unity to niewiarygodnie użyteczne i popularne rozwiązanie przezna‐
czone dla programistów zajmujących się profesjonalnie lub amatorsko tworze‐
niem gier. Książka ta została napisana, aby umożliwić czytelnikom jak naj‐
szybsze rozpoczęcie pracy z Unity (po 24 godzinnych lekcjach). Znajdziesz
tutaj również omówienie podstawowych zasad stosowanych podczas tworzenia
gier. W przeciwieństwie do innych pozycji poświęconych jedynie wybranym
tematom lub tworzeniu pojedynczej gry, w tej książce poruszono ogromną
liczbę zagadnień oraz pokazano opracowywanie czterech przykładowych gier.
Jaką odniesiesz z tego korzyść? Gdy zakończysz lekturę książki, będziesz nie
tylko dysponować teoretyczną wiedzą z zakresu silnika gier Unity, ale również
będziesz mógł się pochwalić opracowanymi grami.

Dla kogo przeznaczona


jest ta książka?
Książka jest przeznaczona dla każdego, kto chciałby poznać środowisko Unity.
Niezależnie od tego, czy jesteś studentem, czy ekspertem na polu programo‐
wania, w przedstawionych tutaj lekcjach zawsze znajdziesz coś nowego. Nie
musisz mieć jakiegokolwiek wcześniejszego doświadczenia w zakresie two‐
rzenia gier. Dlatego też nie przejmuj się, jeśli będą to Twoje pierwsze kroki
w budowaniu gier komputerowych. Nie śpiesz się i dobrze baw. Kolejne zagad‐
nienia będziesz poznawać w krótkim czasie.

W jaki sposób zorganizowana


jest ta książka i co w niej znajdziesz?
Kierując się sprawdzonym podejściem do nauki, w książce umieszczono
24 godzinne lekcje. W poszczególnych lekcjach poruszono następujące tematy.
 Lekcja 1., „Wprowadzenie do Unity” — w tej lekcji znajdziesz wpro‐
wadzenie do środowiska Unity oraz różnych jego komponentów.
 Lekcja 2., „Obiekty gry” — w tej lekcji dowiesz się, jak używać pod‐
stawowych bloków budulcowych środowiska Unity, czyli obiektów
gry. Ponadto poruszone zostaną tematy układów współrzędnych oraz
transformacji.
 Lekcja 3., „Modele, materiały i tekstury” — w tej lekcji zobaczysz,
jak pracować z zasobami graficznymi w Unity, a także jak stosować
tekstury i shadery dla materiałów. Zajmiesz się również nakładaniem
wspomnianych materiałów na różne obiekty 3D.
22 Wprowadzenie

 Lekcja 4., „Teren” — w tej lekcji za pomocą narzędzi oferowanych przez


Unity wyrzeźbisz teren, na którym będzie rozgrywała się akcja gry. Nie
musisz obawiać się ubrudzenia rąk podczas pracy w terenie, a jednak
przygotujesz unikalne i zapierające dech w piersiach krajobrazy.
 Lekcja 5., „Środowisko” — w tej lekcji dowiesz się, jak na wyrzeź‐
bionym wcześniej terenie zastosować efekty środowiska. Najwyższy
czas na posadzenie kilku drzew!
 Lekcja 6., „Światła i kamery” — w tej lekcji szczegółowo zajmiesz się
światłem i kamerą.
 Lekcja 7., „Pierwsza gra — Amazing Racer” — czas na pierwszą grę!
W tej lekcji zdobytą dotąd wiedzę wykorzystasz do opracowania gry
zatytułowanej Amazing Racer.
 Lekcja 8., „Skrypty — część 1.” — w tej lekcji rozpoczniesz pracę ze
skryptami w Unity. Nie przejmuj się, jeśli nie masz żadnego doświad‐
czenia w programowaniu. Powoli omówione zostaną podstawy doty‐
czące tworzenia skryptów.
 Lekcja 9., „Skrypty — część 2.” — w tej lekcji poszerzysz zdobytą
w poprzedniej wiedzę o skryptach. Tym razem skoncentrujesz się na
znacznie bardziej zaawansowanych zagadnieniach.
 Lekcja 10., „Kolizje” — w tej lekcji poznasz różne kolizje, które są
powszechnie obsługiwane w nowoczesnych grach wideo, silnik
fizyczny przeznaczony do obsługi kolizji, a także wyzwalacze kolizji.
Ponadto poruszony zostanie temat materiałów fizycznych i zapew‐
nienia pewnego zróżnicowania obiektów.
 Lekcja 11., „Druga gra — Chaos Ball” — czas na kolejną grę! W tej
lekcji utworzysz grę zatytułowaną Chaos Ball. Nazwa gry jest jak naj‐
bardziej adekwatna, ponieważ zaimplementujesz różne kolizje, wyko‐
rzystasz materiały fizyczne i przygotujesz cele gry. Przygotuj się na
połączenie elementów strategii z szybką akcją.
 Lekcja 12., „Prefabrykaty” — prefabrykaty to doskonałe rozwiązanie
pozwalające na tworzenie obiektów gry gotowych do wielokrotnego
użycia. W tej lekcji dowiesz się, jak tworzyć i modyfikować prefabry‐
katy. Ponadto wykorzystasz prefabrykaty w skryptach.
 Lekcja 13., „Graficzny interfejs użytkownika” — w tej lekcji zoba‐
czysz, jak w środowisku Unity zaimplementować graficzny interfejs
użytkownika (GUI). Poznasz różne komponenty interfejsu oraz spo‐
soby ich umieszczania w interfejsie dwuwymiarowym.
 Lekcja 14., „Sterowanie postaciami” — w tej lekcji utworzysz własny
kontroler postaci. Na końcu lekcji będziesz dysponował samodzielnie
zbudowanym kontrolerem postaci.
Wprowadzenie 23

 Lekcja 15., „Trzecia gra — Captain Blaster” — gra numer 3! W tej


lekcji utworzysz grę w stylu retro, w której gracz steruje statkiem
kosmicznym i strzela do meteorów.
 Lekcja 16., „Systemy cząsteczek” — czas na poznanie efektów cząste‐
czek. W tej lekcji przeprowadzisz eksperymenty ze starszym syste‐
mem cząsteczek w Unity, a także z nowym, zwanym Shuriken. Dowiesz
się, jak tworzyć ciekawe efekty i stosować je we własnych projektach.
 Lekcja 17., „Animacje” — w tej lekcji zajmiesz się animacją oraz
starszym systemem animacji w środowisku Unity. Poeksperymentu‐
jesz z ożywieniem modelu za pomocą zasobów pobranych ze sklepu
Unity Asset Store.
 Lekcja 18., „Animator” — w tej lekcji opanujesz nowy system animacji
w Unity, nazwany Mecanim. Dowiesz się, jak ponownie przeprowa‐
dzić rigging modelu oraz zastosować w nim uniwersalne animacje.
 Lekcja 19., „Czwarta gra — Gauntlet Runner” — gra numer 4 jest
zatytułowana Ganutlet Runner. W tej grze zastosujesz nowy sposób
przewijania tła oraz implementacji kontrolera animacji, aby tym
samym przygotować skomplikowane, łączące się animacje.
 Lekcja 20., „Dźwięk” — w tej lekcji zajmiesz się ważnym tematem,
jakim jest dodanie efektów dźwiękowych. Poznasz systemy audio 2D
i 3D, a także ich różne właściwości.
 Lekcja 21., „Programowanie na platformach mobilnych” — w tej lekcji
dowiesz się, jak tworzyć gry dla urządzeń mobilnych. Poruszone będą
tematy wykorzystania przyśpieszeniomierza i ekranu dotykowego,
które są wbudowane w urządzenia mobilne.
 Lekcja 22., „Kolejne wersje gier” — w tej lekcji powrócisz do czterech
gier utworzonych w tej książce. Tym razem przystosujesz je do dzia‐
łania w urządzeniach mobilnych. Przekonasz się, które schematy
kontroli doskonale sprawdzają się w urządzeniach mobilnych, a które
nie bardzo się nadają.
 Lekcja 23., „Dopracowanie i wdrożenie” — w tej lekcji dowiesz się, jak
dodać do gry wiele scen oraz jak zachowywać dane między poszcze‐
gólnymi scenami. Ponadto poruszony będzie temat ustawień wdro‐
żenia gry oraz jej kompilacji.
 Lekcja 24., „Zakończenie” — ta lekcja jest podsumowaniem dotych‐
czasowej podróży mającej na celu poznanie środowiska Unity. Znaj‐
dziesz tutaj użyteczne informacje o poczynionych dotąd postępach,
a także dowiesz się, co robić dalej.
24 Wprowadzenie

Wersje silnika gier Unity


W książce wykorzyst`ano Unity w wersjach 4.1 i 4.2. Wymienione wersje są
niemalże identyczne z punktu widzenia tematów poruszonych w książce, choć
mogą występować drobne różnice w wyglądzie pewnych elementów graficz‐
nych Unity. I tak na niektórych rysunkach możesz zauważyć menu Terrain
wyświetlane na górze okna edytora Unity. W wersji 4.2 wymienione menu
zostało przeniesione. Jednak nie przejmuj się tym. Wszystkie objaśnienia doty‐
czące tworzenia terenu i zarządzania nim zostały uaktualnione i uwzględniają
nowy proces budowania terenu. Wspominam o tym, aby zaoszczędzić Ci zasko‐
czenia, jeśli niektóre elementy w używanym przez Ciebie edytorze Unity wyglą‐
dają inaczej niż pokazano w książce.
Dziękuję za przeczytanie tego wprowadzenia! Mam nadzieję, że lektura książki
będzie przyjemnością i wiele się z niej nauczysz. Życzę powodzenia w trakcie
poznawania silnika gier Unity!
Lekcja 1
Wprowadzenie do Unity

W czasie tej lekcji dowiesz się:


 jak zainstalować Unity,
 jak utworzyć nowy projekt lub otworzyć istniejący,
 jak używać edytora Unity,
 jak poruszać się po Unity Scene.
W tej lekcji skoncentrujesz się na rozpoczęciu pracy z środowiskiem Unity.
Na początek zapoznasz się z dostępnymi i różniącymi się między sobą
licencjami Unity, wybierzesz jedną, a następnie zainstalujesz środowisko
Unity. Po instalacji przejdziesz do tworzenia nowych projektów oraz otwie-
rania już istniejących. Uruchomisz oferujący potężne możliwości edytor
Unity i poznasz jego poszczególne komponenty. Na końcu dowiesz się, jak
poruszać się po scenie za pomocą myszy i klawiatury. Ta lekcja ma być
praktycznym ćwiczeniem, a więc w jej trakcie pobierzesz środowisko Unity.
26 Lekcja 1. Wprowadzenie do Unity

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.

Pobieranie i instalacja Unity


W tej lekcji przyjąłem założenie, że zdecydowałeś się na wersję Unity Free.
W przypadku wersji Pro proces przebiega bardzo podobnie i różni się jedynie
podczas wyboru licencji. Kiedy będziesz gotowy do pobrania i instalacji Unity,
wykonaj wymienione poniżej kroki.
1. Pobierz program instalacyjny Unity ze strony http://unity3d.com/
unity/download/.
2. Uruchom program instalacyjny i wykonuj kolejne wyświetlane kroki,
podobnie jak ma to miejsce w trakcie instalacji innych programów.
3. Nie zapomnij o zaznaczeniu w jednym z kroków programu
instalacyjnego pól wyboru Example Project, Unity Development Web
Player i MonoDevelop (patrz rysunek 1.1).
4. Wybierz katalog, w którym zostanie zainstalowane środowisko
Unity (patrz rysunek 1.2). Zaleca się pozostawienie domyślnego,
o ile dokładnie wiesz, co robisz.
5. Na tym etapie instalacja zostanie zakończona.
6. W trakcie pierwszego uruchomienia Unity zostaniesz poproszony
o aktywację licencji (patrz rysunek 1.3). W tym momencie wybierasz
wersję Free lub rozpoczęcie 30‐dniowego okresu próbnego wersji Pro.
Jeżeli zakupiłeś licencję Unity Pro, wprowadzenie numeru seryjnego
spowoduje odblokowanie wersji Pro. W tej książce przyjęto założenie,
że wybrałeś wersję Unity Free.
Instalacja Unity 27

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

7. Teraz zostaniesz poproszony o zalogowanie się do swojego konta Unity


(patrz rysunek 1.4). Jeżeli utworzyłeś je wcześniej, w wyświetlonym
tutaj oknie dialogowym podaj dane uwierzytelniające do konta.
W przeciwnym razie kliknij przycisk Create Account i wypełnij
wyświetlony formularz.
8. I to już wszystko! W ten sposób przeprowadziłeś instalację środowiska
Unity.

RYSUNEK 1.4.
Logowanie
do konta Unity

Obsługiwany sprzęt i systemy operacyjne


Środowisko Unity wymaga Maca lub peceta z systemem Windows. Wpraw-
dzie istnieje możliwość tworzenia projektów przeznaczonych do urucha-
miania w systemie Linux, ale edytor Unity nie działa w systemach Linux.
Ponadto komputer musi spełniać wymienione poniżej wymania minimalne
(dane pochodzą z witryny internetowej poświęconej środowisku Unity).
 Windows: XP SP2 lub nowszy. Mac: procesor Intel i system OS X 10.6
(Snow Leopard) lub nowszy. Środowisko Unity nie zostało
przetestowane w serwerowych wersjach systemów Windows i OS X.
 Karta graficzna zapewniająca obsługę DirectX 9 (Shader Model 2.0).
Działać powinna każda karta graficzna wyprodukowana w roku 2004
lub późniejszych latach.
 Funkcja usuwania niewidocznych powierzchni (ang. occlusion culling)
wymaga wbudowanej obsługi w karcie graficznej. Niektóre układy
graficzne Intel nie mają wbudowanej obsługi usuwania niewidocznych
powierzchni.
Warto pamiętać, że to są wymagania minimalne.
Poznajemy edytor Unity 29

Łą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.

Poznajemy edytor Unity


Po zainstalowaniu środowiska Unity można zapoznać się z edytorem. W środo‐
wisku Unity edytor jest komponentem graficznym pozwalającym na tworzenie
gier w sposób WYSIWYG (ang. What You See Is What You Get), czyli efektem
Twojej pracy będzie dokładnie to, co widzisz na ekranie. Ponieważ większość
zadań jest wykonywana w edytorze, bardzo często będziesz się do niego odwo‐
ływać za pomocą zwrotu Unity. Dalej w tej lekcji omówione zostaną różne
elementy tworzące edytor Unity. Dowiesz się również, jak za ich pomocą bu‐
dować gry.

Okno dialogowe Project


Pierwsze okno wyświetlone na ekranie po uruchomieniu środowiska Unity
po raz pierwszy to Project (patrz rysunek 1.5). Okno pozwala na otwieranie
ostatnio używanych projektów, przeglądanie istniejących lub też tworzenie
zupełnie nowych projektów.

RYSUNEK 1.5.
Okno dialogowe
Project

Jeżeli utworzyłeś wcześniej projekt Unity, po uruchomieniu środowiska zosta‐


niesz przeniesiony bezpośrednio do tego projektu. Aby wyświetlić okno dialo‐
gowe Project, musisz w Unity wybrać opcję File/New Project, która spowoduje
przejście do okna Create New Project. Z kolei opcja File/Open Project powo‐
duje wyświetlenie okna dialogowego Open Project.
30 Lekcja 1. Wprowadzenie do Unity

Wyświetlenie okna dialogowego Project


Po uruchomieniu środowiska Unity automatycznie zostanie otworzony
projekt, nad którym ostatnio pracowałeś. Jeżeli zamiast niego chcesz wyświe-
tlić okno dialogowe Project, naciśnij i przytrzymaj klawisz Alt (Control
w Macu) podczas klikania ikony Unity. Jeżeli chcesz, aby wyświetlanie
okna dialogowego Project było zachowaniem domyślnym, wybierz opcję
Edit/Preferences, a następnie zaznacz pole wyboru Always Show Project
Wizard.

 Wypróbuj samodzielnie

Utworzenie pierwszego projektu


Przystąpisz teraz do utworzenia projektu. Warto zwrócić uwagę na miejsce
jego zapisania, aby później nie było problemów z odnalezieniem projektu.
Na rysunku 1.6 pokazano okno dialogowe przed utworzeniem projektu.
1. Wyświetl okno dialogowe Create New Project.
2. Wybierz katalog, w którym zostanie zapisany projekt. Jeżeli nie wiesz,
gdzie zapisać projekt, możesz zdecydować się na katalog domyślny.
W przypadku wyboru katalogu innego niż domyślny utwórz w nim
pusty podkatalog przeznaczony na projekt. Nazwa wspomnianego
pustego podkatalogu stanie się nazwą projektu.
3. Projektowi nadaj nazwę Chapter1_Trial. Nazwą projektu jest ostatni
fragment tekstu w polu tekstowym zatytułowanym Project Location.
4. Nie zaznaczaj żadnego pola wyboru w sekcji Import the following
packages. Do pakietów powrócę jeszcze w tej lekcji.
5. Kliknij przycisk Create.

RYSUNEK 1.6. Ustawienia użyte podczas tworzenia pierwszego projektu


Poznajemy edytor Unity 31

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

Początkujący użytkownicy powinni wiedzieć, że Unity pozwala na dokładny


wybór sposobu pracy. Oznacza to możliwość przesuwania, dokowania, powie‐
lania lub zmiany dowolnych paneli. Przykładowo po kliknięciu słowa Hierarchy
(po lewej stronie okna) wskazany panel można przesunąć i upuścić nad pane‐
lem Inspector (po prawej stronie okna), tworząc w ten sposób jeden panel
z dwoma kartami. Umieszczenie kursora na linii między panelami pozwala na
32 Lekcja 1. Wprowadzenie do Unity

zmianę wielkości okien. Poświęć więc chwilę na eksperymenty i ułóż panele


w sposób zapewniający komfortową pracę. Jeżeli wskutek eksperymentów
powstanie układ, który jednak utrudnia pracę, nie przejmuj się. Bardzo łatwo
i szybko można przywrócić domyślny układ paneli. W tym celu należy wybrać
opcję Window/Layouts/Default Layout. Skoro już poznajesz wbudowany układ
paneli, wypróbuj kilka innych dostarczanych z Unity (sam jestem fanem układu
nazwanego Wide). Jeśli zbudujesz odpowiadający Ci układ paneli, zawsze
możesz go zapisać za pomocą opcji Window/Layouts/Save Layout. Dzięki temu
po przypadkowej zmianie układu masz możliwość przywrócenia zapisanego
wcześniej.

Wybór odpowiedniego układu


Tak jak nie ma dwóch takich samych osób, tak i nie istnieją dwa idealne
układy. Dobry układ pomaga użytkownikowi w pracy nad projektami i uła-
twia wykonywanie zadań. Dlatego też warto poświęcić chwilę na ekspe-
rymenty z układem i przygotowanie takiego, który najlepiej sprawdza się
podczas pracy. W najbliższym czasie będziesz dość często korzystał z Unity.
Czas przeznaczony na przygotowanie komfortowego środowiska pracy na
pewno nie będzie czasem zmarnowanym.

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

szenie elementów w panelu Project odbywa się za pomocą standardowej


techniki przeciągnij i upuść. W ten sposób można umieszczać elementy w pod‐
katalogach oraz na bieżąco zarządzać zasobami projektu.

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

Kiedy klikniesz katalog w panelu Project, jego zawartość zostanie wyświetlona


po prawej stronie panelu. Jak widać na rysunku 1.9, katalog Assets jest obecnie
pusty i dlatego nic nie zostało wyświetlone po prawej stronie panelu. Jeżeli
chcesz utworzyć zasób, możesz to bardzo łatwo zrobić za pomocą rozwijanego
menu Create. Menu pozwala na dodawanie do projektu wszelkiego rodzaju
zasobów i katalogów.

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.

Uważam, że jednym z najlepszych dodatków do panelu Project w Unity 4 jest


obsługa ulubionych elementów oraz integracja ze sklepem Unity Asset Store.
Lista ulubionych elementów pozwala na szybki wybór zasobów określonego
typu. W ten sposób zyskujesz możliwość wyświetlenia określonego typu za‐
sobów. Po kliknięciu jednego z przycisków w ulubionych (np. All Models) lub
podczas przeprowadzania operacji wyszukiwania za pomocą wbudowanego
paska wyszukiwania wynik można zawęzić do elementów znajdujących się
w katalogu Assets lub w sklepie Unity Asset Store. Kliknięcie przycisku Asset
Store pozwala na przeglądanie dostępnych w sklepie Unity Asset Store zasobów,
które spełniają podane kryteria (patrz rysunek 1.10). Wyniki można jeszcze
bardziej zawęzić, wybierając zasoby płatne lub bezpłatne. Jest to fantastyczne
udogodnienie, ponieważ pozwala na przeglądanie i pobieranie zasobów nie‐
zbędnych dla projektu bez opuszczania interfejsu Unity.

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

w panelu Hierarchy. Podobnie jak w panelu Project, także w Hierarchy można


szybko dodawać do sceny nowe elementy za pomocą rozwijanego menu Create.
Ponadto istnieje możliwość wyszukiwania elementów z wykorzystaniem wbu‐
dowanego paska wyszukiwania, a także przy użyciu klikania i przeciągania
elementów oraz ich „zagnieżdżania”.

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.

Na rysunku 1.12 pokazano panel Inspector po kliknięciu obiektu Main Camera


w panelu Hierarchy.
Przeanalizuję teraz wybrane informacje wyświetlane w panelu Inspector.
 Jeżeli klikniesz pole wyboru obok nazwy obiektu, zostanie on wyłą‐
czony i nie będzie wyświetlany w projekcie.
 Rozwijane menu (takie jak Layer lub Tag, więcej informacji na ich
temat znajdziesz dalej w książce) są używane do wyboru zestawów
predefiniowanych opcji.
 Można zmieniać wartości pól tekstowych, rozwijanych menu i suwa‐
ków. Wprowadzane zmiany natychmiast będą automatycznie odzwier‐
ciedlane na scenie, nawet wtedy, kiedy gra jest uruchomiona!
 Każdy obiekt gry działa jak kontener dla różnych komponentów (np.
Transform, Camera i GUILayer, co pokazano na rysunku 1.12). Istnieje
możliwość wyłączenia komponentu, przez usunięcie zaznaczenia
Poznajemy edytor Unity 37

RYSUNEK 1.12.
Panel Inspector

z pola wyboru wyświetlanego obok jego nazwy, lub nawet usunięcia


komponentu po jego kliknięciu prawym przyciskiem myszy i wybraniu
opcji Remove Component.
 Komponent można dodać po kliknięciu przycisku Add Component.

Zmiana właściwości, gdy scena jest uruchomiona


Możliwość zmiany właściwości obiektu i natychmiastowe odzwierciedlenie
tego w działającej scenie to wspaniałe cechy Unity. Pozwalają one na bie-
żące dostrojenie właściwości, takich jak szybkość ruchu, wysokość skoku,
siła kolizji itd., bez konieczności zatrzymywania i ponownego uruchamiania
gry. Musisz jednak pamiętać o zachowaniu ostrożności. Wszelkie zmiany
właściwości obiektu, gdy scena jest uruchomiona, zostaną wycofane po
zakończeniu działania sceny. Jeżeli wprowadzisz zmianę i jej efekt uznasz za
odpowiedni, upewnij się, że zapamiętałeś to, co zostało zmodyfikowane,
aby zmianę można było wprowadzić ponownie po zatrzymaniu sceny.

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

RYSUNEK 1.13. Panel Scene

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

 Ikona pomocnicza sceny . Kontrolka pokazuje aktualny kierunek


sceny oraz pozwala na wyrównanie sceny do wskazanej osi.

Ikona pomocnicza sceny


Ikona pomocnicza sceny w panelu Scene oferuje użyteczne możliwości. Jak
możesz zobaczyć, zawiera strzałki X, Y i Z wskazujące wyrównanie wzglę-
dem trzech wymienionych osi. Dzięki temu można bardzo łatwo sprawdzić,
z której strony patrzysz na scenę. Dokładne omówienie osi i przestrzeni
trójwymiarowej znajduje się dalej w tej książce. Ikona pomocnicza sceny
umożliwia również aktywną kontrolę nad wyrównaniem sceny. Po kliknię-
ciu dowolnej osi zobaczysz, że panel sceny zostaje natychmiast wyrównany
do danej osi, a scena jest wyświetlona z pewnego kierunku, np. z góry lub
z lewej strony. Kliknięcie sześcianu wyświetlanego w środku ikony pomoc-
niczej powoduje przełączanie między trybami izometrycznym i perspekty-
wicznym. W trybie izometrycznym panel trójwymiarowy nie zawiera per-
spektywy. Z kolei tryb perspektywiczny uwzględnia perspektywę w panelu
3D. Wypróbuj samodzielnie wymienione tryby i przekonaj się, jaki mają
wpływ na panel Scene.

Różne wersje, różne przyciski


Jeżeli używasz środowiska Unity w wersji 4.2 lub wcześniejszej, wtedy menu
panelu Scene wygląda tak, jak pokazano na rysunku 1.13. Jednak w wer-
sji 4.3 lub nowszej wygląd będzie nieco inny. Nie przejmuj się tym, ponie-
waż dostępne opcje pozostają bez zmian i są dostępne w rozwijanym menu
Effects. W panelu zauważysz także nowy przycisk 2D, który nie został poka-
zany na poprzednich rysunkach. Przycisk włącza nowe w Unity możliwości
w zakresie grafiki dwuwymiarowej. Ponieważ w tej książce koncentrujemy
się na grach trójwymiarowych, nie będziemy zajmować się nowo wprowa-
dzonymi opcjami dla gier 2D.

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

Brakujący panel Game


Jeśli okaże się, że panel Game jest ukryty pod panelem Scene lub całkowicie
zniknął, nie przejmuj się. Gdy klikniesz przycisk Start, karta z panelem Game
zostanie wyświetlona w edytorze i rozpocznie się uruchamianie gry.

Panel Game jest dostarczany wraz z kontrolkami, które pomagają podczas


testowania gier. Oto one.
 Start. Przycisk pozwala na uruchomienie bieżącej sceny. Wszystkie
kontrolki, animacje, dźwięki i efekty będą obecne i uwzględnione. Gra
po uruchomieniu będzie się zachowywała w dokładnie taki sam spo‐
sób, jakby została uruchomiona w samodzielnym odtwarzaczu, np.
w pececie lub urządzeniu mobilnym. Aby zatrzymać działającą grę,
należy ponownie nacisnąć przycisk Start.
 Pauza. Przycisk powoduje wstrzymanie wykonywania aktualnie
uruchomionego panelu Game. Gra zachowa informacje o stanie, a po
wznowieniu będzie kontynuowała działanie od miejsca, w którym
została wstrzymana. Ponowne kliknięcie przycisku Pauza powoduje
wznowienie działania wstrzymanej gry.
 Dalej. Przycisk działa, gdy gra w panelu Game jest wstrzymana. Naci‐
śnięcie omawianego przycisku powoduje, że gra wykona dokładnie
jedną klatkę. To pozwala na powolne „przejście” przez grę i usunięcie
wszelkich problemów, które mogą występować. Naciśnięcie przycisku
Dalej w trakcie działania gry powoduje jej wstrzymanie.
Poznajemy edytor Unity 41

 Rozwijane menu Aspect. Z poziomu tego rozwijanego menu można


wybrać proporcje, jakie w trakcie uruchomienia gry powinno mieć
okno wyświetlające panel Game. Opcją domyślną jest Free Aspect, ale
możesz wybrać inną, odpowiadającą proporcjom ekranu platformy
docelowej, dla której tworzysz grę.
 Maximize on Play (z ang. maksymalizacja podczas odtwarzania).
Ta opcja określa, czy panel Game po uruchomieniu gry będzie zajmo‐
wał całe okno edytora. Domyślnie omawiana opcja jest wyłączona,
a uruchomiona gra zajmuje co najwyżej wielkość karty panelu Game.
 Stats (z ang. dane statystyczne). Przycisk określa, czy podczas dzia‐
łania gry na ekranie będą wyświetlane generowane dane statystyczne.
Wspomniane dane statystyczne mogą być użyteczne, ponieważ uła‐
twiają przeprowadzanie pomiaru efektywności sceny. Domyślnie
wyświetlanie danych statystycznych jest wyłączone.
 Ikony pomocnicze. To jest jednocześnie przycisk i rozwijane menu.
Za pomocą przycisku określasz, czy podczas działania gry będą
wyświetlane ikony pomocnicze. Domyślnie taka możliwość jest wyłą‐
czona. Z kolei rozwijane menu (mała strzałka) wskazuje, które ikony
pomocnicze są wyświetlane po włączeniu omawianej opcji.

Uruchomienie, wstrzymanie i wyłączenie


Ustalenie znaczenia pojęć uruchomienie, wstrzymanie i wyłączenie może
być na początku trudne. Kiedy gra nie jest uruchomiona w panelu Game,
wtedy mówimy, że jest wyłączona. W wyłączonej grze kontrolki sterujące
nie działają i nie można w nią grać. Po naciśnięciu przycisku Start następuje
uruchomienie gry i wówczas gra działa. Granie, uruchamianie i działanie
gry oznacza to samo. Jeżeli gra jest uruchomiona i nastąpi naciśnięcie przy-
cisku Pauza, wtedy gra zostanie wstrzymana, ale jednocześnie zachowa
informacje o stanie. Na tym etapie gra jest wstrzymana. Różnica pomiędzy
grą wstrzymaną i wyłączoną polega na tym, że wstrzymana wznawia dzia-
łanie od miejsca, w którym naciśnięto pauzę, natomiast wyłączona jest uru-
chamiana od początku.

Wyróżnienie — pasek narzędziowy


Wprawdzie to nie jest panel, ale pasek narzędziowy stanowi bardzo ważną
część edytora Unity. Na rysunku 1.15 pokazano komponenty paska narzę‐
dziowego.
 Narzędzia transformacji. Przyciski pozwalają na przeprowadzanie
operacji na obiektach gry i zostaną dokładnie omówione dalej w tej
książce. Szczególną uwagę należy zwrócić na przycisk z ikoną w postaci
ręki. To narzędzie zostanie przedstawione dalej w tej lekcji.
42 Lekcja 1. Wprowadzenie do Unity

 Włączenie/wyłączenie ikon transformacji. Przyciski określają


sposób wyświetlania ikon pomocniczych w panelu Scene. Obecnie
pozostaw ich ustawienia domyślne.
 Kontrolki panelu Game. Przyciski są odpowiedzialne za kontrolę
panelu Game.
 Rozwijane menu Layers. Za pomocą tego menu można określić
warstwy obiektów, które zostaną wyświetlone w panelu Scene.
Domyślnie panel Scene wyświetla wszystko. Obecnie pozostaw ich
ustawienia domyślne. Warstwami zajmę się dalej w tej książce.
 Rozwijane menu wyboru układu. Menu pozwala na szybką zmianę
układu paneli edytora.

RYSUNEK 1.15.
Pasek
narzędziowy

Poruszanie się po panelu


Scene w Unity
Panel Scene zapewnia kontrolę nad konstrukcją gry. Możliwość umieszczania
i modyfikacji elementów w sposób graficzny to ważna cecha edytora Unity.
Jednak wspomniane możliwości nie będą użyteczne, jeśli nie będzie można
przenosić elementów w ramach sceny. W tym podrozdziale omówię kilka spo‐
sobów zmiany położenia obiektów i nawigacji w panelu Scene.

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

Wszystkie skróty klawiszowe stosowane w Unity znajdziesz na stronie:


http://blogs.unity3d.com/2011/08/24/unity-hotkeys-keyboard-
shortcuts-in-unity/
Podsumowanie 43

Tabela 1.1 Kontrolki narzędzia Hand


Kontrolka Opis
Kliknięcie i przeciągnięcie. Przeciągnięcie kamery
na scenie.
Naciśnięcie i przytrzymanie klawisza Alt, Orbitowanie kamery wokół
a następnie kliknięcie i przeciągnięcie. aktualnego punktu obrotu.
Naciśnięcie i przytrzymanie klawisza Ctrl Przybliżenie lub oddalenie
(Command w Macu), a następnie kliknięcie kamery.
prawym przyciskiem myszy i przeciągnięcie.

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

Tabela 1.2. Kontrolki trybu Flythrough


Akcja Efekt
Przesunięcie myszy. Powoduje obrót kamery i wywołanie
odczucia „rozglądania się” po scenie.
Naciśnięcie klawiszy WASD. Klawisze WASD umożliwiają
poruszanie się po scenie. Każdy
klawisz odpowiada kierunkowi,
odpowiednio, do przodu, w lewo,
do tyłu, w prawo.
Naciśnięcie klawiszy QE. Klawisze QE powodują poruszanie
się po scenie, odpowiednio, w górę
oraz w dół.
Naciśnięcie i przytrzymanie klawisza Taki sam efekt jak wcześniej,
Shift podczas naciskania klawiszy ale ruch odbywa się szybciej.
WASD i QE. Klawisz Shift możesz uznać
za klawisz umożliwiający bieg.

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

W czasie tej lekcji dowiesz się:


 jak pracować ze współrzędnymi 2D i 3D,
 jak korzystać z obiektów gry,
 jak używać transformacji.
Obiekty gry to podstawowe komponenty projektu gry w Unity. Każdy ele-
ment znajdujący się na scenie jest obiektem gry (bądź też został na nim
oparty). W tej lekcji poznasz obiekty gry stosowane w środowisku Unity.
Jednak zanim zaczniesz pracę z obiektami w Unity, musisz poznać układy
współrzędnych 2D i 3D. Później będziesz mógł przystąpić do pracy z obiek-
tami gry wbudowanymi w Unity. Na końcu lekcji zapoznasz się z różnymi
transformacjami, które można przeprowadzać na obiektach gry. Informa-
cje przedstawione w tej lekcji mają znaczenie krytyczne dla całego mate-
riału zawartego w książce. Musisz mieć pewność, że poświęciłeś wystar-
czającą ilość czasu, by opanować ten materiał.
48 Lekcja 2. Obiekty gry

Wymiary i układy współrzędnych


Gry wideo, pomimo całego uroku i atrakcyjności, to po prostu konstrukcje
matematyczne. Wszystkie właściwości, ruch i interakcje można sprowadzić do
liczb. Na szczęście, solidne podstawy zostały już przygotowane przez innych.
Od wieków matematycy pracują mozolnie, odkrywając i upraszczając różne
procesy; wiele z nich ułatwia tworzenie gier za pomocą nowoczesnego opro‐
gramowania. Być może sądzisz, że obiekty w grze po prostu istnieją w dowol‐
nie wybranym miejscu przestrzeni. Jest inaczej, każda przestrzeń gry ma
swoje wymiary, a wszystkie obiekty są umieszczane w układzie współrzędnych
(inaczej mówiąc, na siatce).

Umieszczenie litery D w nazwie 3D


Jak wcześniej wspomniano, każda gra używa pewnego poziomu wymiarów.
Najczęściej spotykane układy wymiarów to te, które dobrze znasz, czyli 2D
i 3D (dwuwymiarowy i trójwymiarowy). System 2D jest nazywany płaskim
układem współrzędnych. W układzie 2D pracujesz jedynie z elementami po‐
ziomymi i pionowymi (ujmując rzecz inaczej: ruch odbywa się w górę, w dół,
w lewą i w prawą stronę). Gry, takie jak Tetris, Pong i Pac Man, są dobrymi
przykładami gier 2D. Z kolei układ współrzędnych 3D jest jak 2D, ale oczy‐
wiście obsługuje dodatkowy wymiar. W układzie współrzędnych 3D, poza
kierunkiem poziomym i pionowym (góra, dół, lewo, prawo), mamy jeszcze
głębokość (przód i tył). Na rysunku 2.1 pokazano różnice między kwadratem
(obiekt 2D) i sześcianem (obiekt 3D). Zwróć uwagę, jak dołączenie osi głębo‐
kości w sześcianie powoduje złudzenie jego „wyskakiwania”.

RYSUNEK 2.1.
Kwadrat (2D)
kontra sześcian
(3D)

Użycie układów współrzędnych


Matematycznym odpowiednikiem systemu wymiarów jest układ współrzęd‐
nych. Układ ten wykorzystuje serię linii nazywanych osiami oraz położeń nazy‐
wanych punktami. Osie bezpośrednio odpowiadają wymiarom. Przykładowo
Wymiary i układy współrzędnych 49

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.

dwuwymiarowy układ współrzędnych składa się z osi X i Y, które przedsta‐


wiają kierunki, odpowiednio, poziomy i pionowy. Jeżeli obiekt porusza się
poziomo, mówimy, że ruch odbywa się wzdłuż osi X. Podobnie w trójwymia‐
rowym układzie współrzędnych używa się osi X, Y i Z odpowiadających ruchowi
w kierunkach, odpowiednio, poziomym, pionowym i głębokości.

Najczęściej stosowana składnia układu współrzędnych


Określając położenie obiektu, po prostu podajemy jego współrzędne.
Powiedzenie, że obiekt znajduje się w pozycji 2 dla osi X i pozycji 4 dla
osi Y jest nieco kłopotliwe. Na szczęście, istnieje skrócony zapis przezna-
czony do wyrażania współrzędnych. W układach 2D współrzędne podajemy
w postaci (x, y), natomiast w układach 3D używamy notacji (x, y, z). Dlatego
też położenie obiektu wspomnianego na początku można określić jako
(2, 4). Jeżeli położenie tego obiektu na osi Z wynosi 10, wtedy współrzędne
mają postać (2, 4, 10).

W każdym układzie współrzędnych istnieje punkt, w którym przecinają się


wszystkie osie. Ten punkt nosi nazwę początku układu współrzędnych
(ang. origin), a jego współrzędne zawsze wynoszą (0, 0) w układach współ‐
rzędnych 2D i (0, 0, 0) w układach współrzędnych 3D. Początek układu współ‐
rzędnych jest bardzo ważny, ponieważ stanowi odniesienie dla wszystkich
pozostałych punktów układu współrzędnych. Współrzędne dowolnego punktu
po prostu oznaczają odległość danego punktu od początku układu współrzęd‐
nych. Im dalej od początku układu współrzędnych, tym współrzędne punktu
mają większe wartości. Przykładowo wraz z przesuwaniem się punktu
w prawą stronę wzrasta wartość dla osi X. Z kolei podczas przesuwania
punktu w lewo wartość dla osi X staje się coraz mniejsza, aż wreszcie minie
początek układu współrzędnych. Od tego miejsca wartość X znów będzie
wzrastała, ale jednocześnie stanie się ujemna. Spójrz na rysunek 2.2. W poka‐
zanym na nim układzie współrzędnych 2D zdefiniowano trzy punkty. Punkt
(2, 2) znajduje się w odległości 2 jednostek od początku układu współrzęd‐
nych zarówno w kierunku X, jak i Y. Z kolei punkt (–3, 3) znajduje się w odle‐
głości 3 jednostek w lewo od początku układu współrzędnych i 3 jednostek
nad początkiem układu współrzędnych. Natomiast punkt (2, –2) znajduje się
2 jednostki w prawo od początku układu współrzędnych oraz 2 jednostki pod
początkiem układu współrzędnych.
50 Lekcja 2. Obiekty gry

RYSUNEK 2.2.
Punkty
w odniesieniu
do początku
układu
współrzędnych

Współrzędne świata kontra lokalne


Poznałeś już wymiary świata gry i układy współrzędnych tworzące wspo‐
mniane wymiary. Omówione dotąd układy współrzędnych to tzw. układy
współrzędnych świata. W tego rodzaju układzie współrzędnych w danej chwili
istnieją tylko trzy osie, czyli X, Y i Z. Podobnie egzystuje tylko jeden początek
układu współrzędnych, który jest współdzielony przez wszystkie obiekty.
Oprócz układu współrzędnych świata możesz jeszcze napotkać tzw. lokalny
układ współrzędnych. Ten układ jest unikalny dla każdego obiektu. Lokalny
układ współrzędnych ma własne osie i początek układu współrzędnych, nie
są one współdzielone z innymi obiektami. Na rysunku 2.3 pokazano układy
lokalny i świata oraz cztery punkty tworzące kwadrat w każdym z układów.
Być może zastanawiasz się, do czego jest przeznaczony lokalny układ współ‐
rzędnych, skoro układ współrzędnych świata jest używany do określania poło‐
żenia obiektów. Dalej w tej lekcji poznasz transformację obiektów gry oraz
relacje między obiektami. Oba te zagadnienia wymagają stosowania lokalnego
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

RYSUNEK 2.3. Współrzędne świata i współrzędne lokalne

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

Utworzenie pewnych obiektów gry


Teraz poświęcisz chwilę na pracę z obiektami gry. Utworzysz kilka prostych
obiektów, a następnie razem przeanalizujemy ich różne komponenty.
1. Utwórz nowy projekt lub nową scenę w bieżącym projekcie.
2. Dodaj pusty obiekt gry, klikając menu GameObject, a następnie
wybierając opcję Create Empty. (Uwaga: pusty obiekt gry można
utworzyć także przez naciśnięcie klawiszy Ctrl+Shift+N w pececie
lub Command+Shift+N w Macu).
3. Spójrz na panel Inspector, a przekonasz się, że utworzony przed chwilą
obiekt gry nie posiada innych komponentów poza transformacją.
Wszystkie obiekty gry zawierają transformację. Kliknięcie przycisku
Add Component w panelu Inspector spowoduje wyświetlenie
komponentów, które można dodać do obiektu. Tym razem
nie dodawaj żadnego.
4. Do projektu dodaj sześcian. W tym celu kliknij menu GameObject,
wybierz opcję Create Other, a następnie z rozwijanej listy wskaż Cube.
5. Zwróć uwagę na różne komponenty znajdujące się w sześcianie, których
brakuje w pustym obiekcie gry. Dzięki komponentowi Mesh sześcian
w ogóle jest widoczny, a komponent Box Collider pozwala na interakcję
sześcianu z innymi obiektami.
6. Na koniec do projektu dodaj źródło światła. W tym celu kliknij rozwijane
menu Create w panelu Hierarchy i z listy wybierz opcję Point Light.
7. Jak widzisz, źródło światła nie współdzieli żadnych komponentów
z sześcianem i całkowicie koncentruje się na emisji światła. Zauważysz
również, że po dodaniu źródła światła pozostałe obiekty na scenie stały
się ciemne. To jest normalne zachowanie. Ponieważ na scenie zostało
umieszczone źródło światła, środowisko Unity wyłączyło naturalne
oświetlenie obiektów.

czasie ta koncepcja stanie się dla Ciebie oczywista. Ponieważ transformacja


składa się z położenia, rotacji i skali, zmiana transformacji oznacza, odpowiednio,
translację, rotację i skalowanie. Wymienione transformacje można przeprowa‐
dzić za pomocą panelu Inspector lub narzędzi transformacji. Na rysunku 2.4
pokazano sekcję transformacji w panelu Inspector, natomiast na rysunku 2.5
— narzędzia odpowiadające poszczególnym rodzajom transformacji.

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

Po wybraniu narzędzia translacji (skrót klawiszowy W) zauważysz, że wybrany


obiekt ulegnie niewielkiej zmianie w panelu Scene. Zmiana polega na wyświe‐
tleniu w środku obiektu trzech strzałek wskazujących trzy osie. Są to ikony
pomocnicze translacji, które pomagają w poruszaniu obiektem na scenie.
Kliknięcie i przytrzymanie dowolnej strzałki osi powoduje zmianę jej koloru
na żółty. Teraz ruch myszą spowoduje przesunięcie obiektu wzdłuż wskazanej
osi. Na rysunku 2.7 pokazano wygląd ikon pomocniczych translacji. Zwróć
uwagę, że wspomniane ikony są wyświetlane jedynie w panelu Scene. Jeżeli
aktualnym panelem jest Game, ikony pomocnicze nie będą widoczne.

RYSUNEK 2.7.
Ikony pomocnicze
translacji
54 Lekcja 2. Obiekty gry

Komponent transformacji i narzędzia transformacji


Unity oferuje dwa sposoby zarządzania transformacjami obiektów. Warto
więc wiedzieć, kiedy korzystać z każdego z nich. Prawdopodobnie zauwa-
żyłeś, że podczas transformacji za pomocą narzędzia transformacji w panelu
Scene dane transformacji w panelu Inspector również ulegają zmianie.
Bardzo często wprowadzenie ogromnych zmian w transformacji obiektu
będzie łatwiejsze przy użyciu panelu Inspector, ponieważ wtedy wystarczy
po prostu wprowadzić odpowiednie wartości. Z kolei narzędzia transfor-
macji doskonale sprawdzają się w trakcie przeprowadzania szybkich, nie-
wielkich zmian. Poznanie obu sposobów zmiany transformacji obiektu może
znacznie usprawnić pracę.

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

Określenie osi rotacji


Jeżeli nie jesteś pewien, względem której osi powinna być przeprowadzona
rotacja obiektu, aby uzyskać żądany efekt, zawsze możesz użyć metody
obrazowego przedstawienia sytuacji. Przyjmij założenie, że obiekt jest
unieruchomiony względem jednej osi. Oznacza to, że może się obracać
tylko względem tej unieruchomionej osi. Teraz spróbuj określić, czy obrót
obiektu względem tej osi przyniesie oczekiwany efekt. Przedstawioną tutaj
procedurę wykonuj po kolei dla poszczególnych osi. W ten sposób ustalisz
oś, względem której trzeba przeprowadzić rotację.
Transformacje 55

Podobnie jak w przypadku narzędzia translacji, także wybór narzędzia rotacji


(skrót klawiszowy E) powoduje wyświetlenie wokół obiektu ikon pomocni‐
czych. Ikony pomocnicze mają postać okręgów symbolizujących ścieżki obrotu
względem poszczególnych osi. Kliknięcie i przeciągnięcie dowolnego z tych
okręgów powoduje zmianę koloru okręgu na żółty i rotację względem wskaza‐
nej osi. Na rysunku 2.9 pokazano wygląd ikon pomocniczych rotacji.

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

Ryzyko związane z transformacjami


Jak wcześniej pisałem, podczas transformacji wykorzystywany jest lokalny
układ współrzędnych. Zatem wprowadzone zmiany potencjalnie mogą mieć
wpływ na kolejne transformacje wykonywane w przyszłości. Spójrz na rysu‐
nek 2.12. Łatwo zauważyć, że dwie takie same transformacje przeprowadzone
w odwrotnej kolejności dają odmienne efekty.
56 Lekcja 2. Obiekty gry

RYSUNEK 2.11.
Ikony pomocnicze
skalowania

RYSUNEK 2.12.
Efekt kolejności
stosowania
transformacji

Jak widać, niezwracanie uwagi na kolejność przeprowadzania transformacji


może przynieść nieoczekiwane skutki. Na szczęście, transformacje charakte‐
ryzują się spójnymi efektami ich stosowania, które można przewidzieć.
 Translacja. To całkiem bierna transformacja. Oznacza to, że ogólnie
rzecz biorąc, nie ma wpływu na zmiany, które będą wprowadzane po
przeprowadzeniu tej transformacji.
 Rotacja. Ta transformacja powoduje zmianę orientacji osi lokalnego
układu współrzędnych. Wszelkie transformacje przeprowadzane po
rotacji będą powodowały przesuwanie obiektu wzdłuż nowo zdefi‐
niowanych osi. Jeżeli przeprowadzisz rotację obiektu o 180 stopni
względem osi Z, a następnie przesuniesz go o wartość dodatnią
wzdłuż osi Y, wtedy odniesiesz wrażenie, że obiekt porusza się w dół
zamiast w górę.
 Skalowanie. Ta transformacja w zasadzie powoduje zmianę siatki
lokalnego układu współrzędnych. Skalowanie mające na celu zwięk‐
szenie obiektu oznacza powiększenie lokalnego układu współrzęd‐
nych. Skutkiem jest wrażenie, że obiekt stał się większy. Ta zmiana
jest multiplikatywna. Jeśli np. obiekt jest skalowany do wartości 1 (to
wielkość domyślna, naturalna), a następnie przeprowadzona zostaje
translacja o 5 jednostek wzdłuż osi X, wtedy powstaje wrażenie prze‐
Podsumowanie 57

sunięcia obiektu o 5 jednostek w prawo. Jednak skalowanie obiektu


do wartości 2, a następnie przeprowadzenie translacji o 5 jednostek
wzdłuż osi X sprawia wrażenie, że obiekt przesunął się o 10 jednostek
w prawo. Wynika to z faktu dwukrotnego powiększenia lokalnego
układu współrzędnych, a wynikiem mnożenia 5 razy 2 jest 10. Ana‐
logicznie skalowanie obiektu do wartości 0.5, a następnie przesu‐
nięcie o 5 jednostek wzdłuż osi X sprawia wrażenie, że obiekt prze‐
sunął się tylko o 2,5 jednostki (0.5 razy 5 daje 2,5).
Po zrozumieniu wymienionych reguł określenie sposobu zmiany obiektu po
zastosowaniu zestawu transformacji stanie się całkiem łatwe.

Transformacja a obiekty zagnieżdżone


W lekcji 1. dowiedziałeś się, jak zagnieżdżać obiekty gry w panelu Hierarchy
(w tym celu wystarczy przeciągnąć jeden obiekt na drugi). Wspominałem
wówczas, że zagnieżdżenie nieco zmienia sposób przeprowadzenia transfor‐
macji. W przypadku zagnieżdżenia jednego obiektu w drugim obiekt najwyż‐
szego poziomu jest nadrzędny, natomiast drugi będzie potomny. Transformacja
zastosowana dla obiektu nadrzędnego działa zgodnie z oczekiwaniami. Ten
obiekt można przesuwać, skalować i obracać. Zmiana zachowania dotyczy
obiektu potomnego. Po jego zagnieżdżeniu transformacja obiektu będzie prze‐
prowadzana względem obiektu nadrzędnego, a nie układu współrzędnych
świata. Dlatego też położenie obiektu potomnego nie zależy od odległości od
początku układu współrzędnych, ale odległości od obiektu nadrzędnego. Pod‐
czas rotacji obiektu nadrzędnego potomny porusza się w ślad za nim. Jeśli
jednak wówczas spojrzysz na rotację obiektu potomnego, nie zauważysz żad‐
nych zmian. Tak samo dzieje się w trakcie skalowania obiektu nadrzędnego —
zmiana wielkości dotyczy również obiektu potomnego. Podobnie jak wcześniej,
jeśli spojrzysz na wartości skalowania obiektu potomnego, to nie zauważysz
żadnych zmian. Takie zachowanie może na początku wydawać się dziwne.
Pamiętaj, że transformacja jest stosowana nie względem obiektu, ale jego układu
współrzędnych. Obiekt nie podlega rotacji, natomiast układ współrzędnych tak.
Efektem jest wrażenie obrotu obiektu. Kiedy układ współrzędnych obiektu
potomnego jest oparty na lokalnym układzie współrzędnych obiektu nadrzęd‐
nego, wszelkie zmiany w układzie współrzędnych obiektu nadrzędnego będą
miały bezpośrednie przełożenie na obiekt potomny (który nawet nie będzie
o tym „wiedział”).

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

wbudowanych w Unity. Później przyszła kolej na transformacje. Miałeś okazję


wypróbować niektóre transformacje, poznałeś związane z nimi niebezpie‐
czeństwa i dowiedziałeś się, jaki mają wpływ na zagnieżdżone obiekty.

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

W czasie tej lekcji:


 poznasz podstawy dotyczące modeli,
 dowiesz się, jak można importować modele zarówno własne,
jak i gotowe,
 nauczysz się pracować z materiałami i shaderami.
W tej lekcji poznasz modele i dowiesz się, jak ich używać w Unity. Na
początek zapoznasz się z podstawowymi regułami dotyczącymi siatki
(ang. mesh) i obiektów trójwymiarowych. Następnie nauczysz się impor-
towania modeli zarówno własnych, jak i pobranych ze sklepu Unity Asset
Store. Na koniec opanujesz oferowane przez środowisko Unity funkcje
związane z materiałami i shaderami.
62 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.

Model czy siatka?


Pojęcia model i siatka są podobne i bardzo często można stosować je
wymiennie. Jednak między nimi istnieje pewna różnica. Siatka zawiera
informacje o wszystkich wierzchołkach definiujących kształt 3D obiektu.
Kiedy odwołujesz się do kształtu lub formy modelu, wtedy odnosisz się do
siatki. Dlatego też model jest obiektem zawierającym siatkę. W modelu
używa się siatki w celu zdefiniowania wymiarów, ale model może zawierać
także animacje, tekstury, materiały, shadery i inne siatki. Oto dobra, ogólna
reguła: jeżeli element zawiera więcej niż tylko informacje o wierzchołkach,
wtedy jest modelem, w przeciwnym razie to siatka.
Podstawy modeli 63

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

Modelowanie z użyciem prostej siatki


Potrzebujesz w grze skomplikowanych obiektów, ale nie możesz znaleźć
odpowiedniego typu modelu? Zagnieżdżanie obiektów w Unity pozwala na
łatwe tworzenie prostych modeli za pomocą wbudowanych siatek. Po
prostu umieść siatki obok siebie i przygotuj w ten sposób potrzebny model.
Następnie wszystkie obiekty zagnieźdź w jednym centralnym obiekcie.
W takim przypadku przesunięcie obiektu nadrzędnego spowoduje także
przesunięcie wszystkich obiektów potomnych. To na pewno nie jest naj-
bardziej elegancki sposób tworzenia modeli dla gry, ale możesz go zasto-
sować, jeśli będzie trzeba.

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

pliku zawierającego model 3D jest wystarczające w celu jego dodania do


projektu. Następnie trzeba przeciągnąć model na scenę lub panel Hierarchy
i tym samym zacząć budować obiekt gry na podstawie danego modelu. Śro‐
dowisko Unity zapewnia obsługę plików zapisanych w formatach .fbx, .dae, .3ds,
.dxf i .obj, zatem umożliwia pracę z praktycznie każdą aplikacją przeznaczoną
do tworzenia modeli 3D.

 Wypróbuj samodzielnie

Importowanie własnych modeli 3D


Oto kroki niezbędne, aby zaimportować własne modele 3D do projektu Unity.
1. Utwórz nowy projekt Unity lub scenę.
2. W panelu Project w katalogu Assets utwórz podkatalog o nazwie
Models (kliknij prawym przyciskiem myszy katalog Assets i wybierz
opcję Create/Folder).
3. Odszukaj plik Torus.fbx, który znajduje się w materiałach przeznaczonych
dla bieżącej lekcji.
4. Obok siebie wyświetl okna systemowej przeglądarki plików oraz edytora
Unity. Następnie w systemowej przeglądarce plików kliknij Torus.fbx
i przeciągnij ten plik do katalogu Models utworzonego w kroku 2.
Z kolei w edytorze Unity kliknij katalog Models, a zobaczysz nowo
dodany model z pliku Torus.fbx. Jeżeli operację przeprowadzisz
prawidłowo, panel Project będzie wyglądał tak, jak pokazano na
rysunku 3.2. Zwróć uwagę na katalog Materials, który został dodany
za Ciebie. Więcej informacji na ten temat znajdziesz dalej w tej lekcji.

RYSUNEK 3.2. Panel Project po dodaniu modelu Torus


5. Kliknij zasób Torus w katalogu Models i spójrz na panel Inspector.
Zmień wartość współczynnika skalowania z 0.01 na 1 i naciśnij przycisk
Apply.
6. Przeciągnij zasób Torus z katalogu Models do panelu Scene. Zauważ,
że na scenie pojawił się obiekt gry zawierający filtr Mesh
i wygenerowaną siatkę. W ten sposób Torus jest wyświetlany na
ekranie. Jeżeli klikniesz obiekt Torus, zobaczysz, że składa się z wielu
połączonych trójkątów.
Podstawy modeli 65

Domyślne skalowanie siatki


W panelu Inspector większość opcji przeznaczonych dla siatki to opcje
zaawansowane i dlatego nie będą tutaj omawiane. Interesująca nas wła-
ściwość to współczynnik skalowania. Domyślnie środowisko Unity importuje
siatki jako przeskalowane w dół. Przez zmianę wartości skalowania z 0.01
na 1 wskazujesz Unity, że model może mieć na scenie taką samą wielkość,
w jakiej został utworzony.

Modele i sklep Asset Store


Nie musisz mieć doświadczenia w przygotowywaniu modeli, aby tworzyć gry
w środowisku Unity. Sklep Asset Store to prosty i efektywny sposób wyszuki‐
wania gotowych modeli, a następnie importowania ich do projektu. W sklepie
Asset Store znajdziesz modele zarówno bezpłatne, jak i płatne, dostarczane
pojedynczo lub w całych kolekcjach podobnych modeli. Niektóre modele zawie‐
rają tekstury, natomiast inne to po prostu siatki danych.

 Wypróbuj samodzielnie

Pobieranie modeli ze sklepu Asset Store


Dowiesz się teraz, jak wyszukiwać i pobierać modele w sklepie Asset Store.
Celem jest pobranie modelu o nazwie Robot Kyle i zaimportowanie go na
scenę.
1. Utwórz nową scenę (wybierz opcję File/New Scene). W pasku
wyszukiwania panelu Project wpisz t:Model (patrz rysunek 3.3).

RYSUNEK 3.3. Kroki prowadzące do odszukania modelu


2. W sekcji filtrów wyszukiwania kliknij przycisk Asset Store: 999+/999+
(patrz rysunek 3.3). Jeżeli ten przycisk nie będzie widoczny, zmień
wielkość okna edytora lub panelu Project.
3. Odszukaj model Robot Kyle i wybierz go.
4. W panelu Inspector kliknij przycisk Import Package. Na tym etapie
zostaniesz poproszony o podanie danych uwierzytelniających do
konta Unity.
66 Lekcja 3. Modele, materiały i tekstury

5. Po wyświetleniu okna dialogowego Importing Package 


pozostaw zaznaczone opcje, a następnie kliknij Import.
6. W projekcie będziesz miał teraz nowy katalog zasobu o nazwie Robot
Kyle. Odszukaj model robota w Assets/Robot Kyle/Model i przeciągnij
go do panelu Scene (patrz rysunek 3.4). Zwróć uwagę, że model
w panelu Scene jest mały. Aby dobrze go zobaczyć, prawdopodobnie
będziesz musiał zbliżyć się do ekranu.

RYSUNEK 3.4. Projekt Unity wraz z dodanym modelem Robot Kyle

Tekstury, shadery i materiały


Dodanie zasobów graficznych do modeli trójwymiarowych może być żmudnym
zadaniem, jeśli nie wiesz, jak można to efektywnie zrobić. Środowisko Unity
oferuje proste rozwiązanie charakteryzujące się dużymi możliwościami
w zakresie ustalenia, jak dokładnie ma wyglądać model. Zasoby graficzne są
podzielone na tekstury, shadery i materiały. Wprawdzie każdy z wymienionych
elementów zostanie omówiony w oddzielnym punkcie, ale na rysunku 3.5
pokazano relacje między nimi. Zwróć uwagę, że tekstury nie są nakładane
bezpośrednio na model. Tekstury i shadery są nakładane na materiały, które
następnie są przypisywane modelowi. W ten sposób wygląd modelu można
bardzo szybko zmienić lub zmodyfikować bez konieczności wykonywania dużej
ilości pracy.
Tekstury, shadery i materiały 67

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

pokazano dwa materiały z zastosowanymi różnymi shaderami. Zauważ, że


każdy z nich ma teksturę bazową, kolor podstawowy, ustawione wartości
Tilling i Offset, a także podgląd materiału (obecnie pusty z powodu braku
tekstury). Jednak w materiale o nazwie Shiny użyto specjalnego shadera Specu-
lar, a ponadto jest dostarczany wraz z właściwościami Specular Color i Shininess.
Wymienione właściwości zostaną omówione w następnej lekcji.

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

Tabela 3.1. Podstawowe shadery z rodziny Normal


Shader Opis
Diffuse Diffuse jest domyślnym shaderem dla materiałów.
To jednocześnie najprostszy z shaderów. Światło
jest równomiernie rozpraszane po całej powierzchni obiektu.
Specular Przy użyciu Specular obiekt zyskuje połysk. Jeżeli chcesz
utworzyć obiekt odbijający światło, powinieneś skorzystać
z tego shadera.
Bumped Shadery Bumped są — ogólnie rzecz biorąc — używane
w połączeniu z innymi rodzajami shaderów
(np. bumped-diffuse lub bumped-specular). Tego rodzaju
shadery wykorzystują zwykłą mapę w celu nadania płaskiej
teksturze wyglądu trójwymiarowego. To doskonałe
rozwiązanie pozwalające na dostarczenie modelom wielu
fizycznych szczegółów bez konieczności tworzenia
skomplikowanych modeli.

Tabela 3.2. Wspólne właściwości shaderów


Właściwość Opis
Main Color Właściwość określa kolor światła otoczenia, które oświetla
obiekt. Nie powoduje zmiany koloru samego obiektu,
a jedynie to, że obiekt jest wyświetlany nieco inaczej.
Przykładowo obiekt z nałożoną niebieską teksturą i kolorem
żółtym zdefiniowanym we właściwości Main Color nie będzie
żółty, ale zielony (ponieważ nałożenie kolorów niebieskiego
i żółtego daje w efekcie kolor zielony). Jeżeli chcesz,
aby kolor modelu pozostał niezmieniony, wybierz biały.
Specular Color Właściwość definiuje kolor „błyszczących” fragmentów
modelu. Ogólnie rzecz ujmując, będzie to kolor biały,
o ile nie chcesz, aby obiekt był oświetlany światłem
o innym kolorze.
Shininess Właściwość określa, jak bardzo błyszczący będzie obiekt.
Texture Blok Texture zawiera informacje o teksturze nakładanej
na model.
Normal Map Blok Normal Map zawiera informacje o mapie, która będzie
nałożona na model. Tego rodzaju mapa służy do mapowania
nierówności w modelu. Omawiana właściwość jest użyteczna
podczas obliczania światła pozwalającego na wyświetlenie
przez model większej ilości szczegółów niż w innych
sytuacjach.
Tekstury, shadery i materiały 71

Tabela 3.2. Wspólne właściwości shaderów — ciąg dalszy


Właściwość Opis
Tiling Właściwość określa, jak często tekstura może być powtarzana
w modelu. Powtarzanie tekstury można zdefiniować
wzdłuż osi X i Y.
Offset Właściwość definiuje odległość, jaka będzie występować
między krawędziami obiektu i teksturą.

 Wypróbuj samodzielnie

Nakładanie tekstur, shaderów i materiałów na modele


W tym ćwiczeniu wykorzystasz zdobytą wiedzę dotyczącą tekstur, shaderów
oraz materiałów i na jej podstawie przygotujesz realistycznie wyglądający
mur z cegieł.
1. Utwórz nowy projekt lub scenę. Pamiętaj, że utworzenie nowego
projektu spowoduje zamknięcie i ponowne otworzenie edytora.
2. Utwórz katalogi Textures i Materials.
3. Odszukaj plik Brick_Texture.png w materiałach przeznaczonych dla tej
lekcji, a następnie przeciągnij go do katalogu Textures utworzonego
w kroku 2.
4. Do sceny dodaj sześcian. Umieść go w położeniu (0, 1, –5) i przeskaluj
(5, 2, 1). Właściwości sześcianu pokazano na rysunku 3.7.

RYSUNEK 3.7. Właściwości sześcianu


5. Utwórz nowy materiał (prawym przyciskiem myszy kliknij katalog
Materials, a następnie wybierz opcję Create/Material) o nazwie BrickWall.
6. Pozostaw domyślny shader Diffuse, natomiast w bloku Texture kliknij
Select. W wyskakującym oknie wybierz Brick_Texture.
7. W panelu Project kliknij materiał, a następnie przeciągnij go na sześcian
w panelu Scene.
8. Łatwo zauważyć, że tekstura jest za bardzo rozciągnięta na ścianie.
Mając nadal zaznaczony materiał, zmień wartość właściwości Tiling X
na 3. Teraz ściana wygląda znacznie lepiej.
72 Lekcja 3. Modele, materiały i tekstury

9. Na scenie umieść światło kierunkowe (kliknij GameObject/Create 


Other/Directional Light). Umieść je w położeniu (0, 10, –10) i zastosuj
rotację (30, 0, 0). Do tematu oświetlenia powrócę w następnej lekcji.
Dodane przed chwilą światło nadaje ścianie trójwymiarowy wygląd.
10. W ten sposób przygotowałeś na scenie teksturowaną ścianę
(patrz rysunek 3.8).

RYSUNEK 3.8. Ściana utworzona w tym ćwiczeniu

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

shaderów omówionych w tej lekcji, a kolejne poznawaj wtedy, gdy będzie


tego wymagał projekt gry.
Pytanie: Skoro w sklepie Unity Asset Store są oferowane płatne zasoby,
czy to oznacza, że i ja mogę sprzedawać samodzielnie przygotowane
zasoby?
Odpowiedź: Dokładnie tak. W rzeczywistości nie jesteś ograniczony jedynie
do zasobów graficznych. Jeżeli potrafisz utworzyć zasoby wysokiej
jakości, bez wątpienia będziesz mógł je sprzedawać w wymienionym
sklepie.

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

1. Utwórz nowy projekt lub scenę.


2. Do projektu dodaj katalogi Materials i Textures. W materiałach
przeznaczonych dla bieżącej lekcji wyszukaj pliki Brick_Normal.png
i Brick_Texture.png, a następnie przeciągnij je do katalogu Textures.
3. W panelu Project zaznacz Brick_Texture. Następnie w panelu Inspector
zmień wartość Aniso Level z 1 na 3 w celu zwiększenia jakości tekstury
w zaokrągleniach. Kliknij przycisk Apply.
4. W panelu Project zaznacz Brick_Normal. Następnie w panelu Inspector
zmień typ tekstury na Normal Map i kliknij przycisk Apply.
5. Na scenie umieść światło kierunkowe (wybierz opcję GameObject/Create
Other/Directional Light). Umieść je w położeniu (0, 10, –10) i zastosuj
rotację (30, 40, 0).
6. Na scenie umieść cztery kule. Każdą z nich przeskaluj (2, 2, 2),
a następnie rozmieść je w położeniach (2, 0, –5), (–2, 0, –5), (–2, 2, –5)
i (2, 2, –5).
7. W katalogu Materials utwórz cztery nowe materiały o nazwach
DiffuseBrick, SpecularBrick, BumpedBrick i BumpedSpecularBrick.
Na rysunku 3.9 pokazano wszystkie właściwości tworzonych
materiałów. Ustaw im wartości widoczne na rysunku.

RYSUNEK 3.9.
Właściwości
materiałów

8. Klikaj i przeciągaj materiały na kule, po jednym materiale na każdą


z czterech kul. Zwróć uwagę na sposób, w jaki światło i krzywizny kul
wchodzą w interakcje z różnymi shaderami. Nie zapomnij o możliwości
poruszania się po panelu Scene, co pozwala na oglądanie kul pod
różnymi kątami.
Lekcja 4
Teren

W czasie tej lekcji:


 poznasz podstawy dotyczące terenu,
 dowiesz się, w jaki sposób można rzeźbić teren,
 nauczysz się, jak dekoruje się teren teksturami.
W tej lekcji zajmiesz się generowaniem terenu. Dowiesz się, co to jest teren,
w jaki sposób można go utworzyć oraz jak rzeźbić. Ponadto zajmiesz się
malowaniem teksturą i dostrajaniem. Zobaczysz również, jak budować
ogromne, ekspansywne i realistycznie wyglądające elementy terenu gotowe
do zastosowania w grach.
76 Lekcja 4. Teren

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).

Dodanie terenu do projektu


Utworzenie płaskiego terenu na scenie jest dość łatwym zadaniem, do tego celu
można wykorzystać kilka prostych parametrów. Aby dodać teren do sceny, po
prostu wybierz opcję GameObject/Create Other/Terrain. W ten sposób na scenie
pojawi się obiekt o nazwie Terrain. Jeżeli będziesz się poruszać po panelu
Scene, zauważysz, że teren jest ogromny. W rzeczywistości wymiary terenu
są znacznie większe niż aktualne wymagania gry, dlatego też warto zmodyfi‐
kować jego pewne właściwości.
W celu ułatwienia sobie zadania zarządzania terenem należy najpierw zmienić
rozdzielczość terenu. Modyfikując rozdzielczość, przeprowadzasz zmianę dłu‐
gości, szerokości i maksymalnej wysokości terenu. Użycie pojęcia rozdzielczość
stanie się bardziej oczywiste dalej w tej lekcji, gdy przejdziemy do map wyso‐
kości. Poniżej przedstawiono kroki prowadzące do zmiany rozdzielczości terenu.
1. W panelu Hierarchy zaznacz teren. Następnie w panelu Inspector
odszukaj i kliknij przycisk Terrain Settings.
2. Przejdź do ustawień rozdzielczości — sekcja Resolution
(patrz rysunek 4.1).
3. Aktualna długość i szerokość terenu wynosi 2000. Obie wartości
zmień na 50.
Pozostałe opcje w sekcji Resolution pozwalają na modyfikację sposobu wyświe‐
tlania tekstur oraz określenia wydajności terenu. W tej chwili pozostaw im
wartości domyślne. Po zmianie długości i szerokości terenu zobaczysz, że stał
się mniejszy i tym samym łatwiejszy w zarządzaniu. Teraz możesz przystąpić
do rzeźbienia terenu.
Generowanie terenu 77

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.

Rzeźbienie mapy wysokości


Tradycyjnie obraz 8‐bitowy oferuje 256 odcieni szarości. Odcienie mieszczą
się w zakresie od 0 (czarny) do 255 (biały). Dysponując taką wiedzą, można
przygotować czarno‐biały obraz i użyć go w charakterze mapy wysokości.
Mapa ta zawiera informacje o wysokości terenu i przypomina mapę topogra‐
ficzną. Ciemne punkty oznaczają teren położony niżej, natomiast jasne punkty —
teren położony wyżej. Przykład mapy wysokości pokazano na rysunku 4.2.
Wprawdzie obraz nie wygląda zbyt interesująco, ale tego rodzaju prosta grafika
może pomóc w wygenerowaniu dynamicznej scenerii.
78 Lekcja 4. Teren

RYSUNEK 4.2.
Prosta mapa
wysokości

Nałożenie mapy wysokości na płaski teren jest prostym zadaniem. Pracę


rozpoczynasz od utworzenia płaskiego terenu, a następnie importujesz do niego
mapę wysokości.

 Wypróbuj samodzielnie

Nałożenie mapy wysokości na teren


Oto kroki pozwalające na zaimportowanie i nałożenie mapy wysokości.
1. W materiałach przeznaczonych dla bieżącej lekcji odszukaj plik
terrain.raw i umieść go w łatwo dostępnym miejscu.
2. W panelu Hierarchy zaznacz teren i kliknij przycisk Terrain Settings.
(Jeżeli nie pamiętasz, gdzie się znajduje, spójrz na rysunek 4.1 pokazany
wcześniej w tej lekcji). Następnie w sekcji Heightmap kliknij Import Raw.
3. Na ekranie zostanie wyświetlone okno dialogowe Import Raw
Heightmap. Odszukaj plik terrain.raw z kroku 1. i kliknij przycisk
Open.
4. Na ekranie zostanie wyświetlone okno dialogowe Import Heightmap
(patrz rysunek 4.3). Pozostaw opcje domyślne i kliknij przycisk Import.
Na tym etapie teren wygląda dziwnie. Problem polega na tym, że
podczas zmniejszania długości i szerokości terenu pozostawiłeś jego
domyślną wysokość wynoszącą 600 jednostek. Ta wartość jest —
oczywiście — zbyt duża.
5. Zmień rozdzielczość terenu, przechodząc ponownie do sekcji Resolution
w ustawieniach terenu wyświetlanych w panelu Inspector. Tym razem
wysokość ustaw na 60. Teraz teren powinien wyglądać znacznie
przyjemniej (patrz rysunek 4.4).
Generowanie terenu 79

RYSUNEK 4.3. Okno dialogowe Import Heightmap

RYSUNEK 4.4. Teren po zaimportowaniu mapy wysokości

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

Formaty map wysokości


W środowisku Unity mapy wysokości muszą być czarno-białymi obrazami
zapisanymi w formacie .raw. Istnieje wiele sposobów wygenerowania tego
typu obrazów, można wykorzystać prosty edytor graficzny lub nawet sam
edytor Unity. Jeżeli tworzysz mapę wysokości za pomocą edytora graficz-
nego, spróbuj zachować proporcje mapy wysokości takie same jak proporcje
terenu. W przeciwnym razie pewne zniekształcenia będą nieuniknione. Jeśli
rzeźbisz teren za pomocą narzędzi dostarczanych przez Unity i chcesz dla
tak przygotowanego terenu wygenerować mapę wysokości, przejdź do
sekcji Heightmap w ustawieniach terenu wyświetlanych w panelu Inspector
i kliknij Export Raw.

Narzędzia do rzeźbienia terenu


oferowane przez Unity
Edytor Unity oferuje wiele narzędzi przeznaczonych do rzeźbienia terenu.
Narzędzia te znajdziesz w komponencie Terrain (Script) panelu Inspector.
Działają one na takiej samej zasadzie: za pomocą pędzla o danej wielkości
i sile nacisku „malujesz” teren. W ten sposób w tle tworzysz mapę wysokości,
która następnie jest wykorzystywana do określenia zmian w terenie trójwy‐
miarowym. Malowanie kumuluje się, czyli im dłużej malujesz dany obszar,
tym większy uzyskujesz efekt malowania na tym obszarze. Na rysunku 4.5
pokazano dostępne narzędzia do rzeźbienia terenu. Za ich pomocą możesz
wygenerować praktycznie każdy teren, który sobie wymyślisz.

RYSUNEK 4.5.
Narzędzia
do rzeźbienia
terenu

Pierwsze narzędzie, z którego będziemy korzystać, służy do podnoszenia i obni‐


żania terenu. Zgodnie ze swoją nazwą, narzędzie pozwala na podnoszenie
i obniżanie terenu w miejscu malowania. Aby skorzystać z omawianego narzę‐
dzia, wykonaj poniższe kroki.
1. Wybierz pędzel, który będzie miał wpływ na wielkość i kształt podczas
rzeźbienia.
2. Wybierz wielkość i krycie pędzla. Krycie wskazuje, jak duży wpływ
będzie miał pędzel na rzeźbiony teren.
Generowanie terenu 81

3. Kliknij i przeciągnij myszą nad terenem w panelu Scene, co spowoduje


podniesienie terenu. Przytrzymanie klawisza Shift podczas kliknięcia
i przeciągania myszą powoduje obniżenie terenu.
Na rysunku 4.6 pokazano dobre opcje początkowe przeznaczone do rzeźbienia
terenu o wielkości 50 na 50 i wysokości 60 jednostek.

RYSUNEK 4.6.
Dobre wartości
początkowe
właściwości
rzeźbienia terenu

Następnie przechodzimy do narzędzia przeznaczonego do malowania wznie‐


sień. To narzędzie działa prawie dokładnie tak samo jak omówione powyżej,
ale pozwala na malowanie terenu do wskazanej wysokości. Jeżeli wskazana
wysokość jest większa niż aktualna wysokość terenu, malowanie spowoduje
podniesienie terenu. Jeżeli zaś wskazana wysokość jest mniejsza niż aktualna
wysokość terenu, malowanie spowoduje obniżenie terenu. To narzędzie jest
więc użyteczne podczas tworzenia płaskowyżów lub innych płaskich struktur
krajobrazu. Wypróbuj to narzędzie samodzielnie!

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.

Ostatnie narzędzie służy do wygładzania wzniesień. Nie powoduje zmiany


terenu w bardzo widoczny sposób. Zamiast tego usuwa wiele poszarpanych
linii powstających w trakcie rzeźbienia terenu. Potraktuj je jako rodzaj szli‐
fierki. Z tego narzędzia będziesz korzystać do wprowadzania niewielkich
zmian już po zakończeniu rzeźbienia terenu.
82 Lekcja 4. Teren

 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.

RYSUNEK 4.7. Przykładowy teren


4. Kontynuuj eksperyment z narzędziami i dodawaj kolejne unikalne
elementy terenu.

Praktyka, praktyka i jeszcze raz praktyka


Opracowanie ciekawych i wciągających poziomów gry jest sztuką samą
w sobie. Większość osób sądzi, że wystarczy dodać wzniesienia, doliny, góry
i jeziora. Jednak elementy graficzne muszą być nie tylko atrakcyjne wizu-
alnie, ale również rozmieszczone na scenie w taki sposób, aby umożliwić
grę. Opracowywanie atrakcyjnych poziomów nie jest sztuką, którą można
opanować w jeden dzień. Musisz nieustannie ćwiczyć i rozwijać umiejętności
w tym zakresie, co w efekcie umożliwi tworzenie ekscytujących i nieza-
pomnianych poziomów do gier.
Tekstury terenu 83

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.

Importowanie zasobów terenu


Podobnie jak rzeźbienie terenu, także jego teksturowanie działa na zasadzie
przypominającej malowanie. Wybierasz pędzel i teksturę, a następnie malujesz
teksturą po świecie. Zanim będziesz mógł przystąpić do malowania świata
teksturami, najpierw musisz je przygotować. Środowisko Unity udostępnia
pewne zasoby terenu, ale wcześniej trzeba je zaimportować. W tym celu należy
wybrać opcję Assets/Import Package/Terrain Assets. Na ekranie zostanie wyświe‐
tlone okno dialogowe Importing package, pokazane na rysunku 4.8. W tym
oknie można dokładnie wskazać zasoby, które mają być zaimportowane.
Usunięcie zaznaczenia obok niepotrzebnych elementów jest dobrym pomysłem,
ponieważ pozwala na utrzymanie w ryzach wielkości projektu. W omawianym
przykładzie pozostaw zaznaczone wszystkie opcje i kliknij przycisk Import.
W tym momencie w panelu Project powinieneś zobaczyć nowy podkatalog
o nazwie Standard Assets umieszczony w katalogu Assets. Nowy podkatalog
zawiera wszystkie zasoby terenu, z których skorzystasz w tej lekcji.

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

uwagę na trzy właściwości liczbowe: wielkość pędzla, krycie i krycie maksy‐


malne. Dwie pierwsze właściwości powinny być już znane, natomiast z ostat‐
nią spotykasz się po raz pierwszy. Krycie maksymalne wskazuje maksymalne
krycie, jakie może być osiągnięte podczas równomiernego malowania. Wartość
ta jest wyrażona w procentach, czyli 1 oznacza 100%. Właściwości tej będziemy
używać w celu uniemożliwienia zbyt mocnego malowania teksturą.
W celu wczytania tekstury wykonaj poniższe kroki.
1. Wybierz opcję Edit Textures/Add Texture.
2. Na ekranie zostanie wyświetlone okno dialogowe Add Terrain Texture.
Kliknij przycisk Select w sekcji Texture (patrz rysunek 4.10), a następnie
wybierz teksturę the Grass (Hill).

RYSUNEK 4.10.
Okno dialogowe
Add Terrain
Texture

3. Kliknij przycisk Add.


Na tym etapie cały teren powinien być pokryty niejednolitą trawą. Teren
wygląda znacznie lepiej niż wcześniej, choć nadal jest daleki od realistycznego.
Podsumowanie 85

Możesz więc przystąpić do malowania i tym samym sprawić, aby teren pre‐
zentował się atrakcyjnie.

 Wypróbuj samodzielnie

Malowanie terenu teksturą


Nałożysz teraz teksturę na teren, aby nadać mu znacznie bardziej reali-
styczny wygląd.
1. Za pomocą przedstawionych wcześniej kroków dodaj nową teksturę.
Tym razem wczytaj teksturę o nazwie Grass&Rock. Po wczytaniu tekstury
kliknij ją. (Wybrana tekstura zostanie otoczona niebieską obwódką).
2. Wielkość pędzla ustaw na 30, krycie na 20, a krycie maksymalne na 0.6.
3. Zacznij malować oszczędnie (klikaj i przeciągaj) szczeliny i strome
elementy krajobrazu. W ten sposób powstanie złudzenie, że trawa
nie rośnie na stromych ścianach wzniesień oraz między szczytami
(patrz rysunek 4.11).

RYSUNEK 4.11. Przykład dwutonowego, teksturowanego klifu


4. Kontynuuj eksperyment z malowaniem teksturą. Możesz jeszcze wczytać
teksturę Cliff i nałożyć ją na strome partie krajobrazu, a także dodać
teksturę Sand i utworzyć ścieżkę.

Postępując w przedstawiony powyżej sposób, możesz wczytać wiele tekstur,


aby przygotować realistycznie wyglądający teren. Pamiętaj o ćwiczeniu tekstu‐
rowania, co pozwoli na wypracowanie metod przynoszących najlepsze efekty.

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

Tworzenie tekstur terenu


Światy w grze są bardzo często unikalne i wymagają tekstur pozwalających
dopasować świat do kontekstu, w którym rozgrywa się akcja gry. Możesz
stosować się do ogólnych reguł dotyczących tworzenia własnych tekstur
dla terenu. Oto pierwsza z nich: zawsze próbuj tworzyć wzorzec możliwy
do powielenia. Oznacza to, że teksturę można później ułożyć jedną obok
drugiej, w sąsiedztwie. Im większa tekstura, tym mniej oczywisty wydaje się
system powtarzania. A to druga reguła: tekstury powinny być kwadratowe.
I jeszcze trzecia, ostatnia reguła: staraj się, aby wielkość tekstur była potęgą
liczby 2, np. 32, 64, 128, 512 itd. Dwie ostatnie reguły mają wpływ na
kompresję i efektywność tekstury. Przy odrobinie wprawy będziesz umiał
w bardzo krótkim czasie tworzyć doskonałe tekstury dla tereny.

Subtelność to najlepsze podejście


Podczas teksturowania pamiętaj, aby efekt pozostał subtelny. Większość
elementów natury płynnie przechodzi od jednego do drugiego bez zbyt
wielu gwałtownych przejść. W trakcie teksturowania staraj się to odzwier-
ciedlić. Jeżeli po oddaleniu fragmentu terenu będzie można wyraźnie wska-
zać punkt początkowy tekstury, oznacza to, że efekt jest zbyt mocny.
Bardzo często lepszym rozwiązaniem jest praca z wieloma małymi i sub-
telnymi fragmentami tekstury niż z jednym, ogromnym.

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

W czasie tej lekcji dowiesz się:


 jak dodać do terenu drzewa i trawę,
 jak wprowadzić do terenu efekty środowiska,
 jak poruszać się po świecie za pomocą kontrolera postaci.
W poprzedniej lekcji dowiedziałeś się, jak w grze rzeźbić teren i dodawać
do niego tekstury. Teraz opiszę efekty środowiska, które nadadzą charakter
tworzonemu światu. Na początek poznasz sposoby dodawania do terenu
roślinności, np. drzew i trawy. Następnie nauczysz się definiowania pozo-
stałych efektów środowiska, takich jak woda, niebo, mgła i Lens Flare.
Na koniec umieścisz na scenie kontroler postaci i dowiesz się, jak można
poruszać się po utworzonym świecie 3D.
90 Lekcja 5. Środowisko

Generowanie drzew i trawy


Świat zawierający jedynie płaskie tekstury jest nudny. W naturze praktycznie
w każdym krajobrazie znajdziemy pewne formy roślinności. W tej części lekcji
dowiesz się, jak dodać i dostosować do własnych potrzeb drzewa oraz trawę,
aby umieścić w terenie atrakcyjnie wyglądającą roślinność.

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.

Do umieszczania drzew na pewnym obszarze terenu służy narzędzie o nazwie


Place Trees. Po zaznaczeniu terenu na scenie dostęp do omawianego narzędzia
uzyskasz z poziomu panelu Inspector, a dokładnie w komponencie Terrain
(Script). Na rysunku 5.1 pokazano narzędzie Place Trees i jego standardowe
właściwości.

RYSUNEK 5.1.
Narzędzie
Place Trees

Właściwości narzędzia umożliwiającego tworzenie drzew opisane zostały


w tabeli 5.1.
Generowanie drzew i trawy 91

Tabela 5.1. Właściwości narzędzia Place Trees


Właściwość Opis
Brush Size Wielkość obszaru, na którym podczas malowania będą
dodawane drzewa.
Tree Density Właściwość określa gęstość występowania drzew.
Color Variation, Właściwości powodują, że poszczególne drzewa różnią
Tree Height/ się między sobą. W ten sposób uzyskujemy wrażenie,
Width że na terenie znajduje się wiele różnych drzew, a nie jedno
i Variations zmultiplikowane.

 Wypróbuj samodzielnie

Umieszczanie drzew w terenie


Poniżej zostały przedstawione kroki pozwalające na umieszczenie drzew
w terenie za pomocą narzędzia o nazwie Paint Trees. W tym ćwiczeniu przy-
jęto założenie, że utworzyłeś nową scenę i dodałeś teren. Wielkość wspo-
mnianego terenu powinna wynosić 100 na 100 jednostek. Znacznie lepszy
efekt można uzyskać, gdy teren jest już wyrzeźbiony i pokryty teksturą.
1. Wybierz opcję Edit Trees/Add Tree, co spowoduje wyświetlenie
pokazanego wcześniej na rysunku 5.1 okna dialogowego Add Tree.
2. Kliknij małą ikonę kółka znajdującą się po prawej stronie pola tekstowego
Tree (patrz rysunek 5.2). To spowoduje wyświetlenie okna dialogowego
Tree Selector.

RYSUNEK 5.2. Okno dialogowe Add Tree


3. Wybierz Palm Tree, a następnie kliknij Add.
4. Ustaw wielkość pędzla na 10, gęstość drzew na 70, a wysokość
i szerokość na 50. Ponadto wybierz dowolne właściwości różnicowania
drzew.
5. Namaluj drzewa w terenie, klikając i przeciągając myszą na obszarze,
na którym mają się znaleźć. Przytrzymanie klawisza Shift podczas
kliknięcia i przeciągnięcia spowoduje usunięcie drzew.
6. Kontynuuj eksperyment, zmieniając wielkość pędzla, gęstość
umieszczania drzew oraz właściwości ich różnicowania.
92 Lekcja 5. Środowisko

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.

Zmiana wyglądu drzew


Kiedy będziesz poruszać się po panelu Scene, możesz zauważyć, że pewne
drzewa ulegają zmianie. To skutek działania wbudowanych w Unity opty-
malizacji mających na celu szybszą pracę projektu. Gdy drzewo znajduje
się daleko od obserwatora, jest generowanie jako znacznie niższej jakości
billboard. Kiedy obserwator zbliża się do drzewa, będzie ono zastąpione
wersją wysokiej jakości. Efektem jest zmiana oglądanych drzew. Masz moż-
liwość wpływu na miejsce i sposób przeprowadzenia wspomnianej zmiany,
odbywa się to za pomocą modyfikowania pewnych ustawień terenu. Do
tego tematu powrócimy w tej lekcji.

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

3. Ustaw właściwości tekstury wedle własnych upodobań. Szczególną


uwagę zwróć na właściwości związane z kolorem, ponieważ określają
one zakres naturalnych kolorów trawy.
4. Po zakończeniu ustawień kliknij Add.
Gdy wczytasz teksturę trawy, pozostanie już tylko wybranie pędzla oraz
określenie jego właściwości. Teraz jesteś gotowy do rozpoczęcia malowania
trawą.
94 Lekcja 5. Środowisko

Realistycznie wyglądająca trawa


Być może zauważyłeś, że gdy rozpoczynasz malowanie trawą, efekt nie
wygląda zbyt realistycznie. Podczas dodawania trawy do terenu musisz
skoncentrować się na kilku kwestiach. Przede wszystkim zwróć uwagę na
kolory wybrane w teksturze trawy. Postaraj się, aby były ciemne i bardziej
dopasowane do ziemi. Kolejna kwestia to wybór niegeometrycznego kształtu
pędzla, bo wtedy unikniesz ostrych krawędzi (na rysunku 5.3 pokazano
dobry pędzel do malowania trawą). Ostatnia kwestia to stosowanie niskich
wartości właściwości krycia i krycia maksymalnego. Dobre ustawienie na
początek wynosi 0.02. Jeżeli potrzebujesz większej ilości trawy, ten sam
obszar możesz malować wielokrotnie.

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

Tabela 5.2. Podstawowe ustawienia terenu


Ustawienie Opis
Pixel Error Liczba dozwolonych błędów podczas wyświetlania
geometrii terenu. Im większa liczba błędów, tym niższy
poziom szczegółowości terenu.
Base Map Dist. Maksymalna odległość od obserwatora, na jakiej będą
wyświetlane tekstury wysokiej rozdzielczości. Gdy
obserwator znajdzie się w większej odległości, będą
stosowane tekstury niższej rozdzielczości.
Cast shadows Właściwość określa, czy geometria terenu rzuca cienie.
Material Ten slot pozwala na przypisanie własnego materiału,
za pomocą którego można wygenerować teren. Materiał
musi zawierać shader generujący teren.

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

Tabela 5.3. Ustawienia obiektów drzewa i mniejszej roślinności


Ustawienie Opis
Draw Ustawienie określa, czy drzewa i mniejsza roślinność
będą wygenerowane na scenie.
Detail Distance Odległość od kamery, po przekroczeniu której mniejsza
roślinność nie będzie generowana na scenie.
Tree Distance Odległość od kamery, po przekroczeniu której drzewa
nie będą generowane na scenie.
Billboard Start Odległość od kamery, po przekroczeniu której modele
drzew 3D będą zamieniane na billboardy o mniejszej
jakości.
Fade Length Odległość, na przestrzeni której drzewa zaczną być
zmieniane z billboardów na modele 3D o wyższej jakości.
Im większa odległość, tym bardziej płynne przejście.
Max Mesh Trees Całkowita liczba drzew, które mogą być jednocześnie
wyświetlane jako siatki trójwymiarowe, a nie billboardy.

Tabela 5.4. Ustawienia wiatru


Ustawienie Opis
Speed Szybkość, a tym samym siła wiatru.
Size Wielkość obszaru trawy, na który wpływ będzie miał
wiatr w danej chwili.
Bending Stopień kołysania się trawy na skutek wiatru.
Grass Tint Wprawdzie to nie jest ustawienie dotyczące wiatru,
ale określa ogólne zabarwienie całej trawy na danym
poziomie.

Symulacja nieba i horyzontu


Pewnie zauważyłeś, że wprawdzie teren jest teksturowany i zawiera sporą
ilość detali, ale niebo nadal jest w jednolitym kolorze. Rozwiązaniem jest doda‐
nie do tworzonego świata symulacji nieba. Jest to po prostu ogromny sześcian
otaczający cały świat budowany w Unity. Choć to sześcian składający się
z sześciu płaskich ścian, ale posiada zwrócone do wewnątrz tekstury, dzięki
którym niebo wygląda na zaokrąglone i nieskończone. Masz możliwość opra‐
cowania własnej symulacji nieba i horyzontu bądź też użycia jednej ze stan‐
dardowo oferowanych przez Unity. W tej książce skorzystasz z wbudowanych
symulacji nieba i horyzontu.
Aby zastosować wbudowaną symulację nieba i horyzontu, musisz najpierw
zaimportować zasoby do projektu. Wybierz opcję Assets/Import Package/
Skyboxes. Na ekranie zostanie wyświetlone okno dialogowe Import Package.
Efekty środowiska 97

Pozostaw zaznaczone wszystkie opcje, a następnie kliknij Import. Po zaim‐


portowaniu zasobów będziesz mógł przystąpić do pracy z symulacją nieba
i horyzontu.
Istnieją dwa sposoby dodania symulacji nieba i horyzontu do tworzonego
świata: dodanie do kamery lub umieszczenie na scenie.

Dodanie symulacji nieba do kamery


Kiedy dodasz symulację nieba do kamery, wszystko widziane przez kamerę
i nienależące do świata gry zostanie zastąpione przez symulację nieba. Poniżej
wymieniono kroki pozwalające na dodanie symulacji nieba do kamery.
1. W panelu Hierarchy wybierz Main Camera.
2. Dodaj komponent nieba, wybierając opcję Component/Rendering/
Skybox.
3. W panelu Inspector odszukaj komponent Skybox, a następnie
kliknij małą ikonę okręgu wyświetlaną obok pola Custom Skybox
(patrz rysunek 5.6). W oknie dialogowym Select Material wybierz
Sunny2 Skybox.

RYSUNEK 5.6.
Komponent
Skybox
4. Uruchom scenę i sprawdź, jak symulacja nieba została dodana
do kamery.

Wiele symulacji nieba


Powodem istnienia opcji pozwalającej na dodanie symulacji nieba do wybra-
nej kamery jest umożliwienie udostępniania różnych symulacji nieba (lub
ich braku) poszczególnym kamerom. W ten sposób świat może wyglądać
odmiennie dla różnych obserwatorów. Jeżeli chcesz zachować elastyczność
wyglądu świata, wtedy symulację nieba dodaj do kamery. Jeśli natomiast
świat ma wyglądać jednakowo dla każdego, symulację nieba dodaj do sceny,
co zostanie omówione w kolejnym podpunkcie.

Dodanie symulacji nieba do sceny


Gdy symulację nieba dodasz do sceny, stanie się widoczna dla wszystkich
obserwatorów. Inną zaletą tej metody jest fakt, że symulacja nieba będzie
widoczna w panelu Scene. Dzięki temu można się bardzo łatwo przekonać, jak
wszystkie elementy świata komponują się ze sobą. Aby dodać symulację nieba
do sceny, należy wykonać wymienione poniżej kroki.
1. Wybierz opcję Edit/Render Settings w celu wyświetlenia w panelu
Inspector ustawień generowania sceny.
2. Odszukaj pole Skybox Material, a następnie kliknij znajdującą się obok
po prawej stronie ikonę okręgu.
98 Lekcja 5. Środowisko

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

Dodanie mgły do sceny


Poniżej przedstawiono kroki pozwalające na dodanie mgły do sceny. Dalej
znajdziesz różne właściwości, które mają wpływ na tworzoną mgłę.
1. Wybierz opcję Edit/Render Settings. W panelu Inspector zostaną
wyświetlone ustawienia generowania sceny.
2. Włącz mgłę przez zaznaczenie pola wyboru Fog.
3. Poeksperymentuj z różnymi kolorami i gęstościami mgły. Poszczególne
właściwości mgły zostały wymienione w tabeli 5.5.

Kilka właściwości ma wpływ na wygląd mgły na scenie. Przedstawiono je


w tabeli 5.5.

Tabela 5.5. Właściwości dotyczące mgły


Właściwość Opis
Fog Color Kolor generowanej mgły.
Fog Mode Właściwość określa sposób generowania mgły.
Dostępne są trzy tryby: Linear, Exponential i Exp2.
Tryb Linear zapewnia płynne przejście do mgły
i jest trybem domyślnym.
Fog Density Właściwość określa siłę efektu mgły. Jest używana
tylko wtedy, gdy wybrany tryb mgły to Exponential
lub Exp2.
Linear Fog Start, Właściwości określają, w jakiej odległości od kamery
Linear Fog End mgła się rozpoczyna oraz w jakiej kończy.
Efekty środowiska 99

Efekt Lens Flare


Efekt Lens Flare to wizualna deformacja powstająca, gdy kamera jest wysta‐
wiona na działanie jasnego źródła światła. Wynikiem jest załamanie światła
w szkle obiektywu. Omawiany efekt może również powstać, gdy spróbujesz
spojrzeć na jasne źródło światła, takie jak słońce (zdecydowanie odradzam
taką próbę). W środowisku Unity można dodawać opcję Lens Flare do źródeł
światła, aby uzyskać znacznie bardziej realistyczny efekt. Wydaje się wówczas,
że źródło światła jest bardzo jasne.

 Wypróbuj samodzielnie

Dodanie efektu Lens Flare do sceny


Zastosowanie efektu Lens Flare na scenie stanie się łatwiejsze, jeśli postarasz
się wykonać przedstawione tutaj kroki. Samo dodanie efektu Lens Flare jest
proste, ale opiera się na kilku nowych elementach, których jeszcze możesz
nie znać. Zanim będziesz mógł dodać omawiany efekt na scenie, konieczne
jest przygotowanie źródła światła oraz kilku zasobów. Wszystko uwzględ-
niono w poniższych krokach.
1. Dodaj światło kierunkowe do sceny, wybierając opcję GameObject/Create
Other/Directional Light. Szczegółowe omówienie światła znajdziesz
w kolejnej lekcji. Teraz pamiętaj jedynie, że światło kierunkowe jest
światłem równoległym, podobnie jak słońce.
2. Po dodaniu światła do sceny obróć je, aby w oczekiwany sposób
oświetlało teren.
3. Teraz będą potrzebne zasoby efektu Lens Flare. Zaimportuj je w edytorze
Unity, klikając Assets/Import Package/Light Flares. W wyświetlonym
oknie dialogowym Import pozostaw zaznaczone wszystkie opcje i kliknij
przycisk Import.
4. W panelu Hierarchy wybierz światło kierunkowe, a następnie w panelu
Inspector odszukaj właściwość Flare.
5. Kliknij ikonę okręgu obok właściwości Flare, w wyświetlonym oknie
dialogowym Select Flare wybierz Sun.

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

Gdzie mogę zobaczyć efekt Lens Flare?


Być może nie będziesz w stanie zobaczyć efektu Lens Flare, ponieważ
kamera nie jest skierowana do źródła światła. Nie przejmuj się teraz kie-
rowaniem kamery na światło. Dalej w tej lekcji dowiesz się, jak poruszać się
po scenie. W ten sposób będziesz mógł wprowadzić wszelkie konieczne
poprawki w ustawieniach sceny.

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

Utworzenie jeziora i dodanie wody


W celu dodania wody trzeba odpowiednio przygotować fragment terenu.
W tym ćwiczeniu wyrzeźbisz jezioro i dodasz wodę.
1. Utwórz nowy teren lub wykorzystaj istniejący. W terenie wyrzeźb nieckę
jeziora.
2. Zaimportuj zasoby wody, klikając Assets/Import Package/Water (Basic).
W oknie dialogowym Import Package pozostaw zaznaczone wszystkie
opcje i kliknij przycisk Import.
3. W panelu Project odszukaj katalog Water (Basic), a następnie zasób
Daylight Simple Water (patrz rysunek 5.8).

RYSUNEK 5.8. Katalog Water (Basic) i zasoby


4. Przeciągnij zasób Daylight Simple Water na panel Scene i umieść
w miejscu przygotowanym dla jeziora. Odpowiednio przeskaluj
i przesuń wodę, aby całkowicie wypełniła jezioro.
Kontroler postaci 101

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.

Dodanie kontrolera postaci


Aby dodać kontroler postaci do sceny, najpierw trzeba zaimportować zasoby.
Kliknij Assets/Import Package/Character Controller. W oknie dialogowym
Import Package pozostaw zaznaczone wszystkie opcje i kliknij przycisk Import.
Nowy podkatalog o nazwie Character Controller powinien pojawić się w panelu
Project, w katalogu Standard Assets. Ponieważ nie mamy jeszcze modelu 3D do
użycia w charakterze gracza, wykorzystamy kontroler First Person. W katalogu
Character Controller odszukaj kontroler First Person (patrz rysunek 5.9),
a następnie przeciągnij go na teren w panelu Scene.

RYSUNEK 5.9.
Kontroler postaci
First Person

Po dodaniu kontrolera postaci do sceny można przystąpić do poruszania się po


utworzonym terenie. Podczas testowania sceny łatwo zauważysz, że obser‐
wujesz krajobraz z miejsca, w którym umieściłeś kontroler. Do poruszania
się po scenie służą klawisze WASD, mysz pozwala na rozglądanie się, a kla‐
wisz spacji umożliwia skakanie. Zapoznaj się z kontrolkami nawigacyjnymi,
jeśli wydają Ci się nieco nietypowe, a następnie spróbuj przemieszczać się po
utworzonym świecie.

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

Komunikat „2 Audio Listeners”


Po dodaniu kontrolera postaci do sceny na dole okna edytora może poja-
wić się komunikat o treści „There are 2 audio listeners in the scene” (na scenie
znajdują się dwa komponenty Audio Listener). Komunikat jest wyświetlany,
ponieważ kamera istniejąca domyślnie (Main Camera) zawiera komponent
Audio Listener, podobnie jak dodany kontroler postaci. Skoro kamery przed-
stawiają perspektywę gracza, tylko jeden komponent może nasłuchiwać
audio. Rozwiązaniem jest usunięcie z kamery Main Camera komponentu
Audio Listener.

Przejście przez świat


Jeżeli okaże się, że kamera „przechodzi” przez świat, gdy tylko uruchomisz
scenę, oznacza to, że kontroler postaci prawdopodobnie jest częściowo
zablokowany na podłożu. Spróbuj nieco podnieść kontroler postaci ponad
podłoże. Po uruchomieniu sceny kamera powinna lekko opaść, aż dotknie
podłoża i tam się zatrzyma

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.

odpowiednia chwila na dopracowanie terenu i usunięcie wszelkich znalezionych


błędów. W panelu Scene zobaczenie wszystkich miejsc wymagających korekty
będzie trudne. Trudność znika, gdy zaczniesz poruszać się po zbudowanym
terenie i będziesz mógł go faktycznie wypróbować.
Jedna z poprawek wartych wprowadzenia dotyczy dodanego wcześniej efektu
Lens Flare. Jeżeli spojrzysz w niebo, dostrzeżesz, że słońce jest częścią tek‐
stury symulacji nieba. Możesz również zobaczyć wspomniany efekt Lens Flare.
Istnieje prawdopodobieństwo, że efekt Lens Flare symulujący słońce i samo
słońce nie są wyrównane. Patrząc na słońce i utworzony efekt, wstrzymaj
działanie sceny. Pamiętaj, że zatrzymanie sceny za pomocą myszy może być
trudne, gdy patrzysz na konkretny element. Na szczęście, do dyspozycji masz
skrót klawiszowy Shift+Ctrl+P (w Macu Shift+Cmd+P). W panelu Scene obracaj
źródło światła aż do chwili, gdy obraz słońca i efektu Lens Flare zostaną wyrów‐
nane. Zapisz informacje o rotacji, ponieważ po zakończeniu działania sceny
wszelkie modyfikacje zostaną utracone. Po zakończeniu działania sceny po
Podsumowanie 103

prostu zmień rotację światła zgodnie z zapisanymi informacjami, a słońce


będzie wyrównane z efektem Lens Flare. W ten sposób z listy rzeczy do zrobie‐
nia możesz skreślić kolejny element.

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

3. Ten obiekt jest sześcianem zawierającym tworzony świat, a jego


tekstury wyglądają jak niebo. Co to jest?
4. Który kontroler postaci dodałeś do sceny, First Person czy Third Person?

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

W czasie tej lekcji:


 dowiesz się, jak używać światła w edytorze Unity,
 poznasz podstawowe elementy kamery,
 nauczysz się pracować z wieloma kamerami na scenie,
 zobaczysz, jak korzystać z warstw.
W tej lekcji dowiesz się, jak stosować w środowisku Unity światła i kamery.
Na początek zapoznasz się z podstawowymi funkcjami związanymi ze
światłem. Następnie przejdziesz do różnych typów światła oraz ich uni-
kalnego przeznaczenia. Gdy zakończysz poznawanie światła, kolejnym
omawianym tematem będzie praca z kamerą. Dowiesz się, jak dodać do
sceny nową kamerę, a także jak za pomocą kamery osiągnąć interesujące
efekty. Na końcu lekcji przeczytasz o warstwach w edytorze Unity.
106 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.

Powtarzające się właściwości


Poszczególne rodzaje światła współdzielą wiele tych samych właściwości.
Jeżeli światło ma właściwość omówioną dla innego rodzaju światła, nie
będę ponownie jej prezentować. Pamiętaj po prostu, że jeśli dwa różne
typy światła mają właściwości o takich samych nazwach, to sposób dzia-
łania tych właściwości jest identyczny.

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.

Tabela 6.1. Właściwości światła punktowego


Właściwość Opis
Type Właściwość wskazuje typ światła komponentu Ligth.
Ponieważ dodaliśmy światło punktowe, wartością
właściwości powinna być opcja Point. Zmiana
tej właściwości prowadzi do zmiany typu światła.
Światło 107

Tabela 6.1. Właściwości światła punktowego — ciąg dalszy


Właściwość Opis
Range Właściwość określa, jak daleko światło będzie świeciło.
Iluminacja będzie równomiernie zanikać od źródła światła
do końca podanego tutaj zakresu.
Color Właściwość określa kolor światła. Kolory mogą się mieszać.
Dlatego też, jeśli czerwonym światłem oświecasz niebieski
obiekt, będzie miał kolor purpurowy.
Intensity Właściwość określa jasność światła. Pamiętaj, że światło
świeci jedynie w zakresie wskazanym we właściwości
Range.
Cookie Właściwość akceptuje mapę sześcianu (podobną
do symulacji nieba), która określa wzorzec dla światła.
Dokładniejsze omówienie tej właściwości znajdziesz
dalej w tej lekcji.
Shadow Type Właściwość wskazuje sposób generowania cieni
dla danego źródła światła na scenie. Twarde cienie
są znacznie dokładniejsze i nie mają zbyt dużego wpływu
na wydajność. Wszystkie cienie wymagają użycia wersji
Unity Pro. Jeżeli korzystasz z wersji Unity Free, jedynym
sposobem uzyskania cieni jest ręczne ich wypalenie
w teksturach.
Draw Halo Właściwość określa, czy efekt świecącej aureoli będzie
występował wokół światła. Ten efekt zostanie dokładniej
omówiony dalej w tej lekcji.
Flare Właściwość akceptuje zasób flary światła i symuluje efekt
jasnego światła, które świeci w obiektyw kamery. Efekt
Lens Flare dla światła wykorzystałeś w poprzedniej lekcji
do symulacji efektu słońca.
Render Mode Właściwość wskazuje wagę danego światła i może przyjąć
jedną z trzech opcji: Auto, Important i Not Important.
Światło uznawane za ważne jest generowane w wyższej
jakości, podczas gdy mniej ważne światło jest generowane
znacznie szybciej.
Culling Mask Właściwość określa warstwy, na które wpływ ma światło.
Domyślnie światło ma wpływ na wszystkie warstwy.
Do tematu warstw powrócę dalej w tej lekcji.
Lightmapping Właściwość wskazuje, czy światło będzie obliczane w czasie
rzeczywistym, czy zostanie osadzone w postaci mapy
światła. To skomplikowana właściwość, której na obecnym
etapie nie potrzebujesz. Pozostaw tutaj wybraną opcję
Auto.
108 Lekcja 6. Światła i kamery

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

Dodanie światła punktowego do sceny


Przygotujesz teraz scenę wraz z dynamicznym oświetleniem punktowym.
Ukończoną wersję projektu znajdziesz w katalogu Hour6_PointLight
w materiałach przeznaczonych dla bieżącej lekcji.
1. Utwórz nową scenę lub projekt.
2. Do sceny dodaj płaszczyznę (wybierz opcję GameObject/Create
Other/Plane). Upewnij się, że płaszczyzna została umieszczona
w położeniu (0, 0.5, 0) i zastosowano dla niej rotację (270, 0, 0).
Płaszczyzna powinna być widoczna dla kamery.
3. Na scenie umieść dwa sześciany w położeniach (–1.5, 1, –5) i (1.5, 1, –5).
4. Do sceny dodaj światło punktowe (wybierz opcję GameObject/Create
Other/Point Light) i umieść je w położeniu (0, 1, –5). Zwróć uwagę,
że — jak pokazano na rysunku 6.1 — światło oświetla wewnętrzne
ściany sześcianów oraz płaszczyznę znajdującą się w tle.

RYSUNEK 6.1. Wynik wykonania omawianego ćwiczenia


5. Kontynuuj poznawanie właściwości światła. Nie zapomnij
poeksperymentować z kolorem światła, jego zakresem i intensywnością.
Światło 109

Reflektor (ang. spotlight) działa podobnie jak światła pozycyjne w samochodzie


lub latarka. Źródło światła reflektora mieści się w pewnym punkcie centralnym,
a następnie rozchodzi w postaci stożka. Innymi słowy, reflektor oświetla to,
co się przed nim znajduje, a resztę pozostawia w ciemnościach. W przeciwień‐
stwie do światła punktowego równomiernie świecącego we wszystkich kie‐
runkach, światło reflektora można skierować na wybrany obiekt.
W celu dodania reflektora do sceny wybierz opcję GameObject/Create
Other/Spotlight. Ewentualnie, jeśli na scenie znajduje się inne światło, jego typ
można zmienić na Spot. W ten sposób istniejące światło zmieni się w reflektor.
Światło typu reflektor ma jedną nieomówioną dotąd właściwość, czyli Spot
Angle. Właściwość ta określa promień stożka światła emitowanego przez
reflektor.

 Wypróbuj samodzielnie

Dodanie reflektora do sceny


Teraz masz szansę na pracę z reflektorami w Unity. W celu zachowania zwię-
złości w tym ćwiczeniu wykorzystasz projekt pochodzący z poprzedniego
ćwiczenia dotyczącego światła punktowego. Jeżeli nie wykonałeś tamtego
ćwiczenia, musisz to zrobić teraz. Ukończoną wersję projektu znajdziesz
w katalogu Hour6_SpotLight w materiałach przeznaczonych dla bieżącej
lekcji.
1. Otwórz poprzednio utworzony projekt.
2. W panelu Hierarchy prawym przyciskiem myszy kliknij Point Light
i wybierz opcję Rename. Nazwę obiektu zmień na Spotlight. Następnie
w panelu Inspector wartość właściwości Type zmień na Spot. Reflektor
umieść w położeniu (0, 1, –13).
3. Poeksperymentuj z właściwościami reflektora. Zwróć uwagę, jak zakres,
intensywność i kąt strumienia światła wpływają na oświetlanie sceny
reflektorem.

Ś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

Światło kierunkowe ma jedną nieomówioną dotąd właściwość, czyli Cookie


Size. Właściwość zostanie dokładnie omówiona dalej w tej lekcji. Określa ona
wielkość cookie („ciasteczka”), a tym samym liczbę jego powtórzeń na scenie.

 Wypróbuj samodzielnie

Dodanie światła kierunkowego do sceny


Teraz dodasz światło kierunkowe do sceny. To ćwiczenie również jest oparte
na projekcie pochodzącym z poprzedniego ćwiczenia, dotyczącego reflek-
tora. Jeżeli nie wykonałeś tamtego ćwiczenia, musisz to zrobić teraz, aby
wykonać bieżące. Ukończoną wersję projektu znajdziesz w katalogu Hour6_
DirectionLight w materiałach przeznaczonych dla bieżącej lekcji.
1. Otwórz poprzednio utworzony projekt.
2. W panelu Hierarchy prawym przyciskiem myszy kliknij Spotlight i wybierz
opcję Rename. Nazwę obiektu zmień na Directional Light. Następnie
w panelu Inspector wartość właściwości Type zmień na Directional.
Rotację światła ustal na (75, 0, 0).
3. Zwróć uwagę, jak światło oświetla obiekty znajdujące się na scenie.
Następnie zmień położenie światła na (50, 50, 50). Zauważ, że sposób
oświetlenia sceny nie zmienił się. Ponieważ światło kierunkowe świeci
równomiernie, położenie nie ma znaczenia. Tylko rotacja światła
kierunkowego może coś zmienić w sposobie oświetlenia sceny.
4. Poeksperymentuj z właściwościami światła kierunkowego. W tym typie
światła nie ma zakresu (lub inaczej jest on nieskończony), ale sprawdź,
jak kolor światła i jego intensywność wpływają na oświetlenie sceny.

Wyróżnienie: światło powierzchniowe


Istnieje jeszcze jeden typ światła, który nie został omówiony w lekcji; jest
to światło powierzchniowe. Światło to jest dostępne jedynie w wersji Unity
Pro i służy do obsługi procesu o nazwie wypalanie mapy światła. Ten temat
znacznie wykracza poza zakres omawiany w książce, a sam proces nie jest
potrzebny w projektach prostych gier. Jeżeli chcesz się dowiedzieć więcej,
zajrzyj do oferowanej w internecie dokumentacji środowiska Unity.

Tworzenie światła z dowolnego obiektu


Ponieważ w środowisku Unity światło jest komponentem, dowolny obiekt na
scenie może być światłem. W celu dodania światła do obiektu najpierw zaznacz
obiekt. Następnie w panelu Inspector kliknij przycisk Add Component. Na ekra‐
nie powinna zostać wyświetlona lista; z niej wybierz Rendering i później Light.
W ten sposób obiekt otrzyma komponent światła. Alternatywnym sposobem
dodania światła do obiektu jest zaznaczenie obiektu, a następnie wybór opcji
Component/Rendering/Light.
Światło 111

Warto wspomnieć o kilku kwestiach związanych z dodaniem światła do obiektu.


Po pierwsze, obiekt nie blokuje światła. Oznacza to, że umieszczenie światła
wewnątrz sześcianu nie uniemożliwia emisji światła. Po drugie, dodanie
światła do obiektu nie powoduje, że obiekt będzie świecił. Sam obiekt nie
będzie wyglądał, jakby emitował światło, choć w rzeczywistości tak właśnie
będzie.

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

Na wielkość aureoli wpływ ma zakres zdefiniowany dla danego światła. Im


większy zakres, tym większa aureola. Edytor Unity zawiera kilka właściwości
dotyczących aureoli umieszczonych na scenie. Dostęp do wspomnianych wła‐
ściwości uzyskasz, wybierając opcję Edit/Render Settings. Odpowiednie opcje
zostaną wyświetlone w panelu Inspector (patrz rysunek 6.3).

RYSUNEK 6.3.
Ustawienia
generowania
aureoli

Właściwość o nazwie Halo Strength określa wielkość aureoli na podstawie


zakresu światła. Jeśli np. zakres światła wynosi 10, a wartość omawianej
właściwości 1, wtedy aureola zostanie utworzona na wszystkich 10 jednostkach.
Jeżeli wartością Halo Strength będzie 0.5, wtedy w omawianym przykładzie
aureola będzie miała wielkość 5 jednostek (10  0.5 = 5). Z kolei właściwość
Halo Texture pozwala na wskazanie innego kształtu dla aureoli za pomocą nowej
tekstury. Jeżeli dla tworzonej aureoli nie chcesz wykorzystać własnej tekstury,
możesz z niej zrezygnować, a wtedy użyta zostanie domyślna w postaci okręgu.

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

Dodanie cookie do reflektora


W tym ćwiczeniu dodasz cookie do reflektora. Dzięki temu poznasz od
początku do końca proces dodawania cookie. To ćwiczenie wymaga pliku
biohazard.png, który znajdziesz w materiałach przeznaczonych dla bieżą-
cej lekcji.
1. Utwórz nowy projekt lub scenę. Dodaj płaszczyznę, umieść
ją w położeniu (0, 1, 0) i zastosuj dla niej rotację (270, 0, 0).
2. Dodaj reflektor do kamery Main Camera. W tym celu zaznacz Main
Camera, kliknij Component/Rendering/Light i zmień typ na Spot. Zakres
reflektora ustaw na 18, kąt na 40, natomiast intensywność na 3.
3. Teksturę biohazard.png przeciągnij do panelu Project. Zaznacz teksturę
w panelu Inspector i zmień jej typ na Advanced. Zaznacz pola wyboru
Alpha from Grayscale i Border Mip Maps. Następnie we właściwości
Wrap wybierz opcję Clamp i kliknij przycisk Apply. Jeżeli nie jesteś
pewien poprawności ustawień, spójrz na rysunek 6.4.
114 Lekcja 6. Światła i kamery

4. Mając zaznaczoną kamerę Main Camera, kliknij i przeciągnij 


teksturę biohazard.png na właściwość Cookie komponentu światła.
Powinieneś zobaczyć wyświetlony na płaszczyźnie symbol zagrożenia
ze strony organizmów żywych (patrz rysunek 6.5).

RYSUNEK 6.5. Użycie reflektora wraz z cookie


5. Poeksperymentuj z różnymi zakresami i intensywnością światła. Spróbuj
obrócić płaszczyznę i zobacz, jak zmienia się sposób wyświetlania
symbolu.

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

Tabela 6.2. Właściwości kamery


Właściwość Opis
Clear Flags Właściwości określa, co kamera będzie wyświetlała
na obszarach, na których nie znajdują się obiekty gry.
Domyślnie to będzie symulacja nieba. Kiedy nie ma
symulacji nieba, kamera będzie wyświetlała jednolity
kolor. Opcji Depth Only należy używać tylko wtedy, kiedy
na scenie istnieje wiele kamer. Z kolei opcja Don’t Clear
powoduje smużenie i dlatego należy ją stosować,
gdy tworzy się własny shader.
Background Właściwość ustala kolor tła, jeśli nie jest używana
symulacja nieba.
Culling Mask Właściwość wskazuje warstwy, które będą uwzględniane
przez kamerę. Domyślnie kamera widzi wszystko. Możesz
usunąć zaznaczenie obok nazw warstw (do warstw
wkrótce wrócę), a wtedy pozostaną one niewidoczne
dla kamery.
Projection Właściwość określa sposób postrzegania świata
przez kamerę. Dostępne są dwie opcje, Perspective
i Orthographic. Po wybraniu pierwszej z nich świat
postrzegany jest w trójwymiarze, w którym obiekty
znajdujące się bliżej są większe, natomiast oddalone
obiekty są małe. Tę opcję należy wybrać, jeśli głębia
ma zostać uwzględniona w grze. Z kolei druga
z wymienionych opcji ignoruje głębię i traktuje wszystkie
obiekty jak płaskie.
Field of View Właściwość określa, jak szeroki obszar kamera może
widzieć.
Clipping Planes Właściwość wskazuje zakres, w którym obiekty
są widoczne dla kamery. Obiekty znajdujące się bliżej
niż najbliższa płaszczyzna lub dalej niż najdalsza
płaszczyzna będą niewidoczne.
Normalized Właściwość określa, która część rzeczywistego ekranu jest
View Port Rect widoczna dla kamery. Domyślnie opcje X i Y mają wartość
0, czyli kamera widzi wszystko, począwszy od lewego
górnego rogu ekranu. Wysokość i szerokość mają
wartość 1, czyli kamera pokrywa 100% powierzchni
ekranu. Do tej właściwości jeszcze powrócę.
Depth Właściwość wskazuje priorytet w przypadku istnienia
wielu kamer. Kamera o niższym priorytecie
jest generowana jako pierwsza. Kamery o wyższym
priorytecie mogą być generowane na tych o niższym,
a tym samym będą mogły je przykrywać.
116 Lekcja 6. Światła i kamery

Tabela 6.2. Właściwości kamery — ciąg dalszy


Właściwość Opis
Rendering Path Właściwość określa sposób generowania widoku przez
kamerę. Należy tutaj pozostawić opcję Use Player Settings.
Target Texture Właściwość pozwala na wskazanie dla kamery tekstury,
która będzie wygenerowana zamiast ekranu. Obsługa tego
rodzaju tekstur jest funkcją wersji Unity Pro.
HDR Właściwość określa, czy wewnętrzne obliczenia światła
w Unity są ograniczone do podstawowego zakresu
kolorów. Omawiana właściwość pozwala na osiągnięcie
zaawansowanych efektów wizualnych. Na razie pozostaw
ją bez zmian.

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.

Wiele komponentów Audio Listener


Jak wcześniej wspomniano, na scenie może znajdować się tylko jeden kom-
ponent Audio Listener. W starszych wersjach Unity umieszczenie dwóch lub
większej liczby wymienionych komponentów powodowało wygenerowanie
błędu i uniemożliwiało uruchomienie sceny. Natomiast w Unity 4 posia-
danie wielu komponentów Audio Listener na scenie powoduje jedynie
wyświetlenie komunikatu ostrzeżenia, choć dźwięk może nie być prawidłowo
odtwarzany. Do tego tematu powrócę jeszcze dalej w tej książce.

Podział ekranu oraz funkcja PiP


Jak się wcześniej przekonałeś, posiadanie wielu kamer na scenie nie przynosi
zbyt wielu korzyści, jeśli poszczególne kamery są po prostu nakładane na
siebie. W tej części lekcji dowiesz się, jak używać właściwości Normalized View
Port Rect do osiągnięcia efektu podziału ekranu, a także efektu PiP.
Właściwość Normalized View Port Rect traktuje ekran jak zwykły prostokąt.
Lewy górny róg prostokąta to (0, 0), natomiast prawy dolny to (1, 1). To
Warstwy 117

 Wypróbuj samodzielnie

Praca z wieloma kamerami


Najlepszym sposobem na zrozumienie, jak wiele kamer może ze sobą
współpracować, jest wykorzystanie kilku kamer w projekcie. W tym ćwi-
czeniu skoncentrujesz się na podstawowych operacjach przeprowadzanych
na kamerze.
1. Utwórz nowy projekt lub scenę i umieść na niej dwa sześciany
w położeniach (–2, 1, –5) oraz (2, 1, 5). Na scenie umieść światło
kierunkowe.
2. Kamerę Main Camera przesuń w położenie (–3, 1, –8) i zmień jej
rotację na (0, 45, 0).
3. Dodaj nową kamerę do sceny (wybierz opcję GameObject/Create
Other/Camera) i umieść ją w położeniu (3, 1, –8), a następnie zmień
jej rotację na (0, 315, 0). Upewnij się, że wyłączyłeś Audio Listener dla
nowo dodanej kamery przez usunięcie zaznaczenia z pola wyboru obok
nazwy wymienionego komponentu.
4. Uruchom scenę. Zwróć uwagę, że obraz generowany przez drugą kamerę
jest jedynym wyświetlanym. Wynika to z faktu, że druga kamera ma
większą wartość właściwości Depth niż Main Camera. Obraz kamery
Main Camera jest generowany jako pierwszy, a dopiero na nim jest
generowany obraz z drugiej kamery. Jeżeli wartość właściwości Depth
kamery Main Camera zmienisz na 1 i ponownie uruchomisz scenę,
wtedy obraz kamery Main Camera będzie jedynym widocznym na
ekranie.

oczywiście nie oznacza, że ekran ma być idealnym kwadratem. Zamiast tego


współrzędne należy potraktować jako wartości procentowe wielkości. Dlatego
też 1 oznacza 100%, natomiast 0.5 oznacza 50%. Gdy będziesz miał to na
uwadze, umieszczanie kamer na ekranie stanie się łatwe. Domyślnie kamery
projektu obejmują ekran od punktu (0, 0), a szerokość i wysokość wynosi
obrazu widzianego przez kamerę wynosi 1. W ten sposób kamera obejmuje
cały ekran. Jeżeli zmienisz wymienione wartości, uzyskasz inny efekt.

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

Utworzenie systemu kamer dzielącego ekran


W tym ćwiczeniu utworzysz system kamer dzielący ekran. Ten system jest
powszechnie spotykany w grach przeznaczonych dla dwóch graczy współ-
dzielących ten sam ekran. Omawiane ćwiczenie jest oparte na wcześniej-
szym, w którym wykorzystano wiele kamer.
1. Otwórz poprzednio utworzony projekt.
2. Upewnij się, że wartość właściwości Depth kamery Main Camera
wynosi –1. Opcje X i Y właściwości Normalized View Port Rect
powinny mieć ustawioną wartość 0. Z kolei opcje W i H, odpowiednio,
1 i 0.5 (100% szerokości i 50% wysokości).
3. Upewnij się, że wartość właściwości Depth drugiej kamery również
wynosi –1. Opcjom X i Y właściwości Normalized View Port Rect ustaw
wartości (0, 0.5). W ten sposób kamera będzie wyświetlała obraz
w dolnej połowie ekranu. Opcjom W i H należy ustawić wartości,
odpowiednio, 1 i 0.5.
4. Uruchom scenę i zobacz, że obie kamery wyświetlają na ekranie obraz
w tym samym czasie (patrz rysunek 6.6). Ekran możesz podzielić
dowolną ilość razy.

RYSUNEK 6.6. Efekt polegający na podziale ekranu

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

Utworzenie efektu PiP


PiP (ang. Picture in Picture) to najczęściej spotykany sposób tworzenia efek-
tów, takich jak minimapa. W tym efekcie jedna z kamer generuje obraz na
określonym obszarze obrazu generowanego przez drugą. Omawiane ćwi-
czenie jest oparte na wcześniejszym, wykorzystującym wiele kamer.
1. Otwórz poprzednio utworzony projekt.
2. Upewnij się, że wartość właściwości Depth kamery Main Camera wynosi
–1. Opcje X i Y właściwości Normalized View Port Rect powinny być
ustawione na 0. Z kolei opcjom W i H ustaw wartość 1.
3. Upewnij się, że wartość właściwości Depth drugiej kamery wynosi 0.
Opcjom X i Y właściwości Normalized View Port Rect ustaw wartości
(0.75, 0.75). Właściwościom W i H należy ustawić wartość 0.2.
4. Uruchom scenę i zobacz, że obraz generowany przez drugą kamerę
jest wyświetlany w prawym górnym rogu ekranu (patrz rysunek 6.7).
Poeksperymentuj z różnymi ustawieniami właściwości Normalized
View Port Rect, aby obraz z drugiej kamery pojawiał się w innych
miejscach ekranu.

RYSUNEK 6.7. Efekt PiP

cztery warstwy do wyboru: Default, TransparentFX, Ignore Raycast i Water.


Większość z nich możesz bezpiecznie zignorować, ponieważ nie są zbyt uży‐
teczne na obecnym etapie.
Wprawdzie aktualnie wbudowane warstwy nie są zbyt użyteczne, ale zawsze
mamy możliwość łatwego utworzenia nowych. Dodanie nowej warstwy odbywa
się w menedżerze TagManager. Można go uruchomić na trzy sposoby.
 Po zaznaczeniu obiektu kliknij rozwijane menu Layer, a następnie
wybierz opcję Add Layer… (patrz rysunek 6.8).
 W menu na górze okna edytora Unity wybierz opcję Edit/Project
Settings/Tags.
120 Lekcja 6. Światła i kamery

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ść.

 Kliknij rozwijane menu Layers na pasku narzędziowym sceny


(patrz rysunek 6.9) i wybierz opcję Edit Layers.

RYSUNEK 6.9. Rozwijane menu Layer na pasku narzędziowym sceny

Po uruchomieniu menedżera TagManager po prostu kliknij po prawej stronie


jednej z warstw użytkownika, a będziesz miał możliwość nadania jej nazwy.
Na rysunku 6.10 pokazano ten proces i dwie nowo dodane warstwy. (Wspo‐
mniane nowe warstwy zostały dodane jedynie na potrzeby tego rysunku,
standardowo nie zobaczysz ich w projekcie).

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

Niewidoczne elementy sceny


Jedną z pomyłek najczęściej popełnianych przez początkujących użytkow-
ników Unity jest przypadkowe wyłączenie widoczności warstw w panelu
Scene. Jeżeli nie wiesz o możliwości ukrycia warstwy, przypadkowe jej ukry-
cie będzie wyjątkowo denerwujące. Warto pamiętać, że jeśli w panelu Scene
nie są widoczne elementy, które powinny się tam znajdować, należy spraw-
dzić rozwijane menu Layers i upewnić się, że włączone zostało wyświetla-
nie wszystkich warstw.

własny interfejs użytkownika, system cieniowania lub korzystasz ze skom‐


plikowanego systemu oświetlania. Aby uniemożliwić oświetlenie elementów
znajdujących się na warstwie, najpierw zaznacz światło. Następnie w panelu
Inspector kliknij właściwość Culling Mask i usuń zaznaczenie z wszystkich
warstw, które mają być zignorowane (patrz rysunek 6.11).
Trzecim celem użycia warstw jest wskazanie elementów, które mają być wi‐
doczne dla kamery. To będzie użyteczne rozwiązanie, jeśli tworzysz własny
efekt wizualny oparty na wielu kamerach dla pojedynczego widza. Podobnie
jak wcześniej, aby zignorować warstwę, należy po prostu kliknąć rozwijane
menu Culling Mask w komponencie kamery, a następnie usunąć zaznaczenie
z wszystkich warstw, które mają być niewidoczne dla danej kamery.

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

Ignorowanie światła i kamer


Poświęć chwilę na pracę z warstwami, światłem i kamerą.
1. Utwórz nowy projekt lub scenę. Dodaj dwa sześciany i umieść
je w położeniach (–2, 1, –5) i (2, 1, –5).
2. Przejdź do menedżera TagManager za pomocą dowolnej z wymienionych
wcześniej metod, a następnie dodaj dwie warstwy o nazwach
IgnoreLights i IgnoreCameras (patrz rysunek 6.10).
3. Wybierz jeden z sześcianów i umieść go na warstwie IgnoreLights.
Natomiast drugi sześcian umieść na warstwie IgnoreCameras.
4. Do sceny dodaj światło punktowe i umieść je w położeniu (0, 1, –7).
We właściwości Culling Mask światła usuń zaznaczenie przy warstwie
IgnoreLights. Zwróć uwagę, że tylko jeden sześcian został oświetlony.
Drugi jest zupełnie ignorowany z powodu umieszczenia go na warstwie,
na której wyłączono światło.
5. Zaznacz kamerę Main Camera i usuń zaznaczenie warstwy
IgnoreCameras z właściwości Culling Mask kamery. Uruchom scenę,
a zobaczysz, że wyświetlony jest tylko jeden nieoświetlony sześcian.
Drugi został zupełnie zignorowany przez kamerę.
Pytania i odpowiedzi 123

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

1. Utwórz nową scenę lub projekt. Do sceny dodaj kulę i umieść ją


w położeniu (0, 0, 0).
2. Do sceny dodaj cztery światła i umieść je w położeniach (–4, 0, 0),
(4, 0, 0), (0, 0, –4) i (0, 0, 4). Każdemu światłu nadaj kolor. Zakres
i intensywność poszczególnych świateł ustaw dowolnie.
3. Ze sceny usuń kamerę Main Camera (kliknij ją prawym przyciskiem
myszy, a następnie wybierz opcję Delete). Do sceny dodaj cztery
kamery i wyłącz komponent Audio Listener dla trzech z nich. Kamery
umieść w położeniach (2, 0, 0), (–2, 0, 0), (0, 0, 2) i (0, 0, –2). Każdą
kamerę obróć wokół osi Y w taki sposób, aby „widziała” kulę.
4. Zmień ustawienia właściwości Normalized View Port Rect, aby osiągnąć
efekt podziału ekranu dla czterech kamer. Każda 1/4 ekranu powinna
być wyświetlana przez inną kamerę (patrz rysunek 6.12). Wykonanie
tego kroku pozostawiam Tobie. Jeśli utkniesz, ukończoną wersję
ćwiczenia znajdziesz w katalogu Hour6_Exercise w materiałach
przeznaczonych dla bieżącej lekcji.

RYSUNEK 6.12.
Ukończone
ćwiczenie
Lekcja 7
Pierwsza gra
— Amazing Racer

W czasie tej lekcji dowiesz się:


 jak przygotować projekt prostej gry,
 jak wykorzystać wiedzę o terenie w celu przygotowania świata,
w którym toczy się akcja gry,
 jak dodać obiekty do gry, aby zapewnić jej interaktywność,
 jak przetestować i usprawnić gotową grę.
W tej lekcji wykorzystasz zdobytą dotąd wiedzę i zbudujesz pierwszą grę,
korzystając z środowiska Unity. Na początku poznasz podstawowe kon-
cepcje projektu elementów gry. Następnie przejdziesz do świata, w którym
będzie się toczyła akcja gry. Kolejnym krokiem będzie dodanie pewnych
interaktywnych obiektów mających na celu zapewnienie grywalności. Na
końcu lekcji zajmiesz się przetestowaniem gry oraz wprowadzeniem nie-
zbędnych usprawnień, które przyczynią się do jej poprawienia.

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

 Fragment prostokątnego terenu, który jednocześnie musi być na tyle


duży, aby zapewnił możliwość prowadzenia atrakcyjnej rozgrywki.
W terenie powinny znajdować się wbudowane przeszkody, a także
punkt początkowy gry oraz strefa zakończenia gry (patrz rysunek 7.1).

RYSUNEK 7.1.
Ogólny
układ terenu
w tworzonej grze
Amazing Racer

 Tekstury i efekty środowiska dla terenu. Wszystkie niezbędne


znajdziesz w standardowych zasobach dostarczanych wraz z Unity.
 Obiekty: punkt rozpoczęcia gry, strefa zakończenia oraz niebezpieczna
woda. Wymienione obiekty zostaną wygenerowane w Unity.
 Kontroler postaci. Znajdziesz go w standardowych zasobach
dostarczanych wraz z Unity.
 Graficzny interfejs użytkownika (GUI). Znajdziesz go w materiałach
przeznaczonych dla bieżącej lekcji.
 Kontroler gry. Utworzysz go w Unity.

Budowanie świata gry


Skoro podstawowe idee gry masz już przygotowane na papierze, najwyższy
czas przystąpić do jej tworzenia. Istnieje wiele elementów, od których można
zacząć budowę gry. W omawianym przykładzie pracę zaczniesz od przygo‐
towania świata, w którym będzie toczyła się akcja gry. Ponieważ gra jest linio‐
wym wyścigiem, świat będzie dłuższy niż szerszy (lub szerszy niż dłuższy,
w zależności od tego, jak spojrzysz na teren). W celu szybkiego utworzenia
gry wykorzystasz wiele standardowych zasobów dostarczanych wraz z Unity.
Budowanie świata gry 129

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.

Tworzenie własnego terenu


W tej lekcji budujesz grę opartą na dołączonej do książki mapie wysokości.
Mapa ta została przygotowana, aby umożliwić Ci szybkie przejście przez
proces tworzenia gry. Oczywiście możesz się zdecydować na samodzielne
utworzenie terenu, a tym samym przygotowanie prawdziwie unikalnej gry.
Jeżeli zdecydujesz się na taki krok, musisz pamiętać, że pewne podane w tej
lekcji współrzędne i wartości rotacji mogą nie pasować do Twojej wersji
gry. W takim przypadku zwracaj baczną uwagę na miejsce umieszczania
obiektów, powinno być odpowiednio dobrane do Twojej wersji.

Dodanie elementów do środowiska


Teraz możesz przystąpić do rozpoczęcia teksturowania i dodawania efektów
środowiska do terenu. Konieczne jest zaimportowanie wymienionych poniżej
pakietów (kliknij Assets/Import Package):
 Terrain Assets,
 Skyboxes,
 Water.
130 Lekcja 7. Pierwsza gra — Amazing Racer

Masz pewną dozę swobody w dekorowaniu świata zgodnie ze swoim wyczu‐


ciem. Wymienione poniżej punkty są jedynie sugestiami. Udekoruj teren
w dowolnie wybrany sposób.
 Do sceny dodaj światło kierunkowe. Obróć światło w taki sposób,
aby oświetlało scenę w satysfakcjonujący Cię sposób.
 Dodaj tekstury do terenu. W przykładowym projekcie wykorzystano
następujące tekstury: Grass (Hill) dla płaskich obszarów terenu, Cliff
(Layered Rock) dla stromych elementów krajobrazu i Grass&Rock dla
obszarów znajdujących się między dwoma wymienionymi wcześniej.
 Do sceny dodaj symulację nieba (wybierz opcję Edit/Render Settings).
W przykładowym projekcie jest to Sunny1 Skybox.
 Do sceny dodaj drzewa. Należy je umieszczać oszczędnie i przede
wszystkim na płaskich obszarach terenu.
 Do sceny dodaj podstawową wodę (w panelu Project przeciągnij
Daylight Simple Water z katalogu Assets/Standard Assets/Water
(Basic)). Umieść wodę w położeniu (88, 29, 49), a następnie przeskaluj
(50, 1, 50).
W tym momencie teren powinien być przygotowany i gotowy do użycia. Poświęć
nieco czasu na jego teksturowanie i upewnij się, że wygląda realistycznie.
Istnieją jeszcze inne elementy nieumieszczone w przykładowym projekcie,
a które możesz dodać. Oto one.
 Mgła.
 Trawa wokół wody; może nieco przesłaniać wodę, aby tym samym
utrudnić rozgrywkę.
 Flary dla światła kierunkowego, mające na celu symulację słońca.
Światło kierunkowe trzeba będzie obrócić, aby zostało dopasowane
od obrazu słońca, o ile taki jest używany.

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

które mogą wymagać wprowadzenia poprawek lub wygładzenia. Zwróć


uwagę na granice. Spróbuj wyszukać wszelkie obszary pozwalające na ucieczkę
ze świata. Tego rodzaju miejsca trzeba będzie podnieść, aby gracz nie mógł
wypaść z mapy. Obecny etap pracy jest przeznaczony na rozwiązanie wszyst‐
kich prostych problemów związanych z terenem.

Wypadnięcie ze świata gry


Ogólnie rzecz biorąc, poziom w grze ma ściany lub inne przeszkody
uniemożliwiające graczowi opuszczenie przygotowanego obszaru. Jeżeli
w grze jest wykorzystywana grawitacja, gracz może wypaść z boku opra-
cowanego świata. Zawsze należy stosować pewne rozwiązania uniemożli-
wiające graczowi przejście tam, gdzie nie powinien się udawać. W projekcie
tworzonej tutaj gry celowo pozostawiono strome podejścia uniemożliwia-
jące graczowi opuszczenie obszaru gry. Na mapie wysokości w materiałach
przeznaczonych dla bieżącej lekcji celowo znajduje się kilka punktów
tworzących wzniesienia, po których gracz może się wspiąć i opuścić obszar
gry. Sprawdź, czy potrafisz je wyszukać i naprawić te niedopatrzenia.

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ść.

Dodanie obiektów kontrolujących grę


Zgodnie z przedstawionymi wcześniej wymaganiami, potrzebujesz czterech
obiektów kontrolujących grę. Pierwszym obiektem będzie punkt początkowy
gry. To naprawdę prosty obiekt istniejący jedynie w celu wskazania miejsca,
w którym powinna się rozpocząć gra. Poniżej wymieniono kroki prowadzące
do utworzenia punktu początkowego gry.
1. Do sceny dodaj pusty obiekt gry (wybierz opcję GameObject/Create
Empty), a następnie umieść go w położeniu (160, 32, 64).
2. W panelu Hierarchy nazwę dodanego pustego obiektu zmień
na SpawnPoint.
132 Lekcja 7. Pierwsza gra — Amazing Racer

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.

Kolejnym krokiem jest utworzenie wykrywacza niebezpiecznej wody. Będzie


to prosta płaszczyzna umieszczona tuż pod wodą. Dla płaszczyzny zdefiniujesz
wyzwalacz kolizji (ten temat zostanie dokładniej omówiony dalej w tej książce)
odpowiedzialny za wykrycie wejścia gracza do wody. Poniżej wymieniono
kroki prowadzące do utworzenia wspomnianego detektora.
1. Do sceny dodaj płaszczyznę (wybierz opcję GameObject/Create
Other/Plane) i umieść ją w położeniu (86, 27, 51). Następnie przeskaluj
płaszczyznę za pomocą wartości (10, 1, 10).
2. W panelu Hierarchy nazwę płaszczyzny zmień na WaterHazardDetector.
3. W panelu Inspector dla komponentu Mesh Collider zaznacz pole wyboru
Is Trigger (patrz rysunek 7.3).
Kolejnym krokiem jest dodanie strefy zakończenia gry. Będzie to prosty obiekt
wraz ze światłem punktowym, aby gracz nie miał wątpliwości, gdzie strefa się
znajduje. Do obiektu zostanie dołączony komponent Capsule Collider pozwa‐
lający na wykrycie wejścia gracza na ten obszar. Poniżej wymieniono kroki
prowadzące do utworzenia strefy zakończenia gry.
1. Do sceny dodaj pusty obiekt gry i umieść go w położeniu (26, 32, 24).
2. W panelu Hierarchy zmień nazwę obiektu na Finish.
Gamifikacja 133

RYSUNEK 7.3.
Panel Inspector
dla obiektu
WaterHazard-
Detector

3. Do obiektu Finish dodaj komponent światła (mając zaznaczony obiekt,


wybierz opcję Component/Rendering/Light). Typ światła zmień
na Point, ustaw jego zakres na 35, natomiast intensywność na 3.
4. Do obiektu Finish dodaj komponent Capsule Collider (mając zaznaczony
obiekt, wybierz opcję Component/Physics/Capsule Collider). Wartość
właściwości Radius zmień na 9. Ponadto w panelu Inspector zaznacz
pole wyboru Is Trigger (patrz rysunek 7.4).

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

3. Kliknij i przeciągnij skrypty do katalogu Scripts w edytorze Unity.


W ten sposób w projekcie gry powinny znaleźć się trzy skrypty:
FinishScript, GameControlScript i RespawnScript.
Użycie skryptów dodanych do projektu jest już bardzo proste. W celu zasto‐
sowania skryptu należy go przeciągnąć z panelu Project na wybrany obiekt
(patrz rysunek 7.5). Skrypty zastosuj w następujący sposób:
 FinishScript dla obiektu gry Finish,
 GameControlScript dla obiektu GameControl,
 RespawnScript dla obiektu WaterHazardDetector.

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

Łączenie obiektów zacznij od WaterHazardDetector. W panelu Hierarchy


zaznacz WaterHazardDetector i spójrz na komponent Respawn Script. Kompo‐
nent powstał na skutek zastosowania wcześniej skryptu Respawn. W kom‐
ponencie zauważysz właściwość o nazwie Respawn Point, która jest miej‐
scem zarezerwowanym dla utworzonego wcześniej obiektu gry SpawnPoint.
Mając zaznaczony obiekt WaterHazardDetector, w panelu Hierarchy kliknij
obiekt SpawnPoint i przeciągnij na właściwość Respawn Point w komponencie
Respawn Script. Od tej chwili, gdy gracz wpadnie do wody, zostanie natychmiast
przeniesiony do punktu początkowego gry.
Teraz skonfiguruj obiekt Finish. Po jego zaznaczeniu w panelu Hierarchy klik‐
nij obiekt GameControl i przeciągnij go na właściwość Game Control Script
w komponencie Finish Script. Od tej chwili, gdy gracz wejdzie do strefy zakoń‐
czenia gry, obiekt kontrolujący grę zostanie poinformowany o tym fakcie.
Ostatni obiekt do konfiguracji to GameControl. W celu jego prawidłowej kon‐
figuracji wykonaj wymienione poniżej kroki.
1. W panelu Hierarchy kliknij obiekt SpawnPoint i przeciągnij
na właściwość Spawn Point komponentu Game Control Script obiektu
GameControl.
2. Kliknij i przeciągnij obiekt Player (to jest kontroler postaci)
na właściwości Player, Motor Script i Look Script komponentu Game
Control Script obiektu GameControl.
136 Lekcja 7. Pierwsza gra — Amazing Racer

RYSUNEK 7.6.
Przypisanie
obiektów gry
do miejsc
zarezerwowanych

3. Konieczne jest wyłączenie skryptu Mouse Look dla kamery


w kontrolerze postaci Player. W tym celu w panelu Hierarchy rozwiń
opcje obiektu Player (kliknij strzałkę znajdującą się po lewej stronie
nazwy Player), a następnie zaznacz kamerę Main Camera zagnieżdżoną
w Player. W panelu Inspector odszukaj komponent Mouse Look (Script)
i usuń zaznaczenie z jego pola wyboru (patrz rysunek 7.7).
W ten sposób wykonałeś wszystkie połączenia między obiektami gry. Możesz
już zagrać w grę! Pewne wykonane czynności mogą jeszcze nie mieć sensu, ale
wszystko stanie się jasne, gdy będziesz lepiej poznawał środowisko Unity.

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

Możliwość wprowadzenia zmian w czasie korzystania z gry jest znacznie ogra‐


niczona, dlatego też tak ważne jest robienie notatek. Zastanów się też, jak
można zmienić grę, aby stała się jeszcze lepsza.
Jedną ze zmian, którą możesz teraz wprowadzić i tym samym wpłynąć na
grywalność, jest szybkość, z jaką porusza się gracz. Gdy zagrasz kilkakrotnie,
przekonasz się, że ruch odbywa się zbyt wolno, a gra nieco się dłuży. Aby postać
poruszała się szybciej, konieczna jest modyfikacja komponentu Character
Motor (Script) obiektu Player. W panelu Inspector rozwiń właściwość Movement
i zmień maksymalną szybkość poruszania się do przodu (patrz rysunek 7.8).
W przykładowym projekcie wartość wynosi 12. Wypróbuj ją i zobacz, czy
Ci odpowiada. Sprawdź mniejsze i większe wartości, a następnie wybierz
najlepszą.

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.

W czasie tej lekcji:


 poznasz podstawy skryptów w środowisku Unity,
 dowiesz się, jak używać zmiennych,
 nauczysz się korzystać z operatorów,
 posłużysz się konstrukcjami warunkowymi,
 zastosujesz pętle.
We wcześniejszych lekcjach dowiedziałeś się, jak tworzyć obiekty w śro-
dowisku Unity. Jednak same obiekty są nieco nudne. Jaką użyteczność ma
sześcian po prostu umieszczony na scenie? Znacznie lepiej byłoby, gdyby
dla sześcianu zdefiniować własną akcję, dzięki której stałby się w pewien
sposób interesujący. Do tego celu przydadzą się skrypty. Skrypty są plikami
kodu używanego do zdefiniowania złożonego lub niestandardowego
zachowania dla danego obiektu. W tej lekcji zostaną przedstawione pod-
stawy skryptów. Na początku dowiesz się, jak rozpocząć pracę ze skryptami
w Unity. Zobaczysz, jak można tworzyć skrypty i używać środowiska skryp-
towego. Następnie przejdziesz do różnych komponentów języka skrypto-
wego. Wspomniane komponenty obejmują zmienne, operatory, konstrukcje
warunkowe i pętle.

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.

Skrypt po utworzeniu możesz wyświetlić i zacząć modyfikować. Kliknięcie


skryptu w panelu Project spowoduje wyświetlenie zawartości skryptu w panelu
Inspector (patrz rysunek 8.1). Dwukrotne kliknięcie skryptu w panelu Project
uruchamia edytor domyślny, w którym następnie można dodać kod skryptu.
Jeśli zainstalowałeś komponenty standardowe i niczego nie zmieniałeś, dwu‐
krotne kliknięcie pliku skryptu spowoduje uruchomienie oprogramowania
MonoDevelop (patrz rysunek 8.2).

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.

2. Prawym przyciskiem myszy kliknij katalog Scripts i wybierz 


opcję Create/C# Script. Nowemu skryptowi nadaj nazwę
HelloWorldScript.
3. Dwukrotnie kliknij plik nowego skryptu i zaczekaj na uruchomienie
oprogramowania MonoDevelop. W oknie edytora MonoDevelop
(patrz rysunek 8.2) usuń całą dotychczasową zawartość skryptu
i zastąp ją poniższym kodem:
using UnityEngine;
using System.Collections;

public class HelloWorldScript : MonoBehaviour {

// Poniższej metody użyj do inicjacji.


void Start() {
print("Hello World");
}

// Metoda Update() jest wywoływana raz w każdej klatce.


void Update() {

}
}
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.

Aby przećwiczyć omawiany proces, teraz utworzony wcześniej skrypt Hello-


WorldScript dołączysz do obiektu Main Camera. W panelu Inspector powinie‐
neś widzieć komponent o nazwie Hello World Script (Script). Jeżeli urucho‐
misz scenę, komunikat wyświetlany przez skrypt (w omawianym przypadku
Hello World) zobaczysz na dole ekranu (patrz rysunek 8.4).
Skrypty 145

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

Anatomia prostego skryptu


W poprzedniej części lekcji zmodyfikowałeś skrypt, aby wyświetlić pewne
informacje na ekranie, ale nie wyjaśniłem sposobu działania kodu tworzącego
skrypt. W tym miejscu przyjrzysz się dokładniej domyślnemu szablonowi, który
jest stosowany w każdym nowym skrypcie C#. Pamiętaj, że skrypty tworzone
w językach JavaScript lub Boo będą zawierały te same komponenty, choć
nieco inny kod. W listingu 8.1 przedstawiony został pełny kod wygenerowany
przez Unity po wybraniu opcji tworzenia nowego skryptu. Dla skryptu
w listingu 8.1 przyjęto, że nazwa pliku skryptu to HelloWorldScript.
Kod można podzielić na trzy części.
146 Lekcja 8. Skrypty — część 1.

Listing 8.1. Domyślny kod skryptu


using UnityEngine;
using System.Collections;

public class HelloWorldScript : MonoBehaviour {

// Poniższej metody użyj do inicjacji.


void Start() {
}

// Metoda Update() jest wywoływana raz w każdej klatce.


void Update() {
}
}

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

// Metoda Update() jest wywoływana raz w każdej klatce.


void Update() {
}
Dokładne omówienie metod znajdziesz w kolejnej lekcji. Teraz wystarczy
wiedzieć, że kod umieszczony w metodzie Start() zostanie wykonany raz
w trakcie uruchamiania sceny. Natomiast kod metody Update() będzie wyko‐
nywany w trakcie każdego uaktualniania gry, czyli około 60 razy na sekundę,
w zależności od szybkości komputera.

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

Użycie wbudowanych metod


Wypróbuj wbudowane metody Start() i Update(), aby przekonać się,
jak działają. Pełną wersję skryptu ImportantFunctions znajdziesz w mate-
riałach przeznaczonych dla bieżącej lekcji. Spróbuj samodzielnie wykonać
poniższe ćwiczenie, ale jeśli napotkasz trudności, zajrzyj do wspomnianych
materiałów.
1. Utwórz nowy projekt lub scenę. Do sceny dodaj skrypt o nazwie
ImportantFunctions. Dwukrotnie kliknij skrypt, aby uruchomić go
w edytorze oprogramowania MonoDevelop.
2. W metodzie Start() skryptu dodaj poniższy wiersz kodu:
print("Metoda Start() jest wykonywana przed uaktualnieniem
obiektu.");
3. Zapisz skrypt, a następnie w edytorze Unity dołącz go do obiektu
Main Camera. Uruchom scenę i zobacz, jak komunikat jest wyświetlany
w oknie konsoli.
4. Powróć do MonoDevelop i dodaj poniższy wiersz kodu w metodzie
Update():
print("Ta metoda jest wywoływana w każdej klatce.");
5. Zapisz skrypt, a następnie szybko uruchom i zatrzymaj scenę w Unity.
Teraz w oknie konsoli znajduje się pojedynczy komunikat z metody
Start() oraz wiele komunikatów z metody Update().

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.

Tabela 8.1. Typy zmiennych w języku C#


Typ Opis
int Typ pozwala na przechowywanie dodatnich lub ujemnych liczb
całkowitych.
float Typ pozwala na przechowywanie liczb zmiennoprzecinkowych
(takich jak 3.4) i jest domyślnym typem liczb w środowisku Unity.
double Typ również pozwala na przechowywanie liczb
zmiennoprzecinkowych, ale nie jest domyślnym typem liczb
w środowisku Unity. Umożliwia przechowywanie znacznie
większych liczb niż typ float.
bool Wartość boolowska, czyli przechowuje wartości prawda lub fałsz
(w kodzie wspomniane wartości są zapisane jako, odpowiednio,
true i false).
char Typ pozwala na przechowywanie znaku, pojedynczej litery, spacji
lub znaku specjalnego. Oto przykłady dozwolonych wartości: a,
5 lub !. Znaki są ujmowane w apostrofy, np. 'T'.
string Typ pozwala na przechowywanie całych słów lub zdań. Wartości
są ujmowane w cudzysłów, np. "Witaj, świecie!".

To ważne, ponieważ zmienne mogą być używane jedynie w blokach, w których


zostały utworzone. Jeżeli więc zmienna została utworzona w metodzie Start()
skryptu, wtedy nie będzie dostępna w metodzie Update() tego skryptu. Próba
użycia niedostępnej zmiennej powoduje wygenerowanie błędu. Wymienione
bloki są dwoma różnymi blokami. Jeśli zmienna zostanie utworzona w klasie,
ale na zewnątrz metody, będzie dostępna w obu metodach. Wynika to z faktu,
że obie metody — Start() i Update() — znajdują się w tym samym bloku,
w którym została zdefiniowana zmienna (blok klasy). Zostało to zademon‐
strowane w listingu 8.2.

Listing 8.2. Demonstracja poziomów klasy i bloku lokalnego


// To jest "blok klasy", który pozostanie
// dostępny w całej klasie.
private int num1;
150 Lekcja 8. Skrypty — część 1.

void Start () {
// To jest "blok lokalny", który pozostaje
// dostępny jedynie w metodzie Start().
int num2;
}

Zmienne publiczne i prywatne


Kiedy dokładnie przyjrzysz się listingowi 8.2, zauważysz słowo kluczowe
private przed num1. To jest tzw. modyfikator dostępu, niezbędny jedynie dla
zmiennych deklarowanych na poziomie klasy. Istnieją dwa modyfikatory
dostępu, z których będziesz korzystać; są to private i public. Wiele można
powiedzieć o obu wymienionych modyfikatorach dostępu, ale musisz tylko
wiedzieć, jak wpływają na zmienne deklarowane na tym poziomie. Zmienne
prywatne (czyli zawierające słowo kluczowe private na początku deklaracji)
mogą być używane jedynie w pliku, w którym zostały utworzone. Inne skrypty
i edytor nie mogą ich „widzieć” lub modyfikować w jakikolwiek sposób. Ozna‐
cza to, że zmienne prywatne są przeznaczone jedynie do użytku wewnętrz‐
nego. Z kolei zmienne publiczne (public) są widoczne dla innych skryptów,
a nawet dla edytora Unity. Oznacza to bardzo łatwą możliwość zmiany ich
wartości w Unity.

 Wypróbuj samodzielnie

Modyfikacja zmiennej publicznej w Unity


Zobacz, jak zmienne publiczne są widoczne w edytorze Unity.
1. Utwórz nowy skrypt C#, a następnie w edytorze MonoDevelop dodaj
poniższy wiersz kodu w klasie, ale jeszcze przed metodą Start().
public int runSpeed;
2. Zapisz skrypt, przejdź do edytora Unity i dołącz skrypt do obiektu Main
Camera.
3. Wybierz obiekt Main Camera i spójrz na panel Inspector. Zwróć
uwagę na skrypt dołączony jako komponent. Powinieneś zobaczyć,
że komponent ma nową właściwość o nazwie Run Speed. Tę właściwość
możesz zmodyfikować w panelu Inspector, a zmiana zostanie
odzwierciedlona w skrypcie po uruchomieniu sceny. Na rysunku 8.6
pokazano komponent wraz z nową właściwością (przyjęto założenie,
że utworzony skrypt ma nazwę ImportantFunctions).

RYSUNEK 8.6. Właściwość Run Speed komponentu skryptu


Operatory 151

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.

Tabela 8.2. Operatory arytmetyczne


Operator Opis

+ Dodawanie. Ten operator powoduje dodanie dwóch liczb.


W ciągach tekstowych znak + oznacza konkatenację
(połączenie) ciągów tekstowych:
"Witaj, " + "świecie!"; // Dane wyjściowe: "Witaj, świecie!".
- Odejmowanie. Od liczby znajdującej się po lewej stronie
operatora zostaje odjęta liczba podana po prawej stronie
operatora.
* Mnożenie. Ten operator mnoży dwie liczby.
/ Dzielenie. Liczba znajdująca się po lewej stronie operatora
zostaje podzielona przez liczbę podaną po prawej stronie
operatora.
% Modulo, czyli reszta z dzielenia. Liczba znajdująca się po lewej
stronie operatora zostaje podzielona przez liczbę podaną
po prawej stronie operatora, ale wynik nie jest zwracany.
Zamiast tego wartością zwrotną jest reszta z dzielenia.
10 % 2; // Wartość zwrotna: 0.
6 % 5; // Wartość zwrotna: 1.
24 % 7; // Wartość zwrotna: 3.

Operatory arytmetyczne mogą być łączone kaskadowo w celu przygotowania


bardziej złożonych wyrażeń matematycznych:
x + (5 * (6 – y) / 3);
W operatorach arytmetycznych stosuje się standardową matematyczną kolej‐
ność wykonywania operacji. Oznacza to obliczenia od lewej do prawej strony,
przy czym operacje w nawiasach są wykonywane jako pierwsze. Mnożenie
i dzielenie są wykonywane jako drugie, natomiast dodawanie i odejmowanie
jako trzecie.
152 Lekcja 8. Skrypty — część 1.

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.

Tabela 8.3. Operatory przypisania


Operator Opis

= Wartość znajdująca się po prawej stronie operatora zostaje


przypisana zmiennej znajdującej się po lewej stronie
operatora.
+=, -=, *=, /= Skrócone zapisy operatora przypisania, który przeprowadza
pewne operacje arytmetyczne na podstawie podanego
symbolu, a następnie wynik przypisuje zmiennej podanej
po lewej stronie operatora.
x = x + 5; // Dodanie wartości 5 do zmiennej x, a następnie
// przypisanie wyniku zmiennej x.
x += 5; // Tak samo jak powyżej, ale za pomocą skróconego
// zapisu.
++, -- Kolejne operatory skrótu. Są nazywane operatorami
inkrementacji i dekrementacji. Ich zadanie polega
na zwiększeniu lub zmniejszeniu wartości o 1.
x = x + 1; // Dodanie wartości 1 do zmiennej x, a następnie
// przypisanie wyniku zmiennej x.
x++; // Tak samo jak powyżej, ale za pomocą skróconego zapisu.

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

Tabela 8.4. Operatory równości


Operator Opis
== Tego operatora nie wolno pomylić z operatorem
przypisania (=). Wartością zwrotną operatora jest true,
jeśli obie porównywane wartości są takie same. W przeciwnym
razie wartością zwrotną jest false.
5 == 6; // Wartość zwrotna: false.
9 == 9; // Wartość zwrotna: true.
>, < To są operatory „większy niż” i „mniejszy niż”.
5 > 3; // Wartość zwrotna: true.
5 < 3; // Wartość zwrotna: false.
>=, <= Te operatory są podobne do wymienionych wcześniej
„większy niż” i „mniejszy niż”, ale oznaczają „większy
niż lub równy” i „mniejszy niż lub równy”.
3 >= 3; // Wartość zwrotna: true.
5 <= 9; // Wartość zwrotna: true.
!= To jest operator „nierówności”. Zwraca wartość true,
jeśli porównywane wartości są różne. W przeciwnym razie
wartością zwrotną jest false.
5 != 6; // Wartość zwrotna: true.
9 != 9; // Wartość zwrotna: false.

Dodatkowe informacje o operatorach


W plikach dołączonych do książki znajduje się skrypt o nazwie Equality-
AndOperations.cs. Przejrzyj go, ponieważ znajdziesz tam więcej informacji
o różnych operatorach.

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.

Tabela 8.5. Operatory logiczne


Operator Opis
&& Operator logiczny AND. Porównuje dwie wartości boolowskie
i ustala, czy obie mają wartość true. Jeżeli którakolwiek
lub obie mają wartość false, wtedy wartością zwrotną jest
false.
true && false; // Wartość zwrotna: false.
false && true; // Wartość zwrotna: false.
false && false; // Wartość zwrotna: false.
true && true; // Wartość zwrotna: true.
|| Operator logiczny OR. Porównuje dwie wartości boolowskie
i ustala, czy choć jedna z nich ma wartość true. Jeżeli jedna
lub obie mają wartość true, wtedy wartością zwrotną jest
true.
true && false; // Wartość zwrotna: true.
false && true; // Wartość zwrotna: true.
false && false; // Wartość zwrotna: false.
true && true; // Wartość zwrotna: true.
! Operator logiczny NOT. Wartością zwrotną jest przeciwna
wartość boolowska.
!true; // Wartość zwrotna: false.
!false; // Wartość zwrotna: true.

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

Pamiętaj, że wartością warunku w konstrukcji if musi być wartość true lub


false. Umieszczenie liczb, słów lub innych elementów nie działa:
if("witaj" == "witaj") // Prawidłowo.
{}

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.");
}

Konstrukcja if z tylko pojedynczym wierszem kodu


Jeżeli blok poleceń w konstrukcji if składa się tylko z pojedynczego wier-
sza, nie ma konieczności użycia nawiasów klamrowych. Dlatego też kod
w postaci:
if(x > y)
{
print("X jest większe niż Y");
}
można zapisać również w następujący sposób:
if(x > y)
print("X jest większe niż Y");

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.

while(count <= 100)


{
sum += count;
count++;
}

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;

for(int count = 1; count <= 100; count++)


Podsumowanie 159

{
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.

W czasie tej lekcji dowiesz się:


 jak tworzyć metody,
 jak przechwytywać dane wejściowe użytkownika,
 jak korzystać z komponentów lokalnych,
 jak pracować z obiektami gry.
W poprzedniej lekcji poznałeś podstawy skryptów w środowisku Unity.
W tej lekcji wykorzystasz poprzednio zdobytą wiedzę do wykonywania
znacznie bardziej złożonych zadań. Na początek zajmiesz się metodami.
Dowiesz się, co to jest metoda, jak działa oraz w jaki sposób należy ją
utworzyć. Następnie przejdziesz do danych wejściowych użytkownika.
Kolejnym poruszonym tematem będzie uzyskanie dostępu do komponen-
tów z poziomu skryptów. Na końcu lekcji dowiesz się, jak za pomocą kodu
uzyskać dostęp do innych obiektów gry i ich komponentów.

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.

Typ wartości zwrotnej


Każda metoda ma możliwość zwrócenia zmiennej do wywołującego ją kodu.
Typ tej zmiennej jest nazywany typem wartości zwrotnej. Jeżeli metoda zwraca
liczbę całkowitą, wtedy typem jej wartości zwrotnej jest int. Podobnie jeśli
metoda zwraca wartość true lub false, wówczas typem wartości zwrotnej
jest bool. Jeżeli metoda nie zwraca żadnej wartości, to jednak nadal posiada typ
Metody 163

wartości zwrotnej. W takim przypadku to będzie typ void oznaczający brak


wartości. Każda metoda zwracająca wartość używa do tego celu słowa klu‐
czowego return.

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

Identyfikacja poszczególnych elementów metody


Poświęć chwilę na utrwalenie poszczególnych elementów metod. Czy dla
poniższej metody:
int TakeDamage(int damageAmount)
{
int health = 100;
return health – damageAmount;
}
potrafisz odpowiedzieć na pytania dotyczące jej elementów?
1. Jaka jest nazwa metody?
2. Jaki jest typ wartości zwrotnej metody?
3. Jakie są parametry metody? Ile ich jest?
4. Który fragment kodu jest nazywany blokiem metody?

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.

Metoda jako fabryka


Koncepcja metody może być niejasna dla stawiających pierwsze kroki
w programowaniu. Bardzo często popełniają pomyłki dotyczące parametrów
i wartości zwrotnej metod. Ułatwieniem może być potraktowanie metody
jako fabryki. Do fabryk są dostarczane materiały, które następnie służą do
wytworzenia produktów. Metody działają na takiej samej zasadzie. Parametry
są materiałami przekazywanymi do „fabryki”, natomiast wartość zwrotna to
produkt wytwarzany przez fabrykę. Z kolei metody niewymagające parame-
trów należy traktować jak fabryki, które nie potrzebują surowców, natomiast
metody niezwracające wartości jak fabryki, które nie wytwarzają produktu.
Porównanie metod do fabryk może ułatwić zrozumienie koncepcji metody.

1. Jakie konkretne zadanie ma wykonywać dana metoda?


2. Czy do wykonania zadania metoda potrzebuje jakichkolwiek
zewnętrznych danych?
3. Czy metoda musi zwracać jakiekolwiek dane?
Udzielenie odpowiedzi na powyższe pytania pomoże w określeniu nazwy
metody, jej parametrów i wartości zwrotnej.
Rozważ przedstawiony poniżej przykład: gracz został uderzony kulą ognia.
Konieczne jest utworzenie metody symulującej to uderzenie przez odjęcie
5 punktów zdrowia. W tym momencie dokładnie określono zadanie, jakie do
wykonania ma metoda. Wiemy również, że metoda nie potrzebuje żadnych
danych (przecież jej zadanie polega na odjęciu 5 punktów) i prawdopodobnie
powinna zwrócić wartość przedstawiającą ilość pozostałych punktów zdrowia.
Omówioną metodę można utworzyć następująco.
int TakeDamageFromFireball()
{
int playerHealth = 100;
return playerHealth – 5;
}
Jak możesz zobaczyć w kodzie metody, liczba punktów zdrowia gracza wynosi
100, a 5 zostaje odjętych. Wynik (95 punktów) zostaje przekazany z powrotem
jako wartość zwrotna. Oczywiście tę metodę można ulepszyć. Wcześniej wspo‐
mniano, że uderzenie kulą ognia zabiera 5 punktów, ale co zrobić w sytuacji,
gdy będziesz chciał tę liczbę zmienić? Trzeba dokładnie znać liczbę punktów
zdrowia odejmowanych graczowi w danej chwili po uderzeniu go przez kulę
ognia. Potrzebujemy więc zmiennej, która w omawianym przypadku jest para‐
metrem. Zmodyfikowana wersja metody może się przedstawiać następująco.
int TakeDamageFromFireball(int damage)
{
int playerHealth = 100;
return playerHealth – damage;
}
Metody 165

Jak widzisz, liczba odejmowanych punktów (damage) jest odczytywana przez


metodę i stosowana w trakcie jej wykonywania. Innym usprawnieniem jest
sama liczba pozostałych graczowi punktów zdrowia. Aktualnie gracz nigdy nie
przegrywa, ponieważ początkowa liczba punktów zdrowia, od której odej‐
mowane są punkty po uderzeniu kulą ognia, wynosi 100. W rzeczywistości
liczbę punktów zdrowia należy trwale przechowywać. Metoda powinna
odczytać tę liczbę, a następnie odjąć odpowiednią liczbę punktów. Po kolejnej
modyfikacji metoda może przedstawiać się tak.
int TakeDamageFromFireball(int damage, int playerHealth)
{
return playerHealth – damage;
}
Dzięki analizie potrzeb możesz tworzyć lepsze, solidniejsze metody dla opra‐
cowywanej gry.

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);

// Wywołanie metody wraz z przekazaną jej zmienną.


int x = 5;
DowolnaMetoda(x); // W wywołaniu nie stosujemy zapisu "int x".
166 Lekcja 9. Skrypty — część 2.

Zauważ, że w trakcie wywoływania metody nie trzeba podawać typu zmiennej


używanej w charakterze parametru. Jeżeli DowolnaMetoda() zwraca wartość,
trzeba ją przechwycić do zmiennej. Odpowiedni kod może się wówczas przed‐
stawiać następująco (przyjęto założenie, że typem wartości zwrotnej jest
Boolean, w rzeczywistości może być dowolny):
bool wynik = DowolnaMetoda();
Taka prosta składnia jest wystarczająca.

 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.

Podstawy danych wejściowych


W środowisku Unity (podobnie jak w większości silników gier) w kodzie można
wykryć naciśnięcie określonych klawiszy i tym samym zapewnić możliwość
interakcji. Jednak dobrym rozwiązaniem jest unikanie takiego podejścia, ponie‐
waż utrudnia ono graczowi zmianę mapowania sposobu sterowania na zgodny
z własnymi przyzwyczajeniami. Na szczęście, Unity zawiera wbudowany prosty
system mapowania kontrolek. W Unity analizując określoną oś, można się
dowiedzieć, czy gracz zamierzał wykonać daną akcję. Dlatego też kiedy gracz
uruchamia grę, zyskuje możliwość przypisania kontrolkom różnych osi.
Przejrzenie, edycję i dodawanie osi można przeprowadzić za pomocą mene‐
dżera InputManager. W celu uzyskania dostępu do tego menedżera należy
wybrać opcję Edit/Project Settings/Input. Po uruchomieniu menedżera można
przejrzeć przypisania różnych osi poszczególnym akcjom danych wejścio‐
wych. Domyślnie dostępnych jest 15 osi danych wejściowych, ale możesz
dodać własne, jeśli będzie trzeba. Na rysunku 9.1 pokazano domyślne usta‐
wienia menedżera InputManager dla osi poziomej.

RYSUNEK 9.1.
Menedżer Input
Manager

Wprawdzie oś pozioma bezpośrednio niczym nie steruje (odpowiednie skrypty


dopiero utworzysz), ale wskazuje, że gracz porusza się na boki. Właściwości
osi zostały wymienione w tabeli 9.1.
168 Lekcja 9. Skrypty — część 2.

Tabela 9.1. Właściwości osi


Właściwość Opis
Name Nazwa osi. W ten sposób będziemy się do niej
odwoływać w kodzie.
Descriptive Name / Dłuższa nazwa osi, która będzie wyświetlana graczowi
Descriptive w konfiguracji gry. Z kolei nazwa podana w Negative
Negative Name jest nazwą przeciwną. Przykładowo „idź w lewo”
i „idź w prawo” to para nazw przeciwstawnych.
Negative Button / Przyciski przekazujące osi nazwę standardową
Positive Button i przeciwną. Dla osi poziomej będzie to strzałka
w lewo i strzałka w prawo.
Alt Negative Alternatywne przyciski służące do przekazywania
Button / Alt wartości do osi. Dla osi poziomej to będą klawisze
Positive Button A i D.
Gravity Właściwość określa, jak szybko wartość osi wraca
do zera, gdy klawisz nie jest dłużej naciśnięty.
Dead Wszelkie dane wejściowe mniejsze niż podana wartość
będą ignorowane. To chroni przez drganiami
powodowanymi przez dżojstik.
Sensitivity Wartość określa, jak szybko oś odpowiada na dane
wejściowe.
Snap Po zaznaczeniu tego pola tekstowego wartość osi
wraca do zera natychmiast po naciśnięciu klawisza
oznaczającego kierunek przeciwny.
Invert Zaznaczenie tego pola wyboru powoduje zamianę
kontrolek.
Type Właściwość wskazuje typ danych wejściowych.
Dostępne typy to klawisze lub przyciski myszy, ruch
myszą i ruch dżojstikiem.
Axis Odpowiadająca oś z urządzenia danych wejściowych.
Ta właściwość nie ma zastosowania dla przycisków.
Joy Num Właściwość wskazuje dżojstik, z którego pochodzą
dane wejściowe. Domyślnie dane wejściowe
są pobierane z wszystkich dżojstików.

Skrypty przeznaczone do obsługi


danych wejściowych
Po ustawieniu osi w menedżerze InputManager praca z nimi w kodzie jest
łatwa. W celu uzyskania dostępu do danych wejściowych użytkownika będziemy
używać obiektu Input, a dokładnie wykorzystamy metodę GetAxis(). Zada‐
Dane wejściowe 169

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

Odczyt danych wejściowych użytkownika


W tym miejscu przedstawiono przykład pracy z osiami pionowymi i pozio-
mymi, co pozwoli Ci na lepsze zrozumienie, jak używać danych wejściowych
użytkownika.
1. Utwórz nowy projekt lub scenę. Do projektu dodaj skrypt o nazwie
PlayerInput, a następnie dołącz go do obiektu Main Camera.
2. W metodzie Update() skryptu PlayerInput umieść przedstawiony
poniżej kod.
float hVal = Input.GetAxis("Horizontal");
float vVal = Input.GetAxis("Vertical");

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.

Dane wejściowe z określonych klawiszy


Wprawdzie pracujesz z ogólnymi osiami w celu pobrania danych wejściowych,
ale czasami trzeba ustalić, czy został naciśnięty określony klawisz. To również
wymaga użycia wspomnianego wcześniej obiektu Input. Jednak tym razem
wykorzystasz metodę GetKey(). Metoda odczytuje specjalny kod odpowiada‐
jący wskazanemu klawiszowi. Następnie zwraca wartość true, jeśli klawisz
jest aktualnie naciśnięty, lub false w przeciwnym razie. W celu ustalenia,
czy aktualnie jest naciśnięty klawisz K, należy użyć poniższego wywołania:
bool isKeyDown = Input.GetKey(KeyCode.K);
170 Lekcja 9. Skrypty — część 2.

Wyszukiwanie kodów klawiszy


Każdy klawisz ma przypisany określony kod. Ustalenie kodu konkretnego
klawisza jest możliwe na podstawie dokumentacji dla środowiska Unity.
Alternatywne rozwiązanie polega na wyszukaniu kodów za pomocą narzę-
dzi wbudowanych w oprogramowanie MonoDevelop. Kiedy pracujesz nad
skryptem w MonoDevelop, zawsze możesz wpisać nazwę obiektu i kropkę.
To spowoduje wyświetlenie rozwijanej listy wraz z wszystkimi dostępnymi
opcjami. Podobnie wpisanie nawiasu otwierającego po nazwie metody
spowoduje wyświetlenie tej samej rozwijanej listy zawierającej różne opcje.
Na rysunku 9.2 pokazano automatycznie rozwijaną listę pomagającą
w wyszukaniu kodu dla klawisza Esc.

RYSUNEK 9.2.
Automatycznie
rozwijana lista
w edytorze
oprogramowania
MonoDevelop

 Wypróbuj samodzielnie

Odczyt naciśnięcia określonego klawisza


W tym ćwiczeniu utworzysz skrypt pozwalający na ustalenie, czy naciśnięto
określony klawisz.
1. Utwórz nowy projekt lub scenę. Do projektu dodaj skrypt o nazwie
PlayerInput, a następnie dołącz go do obiektu Main Camera.
2. W metodzie Update() skryptu PlayerInput umieść przedstawiony
poniżej kod.
if(Input.GetKey(KeyCode.M))
print("Klawisz 'M' został naciśnięty.");
3. Zapisz skrypt i uruchom scenę. Zobacz, co się stanie po naciśnięciu
klawisza M.

Dane wejściowe myszy


Poza naciśnięciami klawiszy trzeba również przechwytywać dane wejściowe
dostarczane przez użytkownika za pomocą myszy. Istnieją dwa komponenty
danych wejściowych myszy; są to przyciski myszy i ruch myszą. Ustalenie,
czy został naciśnięty przycisk myszy, jest bardzo podobne do omówionego
wcześniej sposobu określania naciśnięć klawiszy. W przypadku myszy również
będziemy używać obiektu Input, ale tym razem skorzystamy z metody
GetMouseButtonDown(). Metoda pobiera liczbę całkowitą z zakresu od 0 do 2
Dane wejściowe 171

wskazującą interesujący nas przycisk myszy. Metoda zwraca wartość boolow‐


ską określającą, czy wskazany przycisk został naciśnięty. Kod pozwalający na
sprawdzenie naciśnięcia przycisku myszy może mieć następującą postać.
bool isButtonDown;
isButtonDown = Input.GetMouseButtonDown(0); // Lewy przycisk myszy.
isButtonDown = Input.GetMouseButtonDown(1); // Prawy przycisk myszy.
isButtonDown = Input.GetMouseButtonDown(2); // Środkowy przycisk myszy.
Ruch myszą może się odbywać jedynie wzdłuż osi X i Y. Aby pobrać informacje
o ruchu myszą, używamy metody GetAxis() obiektu Input. Nazwy Mouse X
i Mouse Y można wykorzystać do odczytania informacji o ruchu wzdłuż osi,
odpowiednio, X i Y. Kod pozwalający na odczyt ruchu myszą może mieć nastę‐
pującą postać.
float value;
value = Input.GetAxis("Mouse X"); // Ruch wzdłuż osi X.
value = Input.GetAxis("Mouse Y"); // Ruch wzdłuż osi Y.
W przeciwieństwie do naciśnięć przycisków, ruch myszą jest mierzony przez
zmianę położenia od chwili wygenerowania poprzedniej klatki. Ogólnie rzecz
biorąc, przytrzymanie klawisza spowoduje zwiększanie wartości, aż do osią‐
gnięcia jej maksimum na poziomie –1 lub 1 (w zależności od tego, czy jest
dodatnia, czy ujemna). W przypadku ruchu myszą otrzymywane są mniejsze
wartości, ponieważ są mierzone i zerowane dla każdej klatki.

 Wypróbuj samodzielnie

Odczyt ruchu myszą


W tym ćwiczeniu utworzysz skrypt pozwalający na odczyt ruchu myszy,
a dane dotyczące ruchu będą wyświetlone w oknie konsoli.
1. Utwórz nowy projekt lub scenę. Do projektu dodaj skrypt o nazwie
PlayerInput, a następnie dołącz go do obiektu Main Camera.
2. W metodzie Update() skryptu PlayerInput umieść przedstawiony
poniżej kod.
float mxVal = Input.GetAxis("Mouse X");
float myVal = Input.GetAxis("Mouse Y");
if(mxVal != 0)
print("Ruch myszą wzdłuż osi X: " + mxVal);
if(myVal != 0)
print("Ruch myszą wzdłuż osi Y: " + myVal);
3. Zapisz skrypt i uruchom scenę. Wyświetl okno konsoli i zobacz, jakie
dane wyjściowe będą wyświetlane podczas ruchu myszą.
172 Lekcja 9. Skrypty — część 2.

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);

// Rotacja obiektu wokół osi Z.


transform.Rotate(0f, 0f, 1f);

// Dwukrotne zwiększenie obiektu we wszystkich kierunkach.


transform.localScale = new Vector3(1.5f, 1.5f, 1.5f);
Ponieważ Translate() i Rotate() są metodami, umieszczenie powyższego
fragmentu kodu w metodzie Update() spowoduje, że obiekt będzie nieustan‐
nie przesuwał się wzdłuż dodatniej osi X i jednocześnie będzie obracał się
wokół osi Z.

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.

Wyszukanie innych obiektów


Pierwszy i najłatwiejszy sposób wyszukania innych obiektów polega na uży‐
ciu edytora. Kiedy utworzysz na poziomie klasy zmienną publiczną typu
GameObject, zyskujesz możliwość po prostu przeciągnięcia obiektu na kom‐
ponent skryptu w panelu Inspector. Kod przygotowujący odpowiednią konfi‐
gurację może przedstawiać się następująco.
// Ten wiersz jest tylko w celu zapewnienia punktu odniesienia.
public class SomeClassScript : MonoBehaviour {

// To jest obiekt gry, do którego chcesz uzyskać dostęp.


public GameObject objectYouWant;

// Ten wiersz jest tylko w celu zapewnienia punktu odniesienia.


Void Start() {
}
}
Po dołączeniu skryptu do obiektu gry w panelu Inspector zobaczysz właściwość
o nazwie Object You Want (patrz rysunek 9.3). Po prostu przeciągnij dowolny
obiekt gry na tę właściwość, a uzyskasz do niego dostęp z poziomu skryptu.

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 {

// To jest obiekt gry, do którego chcesz uzyskać dostęp.


public GameObject target;

// Ten wiersz jest tylko w celu zapewnienia punktu odniesienia.


void Start() {
target = GameObject.Find("Cube");
}
}
Wadą metody Find() jest to, że zwraca po prostu pierwszy znaleziony ele‐
ment o podanej nazwie. Jeżeli na scenie znajduje się wiele obiektów Cube,
wtedy nie będzie wiadomo, który z nich jest zwracany.
Ostatnim sposobem wyszukania obiektu jest użycie jego tagu. Tag obiektu
przypomina warstwę (warstwy zostały omówione wcześniej). Jedyna różnica
między tagiem a warstwą polega na semantyce. Warstwa jest używana dla
szerokiej kategorii interakcji, podczas gdy tag tylko do prostej identyfikacji.
Utworzenie tagu jest możliwe za pomocą menedżera TagManager (wybierz
opcję Edit/Project Settings/Tags). Na rysunku 9.4 pokazano, jak dodać nowy
tag za pomocą menedżera TagManager.

RYSUNEK 9.4.
Dodawanie
nowego tagu

Po utworzeniu tagu należy po prostu dołączyć go do obiektu za pomocą roz‐


wijanej listy Tag w panelu Inspector (patrz rysunek 9.5).
Po dodaniu do obiektu tag można odszukać za pomocą metody FindWithTag().
Uzyskanie dostępu do innych obiektów 175

RYSUNEK 9.5.
Wybór tagu

// Ten wiersz jest tylko w celu zapewnienia punktu odniesienia.


public class SomeClassScript : MonoBehaviour {

// To jest obiekt gry, do którego chcesz uzyskać dostęp.


public GameObject target;

// Ten wiersz jest tylko w celu zapewnienia punktu odniesienia.


void Start() {
target = GameObject.FindWithTag("TargetCube");
}
}

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.

Modyfikacja komponentów obiektu


Po uzyskaniu odniesienia do innego obiektu praca z komponentami tego obiektu
jest prawie w 100% taka sama. Jedyna różnica polega na tym, że zamiast poda‐
wać nazwę komponentu, konieczne jest wpisanie zmiennej obiektu i kropki.
// Uzyskanie dostępu do komponentu lokalnego (tego rozwiązania należy unikać).
transform.Translate(0, 0, 0);

// Uzyskanie dostępu do obiektu docelowego (takie rozwiązanie należy stosować).


targetObject.transform.Translate(0, 0, 0);
176 Lekcja 9. Skrypty — część 2.

 Wypróbuj samodzielnie

Transformacja obiektu docelowego


Poświęć chwilę na przećwiczenie modyfikacji obiektu docelowego za
pomocą skryptu.
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 TargetCubeScript i dołącz go do obiektu
Main Camera. Następnie w edytorze MonoDevelop wprowadź
do utworzonego skryptu przedstawiony poniżej kod.
// To jest obiekt gry, do którego chcesz uzyskać dostęp.
public GameObject target;

// Ten wiersz jest tylko w celu zapewnienia punktu odniesienia.


void Start() {
target = GameObject.Find("Cube");
}

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

Pytanie: Dlaczego w rozdziale nie przedstawiono więcej informacji


na temat padów?
Odpowiedź: Problem związany z padami do gier polega na tym, że są one
różne. Ponadto są odmiennie traktowane przez poszczególne systemy
operacyjne. Dlatego też padów nie omawiałem w rozdziale — ich ogromne
zróżnicowanie nie pozwoliłoby na zachowanie spójności tekstu, a ponadto
nie każdy ma pad do gier.
Pytanie: Czy każdy komponent może być edytowany przez skrypt?
Odpowiedź: Tak. Dotyczy to przynajmniej wbudowanych komponentów.

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

W czasie tej lekcji:


 poznasz podstawy dotyczące brył sztywnych,
 dowiesz się, jak używać komponentów Collider,
 nauczysz się korzystać ze skryptów wraz z wyzwalaczami,
 zobaczysz, jak stosować raycasting.
W tej lekcji dowiesz się, jak pracować z szeroko rozpowszechnionymi
w grach wideo koncepcjami fizycznymi, czyli kolizjami. Ujmując rzecz naj-
prościej, kolizja wskazuje, że krawędź jednego obiektu zetknęła się z innym
obiektem. Na początku lekcji dowiesz się, czym są bryły sztywne oraz jak
można je wykorzystać w grze. Następnie przejdziesz do eksperymentów
z wbudowanym w Unity i oferującym użyteczne możliwości silnikiem fizycz-
nym. W trakcie eksperymentów będziesz wywoływać kolizje obiektów.
Dalej w tej lekcji poznasz znacznie subtelniejsze sposoby użycia kolizji
wraz z wyzwalaczami. Na końcu przedstawione zostanie wykorzystanie
techniki raycastingu do wykrywania kolizji.
180 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

Komponent Rigidbody zawiera wiele nowych właściwości, z którymi nie mia‐


łeś okazji się zetknąć. Krótkie ich omówienie znajdziesz w tabeli 10.1.

Tabela 10.1. Właściwości komponentu Rigidbody


Właściwość Opis
Mass Masa obiektu wyrażona w dowolnych jednostkach.
Cięższy obiekt będzie miał większą masę.
Drag Właściwość określa opór powietrza, jaki będzie napotykał
obiekt podczas poruszania się. Większy opór oznacza
konieczność użycia większej siły do przesunięcia obiektu
i szybciej spowoduje zatrzymanie poruszającego się
obiektu. Wartość 0 omawianej właściwości oznacza brak
oporu powietrza.
Angular Drag Właściwość podobna do Drag, oznacza opór powietrza
w trakcie obracania obiektu.
Use Gravity Właściwość określa, czy środowisko Unity ma obliczać
grawitację dla danego obiektu. Grawitacja w mniejszym
lub większym stopniu wpływa na obiekt, w zależności
od oporu powietrza.
Is Kinematic Włączenie tego pola wyboru powoduje, że silnik fizyczny
w Unity nie będzie miał wpływu na dany obiekt. Zdarzają
się sytuacje, w których chcesz, aby obiekt był bryłą
sztywną, ale nie podlegał działaniu wbudowanego
w Unity silnika fizycznego.
Bryły sztywne 181

Tabela 10.1. Właściwości komponentu Rigidbody — ciąg dalszy


Właściwość Opis
Interpolate Właściwość określa, czy i jak będzie następowało
wygładzenie ruchu obiektu. Domyślną opcją wybraną
w tej właściwości jest Smooth. W tym przypadku
interpolacja jest oparta na wygładzeniu w poprzedniej
klatce. Z kolei opcja Extrapolate opiera wygładzanie
na następnej planowanej klatce. Zaleca się włączenie
omawianej właściwości dla obiektu gracza i wyłączenie
jej dla wszystkich pozostałych. W ten sposób osiągniesz
najlepszą wydajność i jakość.
Collision Właściwość określa sposób wykrywania kolizji. Domyślną
Detection opcją jest Discrete, wówczas każdy obiekt jest sprawdzany
względem pozostałych. Opcja Continuous może okazać
się pomocna, jeśli występują problemy z wykrywaniem
kolizji dla bardzo szybko poruszających się obiektów.
Musisz jednak mieć świadomość, że użycie opcji
Continuous może mieć ogromny, negatywny wpływ
na wydajność. Z kolei zastosowanie opcji Continuous
Dynamic spowoduje użycie wykrywania Discrete względem
innych obiektów Discrete oraz wykrywania Continuous
względem innych obiektów Continuous.
Constraints Właściwość powoduje określenie ograniczeń ruchu
wymuszanych na obiekcie przez bryłę sztywną. Domyślnie
omawiana właściwość jest wyłączona. Zamrożenie
położenia osi uniemożliwi obiektowi poruszanie się
wzdłuż danej osi. Natomiast zamrożenie osi rotacji
uniemożliwi obiektowi obracanie się wokół danej osi.

 Wypróbuj samodzielnie

Użycie brył sztywnych


Poświęć chwilę i zobacz bryły sztywne w akcji.
1. Utwórz nowy projekt lub scenę. Do sceny dodaj sześcian i umieść go
w położeniu (0, 1, –5). Opcjonalnie do sceny możesz dodać również
światło kierunkowe.
2. Uruchom scenę. Zobacz, jak sześcian pływa przed kamerą.
3. Do obiektu dodaj komponent Rigidbody (wybierz opcję
Components/Physics/Rigidbody).
4. Uruchom scenę. Zobacz, jak sześcian spada ze względu na grawitację.
5. Kontynuuj eksperymenty z właściwościami Drag i Constraints.
182 Lekcja 10. Kolizje

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.

Wymagania dotyczące kolizji


Warto w tym miejscu wspomnieć, że obiekt nie wymaga komponentu
Rigidbody, aby możliwe było wykrywanie kolizji. Do wykrycia kolizji konieczne
jest, aby wszystkie uczestniczące w niej obiekty miały dodany komponent
Collider. Komponent Rigidbody został użyty w tej lekcji, ponieważ pomaga
w wyjaśnieniu pewnych tematów i umożliwia obiektom spadek. Ponadto
komponent Rigidbody jest wymagany przez wyzwalacze kolizji, ale do tego
zagadnienia powrócę dalej w tej lekcji.

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

Po dodaniu do obiektu właściwości komponentu Collider są wyświetlane


w panelu Inspector. Właściwości komponentu Collider wymieniono w tabeli 10.2.
Kolizje 183

Tabela 10.2. Właściwości komponentu Collider


Właściwość Opis
Is Trigger Właściwość określa, czy komponent Collider jest oparty
na fizyce, czy na wyzwalaczu. Wyzwalacze zostaną
dokładnie omówione w następnej lekcji.
Material Komponent Collider pozwala na stosowanie materiałów
fizycznych dla obiektów i ich zmianę zgodnie
z zachowaniem danego materiału. Dlatego też obiekt
może zachowywać się jak np. drewno, metal, guma itd.
Materiały fizyczne to temat, który zostanie poruszony
dalej w tej lekcji.
Center Właściwość wskazuje punkt centralny komponentu
Collider względem zawierającego go obiektu.
Size Wielkość komponentu Collider.
Geometric Jeżeli komponent Collider jest kulą lub kapsułą, może być
properties dostępna właściwość dodatkowa, np. Radius (promień).
Jej zachowanie jest zgodnie z oczekiwaniami.

Łączenie i dopasowywanie komponentów Collider


Zastosowanie na obiekcie komponentów Collider o różnych kształtach
może przynieść interesujące efekty. Przykładowo komponent Collider
o kształcie sześcianu większego niż obiekt sześcianu powoduje, że sześcian
wygląda jakby pływał nad powierzchnią. Podobnie komponent Collider
mniejszy niż obiekt powoduje, że obiekt „tonie” pod powierzchnią. Co
więcej, dodanie do sześcianu komponentu Collider w kształcie kuli pozwala
sześcianowi na toczenie się, tak jak kula. Eksperymenty z różnymi sposobami
definiowania komponentu Collider dla obiektów zapewnią Ci wiele rozrywki.

 Wypróbuj samodzielnie

Eksperymenty z komponentem Collider


Najwyższy czas wypróbować niektóre komponenty Collider i zobaczyć, jak
wchodzą w interakcje z innymi. Upewnij się, że zapisałeś projekt tego ćwi-
czenia, ponieważ powrócisz do niego jeszcze w tej lekcji.
1. Utwórz nowy projekt lub scenę. Dodaj dwa sześciany i światło
kierunkowe. Pierwszy sześcian umieść w położeniu (0, 1, –5) i dodaj
komponent Rigidbody. Drugi sześcian umieść w położeniu (0, –1, –5)
i przeskaluj (4, 0.1, 4) oraz zastosuj rotację (0, 0, 15). Do drugiego
sześcianu dodaj komponent Rigidbody oraz usuń zaznaczenie pola
wyboru Use Gravity.
184 Lekcja 10. Kolizje

2. Uruchom scenę i zobacz, jak sześcian znajdujący się na górze


upada na dolny. Następnie oba sześciany spadają ze sceny. Teraz
dla dolnego sześcianu we właściwości Constraints komponentu
Rigidbody zamroź wszystkie trzy osie dla położenia i rotacji.
3. Uruchom ponownie scenę i zobacz, że górny sześcian spada na dolny
i zatrzymuje się na nim. Usuń Box Collider z górnego sześcianu (prawym
przyciskiem myszy kliknij komponent Box Collider i wybierz opcję
Remove Component). Teraz do górnego sześcianu dodaj Sphere
Collider (wybierz opcję Component/Physics/Sphere Collider). W dolnym
sześcianie zastosuj rotację (0, 0, 350).
4. Uruchom scenę. Zauważ, że sześcian stacza się z pochylni jak kula,
choć tak naprawdę jest sześcianem.
5. Kontynuuj eksperymenty z różnymi komponentami Collider. Innym
ciekawym eksperymentem jest modyfikacja ograniczeń nakładanych
na dolny sześcian. Spróbuj zamrozić jedynie oś Y dla położenia i odmrozić
wszystkie pozostałe. Wypróbuj różne sposoby wywoływania kolizji
między obiektami.

Skomplikowane komponenty Collider


Prawdopodobnie zauważyłeś komponent o nazwie Mesh Collider. Celowo
został pominięty w tekście, ponieważ wymaga większej praktyki w mode-
lowaniu niż wszystko pozostałe. Ogólnie rzecz ujmując, komponent Mesh
Collider ma dokładnie kształt modelu 3D. Wprawdzie to brzmi użytecznie,
ale w praktyce może drastycznie zmniejszyć wydajność gry. Co więcej,
środowisko Unity nakłada ograniczenie w zakresie liczby wielokątów
dozwolonych dla Mesh Collider. Znacznie lepszym nawykiem będzie utwo-
rzenie skomplikowanego komponentu Collider za pomocą kilku podstawo-
wych. Jeżeli masz model człowieka, spróbuj użyć dla głowy komponentu
Collider w postaci kuli, natomiast dla tułowia, rąk i nóg komponentów
Collider w postaci kapsuły. W ten sposób unikniesz spadku wydajności,
a nadal zapewnisz sobie precyzyjne wykrywanie kolizji.

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

o nazwach Bouncy, Ice, Metal, Rubber i Wood. W celu utworzenia własnego


materiału w panelu Inspector kliknij prawym przyciskiem myszy katalog Assets
i wybierz opcję Create/Physic Material.
Materiał fizyczny ma pewien zestaw właściwości określających jego zacho‐
wanie na poziomie fizycznym (patrz rysunek 10.3). Właściwości materiałów
fizycznych zostały wymienione w tabeli 10.3. Materiał fizyczny można nałożyć
na obiekt przez przeciągnięcie materiału z panelu Project na obiekt.

RYSUNEK 10.3.
Właściwości
materiału
fizycznego

Efekt zastosowania materiałów fizycznych może być subtelny lub wyraźnie


widoczny, to zależy tylko od Ciebie. Wypróbuj je samodzielnie i zobacz, jakie
interesujące zachowania można zdefiniować.

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

TABELA 10.3. Właściwości materiałów fizycznych


Właściwość Opis
Dynamic Właściwość określa tarcie, jakie będzie występować
Friction podczas poruszania się obiektu. Mniejsze wartości
powodują, że obiekt jest bardziej śliski.
Static Friction Właściwość określa tarcie, jakie będzie występować dla
nieruchomego obiektu. Mniejsze wartości powodują,
że obiekt jest bardziej śliski.
Bounciness Właściwość określa ilość energii pozostawioną
ze zderzenia. Wartość 1 powoduje, że obiekt będzie
podskakiwał bez utraty energii, czyli w nieskończoność.
Z kolei wartość 0 uniemożliwia podskakiwanie obiektu.
Friction Właściwość określa sposób obliczania tarcia dla dwóch
Combine zderzających się obiektów. Użyte może być tarcie
uśrednione, najmniejsze, największe lub pomnożone.
Bounce Właściwość określa sposób obliczania podskakiwania
Combine dla dwóch zderzających się obiektów. Użyta może
być wartość uśredniona, najmniejsza, największa
lub pomnożona.
Friction Właściwości należy użyć, jeśli obiekt ma mieć odmienną
Direction 2 wartość tarcia w określonym kierunku. (Przykładem może
być tutaj łyżwa).
Dynamic Podobnie jak w przypadku właściwości Dynamic Friction,
Friction 2 ale ta wartość jest stosowana tylko we wskazanym
kierunku. Właściwość może być użyta tylko w połączeniu
z właściwością Friction Direction 2.
Static Friction 2 Podobnie jak w przypadku właściwości Static Friction,
ale ta wartość jest stosowana tylko we wskazanym
kierunku. Właściwość może być użyta tylko w połączeniu
z właściwością Friction Direction 2.

void OnTriggerEnter(Collider other)


{
print("Obiekt przekroczył krawędź.");
}

Wyzwalacz nie działa


Aby wyzwalacz działał, obiekt musi mieć dodany komponent Rigidbody.
Jeżeli obiekt pozbawiony wymienionego komponentu wejdzie do wyzwa-
lacza, nie spowoduje żadnego efektu. Jeśli zauważysz, że pewne obiekty na
scenie nie wyzwalają oczekiwanych akcji, upewnij się, że dodałeś do tych
obiektów komponent Rigidbody.
Raycasting 187

Być może zwróciłeś uwagę na jeden parametr metod wyzwalaczy, czyli na


zmienną innego typu komponentu Collider. To jest odniesienie do innego
obiektu, który wszedł do wyzwalacza. Za pomocą tej zmiennej można w prak‐
tycznie dowolny sposób manipulować obiektem. Przykładowo przedstawiony
wcześniej fragment kodu można zmodyfikować tak, aby komunikat zawierał
nazwę obiektu wchodzącego do wyzwalacza.
void OnTriggerEnter(Collider other)
{
print(other.gameObject.name + " wszedł do wyzwalacza.");
}
Istnieje możliwość podjęcia znacznie radykalniejszych działań, np. zniszczenia
obiektu, który wszedł do wyzwalacza.
void OnTriggerEnter(Collider other)
{
Destroy(other.gameObject);
}

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

Druga metoda obsługi raycastingu to wyszukanie obiektów, które będą koli‐


dowały z promieniem. W tym przypadku metoda korzysta ze specjalnego typu
zmiennej RaycastHit. Wiele wersji metody Raycast() wykorzystuje (lub
nie) odległość i maskę. Poniżej przedstawiono najbardziej podstawowy sposób
użycia tej wersji metody:
bool Raycast(Vector3 origin, Vector3 direction, out Raycast hit,
float distance);
Istnieje wiele interesujących kwestii dotyczących powyższej wersji metody.
Być może zauważyłeś użycie nowego słowa kluczowego, z którym się wcze‐
śniej nie spotkałeś, czyli out. To słowo kluczowe oznacza, że w trakcie wyko‐
nywania metody zmienna hit będzie zawierała aktualnie napotkany obiekt.
Po zakończeniu działania metoda praktycznie zwraca wartość hit.

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

Utworzenie pewnych promieni


W tym ćwiczeniu przygotujesz interaktywny program pozwalający na
„strzelanie”. Zadaniem programu jest wyrzucenie promienia od kamery
i zniszczenie obiektów, które staną na jego drodze. Pełny projekt zawie-
rający to ćwiczenie (Hour10_RaycastExercise) znajdziesz w materiałach prze-
znaczonych dla bieżącej lekcji.
1. Utwórz nowy projekt lub scenę. Do sceny dodaj cztery kule i zmień ich
nazwy: od Sphere1 do Sphere4. Następnie kule umieść w położeniach
(–1, 1, –5), (1, 1.5, –5), (–1, –2, 5) i (1.5, 0, 0).
2. Utwórz nowy skrypt o nazwie RaycastScript i dołącz go do kamery Main
Camera. W metodzie Update() skryptu umieść następujący kod.
float dirX = Input.GetAxis("Mouse X");
float dirY = Input.GetAxis("Mouse Y");

// Odwracamy osie, ponieważ przeprowadzimy wokół nich rotację.


transform.Rotate(dirY, -dirX, 0);

CheckForRaycastHit(); // Tę metodę dodamy w kolejnym kroku.


3. Teraz dodaj do skryptu metodę CheckForRaycastHit(). Umieść ją
w klasie, ale nie wewnątrz jakiejkolwiek istniejącej metody.
void CheckForRaycastHit()
{
RaycastHit hit;
if(Physics.Raycast(transform.position, transform.forward,
out hit))
{
print (hit.collider.gameObject.name + " zniszczony!");
Destroy(hit.collider.gameObject);
}
}
4. Uruchom scenę. Zauważ, że ruch myszą powoduje przesunięcie kamery.
Spróbuj wyśrodkować kamerę na kolejnych kulach. Zwróć uwagę, jak
poszczególne kule są niszczone, a odpowiedni komunikat
wyświetlany w oknie konsoli.

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

 Kiedy kula wejdzie, wyjdzie lub będzie w którymkolwiek


z wyzwalaczy, odpowiedni komunikat powinien być wyświetlony
w oknie konsoli.
Nazwa wyzwalacza, do którego weszła kula (LTrigger lub RTrigger), także
powinna znajdować się we wspomnianym powyżej komunikacie.
Powodzenia!
Lekcja 11
Druga gra — Chaos Ball

W czasie tej lekcji dowiesz się:


 jak zaprojektować grę Chaos Ball,
 jak utworzyć arenę w grze Chaos Ball,
 jak zbudować elementy gry Chaos Ball,
 jak przygotować obiekty kontrolne w grze Chaos Ball,
 jak jeszcze bardziej usprawnić grę Chaos Ball.
Nadeszła odpowiednia pora, aby po raz drugi wykorzystać zdobytą dotąd
wiedzę do utworzenia gry. W tej lekcji opracujesz aplikację Chaos Ball,
która będzie grą zręcznościową. Na początek zajmiesz się podstawowym
zaprojektowaniem elementów gry. Następnie przejdziesz do zbudowania
areny oraz obiektów gry. Każdy obiekt będzie unikalny i otrzyma specjalne
właściwości obsługi kolizji. Kolejnym krokiem będzie dodanie interaktyw-
ności, aby gra zapewniała rozrywkę. Na końcu lekcji zajmiesz się przetesto-
waniem gry oraz wprowadzeniem w niej niezbędnych usprawnień.

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

 Kontroler postaci, który znajdziesz w standardowych zasobach Unity.


 Kontroler gry, który utworzysz w Unity.
 Materiał fizyczny pozwalający na odbijanie się kul, który zostanie
utworzony w Unity.
 Kolorowe oznaczenia narożników, które zostaną wygenerowane
w Unity.
 Interaktywne skrypty, które przygotujesz w edytorze
oprogramowania MonoDevelop.

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

3. Do sceny dodaj sześcian. Umieść go w położeniu (0, 1.5, 2.5) i przeskaluj


(1.5, 3, 51). Zwróć uwagę, jak zmodyfikowany sześcian stał się jedną
ścianą muru otaczającego arenę. Nazwę sześcianu zmień na Wall.
4. W katalogu Scenes zapisz tę scenę pod nazwą Main.

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

3. W panelu Inspector nałóż teksturę Cliff (Layered Rock) na materiał


muru (patrz rysunek 11.3).
4. Kliknij i przeciągnij materiał na utworzony wcześniej obiekt muru.
Teraz przejdź do teksturowania podłoża. Ponieważ podłoże jest terenem,
będzie teksturowane nieco inaczej, o czym powinieneś już wiedzieć.
1. Po zaznaczeniu terenu w panelu Inspector wybierz narzędzie
przeznaczone do teksturowania terenu (patrz rysunek 11.4).
2. Kliknij Edit Textures/Add Texture. W wyświetlonym oknie dialogowym
Add Terrain Texture wybierz Grass (Hill) i kliknij przycisk Add.
3. Teren powinien otrzymać teksturę trawy.

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

1. Prawym przyciskiem myszy kliknij katalog Materials i wybierz


opcję Create/Physical Material. Materiałowi nadaj nazwę
SuperBouncyMaterial.
2. Ustaw dla materiału właściwości pokazane na rysunku 11.5. Ogólnie
rzecz biorąc, konieczne jest zminimalizowanie wszystkich parametrów,
które powodują redukcję energii.

RYSUNEK 11.5.
Ustawienia materiału
SuperBouncyMaterial

3. Kliknij nowy materiał, a następnie przeciągnij go na obiekt ściany


muru. Materiał zostanie automatycznie zastosowany jako materiał
fizyczny dla komponentu Collider. Powinieneś zobaczyć, że materiał
jest wymieniony we właściwości Material komponentu Box Collider.
Elementy gry 199

Zakończenie prac nad areną


Po przygotowaniu ściany i podłoża możesz przystąpić do zakończenia prac nad
areną. Najtrudniejsze zadania zostały już wykonane i pozostało tylko powie‐
lenie ściany (kliknij ją prawym przyciskiem myszy w panelu Hierarchy, a następ‐
nie wybierz opcję Duplicate). Oto kroki do wykonania.
1. Jednokrotnie powiel ścianą i nową umieść w położeniu (50, 1.5, 25).
2. Ponownie powiel ścianę, umieść ją w położeniu (25, 1.5, 0) i zastosuj
rotację (0, 90, 0).
3. Powiel ścianę utworzoną w poprzednim kroku (tę obróconą),
a następnie umieść ją w położeniu (25, 1.5, 50).
Arena powinna teraz zawierać mur składający się z wszystkich czterech ścian
i pozbawiony luk (patrz rysunek 11.1).

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

3. W panelu Hierarchy kliknij paletkę i przeciągnij na kontroler First


Person. W ten sposób paletka zostanie zagnieżdżona w kontrolerze.
Następnie zmień położenie paletki na (0, 0, 0.1) i zastosuj rotację
(0, 0, 0). Paletka znajdzie się teraz w niewielkiej odległości przed
kontrolerem.
Ostatnim krokiem jest przyśpieszenie nieco gracza. Zaznacz kontroler First
Person, a następnie w panelu Inspector rozwiń właściwość Movement kom‐
ponentu Character Motor (Script). Ustaw maksymalną szybkość do przodu
na 11, natomiast maksymalną szybkość na boki na 10.

Kula chaos ball


Kule chaos ball to szybko i szaleńczo poruszające się kule, które mają utrud‐
niać grę i przeszkadzać graczowi. Pod wieloma względami są podobne do kul
kolorowych, a więc praca polega na nadaniu im uniwersalnych zasobów.
W celu utworzenia pierwszej kuli typu chaos ball wykonaj opisane poniżej
kroki.
1. Dodaj kulę do sceny. Następnie zmień nazwę kuli na Chaos, umieść
ją w położeniu (15, 2, 25) i przeskaluj (0.5, 0.5, 0.5).
2. Kliknij materiał SuperBouncyMaterial i przeciągnij go na kulę.
3. Utwórz nowy materiał (niefizyczny) dla kuli i nadaj mu nazwę
ChaosBallMaterial. W sekcji koloru materiału wybierz kolor jasnożółty
(patrz rysunek 11.6). Nowo utworzony materiał przeciągnij na kulę.

RYSUNEK 11.6.
Ustawienia
materiału
ChaosBallMaterial

4. Do kuli dodaj komponent Rigidbody. Właściwości Angular Drag ustaw


wartość 0 i usuń zaznaczenie przy Use Gravity. Z rozwijanego menu
właściwości Collision Detection wybierz opcję Continuous. Z kolei we
właściwości Constraints zamroź położenie Y — nie chcesz, aby kula
mogła poruszać się w górę oraz w dół.
Elementy gry 201

5. Przejdź do menedżera TagManager (wybierz opcję Edit/Project


Settings/Tags), rozwiń sekcję Tags, klikając strzałkę znajdującą się
obok nazwy sekcji, a następnie w pozycji Element 0 dodaj tag Chaos.
Przy okazji dodaj także tagi Green, Orange, Red i Blue — wykorzystasz
je później w tym projekcie.
6. Zaznacz kulę, a następnie w panelu Inspector zmień jej tag na Chaos
(patrz rysunek 11.7).

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.

Listing 11.1. Skrypt VelocityScript.cs


using UnityEngine;
using System.Collections;

public class VelocityScript : MonoBehaviour {


public float max = 50;

// Metoda używana do inicjacji.


void Start () {
rigidbody.velocity = new Vector3(Random.Range(0, max), 0,
Random.Range(0,
max));
}
// Metoda wywoływana raz w trakcie każdej klatki.
void Update () {
}
}
202 Lekcja 11. Druga gra — Chaos Ball

Jak możesz zobaczyć w listingu, metoda Random.Range() jest użyta w celu


nadania kuli prędkości początkowej dla osi X i Y, wygenerowanej losowo
w przedziale od 0 do 50. Parametrami funkcji Random.Range() są dwie liczby,
natomiast wartością zwrotną jest liczba z zakresu tworzonego przez dwie
liczby będące parametrami.
Uruchom scenę i zobacz, jak kula porusza się po arenie. Na tym etapie kula
chaos ball jest już gotowa. W panelu Hierarchy powiel tę kulę czterokrotnie.
Rozrzuć nowo utworzone kule po arenie (upewnij się, że zmieniają jedynie
położenie w zakresie osi X i Z), a ponadto dla każdej z nich zastosuj inną
wartość rotacji wokół osi Y. Pamiętaj, że ruch wzdłuż osi Y jest niemożliwy
i dlatego każda kula powinna mieć wartość 2 dla osi Y.

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

Jeżeli teraz uruchomisz scenę, powinieneś zobaczyć niebieską kulę szybko


poruszającą się po arenie. Można więc przystąpić do budowania trzech pozosta‐
łych kul, z których każda będzie kopią niebieskiej. W celu utworzenia pozo‐
stałych kul wykonaj wymienione poniżej kroki.
1. Powiel istniejącą niebieską kulą i nowym kulom nadaj nazwy
odpowiadające ich kolorom, czyli Red, Orange i Green.
2. Nowym kulom nadaj tagi odpowiadające nazwie. Bardzo ważne jest,
aby nazwa i tag były dokładnie takie same.
3. Przeciągnij odpowiednie materiały na nowe kule. Bardzo ważne jest,
aby kolor kuli odpowiadał jej nazwie.
4. Nowe kule umieść w losowo wybranych położeniach, zmień dowolnie
ich rotację, ale upewnij się, że wartość Y dla położenia wynosi 2.
Na tym etapie prac elementy gry są już gotowe. Kiedy uruchomisz scenę, zoba‐
czysz wszystkie kule poruszające się po arenie.

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

Kolejnym krokiem jest utworzenie skryptu o nazwie GoalScript i dołączenie go


do niebieskiego narożnika. Zawartość skryptu przedstawiono w listingu 11.2.

Listing 11.2. Skrypt GoalScript.cs


using UnityEngine;
using System.Collections;

public class GoalScript : MonoBehaviour {


private bool solved = false;

// Metoda używana do inicjacji.


void Start () {
}

// Metoda wywoływana raz w trakcie każdej klatki.


void Update () {
}

void OnTriggerEnter(Collider other)


{
if(other.tag == tag)
{
solved = true;
other.rigidbody.isKinematic = true;
}
}

public bool IsSolved()


{
return solved;
}
}
Obiekty kontrolne 205

Jak możesz zobaczyć w skrypcie, metoda OnTriggerEnter() sprawdza wartość


tagu każdego obiektu zderzającego się z narożnikiem i porównuje z tagiem
narożnika. W przypadku dopasowania tagów kula zostaje unieruchomiona,
a cel oznaczony jako osiągnięty.

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.

Po przygotowaniu skryptu i dołączeniu go do narożnika (celu) możesz przy‐


stąpić do powielania narożnika. Aby utworzyć pozostałe, wykonaj wymienione
poniżej kroki.
1. Powiel narożnik BlueGoal i powstałym narożnikom nadaj nazwy
odpowiadające kolorom, czyli RedGoal, GreenGoal i OrangeGoal.
2. Tag celu zmień na odpowiadający kolorowi.
3. Kolor światła narożnika zmień na odpowiadający celowi.
4. Umieść narożnik w odpowiednim położeniu. Kolory mogą być
umieszczane w dowolnych narożnikach, jednak każdy kolor
w oddzielnym. Trzy pozostałe położenia narożników to (1.6, 2, 48.4),
(48.4, 2, 1.6) i (48.4, 2, 48.4).
Wszystkie narożniki powinny być już przygotowane i w pełni gotowe do
działania.

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

3. Po zaznaczeniu kontrolera gry kliknij i przeciągnij poszczególne


narożniki (cele) na odpowiadające im właściwości w komponencie
Game Control Script (patrz rysunek 11.10).

Listing 11.3. Skrypt GameControlScript


using UnityEngine;
using System.Collections;

public class GameControlScript : MonoBehaviour {


public GoalScript red;
public GoalScript blue;
public GoalScript orange;
public GoalScript green;

private bool isGameOver = false;

// Metoda używana do inicjacji.


void Start () {
}

// Metoda wywoływana raz w trakcie każdej klatki.


void Update () {
if(red.IsSolved() && blue.IsSolved() && orange.IsSolved()
&& green.IsSolved())
{
isGameOver = true;
}
}

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!");
}
}
}

Jak możesz zobaczyć w przedstawionym powyżej skrypcie, kontroler gry


zawiera odniesienia do wszystkich czterech celów. W trakcie generowania
każdej klatki kontroler sprawdza wszystkie cztery cele, aby ustalić, czy zostały
osiągnięte. Jeżeli tak się stanie, zmiennej isGameOver przypisana zostaje war‐
tość true i na ekranie wyświetlany jest komunikat kończący grę.
Gratulacje! W ten sposób zakończyłeś tworzenie gry Chaos Ball.
Usprawnienie gry 207

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

W czasie tej lekcji:


 poznasz podstawy prefabrykatów,
 dowiesz się, jak pracować z własnymi prefabrykatami,
 zobaczysz, jak ustanawiać prefabrykaty w kodzie.
Prefabrykat to skomplikowany obiekt istniejący w postaci pakietu, co
pozwala na jego ponowne, wielokrotne wykorzystanie przy jedynie mini-
malnym wysiłku. W tej lekcji poznasz prefabrykaty. Na początku dowiesz
się, czym są prefabrykaty i do czego służą. Następnie przejdziesz do two-
rzenia prefabrykatów w Unity. Poznasz również koncepcję dziedziczenia.
Na końcu lekcji dowiesz się, jak dodawać prefabrykaty do sceny zarówno
za pomocą edytora, jak i kodu.
212 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.

Terminologia związana z prefabrykatami


Przed podjęciem pracy z prefabrykatami trzeba koniecznie poznać pewną
terminologię. Jeżeli koncepcje programowania zorientowanego obiektowo nie
są Ci obce, możesz dostrzec pewne podobieństwa.
 Prefabrykat. Jest to obiekt bazowy, wyświetlany jedynie w panelu
Project. Ten obiekt możesz potraktować jak matrycę.
 Egzemplarz. Umieszczony na scenie rzeczywisty obiekt prefabrykatu.
Jeżeli prefabrykat jest matrycą samochodu, egzemplarz będzie
rzeczywistym samochodem. Jeżeli obiekt w panelu Scene odwołuje
się do prefabrykatu, to odnosi się do egzemplarza prefabrykatu.
Wyrażenie egzemplarz prefabrykatu jest synonimem obiektu
prefabrykatu.
Podstawy prefabrykatów 213

 Tworzenie egzemplarza. Jest to proces tworzenia egzemplarza


prefabrykatu. Wyrażenie jest używane w następujący sposób: muszę
utworzyć egzemplarz tego prefabrykatu.
 Dziedziczenie. To nie jest ta sama koncepcja jak koncepcja
dziedziczenia w językach programowania. W środowisku Unity
pojęcie dziedziczenie odnosi się do sytuacji, gdy wszystkie
egzemplarze prefabrykatu są połączone z samym prefabrykatem.
Dokładne omówienie tej kwestii znajdziesz dalej w tej lekcji.

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

Kiedy spojrzysz na panel Hierarchy, zawsze możesz wskazać obiekty będące


prefabrykatami, ponieważ ich nazwy są wyświetlane w kolorze niebieskim
(patrz rysunek 12.2). Podobnie jak w przypadku skomplikowanych obiektów
214 Lekcja 12. Prefabrykaty

RYSUNEK 12.2.
W panelu
Hierarchy
egzemplarze
prefabrykatów
są wyświetlane
w kolorze
niebieskim

niebędących prefabrykatami, także skomplikowane egzemplarze prefabryka‐


tów zawsze mają strzałkę pozwalającą na rozwinięcie zawartości i modyfi‐
kację obiektów znajdujących się w środku.
Ponieważ prefabrykat jest zasobem należącym do projektu, a nie konkretnej
sceny, to edycję prefabrykatu można przeprowadzić w panelu Project. Podob‐
nie jak obiekty gry, także prefabrykaty mogą być skomplikowane. Edycja
elementów potomnych prefabrykatu odbywa się przez kliknięcie strzałki
wyświetlanej po prawej stronie prefabrykatu (patrz rysunek 12.3). Kliknięcie
tej strzałki powoduje rozwinięcie zawartości obiektu i umożliwia jego edycję.
Ponowne kliknięcie strzałki ukrywa zawartość obiektu.

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

Kolejnym krokiem jest wypełnienie prefabrykatu zawartością. W prefabry‐


kacie można umieścić dowolny obiekt gry. Po prostu wystarczy utworzyć
obiekt tylko raz w panelu Scene, a następnie kliknąć i przeciągnąć go na zasób
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).

RYSUNEK 12.5. Kula została zagnieżdżona w sześcianie


216 Lekcja 12. Prefabrykaty

4. Za pomocą panelu Project utwórz w katalogu Assets nowy 


podkatalog i nadaj mu nazwę Prefabs. W katalogu Prefabs opracuj
nowy prefabrykat (w tym celu kliknij katalog prawym przyciskiem
myszy i wybierz opcję Create/Prefab). Prefabrykatowi nadaj nazwę
Lamp.
5. W panelu Hierarchy kliknij sześcian (zawierający kulę) i przeciągnij go na
prefabrykat w panelu Project (patrz rysunek 12.6). Prefabrykat wygląda
teraz jak lampa. Ponadto warto zauważyć, że w panelu Hierarchy
sześcian i kula są wyświetlane w kolorze niebieskim. Na tym etapie
możesz usunąć sześcian i kulę ze sceny, ponieważ znajdują się
w prefabrykacie.

RYSUNEK 12.6. Dodanie obiektu do prefabrykatu

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

Tworzenie wielu egzemplarzy prefabrykatu


W poprzednim ćwiczeniu przygotowałeś prefabrykat Lamp. Tym razem
wykorzystasz go do umieszczenia wielu lamp na scenie. Zapisz utworzoną
tutaj scenę, ponieważ będzie potrzebna dalej w tej lekcji.
1. W projekcie poprzedniego ćwiczenia utwórz nową scenę.
2. Do sceny dodaj sześcian, umieść go w położeniu (0, 0, 0) i przeskaluj
(5, 0.1, 5).
3. Kliknij prefabrykat Lamp i przeciągnij go na spłaszczony wcześniej
sześcian (patrz rysunek 12.7). Tę operację powtórz dowolną ilość razy.
Zwróć uwagę, jak lampy mogą być łatwo umieszczane na sześcianie.
Ponadto zauważ, że nazwą obiektu nie jest już Cube. Obecna nazwa
obiektu to Lamp, czyli taka sama jak prefabrykatu.

RYSUNEK 12.7. Umieszczenie lamp na scenie

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

rozwinąć (wyświetlić zawartość) prefabrykat w opisany wcześniej sposób,


a następnie odpowiednio zmienić obiekty prefabrykatu.
Drugim sposobem modyfikacji zasobu prefabrykatu jest przeciągnięcie egzem‐
plarza na scenę. Wówczas można wprowadzić wszelkie konieczne modyfikacje.
Po zakończeniu pracy należy przeciągnąć egzemplarz z powrotem na zasób
prefabrykatu i tym samym go uaktualnić.

 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.

RYSUNEK 12.8. Zmodyfikowane egzemplarze lampy


3. Zaznacz jeden z egzemplarzy lampy na scenie. Wyświetl jego zawartość,
klikając w panelu Hierarchy strzałkę znajdującą się po lewej stronie
nazwy. Następnie zaznacz obiekt potomny Sphere. Światło emitowane
przez kulę z powrotem zmień na białe. Zauważ, że inne obiekty
prefabrykatów nie uległy zmianie.
Praca z prefabrykatami 219

4. Kliknij egzemplarz zmodyfikowanej lampy i przeciągnij go 


na zasób prefabrykatu (patrz rysunek 12.9). Zauważ, że teraz
wszystkie egzemplarze prefabrykatu mają znów światło w kolorze
białym.

RYSUNEK 12.9. Uaktualnienie prefabrykatu Lamp za pomocą zmodyfikowanego egzemplarza

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

Tworzenie egzemplarza prefabrykatu


w kodzie
Umieszczanie obiektów prefabrykatów na scenie jest doskonałym sposobem
na przygotowanie spójnych i zaplanowanych poziomów gry. Jednak czasami
trzeba utworzyć egzemplarze w trakcie działania gry. Być może wróg ma
ponownie pojawić się na scenie lub ma zostać umieszczony w losowo wybra‐
nym miejscu. Może się zdarzyć również następująca sytuacja: potrzebnych
będzie tak wiele egzemplarzy, że ich ręczne rozmieszczanie jest zbyt żmud‐
nym zadaniem. Wtedy, niezależnie od powodu, umieszczanie na scenie pre‐
fabrykatów za pomocą kodu jest dobrym rozwiązaniem.
Istnieją dwa sposoby umieszczania obiektów prefabrykatów na scenie i w obu
korzysta się z metody Instantiate(). Pierwszy polega na użyciu metody
Instantiate() w następujący sposób:
Instantiate(GameObject prefab);
Jak możesz zobaczyć, powyższe wywołanie metody po prostu odczytuje
zmienną obiektu gry i tworzy na jej podstawie nowy obiekt. Położenie, rotacja
i skala nowego obiektu są takie same jak prefabrykatu w panelu Project. Drugi
sposób polega na użyciu metody Instantiate() następująco:
Instantiate(GameObject prefab, Vector3 position, Quaternion rotation);
To wywołanie metody wymaga trzech parametrów. Pierwszym nadal jest
obiekt, na podstawie którego zostanie utworzony nowy. Natomiast drugi i trzeci
parametr to żądane położenie i rotacja nowego obiektu. Zapewne zauważyłeś,
że rotacja jest przechowywana w elemencie typu Quaternion. Wystarczy
wiedzieć, że środowisko Unity w taki sposób przechowuje informacje o rotacji
obiektu. Omówienie tego typu wykracza poza zakres tematyczny tej lekcji.
Przykłady użycia obu metod tworzenia obiektów za pomocą kodu znajdziesz
w ćwiczeniu przedstawionym na końcu lekcji.

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.

Listing 12.1. Skrypt PrefabGenerator.cs


using UnityEngine;
using System.Collections;

public class PrefabGenerator : MonoBehaviour {


// W panelu Inspector będziemy mieli odniesienie do prefabrykatu docelowego.
public GameObject prefab;

// Metoda używana do inicjacji.


void Start () {
}

// Metoda wywoływana raz w trakcie każdej klatki.


void Update () {
// Naciśnięcie klawisza B spowoduje wygenerowanie obiektu prefabrykatu
// w położeniu, w którym znajduje się oryginalny prefabrykat.
// Z kolei naciśnięcie klawisza spacji spowoduje wygenerowanie obiektu
// prefabrykatu
// w położeniu obiektu SpawnPoint, do którego jest dołączony skrypt.
if(Input.GetKeyDown(KeyCode.B))
Instantiate(prefab);

if(Input.GetKeyDown(KeyCode.Space))
Instantiate(prefab, transform.position,
transform.rotation);
}
}

4. Mając zaznaczony obiekt SpawnPoint, przeciągnij prefabrykat Lamp


na właściwość Prefab komponentu Prefab Generator. Teraz uruchom
scenę. Naciśnięcie klawisza B spowoduje utworzenie lampy
Ćwiczenie 223

w domyślnym położeniu prefabrykatu, natomiast naciśnięcie spacji


tworzy lampę w miejscu położenia obiektu SpawnPoint. Zwróć również
uwagę, jak prefabrykaty kolidują ze sobą i powodują różne unikalne
interakcje.
Jak możesz zauważyć, w trakcie działania sceny lampy są jedynie tworzone
i nigdy nie będą usuwane ze sceny. Dodatkowym wyzwaniem może być
utworzenie pod sceną płaszczyzny wraz wyzwalaczem powodującej usunięcie
lampy, gdy tylko zostanie na niej umieszczona. W ten sposób gra będzie usu‐
wać lampy, a tym samym po dłuższej grze wydajność nie będzie stanowiła
problemu.
224 Lekcja 12. Prefabrykaty
Lekcja 13
Graficzny interfejs
użytkownika

W czasie tej lekcji:


 poznasz podstawy graficznego interfejsu użytkownika w Unity,
 dowiesz się, w jaki sposób używać różnych kontrolerów
graficznego interfejsu użytkownika,
 zobaczysz, jak dostosować do własnych potrzeb graficzny
interfejs użytkownika.
Graficzny interfejs użytkownika (ang. Graphical User Interface, GUI) to
zestaw komponentów odpowiedzialnych za wysyłanie informacji do użyt-
kownika oraz odczyt informacji podanych przez użytkownika. W tej lekcji
poznasz wbudowany w Unity system GUI. Na początku przedstawione
zostaną podstawy dotyczące GUI. Następnie przejdziesz do wypróbowania
różnych kontrolek GUI. Na końcu lekcji zobaczysz, jak dostosować do
własnych potrzeb wygląd kontrolera GUI przy użyciu zarówno stylów, jak
i skórek.
226 Lekcja 13. Graficzny interfejs użytkownika

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.

Aby do projektu dodać kod odpowiedzialny za utworzenie GUI, w skrypcie


potrzebna jest funkcja specjalna. Nie ma tutaj znaczenia skrypt, w którym
zostanie ona zaimplementowana. GUI będzie dostępny w grze, dopóki skrypt
pozostaje aktywny, a obiekt, do którego go dołączono, znajduje się w działa‐
jącej scenie. Metoda odpowiedzialna za utworzenie GUI nosi nazwę OnGUI()
i przedstawia się następująco.
void OnGUI()
{
// Miejsce na kod tworzący GUI.
}
Kontrolki GUI 227

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).

RYSUNEK 13.1. Komunikat Hello World wyświetlony na ekranie

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

new Rect(<lewy>, <góra>, <szerokość>, <wysokość>)


Powyższe wywołanie tworzy nową strukturę typu Rect zawierającą wartości
dla położenia osi X od lewej strony, położenia osi Y od góry oraz szerokość
i wysokość. Kiedy zatem chcesz wskazać prostokąt zaczynający się w lewym
górnym rogu o wielkości 100 jednostek szerokości oraz 50 jednostek wyso‐
kości, użyj następującego polecenia:
new Rect(0, 0, 100, 50)
Poza strukturą Rect zawierającą informacje o położeniu, każda kontrolka
wymaga pewnych informacji dodatkowych, które zostaną omówione oddzielnie.
Ostatnią rzeczą, którą trzeba wiedzieć przed rozpoczęciem pracy z poszcze‐
gólnymi komponentami, jest sposób określania współrzędnych ekranu. Jak
wcześniej wspomniano, ekran ma jedynie dwa wymiary. Lewy górny narożnik
jest punktem początkowym (0, 0), natomiast prawy dolny to maksymalna
wielkość ekranu. Ponieważ środowisko Unity może jednocześnie pracować
z wieloma ekranami o różnych wielkościach, trudno dokładnie określić mak‐
symalną wielkość ekranu. Do ustalenia maksymalnej wielkości ekranu używa
się więc dwóch wbudowanych zmiennych, Screen.width i Screen.height.
Przykładowo kod tworzący strukturę Rect, której lewy górny narożnik znaj‐
duje się dokładnie na środku ekranu, przedstawia się następująco:
new Rect(Screen.width / 2, Screen.height / 2, 100, 50)

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

GUI.Label(new Rect(<x>, <y>, <w>, <h>), <Dowolny ciąg tekstowy>);


Utworzenie w lewym górnym rogu ekranu etykiety wyświetlającej komunikat
Hello World wymaga użycia poniższego polecenia:
GUI.Label(new Rect(0, 0, 80, 20), "Hello World");
Jak działa powyższe polecenie, widziałeś w poprzednim ćwiczeniu.

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

Umieszczenie przycisku w lewym górnym rogu ekranu i dodanie do niego


polecenia warunkowego przypisującego zmiennej wartość true po kliknięciu
wymaga użycia poniższego fragmentu kodu:
if(GUI.Button(new Rect(0, 0, 40, 20), "Exit ?"))
{
gameOver = true;
}
Próba uruchomienia powyższego kodu zakończy się niepowodzeniem, ponie‐
waż zmienna gameOver nie istnieje. Kod został użyty jedynie w celach dydak‐
tycznych. Na rysunku 13.3 pokazano przycisk utworzony za pomocą oma‐
wianego kodu.

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

Dobrym przykładem wykorzystania pola wyboru jest utworzenie wartości


boolowskiej poza metodą OnGUI() w celu przechowywania informacji o stanie
pola wyboru. W opisanej sytuacji można użyć poniższego fragmentu kodu.
bool toggleState = false;

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.

RYSUNEK 13.5. Pasek narzędziowy wyświetlony na ekranie

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

Wypróbuj przedstawiony kod! W tym miejscu trzeba wspomnieć o jednym:


niezależnie od wysokości pola tekstowego może ono zawierać tylko jeden
wiersz tekstu. Pole tekstowe pokazano na rysunku 13.6.

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

Łączenie i dopasowywanie stylów


W tym ćwiczeniu opracujesz pole wyboru wyglądające jak przycisk.
1. Utwórz nowy projekt lub scenę. Do sceny dodaj skrypt o nazwie
GUIScript; dołącz go do obiektu Main Camera.
2. W skrypcie umieść przedstawiony poniżej kod. Zwróć uwagę, że
kontrolka ma dodatkowy parametr przyjmujący wartość button.
bool value = false;

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.

Jeżeli nie chcesz ponownie używać żadnego z wbudowanych stylów kontrolek,


możesz przygotować własny. Wprawdzie istnieje możliwość opracowania
stylu w kodzie, ale znacznie łatwiejsze będzie użycie edytora. By użyć edytora
do utworzenia stylu, w skrypcie trzeba najpierw umieścić zmienną typu
GUIStyle. Poniżej przedstawiono kroki prowadzące do przygotowania wła‐
snego stylu.
1. Jeżeli nie zrobiłeś tego wcześniej, do sceny dodaj skrypt wraz z metodą
OnGUI(). Jeżeli masz już tego rodzaju skrypt, możesz go tutaj
wykorzystać. Upewnij się, że dołączyłeś skrypt do obiektu.
2. Do skryptu dodaj zmienną typu GUIStyle. Składnia definiowania
zmiennej jest następująca:
public GUIStyle <variable name>;
Powyższe polecenie trzeba umieścić w klasie, ale nie w żadnej
jej metodzie.
3. W edytorze Unity zaznacz obiekt z dołączonym skryptem
i zwróć uwagę na właściwość Style w komponencie skryptu
(patrz rysunek 13.8). Możesz klikać różne właściwości stylu
i zmieniać je według potrzeb.

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

GUI. Najogólniej mówiąc, skórka GUI to kolekcja stylów. Po utworzeniu jed‐


nej skórki zyskujesz możliwość określania wyglądu wszystkich kontrolek
w projekcie.
Aby dodać skórkę do projektu, należy po prostu kliknąć prawym przyciskiem
myszy katalog Assets w panelu Project, a następnie wybrać opcję Create/GUI
Skin. Po zaznaczeniu nowo utworzonej skórki w panelu Inspector zostanie
wyświetlona lista stylów — to są style dla wszystkich kontrolek GUI. Ponadto
dostępnych jest kilka opcji dodatkowych, np. uniwersalna czcionka dla wszyst‐
kich kontrolek. Dołączanie skórki do GUI jest obsługiwane przez skrypt.
W skrypcie trzeba utworzyć zmienną typu GUISkin. Poniżej przedstawiono
składnię polecenia tworzącego tę zmienną:
public GUISkin <variable name>;
Mając zdefiniowaną wartość zmiennej w edytorze, po prostu przypisujesz ją
graficznemu interfejsowi użytkownika. Składnia dla całego rozwiązania przed‐
stawia się następująco.
public GUISkin skin;

void OnGUI()
{
GUI.skin = skin;
// Miejsce na kod GUI.
}
Dostosowanie kontrolki do własnych potrzeb 237

 Wypróbuj samodzielnie

Utworzenie własnego stylu


W tym ćwiczeniu przygotujesz własny styl, a następnie zastosujesz go na
kontrolce przycisku.
1. Utwórz nowy projekt lub scenę. Dodaj skrypt GUIScript i dołącz go
do kamery.
2. W skrypcie umieść poniższy fragment kodu.
public GUIStyle style;

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.

RYSUNEK 13.9. Zmiana koloru zwykłego tekstu


238 Lekcja 13. Graficzny interfejs użytkownika

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

Praca ze skórkami GUI


W tym ćwiczeniu wypróbujesz skórkę GUI.
1. Utwórz nowy projekt lub scenę. Dodaj skrypt o nazwie GUIScript
i dołącz go do kamery.
2. W skrypcie umieść poniższy fragment kodu.
public GUISkin skin;

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).

RYSUNEK 13.10. Zmiana koloru tekstu aktywnego przycisku


Podsumowanie 239

4. Mając zaznaczoną kamerę, kliknij zasób NewSkin i przeciągnij 


na właściwość Skin komponentu GUI Script (patrz rysunek 13.11).
Uruchom scenę i kliknij przycisk. Kolor tekstu przycisku zmienił się
na czerwony.

RYSUNEK 13.11. Zastosowanie skórki GUI

Słowo dotyczące czcionek


Istnieje możliwość zastosowania zarówno stylów, jak i skórek do określenia
czcionek używanych w kontrolkach GUI. W środowisku Unity zasób czcio-
nek działa dokładnie tak samo jak każdy inny. Po prostu przeciągnij wybraną
czcionkę na katalog Assets, a Unity automatycznie ją rozpozna. Następnie
czcionki można użyć w dowolnej właściwości czcionki. Jedyne wymaganie
stawiane czcionkom jest następujące: powinny to być pliki typu .ttf lub .dfont.

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

Pytanie: Czy istnieją jakiekolwiek kwestie wydajności, które trzeba wziąć


pod uwagę podczas pracy z GUI?
Odpowiedź: Oczywiście. W środowisku Unity system GUI może stać się
niezwykle nieefektywny, jeśli będzie zbyt często używany. Dotyczy to
szczególnie platform mobilnych. To oczywiście nie oznacza, że należy
rezygnować z GUI — trzeba to robić z głową, oszczędnie i odpowiednio.
Warto przypomnieć ponownie, że wszystko sprowadza się do użycia
GUI w celu wyświetlenia niezbędnych informacji bez jednoczesnego
umieszczania zbyt dużej ilości danych na ekranie.

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

 Do sceny dodaj pole tekstowe, nie powinno zawierać żadnego tekstu.


 Do sceny dodaj przycisk, powinien zawierać tekst Kliknij mnie.
 Do sceny dodaj etykietę, nie powinna zawierać żadnego tekstu.
 Gdy przycisk zostanie kliknięty, z pola tekstowego powinien zostać
pobrany ciąg tekstowy i umieszczony w etykiecie.
 Za pomocą skórki GUI nadaj unikalny wygląd polu tekstowemu,
przyciskowi i etykiecie. Wszystkie wymienione kontrolki powinny
mieć spójny schemat kolorów i czcionkę. W tym miejscu możesz
wykazać się kreatywnością. Masz możliwość utworzenia czegoś
zupełnie unikalnego.
242 Lekcja 13. Graficzny interfejs użytkownika
Lekcja 14
Sterowanie postaciami

W czasie tej lekcji:


 poznasz podstawy kontrolera postaci w Unity,
 dowiesz się, jak tworzyć skrypty dla kontrolera postaci,
 zobaczysz, jak przygotować prosty, własny kontroler postaci.
W tej lekcji poznasz komponenty kontrolerów postaci w środowisku Unity.
Na początku przedstawione zostaną podstawy dotyczące kontrolerów
postaci. Dowiesz się, czym są oraz w jaki sposób funkcjonują. Następnie
przejdziesz do tworzenia skryptów pozwalających na manipulowanie kon-
trolerami postaci i wykorzystywanie oferowanych przez nie możliwości.
Na końcu lekcji opracujesz zupełnie od początku własny kontroler postaci.

Dlaczego omawiane są kontrolery postaci?


Być może zastanawiasz się, dlaczego opisuję kontrolery
postaci, skoro środowisko Unity dostarcza dwa solidne kon-
trolery (First Person i Third Person). Wprawdzie nie ulega
wątpliwości, że kontrolery te oferują użyteczne możliwości,
ale można spotkać wiele sytuacji, w których okazują się
niewystarczające. Co zrobić, gdy potrzebny jest kontroler do
gry 2D? Co zrobić, gdy chcemy mieć kontroler, który inaczej
obsługuje grawitację? Bardzo ważne jest zatem poznanie
wewnętrznego sposobu działania kontrolera postaci, aby
można było samodzielnie tworzyć określone rozwiązania
potrzebne dla własnych projektów.
244 Lekcja 14. Sterowanie postaciami

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.

Dodanie kontrolera postaci


Kontroler postaci sam w sobie jest komponentem i może być dodany do dowol‐
nego obiektu gry. Wprawdzie pojęcie postaci, ogólnie rzecz ujmując, odnosi
się do gracza, ale może być stosowane również względem wszystkich elemen‐
tów poruszających się po scenie (graczy, wrogów, samochodów itd.). Aby
dodać kontroler postaci do obiektu, należy po prostu zaznaczyć obiekt, a następ‐
nie wybrać opcję Component/Physics/Character Controller, a kontroler postaci
pojawi się pod obiektem w panelu Inspector.

Komponent Collider Quarrel


Ponieważ kontroler postaci zawiera własny komponent Capsule Collider,
gdy spróbujesz go dodać do obiektu posiadającego już komponent Col-
lider, możesz zobaczyć pokazany na rysunku 14.1 komunikat ostrzeżenia.
Dostępne opcje to przerwanie operacji dodawania kontrolera postaci, zastą-
pienie istniejącego komponentu Collider nowym lub zachowanie obu kom-
ponentów Collider w obiekcie. Oczekiwany efekt określa opcję, którą powi-
nieneś wybrać. Ogólnie rzecz biorąc, jeżeli używasz kontrolera postaci
do normalnego ruchu, istniejący komponent Collider należy zastąpić przez
Capsule Collider.

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

Dodanie kontrolera postaci do obiektu


W tym ćwiczeniu dodasz kontroler postaci do obiektu na scenie.
1. Utwórz nowy projekt lub scenę. Do sceny dodaj sześcian.
2. Zaznacz sześcian, a następnie dodaj kontroler postaci, wybierając
opcję Component/Physics/Character Controller.
3. W panelu Inspector dla sześcianu powinien być teraz widoczny
kontroler postaci. Ponadto w panelu Scene komponent Capsule
Collider powinien być zlokalizowany wewnątrz sześcianu.

Kontroler postaci i komponent Rigidbody


Ponieważ zarówno kontroler postaci, jak i Rigidbody są komponentami,
oba mogą być dodane do obiektu. Jednak nie jest to dobre rozwiązanie.
Komponenty kontrolera postaci i Rigidbody będą próbowały uzyskać kon-
trolę nad poruszaniem obiektu w określony sposób. Skutkiem może być
dziwne zachowanie obiektów. Dlatego też najlepiej wybrać jeden z dwóch
wymienionych komponentów. Użycie dwóch można zaryzykować, jeśli
próbujesz osiągnąć pewien określony cel i doskonale wiesz, co robisz.

Właściwości kontrolera postaci


Kontroler postaci wyposażony został w dwa zestawy właściwości. Istnieją więc
właściwości używane za pomocą panelu Inspector w edytorze Unity (omó‐
wione poniżej) oraz właściwości dostępne przy użyciu skryptów (zostaną
omówione dalej w tej lekcji). Na rysunku 14.2 pokazano różne właściwości
komponentu kontrolera postaci.

RYSUNEK 14.2.
Komponent
kontrolera postaci

Wszystkie właściwości kontrolera postaci zostały opisane w tabeli 14.1.

Skrypty dla kontrolerów postaci


Prawdopodobnie zauważyłeś, że umieszczenie kontrolera postaci w obiekcie
gry nie powoduje żadnego szczególnego efektu. Faktycznie, po utworzeniu sceny
zawierającej jakiekolwiek spadające lub poruszające się elementy zobaczysz,
246 Lekcja 14. Sterowanie postaciami

Tabela 14.1. Właściwości kontrolera postaci


Właściwość Opis
Slope Limit Właściwość określa najbardziej strome wzniesienie,
na które może wspiąć się kontroler postaci. Wszelkie
wzniesienia bardziej strome niż podana tutaj wartość
będą niemożliwe do pokonania przez kontroler postaci.
Step Offset Wszelkie stopnie znajdujące się bliżej ziemi niż podana
wartość będą możliwe do pokonania przez kontroler
postaci. Wszystkie większe już nie.
Skin Width Właściwość określa, jak głęboko komponent Collider
może wejść do komponentu Collider kontrolera postaci,
zanim wykryta będzie kolizja. Wartość zbyt mała
powoduje drganie kontrolera, natomiast zbyt duża
blokuje go. Dobrym ogólnym ustawieniem jest wartość
równa 10% promienia kontrolera.
Min Move Wartość określa minimalną odległość, jaką kontroler może
Distance pokonać. Jest ona niezbędna do ograniczenia drgań
kontrolera. Jednak ustawienie zbyt dużej wartości może
spowodować, że kontroler będzie odbierany jako
niereagujący na polecenia gracza. Dobrą zasadą jest
przypisanie tej właściwości wartości 0 i jej zwiększenie
tylko wtedy, gdy będzie trzeba.
Center Właściwość określa środek komponentu Capsule Collider
należącego do kontrolera postaci.
Radius Właściwość określa promień komponentu Capsule Collider
należącego do kontrolera postaci.
Height Właściwość określa wysokość komponentu Capsule
Collider należącego do kontrolera postaci.

że będą kolidować z obiektem zawierającym kontroler postaci, ale kontroler


nie będzie ich poruszać. Największe możliwości kontrolera postaci zaimple‐
mentujesz, dodając skrypty. Warto pamiętać, że kontroler postaci oferuje jedynie
podstawy kontroli, a rzeczywista implementacja należy do Ciebie. Oznacza to
konieczność wykonania nieco większej ilości pracy związanej z kontrolerami,
ale efekt może być naprawdę imponujący, dopracowany i doskonale dostoso‐
wany do potrzeb.

Praca z kontrolerem za pomocą skryptów


Jak wcześniej wspomniano, kontroler postaci zawiera serie właściwości (zmien‐
nych) dostępnych za pomocą skryptów, a tym samym oferujących naprawdę
potężne możliwości. Zanim jednak będziesz mógł pracować z kontrolerem
w kodzie, najpierw musisz uzyskać odniesienie do niego.
Skrypty dla kontrolerów postaci 247

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.

Najczęściej używane funkcje


Komponent kontrolera postaci jest elementem potomnym komponentu
Collider. Mówi się więc, że kontroler postaci dziedziczy po komponencie
Collider. Dlatego też kontroler ma dostęp do wszystkich możliwości skryp-
towych, jakie oferują komponenty Collider. W tej lekcji omówione zostaną
jednak tylko te elementy, które są unikalne dla kontrolera postaci. Warto
zwrócić uwagę na relacje między kontrolerami i komponentami Collider.
Gdy dostrzeżesz pewne dodatkowe funkcje w kodzie i będziesz się zastana-
wiał, skąd pochodzą, być może wyjaśnieniem będą te relacje.

Tabela 14.2. Zmienne dotyczące kontrolera postaci


Zmienna Opis
slopeLimit, Zmienne mają takie samo znaczenie jak wymienione
stepOffset, w tabeli 14.1 właściwości komponentu.
center, radius,
height
isGrounded Wartość boolowska określająca, czy kontroler
aktualnie dotyka ziemi. Przydaje się do obsługi
skoków i mechaniki lotu.
velocity Zmienna typu Vector3 określająca szybkość, z jaką
kontroler porusza się wzdłuż wszystkich osi. Szybkość
jest ustalana przez obliczenie położenia przed i po
wywołaniu Move() lub SimpleMove() — zostanie
to omówione dalej w tej lekcji.
collisionFlags Zmienna określa, czy wystąpiła kolizja z kontrolerem
(więcej na ten temat znajdziesz dalej w tej lekcji).
detectCollisions Wartość boolowska określająca, czy kontroler
postaci będzie wykrywał kolizje z innymi
komponentami Collider lub Rigidbody. Domyślnie
wartością omawianej zmiennej jest true.
248 Lekcja 14. Sterowanie postaciami

Kontroler postaci wraz z zestawem zmiennych dostarcza również dwie nowe


metody o nazwach SimpleMove() i Move(). W metodach wykorzystano ideę
ruchu w celu przesuwania obiektu. Oznacza to, że obiekty nie są umieszczane,
popychane lub poddawane translacji. Efekt jest oparty na rzeczywistych danych
wejściowych kontrolek ustawionych w menedżerze InputManager. Wynikiem
jest to, że ruch kontrolera przypomina przesuwanie, co wydaje się nieco bar‐
dziej realistyczne.
bool SimpleMove(Vector3 movement)
Jak sama nazwa wskazuje, metoda SimpleMove() to prosty sposób na poru‐
szanie obiektami. Metoda odczytuje zmienną typu Vector3 zawierającą infor‐
macje, jak daleko obiekt powinien poruszyć się wzdłuż poszczególnych osi.
Wartością zwrotną metody jest wartość boolowska wskazująca, czy obiekt jest
uziemiony (dotyka ziemi). Wewnętrznie metoda automatycznie stosuje gra‐
witację dla danego obiektu. Dlatego też metoda SimpleMove() ignoruje wszelki
podany ruch wzdłuż osi Y. Skutkiem jest brak możliwości zastosowania wła‐
snych reguł grawitacji, a tym samym skakania lub latania obiektu. Jeżeli chcesz
wykorzystać wymienione możliwości, musisz użyć metody Move(). Warto
w tym miejscu zwrócić uwagę, że metoda SimpleMove() inaczej oblicza odle‐
głość niż Move(). Oznacza to, że jeśli chcesz przesunąć obiekt na określoną
odległość, podawana metodzie SimpleMove() wartość przesunięcia jest inna
niż w przypadku Move():
CollisionFlags Move(Vector3 movement)
Podobnie jak SimpleMove(), metoda Move() jest odpowiedzialna za porusza‐
nie obiektem na scenie. Pobiera zmienną typu Vector3 zawierającą informacje,
jak daleko obiekt powinien poruszyć się wzdłuż poszczególnych osi. Warto‐
ścią zwrotną metody jest zmienna typu CollisionFlags (omówiona dalej
w tej lekcji), zawierająca dane kolizji, które mogły wystąpić podczas ruchu.
Metoda Move() nie stosuje automatycznie żadnej grawitacji, a więc trzeba ją
obliczyć i nałożyć samodzielnie.

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

Zmienna typu CollisionFlags


Zmienna typu CollisionFlag to skomplikowana zmienna zawierająca infor‐
macje o kolizjach, które wystąpiły podczas ruchu kontrolera postaci. Jest ona
mapą bitową, co oznacza, że dane są przechowywane w kodzie binarnym.
Istnieją różne sposoby na wyodrębnianie z niej niezbędnych informacji. Zmienna
typu CollisionFlags może być wartością lub zawierać wartość. Różnica
polega na tym, że jeśli opcje są określoną wartością, wówczas wszystkie pozo‐
stałe wartości będą wykluczone. Z drugiej strony, zmienna typu Collistion
Flags może zawierać wiele różnych wartości. Takie rozwiązanie ma sens
w omawianym przykładzie.
Przyjmujemy założenie, że trzeba ustalić, czy następuje kolizja tylko z obiek‐
tem znajdującym się poniżej. W tym celu można wykorzystać poniższy frag‐
ment kodu.
if (controller.collisionFlags == CollisionFlags.Below)
print("Występuje kolizja jedynie z obiektem znajdującym
się poniżej.");
Jeżeli powyższe stwierdzenie jest prawdziwe, wiadomo, że obiekt nie może
kolidować z żadnym innym w pozostałych kierunkach. Gdy trzeba ustalić,
czy obiekt koliduje z obiektem znajdującym się na dole oraz z obiektem
w innym kierunku, wtedy można wykorzystać poniższy fragment kodu.
if (controller.collisionFlags & CollisionFlags.Below)
print("Występuje kolizja z obiektem znajdującym się poniżej.
Może też kolidować z innymi.");
Różnica pomiędzy dwoma przedstawionymi fragmentami polega na tym, że
w pierwszym wartością jest Below, natomiast drugi zawiera Below. Oczywiście,
zmienna CollisionFlags może być równa jedynie None. Nie może zawierać
None i innej wartości, ponieważ nie ma możliwości, aby obiekt nie kolidował
250 Lekcja 14. Sterowanie postaciami

i jednocześnie kolidował z obiektem w jednym z kierunków. Zmienna typu


CollisionFlags może zawierać wartości None, Sides, Above i Below. Są one
zapisywane w następujący sposób.
CollisionFlags.None
CollisionFlags.Above
CollisionFlags.Sides
CollisionFlags.Below
Za pomocą wymienionych opcji można ustalić dokładny sposób kolizji z kon‐
trolerem postaci.

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.

Tworzenie kontrolera postaci


Dowiedziałeś się już sporo o komponencie kontrolera postaci i wiesz, jak
działa; zdobyta wiedza pozwala na rozpoczęcie budowy własnych kontrole‐
rów postaci. Pamiętaj, że nie istnieją dokładnie dwa takie same kontrolery
postaci. Zostały opracowane w taki sposób, aby można je było łatwo modyfi‐
kować i dopasowywać do własnych potrzeb. Dlatego też zaprezentowany
w tej części lekcji sposób tworzenia kontrolera postaci nie jest jedynym właści‐
wym. To po prostu jedno z dostępnych rozwiązań budowy kontrolerów postaci.
Istnieje wiele różnych kontrolerów postaci, które mogłyby zostać przedsta‐
wione w tym miejscu. Tworzony tutaj kontroler jest przeznaczony dla dwu‐
wymiarowych gier platformowych, takich jak Super Mario Bros. Ukończony
projekt (Hour14_Controller) znajdziesz w materiałach przeznaczonych dla bie‐
żącej lekcji.
Tworzenie kontrolera postaci 251

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

3. Jeden z sześcianów umieść w położeniu (0, 0, –5) i zastosuj skalę


(20, 0.5, 2). Będzie on działał w charakterze podłoża. Natomiast
drugi umieść w położeniu (3, 3, –5) i zastosuj skalę (3, 0.5, 1).
4. Umieść kapsułę w położeniu (0, 2, –5). Do kapsuły dodaj komponent
kontrolera postaci (wybierz opcję Component/Physics/Character
Controller). Po wyświetleniu komunikatu ostrzeżenia kliknij przycisk
Replace, zgadzając się tym samym na zastąpienie istniejącego
komponentu Collider nowym.
5. Do sceny dodaj katalog Scripts. Następnie do utworzonego katalogu
dodaj skrypt o nazwie ControllerScript. Skrypt dołącz do kapsuły.
Kapsuła będzie obiektem kontrolowanym przez kontroler postaci.
Zmodyfikuj skrypt, aby zawierał przedstawiony poniżej kod.
CharacterController controller;

void Start () {
controller = GetComponent<CharacterController>();
}
252 Lekcja 14. Sterowanie postaciami

Po uruchomieniu sceny zobaczysz widok podobny do pokazanego na rysun‐


ku 14.5. W tym momencie scena jest przygotowana i możesz zacząć dodawać
kolejne funkcje.
RYSUNEK 14.5.
Ukończona scena

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

taTime. Tego rodzaju rozwiązanie zastosowano, aby scena była uruchamiana


dokładnie w taki sam sposób w dowolnym komputerze, niezależnie od często‐
tliwości odświeżania.
Uruchom scenę i zobacz, jak możesz teraz poruszać kapsułą do przodu i do
tyłu. Powinieneś zobaczyć, że kapsuła jest zatrzymywana przez platformę.
Ponadto powinno być widać, że kapsuła płynie w przestrzeni. Na razie nie
zastosowano dla niej żadnej grawitacji.

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

// Kod odpowiedzialny za obsługę ruchu i grawitacji.

if (Input.GetButton("Jump") && controller.isGrounded == true)


movement.y = jumpSpeed;

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;

void OnControllerColliderHit(ControllerColliderHit hit) {


Rigidbody body = hit.collider.attachedRigidbody;
if (body == null || body.isKinematic)
return;

if (hit.moveDirection.y < -0.3f)


return;

Vector3 pushDir = new Vector3(hit.moveDirection.x, 0f, 0f);


body.velocity = pushDir * pushPower;
}
Upewnij się, że dodałeś powyższy kod do klasy, ale nie do żadnej z jej metod.
W wierszu pierwszym mamy polecenie tworzące zmienną, która określa moż‐
liwości obiektu w zakresie popychania innych obiektów. Następnie w meto‐
dzie OnControllerColliderHit() znajduje się właściwy kod obsługujący
„popychanie”. W metodzie pobierane jest odniesienie do komponentu Rigidbody
obiektu, z którym doszło do kolizji. Jeżeli komponent Rigidbody nie istnieje
lub ma ustawioną właściwość Kinematic, metoda kończy działanie. Następnie
sprawdzany jest kierunek kolizji, aby upewnić się, że nie następuje próba
Tworzenie kontrolera postaci 255

popchnięcia obiektów poniżej kontrolera postaci. Po przeprowadzeniu wszyst‐


kich operacji sprawdzenia obliczamy kierunek i następnie popychamy obiekt we
właściwym kierunku. Szybkość obiektu jest mnożona przez siłę popchnięcia.
Przed wypróbowaniem sceny dodaj do niej kulę i umieść ją w położeniu
(1.5, 1, –5). Upewnij się, że dodałeś do kuli komponent Rigidbody. Teraz możesz
uruchomić scenę. Zwróć uwagę, jak kapsuła może popychać kulę. Spróbuj
popychać kulę w obu kierunkach na platformie.

Pełny kod skryptu


Poniżej przedstawiono pełny kod skryptu. Pewne fragmenty zostały nieco zmo‐
dyfikowane — zrobiono to tylko z powodów organizacyjnych.
using UnityEngine;
using System.Collections;

public class ControllerScript : MonoBehaviour {

CharacterController controller;

Vector3 movement = Vector3.zero;


public float speed = 5.0f;
public float jumpSpeed = 8.0f;
public float pushPower = 2.0f;

void Start () {
controller = GetComponent<CharacterController>();
}

void Update() {

movement.x = Input.GetAxis("Horizontal") * speed;

if(controller.isGrounded == false)
movement.y += Physics.gravity.y * Time.deltaTime;

if (Input.GetButton("Jump") && controller.isGrounded == true)


movement.y = jumpSpeed;

controller.Move(movement * Time.deltaTime);
}

void OnControllerColliderHit(ControllerColliderHit hit) {


Rigidbody body = hit.collider.attachedRigidbody;
if (body == null || body.isKinematic)
return;

if (hit.moveDirection.y < -0.3f)


return;
256 Lekcja 14. Sterowanie postaciami

Vector3 pushDir = new Vector3(hit.moveDirection.x, 0f, 0f);


body.velocity = pushDir * pushPower;
}
}

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

W czasie tej lekcji dowiesz się:


 jak zaprojektować grę Captain Blaster,
 jak zbudować świat gry Captain Blaster,
 jak opracować postacie gry Captain Blaster,
 jak zaprojektować kontrolki gry Captain Blaster,
 jak jeszcze bardziej usprawnić grę Captain Blaster,
W tej lekcji utworzysz dwuwymiarową grę, będzie to strzelanka z przewija-
nym tłem zatytułowana Captain Blaster. Pracę rozpoczniesz od zaprojek-
towania różnych elementów gry. Następnie przystąpisz do opracowania
przewijanego tła. Po przygotowaniu obsługi ruchu rozpoczniesz tworze-
nie poszczególnych elementów gry. Gdy wszystkie elementy będą gotowe,
przejdziesz do budowy kontrolek i gamifikacji projektu. Na końcu lekcji
zajmiesz się analizą gry i wyszukaniem obszarów, na których można ją
usprawnić.

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

1. Do sceny dodaj sześcian. Zmień jego nazwę na Background, umieść


w położeniu (0, 0, 0) i zastosuj skalowanie (15, 15, 0.1).
2. Za pomocą panelu Project utwórz nowy katalog o nazwie Textures.
W materiałach przeznaczonych dla bieżącej lekcji odszukaj plik
o nazwie Star_Sky.png, kliknij go i przeciągnij na katalog Textures.
Następnie z panelu Project przeciągnij teksturę Star_Sky.png na tło.
3. Za pomocą panelu Project utwórz nowy katalog o nazwie Scripts.
Następnie w katalogu utwórz skrypt o nazwie BackgroundScript
i przeciągnij go na sześcian. W skrypcie umieść przedstawiony
poniżej fragment kodu.
public float speed = -2;

// Metoda używana do inicjacji.


void Start () {
}

// Metoda wywoływana raz w trakcie każdej klatki.


void Update () {
transform.Translate(0f, speed * Time.deltaTime, 0f);
if(transform.position.y <= -15)
{
transform.Translate(0f, 30f, 0f);
}
}
4. Powiel sześcian tła i umieść go w położeniu (0, 15, 0). Uruchom scenę.
Powinieneś zobaczyć, jak tło jest płynnie przewijane.
Świat 263

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

W ten sposób przygotowałeś elegancki, teksturowany i zwrócony do góry


statek kosmiczny gotowy do niszczenia meteorów!

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

3. Plik Meteor1.fbx przeciągnij na panel Scene. Obiekt umieść w położeniu


(0, 0, –5), zastosuj rotację (0, 0, 0) i przeskaluj go (1, 1, 1). (Obiekt został
zaimportowany wraz z zastosowaną pewną rotacją i skalowaniem).
4. W katalogu Textures odszukaj plik Meteor1_TXTR.png i przeciągnij
go na meteor znajdujący się na scenie.
5. Do obiektu meteoru dodaj komponent Rigidbody i usuń zaznaczenie
obok właściwości Use Gravity. Ponadto dodaj komponent Capsule
Collider.
6. Utwórz nowy katalog o nazwie Prefabs. Następnie utwórz w nim nowy
prefabrykat o nazwie Meteor. W panelu Hierarchy kliknij obiekt
Meteor1 i przeciągnij na nowo utworzony prefabrykat. Teraz obiekt
Meteor1 możesz usunąć ze sceny.
W ten sposób przygotowałeś wielokrotnego użytku meteor czekający na powo‐
dowanie zniszczeń.

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;

public class GameControlScript : MonoBehaviour {

// Czy gra nadal się toczy?


bool isRunning = true;
int playerScore = 0;

void Start () {}
void Update () {}

public void AddScore()


{
playerScore++;
}

public void PlayerDied()


{
isRunning = false;
}

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

Zawartość skryptu meteoru zastąp przedstawionym poniżej kodem.


268 Lekcja 15. Trzecia gra — Captain Blaster

using UnityEngine;
using System.Collections;

public class MeteorScript : MonoBehaviour {

float speed = -5f;

// Losowo wybrana rotacja.


float rotation;

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;

public class MeteorSpawnScript : MonoBehaviour {

// Licznik czasu dotyczący tworzenia meteoru.


float spawnThreshold = 100;
float spawnDecrement = .1f;

// Prefabrykat meteoru.
public GameObject meteor;

void Start () {}

void Update () {
Obiekty kontrolne 269

// Ustalenie, czy należy utworzyć meteor.


if(Random.Range(0, spawnThreshold) <= 1)
{
// Utworzenie meteoru w losowo wybranym położeniu X.
Vector3 pos = transform.position;
Instantiate(meteor, new Vector3(pos.x +
Random.Range(-6, 6), pos.y,
pos.z), Quaternion.identity);

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

void OnTriggerEnter(Collider other)


{
Destroy(other.gameObject);
}
Działanie skryptu jest proste i polega na usunięciu każdego obiektu, z którym
następuje kolizja. Ponieważ gracz nie może poruszać się pionowo, nie trzeba
się przejmować niebezpieczeństwem zniszczenia obiektu gracza. Tylko pociski
i meteory będą kolidowały z wyzwalaczami.

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;

public class PlayerScript : MonoBehaviour {

// Szybkość poruszania się gracza.


public float speed = 10f;

// Prefabrykat pocisku.
public GameObject bullet;

// Skrypt kontrolny.
public GameControlScript control;

// Gracz może wystrzelić pocisk co pół sekundy.


public float bulletThreshold = .5f;
float elapsedTime = 0;

void Start () {}

void Update () {
// Monitorowanie czasu dla wystrzeliwania pocisków.
elapsedTime += Time.deltaTime;

// Przesuwanie obiektu gracza.


transform.Translate(Input.GetAxis("Horizontal") * speed *
Time.deltaTime,
0f, 0f);

// Spacja powoduje wystrzelenie pocisku. Obecna konfiguracja określa


// to mianem "skoku" (ang. Jump).
// Pozostawiono to, aby uniknąć zamieszania.
if(Input.GetButtonDown("Jump"))
{
Obiekty kontrolne 271

// Sprawdzenie, czy minęło wystarczająco dużo czasu, aby można było


// oddać kolejny strzał.
if(elapsedTime > bulletThreshold)
{
// Wystrzelenie pocisku w bieżącym położeniu.
// Upewnij się, że utworzyłeś pocisk przed graczem,
// aby uniknąć kolizji między graczem i pociskiem.
Instantiate(bullet, new Vector3(transform.position.x,
transform.position.y + 1.2f, -5f),
Quaternion.identity);

// Wyzerowanie licznika wystrzeliwania pocisku.


elapsedTime = 0f;
}
}
}

// Jeżeli meteor uderzył w gracza.


void OnTriggerEnter(Collider other)
{
Destroy(other.gameObject);
control.PlayerDied();
Destroy(this.gameObject);
}
}
Skrypt wykonuje wiele zadań. Na początku tworzone są zmienne przeznaczone
do przechowywania szybkości, prefabrykatu pocisku, skryptu kontrolnego i licz‐
nika czasu dotyczącego wystrzeliwania pocisków.
W metodzie Update() skrypt pobiera aktualną godzinę, będzie ona wykorzy‐
stana do ustalenia, czy minęło wystarczająco dużo czasu od chwili ostatniego
wystrzelenia pocisku. W regułach gry przyjęto, że gracz może wystrzelić pocisk
co pół sekundy. Obiekt gracza jest przesuwany wzdłuż osi X na podstawie
danych wejściowych. Następnie skrypt ustala, czy gracz nacisnął spację. Stan‐
dardowo w środowisku Unity spacja jest uznawana za akcję skoku. To można
ustawić w menedżerze InputManager, ale pozostawiono oryginalną nazwę
w celu uniknięcia zamieszania. Jeżeli gracz nacisnął spację, skrypt sprawdza
ilość czasu, jaka upłynęła od ostatniego strzału, i porównuje ją z wartością
bulletThreshold (aktualnie to pół sekundy). Gdy ilość czasu jest większa od
wspomnianej wartości, następuje utworzenie pocisku. Zauważ, że skrypt tworzy
pocisk nieco powyżej statku kosmicznego, aby zapobiec kolizji między poci‐
skiem i statkiem kosmicznym. Dalej następuje wyzerowanie czasu, jaki minął
od wystrzelenia pocisku, i licznik zaczyna działać od początku.
Ostatnia część skryptu zawiera metodę OnTriggerEnter(). Jest ona wywoły‐
wana, gdy meteor trafi obiekt gracza. W takiej sytuacji meteor zostaje znisz‐
czony, skrypt kontrolny poinformowany o śmierci gracza, a następnie statek
kosmiczny gracza również zostaje zniszczony.
272 Lekcja 15. Trzecia gra — Captain Blaster

Teraz powracamy do edytora Unity. Kliknij prefabrykat pocisku i przeciągnij


go na właściwość Bullet skryptu obsługi gracza. Następnie kliknij obiekt kon‐
trolny gry i przeciągnij go na skrypt obsługi gracza, dając mu tym samym dostęp
do skryptu kontrolnego (patrz rysunek 15.6). Uruchom scenę i zobacz, że możesz
teraz poruszać obiektem gracza. Ponadto gracz może wystrzeliwać pociski,
które jednak nie poruszają się. Zwróć uwagę, że gracz może zostać zniszczony,
co oznacza koniec gry.

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;

public class BulletScript : MonoBehaviour {

float speed = 10f;

// Skrypt kontrolny gry.


GameControlScript control;

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);
}

// Ani pocisk, ani meteor nie są wyzwalaczami. Dlatego też


// w tym miejscu trzeba użyć innej metody kolizji.
void OnCollisionEnter(Collision other)
{
Destroy(other.gameObject);
control.AddScore();
Destroy(this.gameObject);
}
}
Podstawowa różnica między tym skryptem a skryptem przeznaczonym do
obsługi meteoru polega na tym, że omawiany skrypt musi uwzględniać koli‐
zje i przyznawanie punktów graczowi. Podobnie jak w skrypcie gracza, także
tutaj zdefiniowano zmienną przeznaczoną do przechowywania skryptu kon‐
trolnego. Ponieważ pocisk nie znajduje się w panelu Scene, dostęp do skryptu
kontrolnego uzyskuje w nieco inny sposób. W metodzie Start() skrypt odszu‐
kuje obiekt GameControl, a następnie wywołuje metodę GetComponent()
w celu wyszukania skryptu dołączonego do wymienionego obiektu. W ten spo‐
sób skrypt kontrolny jest przechowywany w zmiennej control.
Ponieważ ani pocisk, ani meteor nie mają zdefiniowanego wyzwalacza kolizji,
zastosowanie metody OnTriggerEnter() okazuje się niemożliwe. Zamiast tego
w skrypcie wykorzystano metodę OnCollisionEnter(). Metoda nie odczytuje
zmiennej Collider, ale Collision. W omawianej grze różnice między obiema
metodami są nieistotne. Jedyne wykonywane zadanie to usunięcie obu koli‐
dujących obiektów oraz poinformowanie skryptu kontrolnego, że gracz zdo‐
był punkt.
Wypróbuj grę! Zwróć uwagę, że w obecnej postaci gra jest w pełni grywalna.
Wprawdzie nie możesz wygrać (to celowe założenie), ale niewątpliwie możesz
przegrać. Zagraj i przekonaj się, ile punktów możesz zdobyć!

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

Poniżej przedstawiono kilka propozycji zmian wartych rozważenia.


 Spróbuj zmodyfikować szybkość pocisków, częstotliwość
wystrzeliwania pocisków lub ścieżkę, po której poruszają się pociski.
 Spróbuj umożliwić graczowi wystrzelenie dwóch pocisków obok
siebie.
 Spróbuj dodać innego rodzaju meteor.
 Udostępnij graczowi dodatkowe punkty zdrowia, być może nawet
tarczę.
 Pozwól graczowi na poruszanie się w kierunkach pionowym
i poziomym.
Zbudowałeś grę dość popularnego gatunku, ale istnieje wiele sposobów, które
sprawią, że stanie się unikalna. Zobacz, jak bardzo możesz ją zmodyfikować
i odróżnić od innych. Warto również w tym miejscu dodać, że kiedy poznasz
system cząstek omówiony dalej w tej książce, gra ta będzie doskonałym kan‐
dydatem do ich zastosowania.

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

Pytanie: Dlaczego dla statku kosmicznego używany jest komponent


Capsule Collider?
Odpowiedź: Efektywne i dokładne wykrywanie kolizji może być trudne.
Większy obiekt typu Collider będzie obejmował także skrzydła i zapewni
znacznie dokładniejsze wykrywanie kolizji. Jednak tego rodzaju
Collider będzie powodował „fałszywe alarmy”, gdy meteor znajdzie
się obok kokpitu. Dlatego też kapsuła jest kompromisem. Najlepszym
sposobem zapewnienia maksymalnej dokładności jest wykorzystanie
wielu komponentów Collider. Z takiego rozwiązania jednak zrezygnowano
w omawianej grze, aby zachować prostotę i przejrzystość przykładu.

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

W czasie tej lekcji:


 poznasz podstawy systemu cząsteczek,
 dowiesz się, jak pracować z modułami,
 zobaczysz, jak używać edytora krzywych.
W tej lekcji poznasz oferowane przez środowisko Unity systemy cząsteczek.
Na początek dowiesz się wszystkiego o systemie cząsteczek i sposobie jego
działania. Następnie przejdziesz do nowego w Unity systemu cząsteczek
Shuriken. Kolejnym krokiem będzie przeprowadzenie eksperymentów
z wieloma różnymi modułami systemu cząsteczek. Na końcu lekcji zajmiesz
się oferowanym przez Unity edytorem krzywych.
278 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.

Systemy cząsteczek w Unity


Od wersji 3.5 Unity oferuje nowy silnik cząsteczek o nazwie Shuriken. Każdy
utworzony przez Ciebie system cząsteczek będzie oparty na nowym silniku.
Warto dodać, że systemy cząsteczek budowane we wcześniejszych wersjach niż
Unity 3.5 nadal będą działać. Dalej w tej lekcji będziesz miał okazję wypró‐
bować pewne starsze systemy cząsteczek dostarczane wraz z Unity.
Aby utworzyć system cząsteczek na scenie, należy dodać obiekt systemu czą‐
steczek lub komponent systemu cząsteczek do już istniejącego obiektu. W celu
dodania obiektu systemu cząsteczek musisz wybrać opcję menu GameObject/
Create Other/Particle System. Natomiast aby dodać komponent systemu czą‐
steczek do istniejącego obiektu, trzeba zaznaczyć obiekt, a następnie wybrać
opcję Component/Effects/Particle System.

Kontrolki systemu cząsteczek


Prawdopodobnie zauważyłeś, że po dodaniu systemu cząsteczek do sceny
zaczyna on emitować cząsteczki w panelu Scene. Można również dostrzec
wyświetlone na ekranie kontrolki efektu systemu cząsteczek (patrz rysu‐
nek 16.2). Kontrolki pozwalają na wstrzymanie, zatrzymanie i ponowne uru‐
chomienie animacji cząsteczek na scenie. Okazują się niezwykle pomocne
podczas dostosowania do własnych potrzeb zachowania komponentów systemu
cząsteczek.
Systemy cząsteczek 279

 Wypróbuj samodzielnie

Utworzenie systemu cząsteczek


W tym ćwiczeniu umieścisz na scenie obiekt systemu cząsteczek.
1. Utwórz nowy projekt lub scenę.
2. Dodaj system cząsteczek, wybierając opcję menu GameObject/Create
Other/Particle System.
3. Zwróć uwagę, jak system cząsteczek emituje białe cząsteczki w panelu
Scene (patrz rysunek 16.1). To jest podstawowy system cząsteczek.
Spróbuj przeprowadzić rotację i skalowanie systemu cząsteczek, aby
zobaczyć, w jaki sposób reaguje.

Rysunek 16.1. Podstawowy system cząsteczek

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

Kontrolki pozwalają również na przyśpieszenie odtwarzania animacji i okre‐


ślenie długości efektu. Są też bardzo użyteczne w trakcie testowania czasu
trwania efektu systemu 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ą.

Moduły systemu cząsteczek


U podstaw systemu cząsteczek znajduje się po prostu pewien punkt w prze‐
strzeni, który emituje obiekty cząsteczek. Wygląd, zachowanie i efekty powo‐
dowane przez cząsteczki są określane przez moduły. Moduł to różne właści‐
wości definiujące różne formy zachowania. W nowym systemie cząsteczek
Shuriken wprowadzonym w Unity moduły są zintegrowanymi i istotnymi
komponentami. W tej części lekcji poznasz dostępne moduły i ich działanie.
Warto pamiętać, że z wyjątkiem omówionego na początku modułu domyślnego
wszystkie pozostałe mogą być włączane lub wyłączane. Aby włączyć lub
wyłączyć moduł, należy umieścić (lub usunąć) znak wyboru obok nazwy
modułu. Do ukrywania lub wyświetlania modułów służy znak plus znajdujący
się obok Particle Systems (patrz rysunek 16.3). Domyślnie wszystkie moduły są
widoczne, a tylko Emission, Shape i Renderer są włączone. Aby rozwinąć zawar‐
tość modułu, po prostu kliknij jego nazwę.

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

Stała, krzywa, losowa


W nowym systemie Shuriken wprowadzono koncepcję krzywych wartości.
Krzywa pozwala na zmianę wartości właściwości w trakcie cyklu życiowego
systemu cząsteczek. Właściwości, w których można stosować krzywe, mają
obok wartości wyświetloną strzałkę skierowaną w dół. Dostępnymi opcjami
są Constant, Curve, Random Between Two Constants i Random Between
Two Curves. W tej części lekcji wszystkie wartości są traktowane jako Con-
stants. Dalej w tej lekcji będziesz miał okazję dokładniej zapoznać się z edy-
torem krzywych.

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

Tabela 16.1. Właściwości modułu domyślnego


Właściwość Opis
Duration Wyrażony w sekundach czas działania systemu cząsteczek.
Looping Właściwość określa, czy system cząstek ponownie rozpoczyna
działanie po upłynięciu czasu zdefiniowanego we właściwości
Duration.
Prewarm Po zaznaczeniu tej właściwości system cząsteczek rozpocznie
działanie, jakby już emitował cząsteczki z poprzedniego
cyklu.
Start Delay Wyrażony w sekundach czas oczekiwania zanim system
cząsteczek zacznie emitować cząsteczki.
Start Lifetime Wyrażony w sekundach czas życia każdej cząsteczki.
Start Speed Początkowa szybkość cząsteczek.
Start Rotation Początkowa rotacja cząsteczek.
Start Color Kolor wyemitowanych cząsteczek.
Gravity Właściwość określa siłę ziemskiej grawitacji, która będzie
Modifier oddziaływała na cząsteczki.
Inherit Velocity Właściwość określa szybkość systemu cząsteczek (o ile taki
występuje) przekazywaną cząsteczkom.
Simulation Właściwość określa, czy cząsteczki są symulowane
Space w przestrzeni lokalnej, czy świata.
Play On Właściwość określa, czy system cząsteczek rozpoczyna
Wake emisję cząsteczek natychmiast po jego utworzeniu.
Max Właściwość określa całkowitą liczbę cząsteczek, które mogą
Particles istnieć w systemie w danym czasie. Po osiągnięciu
zdefiniowanej tutaj liczby system wstrzyma emisję nowych
do czasu, kiedy pewne cząsteczki nie zostaną
usunięte z systemu.

Tabela 16.2. Właściwości modułu Emission


Właściwość Opis
Rate Ilość cząstek emitowanych na przestrzeni czasu
lub na określoną odległość.
Bursts Jeżeli częstotliwość emisji jest wyrażona w czasie, właściwość
określa liczbę fal emisji. Utworzenie fali następuje
po kliknięciu plusa, natomiast usunięcie po kliknięciu
minusa (patrz rysunek 16.4).
Moduły systemu cząsteczek 283

RYSUNEK 16.4.
Moduł Emission

Moduł Velocity over Lifetime


Moduł Velocity over Lifetime bezpośrednio animuje każdą cząsteczkę przez
zastosowanie szybkości dla jej osi X, Y i Z. Warto pamiętać, że jest to zmiana
szybkości dla każdej cząsteczki na przestrzeni cyklu życiowego cząsteczki, a nie
cyklu życiowego systemu cząsteczek. Właściwości modułu Velocity over Lifetime
zostały wymienione w tabeli 16.3.

Tabela 16.3. Właściwości modułu Velocity over Lifetime


Właściwość Opis
XYZ Szybkość nadana każdej cząsteczce. To może być stała,
krzywa lub losowo wybrana liczba między stałą i krzywą.
Space Właściwość określa, czy szybkość jest nadawana
na podstawie przestrzeni lokalnej, czy świata.

Moduł Limit Velocity over Lifetime


Moduł o tej długiej nazwie może być używany w celu zwiększenia lub zmniej‐
szenia szybkości cząsteczki. Ogólnie rzecz biorąc, uniemożliwia cząsteczce
przekroczenie wartości granicznej szybkości w jednej lub we wszystkich
osiach. Właściwości modułu Limit Velocity over Lifetime wymieniono
w tabeli 16.4.

Tabela 16.4. Właściwości modułu Limit Velocity over Lifetime


Właściwość Opis
Separate Axis Jeżeli ta właściwość nie zostanie wybrana, wtedy
dla każdej osi będzie używana ta sama wartość. Z kolei
wybór tej właściwości powoduje, że poszczególne osie
są wyświetlane jako właściwości przestrzeni lokalnej
lub świata.
Speed Wartość graniczna szybkości dla poszczególnych
lub wszystkich osi.
Dampen Wartość z zakresu od 0 do 1, o jaką cząsteczka będzie
zwolniona po przekroczeniu wartości granicznej wskazanej
przez właściwość Speed. Wartość 0 w ogóle nie spowalnia
cząsteczki, natomiast 1 spowolni cząsteczkę o 100%.
284 Lekcja 16. Systemy cząsteczek

Moduł Force over Lifetime


Moduł Force over Lifetime jest podobny do modułu Velocity over Lifetime.
Różnica polega na tym, że omawiany moduł ma zastosowanie do siły, a nie
szybkości każdej cząsteczki. Moduł pozwala również na losowy wybór siły
w każdej klatce; jest to przeciwieństwo stosowania wcześniej ustalonej siły.

Moduł Color over Lifetime


Moduł Color over Lifetime pozwala na zmianę koloru cząsteczki na prze‐
strzeni czasu. To jest użyteczna możliwość podczas tworzenia efektów, takich
jak iskry, które na początku mają kolor jasnopomarańczowy, a przed zga‐
śnięciem ciemnoczerwony. W celu użycia omawianego modułu trzeba wska‐
zać kolor gradientu. Istnieje również możliwość wskazania dwóch kolorów
gradientu, a Unity losowo wybierze jeden z nich. Do edycji gradientu służy
oferowany przez Unity edytor gradientu (patrz rysunek 16.5).

RYSUNEK 16.5.
Edytor gradientu

Warto zwrócić uwagę, że kolor gradientu będzie używany przez właściwość


Start Color w module domyślnym. Oznacza to, że jeśli na początku będzie usta‐
wiony kolor czarny, użycie omawianego modułu nie będzie miało żadnego
efektu.

Moduł Color by Speed


Moduł Color by Speed pozwala na zmianę koloru cząsteczki na podstawie jej
szybkości. Właściwości modułu Color by Speed wymieniono w tabeli 16.5.

Moduł Size over Lifetime


Moduł Size over Lifetime pozwala na określenie zmiany wielkości cząsteczki.
Wielkość musi być krzywą i określa, kiedy cząsteczka rośnie, a kiedy maleje.
Moduły systemu cząsteczek 285

Tabela 16.5. Właściwości modułu Color by Speed


Właściwość Opis
Color Gradient (lub dwa gradienty dla losowo wybranych
kolorów), który będzie użyty do określenia koloru cząsteczki.
Speed Minimalna i maksymalna wartość szybkości mapowana
na kolor gradientu.
Range Cząsteczki poruszające się z minimalną szybkością będą
mapowane po lewej stronie gradientu, natomiast kolory
dla szybkości maksymalnej będą mapowane po prawej
stronie gradientu.

Moduł Size by Speed


Podobnie jak w module Color by Speed, moduł Size by Speed pozwala na zmianę
wielkości cząsteczki na podstawie jej szybkości między wartością minimalną
i maksymalną.

Moduł Rotation over Lifetime


Moduł Rotation over Lifetime pozwala na określenie rotacji w trakcie cyklu
życiowego cząsteczki. Trzeba zwrócić uwagę, że rotacja dotyczy samej cząsteczki,
a nie krzywej w układzie współrzędnych świata. Oznacza to, że jeśli cząsteczka
jest zwykłym okręgiem, nie będziesz w stanie dostrzec rotacji. Jeśli jednak
cząsteczka ma jakiekolwiek szczegóły, wtedy zauważysz obrót. Wartością rotacji
może być stała, krzywa lub losowo wybrana liczba.

Moduł Rotation by Speed


Moduł Rotation by Speed działa podobnie jak Rotation over Lifetime, ale zmiana
jest wprowadzana na podstawie szybkości cząsteczki. Rotacja będzie się zmie‐
niać na podstawie minimalnej i maksymalnej wartości szybkości.

Moduł External Forces


Moduł External Forces pozwala na zastosowanie mnożnika dla dowolnej siły
istniejącej na zewnątrz systemu cząsteczek. Dobrym przykładem będzie tutaj
dowolna siła wiatru zdefiniowanego dla sceny. Właściwość Multiplier w zależ‐
ności od wartości spowoduje przeskalowanie siły w górę lub w dół.

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

na wcześniej określonych powierzchniach (Plane mode: most efficient) lub


z obiektami na scenie (World mode: slows performance). W zależności od
wybranego typu kolizji moduł Collision ma pewne najczęściej stosowane wła‐
ściwości oraz kilka unikalnych. W tabeli 16.6 wymieniono najczęściej używane
właściwości modułu Collision. Z kolei w tabelach 16.7 i 16.8 opisano właści‐
wości stosowane w trybach, odpowiednio, Planes i World.

Tabela 16.6. Najczęściej używane właściwości modułu Collision


Właściwość Opis
Planes / World Właściwość określa typ kolizji. Planes powoduje kolizje
ze zdefiniowanymi płaszczyznami, natomiast World
powoduje kolizje ze wszystkimi obiektami znajdującymi
się na scenie.
Dampen Właściwość określa, jak bardzo cząsteczka zwolni po kolizji.
Właściwość przyjmuje wartości z zakresu od 0 do 1.
Bounce Właściwość określa, jaka część komponentu szybkości
zostanie zachowana. W przeciwieństwie do właściwości
Dampen, omawiana właściwość wpływa jedynie na te
osie cząsteczki, względem których się odbija. Właściwość
przyjmuje wartości z zakresu od 0 do 1.
Lifetime Loss Właściwość określa, jaką część życia cząsteczka traci
w trakcie kolizji. Właściwość przyjmuje wartości z zakresu
od 0 do 1.
Min Kill Speed Właściwość określa minimalną szybkość cząsteczki,
zanim zostanie „zabita” przez kolizję.
Send Collision Właściwość określa, czy komunikaty kolizji będą wysyłane
Messages do obiektów kolidujących z cząsteczkami.

Tabela 16.7. Właściwości trybu Planes


Właściwość Opis
Planes Zbiór transformacji używanych do ustalenia, czy cząsteczki
mogą kolidować. Oś Y transformacji określa rotację
płaszczyzny.
Visualization Właściwość określa, jak płaszczyzny będą wyświetlane
w panelu Scene. Dostępne opcje to Solid (bryła) i Grid
(siatka).
Scale Plane Właściwość powoduje zmianę sposobu wizualizacji
płaszczyzn.
Particle Radius Właściwość może być użyta, aby cząsteczki wydawały
się większe lub mniejsze, w zależności od potrzeb kolizji.
Moduły systemu cząsteczek 287

Tabela 16.8. Właściwości trybu World


Opis Właściwość
Collides With Właściwość określa, z którymi warstwami będą
kolidować cząsteczki. Opcją domyślną jest Everything,
czyli ze wszystkimi warstwami.
Collision Quality Właściwość określa jakość kolizji ze światem. Dostępne
opcje to High, Medium i Low. Oczywiście użycie opcji
High wiąże się ze zużyciem największej ilości zasobów
procesora i jednocześnie daje najlepsze efekty.
Analogicznie użycie opcji Low oznacza zużycie
najmniejszej ilości zasobów procesora, choć jednocześnie
charakteryzuje się najniższą jakością efektu końcowego.
Voxel Size Właściwość jest bardziej zaawansowana i stosowana
do określenia gęstości Voxel używanej po wybraniu
opcji Medium lub Low w ustawieniach jakości. Najlepiej
pozostaw tę wartość bez zmian, chyba że doskonale
wiesz, co robisz.

 Wypróbuj samodzielnie

Wywołanie kolizji cząsteczek


W tym ćwiczeniu zdefiniujesz kolizje z systemem cząsteczek. Wykorzystane
zostaną oba tryby kolizji, czyli Planes i World.
1. Utwórz nowy projekt lub scenę. Do sceny dodaj system cząsteczek
i umieść go w położeniu (0, 0, 0).
2. W panelu Inspector włącz moduł Collision, klikając kółko wyświetlane
obok jego nazwy. Następnie kliknij mały plus obok właściwości Planes,
a pojawi się płaszczyzna (patrz rysunek 16.6). Być może trzeba będzie
zmienić wizualizację na Grid, aby dopasować efekt do pokazanego
na rysunku 16.6. Zwróć uwagę, jak cząsteczki odbijają się od płaszczyzny.
Przesuwaj i obracaj płaszczyznę, obserwując jednocześnie, jak to wpływa
na zachowanie cząsteczek.
3. Do sceny dodaj sześcian. Umieść go w położeniu (0, 4, 0) i przeskaluj
(5, 1, 5).
4. Zwróć uwagę, jak cząsteczki przechodzą przez sześcian. W module
Collision ustaw tryb World (patrz rysunek 16.7) i zauważ, jak cząsteczki
zaczynają się odbijać od sześcianu. Kontynuuj eksperymenty z różnymi
właściwościami modułu i obserwuj, jaki mają wpływ na cząsteczki.
288 Lekcja 16. Systemy cząsteczek

Rysunek 16.6. Dodanie płaszczyzny

Rysunek 16.7. Zmiana typu kolizji na World

Moduł Sub Emitter


Moduł Sub Emitter oferuje niewiarygodnie potężne możliwości i pozwala na
tworzenie nowych systemów cząsteczek dla pewnych zdarzeń dla każdej
cząsteczki w bieżącym systemie cząsteczek. Nowy system cząsteczek można
zbudować za każdym razem, gdy cząsteczka jest tworzona, niszczona lub ulega
kolizji. Takie rozwiązanie pozwala na generowanie skomplikowanych i zawi‐
łych efektów (np. fajerwerków). Moduł zawiera trzy właściwości: Birth, Death
i Collision. Każda z właściwości przechowuje zero lub więcej systemów cząste‐
czek tworzonych w trakcie wymienionych zdarzeń.

Moduł Texture Sheet


Moduł Texture Sheet pozwala na zmianę współrzędnych tekstury używanej
dla cząsteczki w trakcie cyklu życiowego. Oznacza to możliwość umieszczenia
w pojedynczym obrazie wielu tekstur dla cząsteczki, a następnie zmianę tekstur
w trakcie cyklu życiowego cząsteczki. Właściwości modułu Texture Sheet zostały
wymienione w tabeli 16.9.
Moduły systemu cząsteczek 289

Tabela 16.9. Właściwości modułu Texture Sheet


Właściwość Opis
Tiles Właściwość określa kafelkowanie tekstury.
Animation Właściwość określa, czy tekstury dla cząsteczki zawierają
cały obraz, czy tylko jeden wiersz.
Cycles Właściwość wskazuje szybkość animacji.

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.

Tabela 16.10. Właściwości modułu Renderer


Właściwość Opis
Render Mode Właściwość określa, jak faktycznie będą wyświetlone
cząsteczki. Dostępne tryby to Billboard, Stretched
Billboard, Horizontal Billboard, Vertical Billboard i Mesh.
Wszystkie tryby typu Billboard powodują wyrównanie
cząsteczek względem kamery lub dwóch z trzech osi.
Z kolei tryb Mesh powoduje wyświetlenie cząsteczek
w 3D w sposób narzucony przez siatkę.
Normal Direction Właściwość określa, jak bardzo cząsteczka jest odwrócona
w stronę kamery. Wartość 1 oznacza, że cząsteczka
jest zwrócona bezpośrednio w stronę kamery.
Material Właściwość ustala materiał użyty do wyświetlenia
cząsteczki.
Sort Order Właściwość wskazuje kolejność wyświetlania cząsteczek.
Dostępne opcje to None, By Distance, Youngest First
i Oldest First.
Sorting Fudge Właściwość wskazuje kolejność wyświetlania systemów
cząsteczek. Im niższa wartość, tym większe
prawdopodobieństwo, że system cząsteczek będzie
wyświetlony nad innymi obiektami i cząsteczkami.
Cast Shadows Właściwość określa, czy cząsteczki rzucają cień.
Receive Shadows Właściwość określa, czy cząsteczki otrzymują cień.
Max Particle Size Właściwość pozwala na określenie maksymalnej
wielkości względnej. Dozwolone wartości mieszczą
się w zakresie od 0 do 1.
290 Lekcja 16. Systemy cząsteczek

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

Tytułem krzywej jest określana wartość. W przypadku pokazanym na


rysunku 16.8 wartością będzie siła stosowana wzdłuż osi X w module Force
over Lifetime. Zakres wskazuje wartości minimalną i maksymalną. Można je
zmienić, powodując zmniejszenie lub zwiększenie zakresu. Wyświetlona
w edytorze krzywa to konkretne wartości na przestrzeni czasu tworzące
kształty, które przypominają krzywe.
Krzywą można przesuwać w dowolnym z jej punktów kluczowych. Wspomniane
punkty są wyświetlane jako punkty widoczne na krzywej. Domyślnie istnieją
tylko dwa punkty kluczowe: po jednym na początku i końcu krzywej. Istnieje
możliwość dodania nowego punktu kluczowego w dowolnym miejscu krzywej
przez kliknięcie jej prawym przyciskiem myszy, a następnie wybranie opcji
Add Key Point.

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

Użycie edytora krzywych


Teraz popracujesz z edytorem krzywych. W tym ćwiczeniu zmienisz wielkość
emitowanych cząsteczek w trakcie jednego cyklu systemu cząsteczek.
1. Utwórz nowy projekt lub scenę. Dodaj system cząsteczek i umieść
go w położeniu (0, 0, 0).
2. Kliknij rozwijaną strzałkę skierowaną w dół i umieszczoną obok
właściwości Start Size, a następnie wybierz opcję Curve.
3. Zmień zakres krzywej na od 1 do 2. Mniej więcej w połowie krzywej
kliknij ją prawym przyciskiem myszy i dodaj nowy punkt kluczowy.
To samo zrób na końcu krzywej. Teraz przeciągnij punkt środkowy
w górę edytora krzywych, co spowoduje przypisanie punktowi wartości
2 (patrz rysunek 16.9). Zwróć uwagę, jak emitowane cząsteczki zmieniają
wielkość w trakcie 5-sekundowego cyklu systemu cząsteczek.

Rysunek 16.9. Ustawienie Start Size dla krzywej

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

W czasie tej lekcji dowiesz się:


 jakie są wymagania dotyczące animacji,
 jak przygotować model do animacji,
 jak zastosować animację,
 jak wywoływać animację za pomocą skryptów.
W tej lekcji zajmiesz się animacją w środowisku Unity. Na początek dowiesz
się, czym dokładnie jest animacja oraz jakie są wymagania, które trzeba
spełnić, by działała. Następnie przejdziesz do rzeczywistego modelu, na
podstawie którego zobaczysz, jak przygotować model do animacji. Później
zostanie przedstawiona anatomia animacji i jej zastosowanie na modelu.
Na końcu lekcji poruszone zostanie zagadnienie wyzwalania animacji
za pomocą skryptów.

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

Kości i złączenia współdziałają w celu zdefiniowania struktury fizycznej modelu.


Struktura będzie używana do rzeczywistej animacji modelu.

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.

Przygotowanie modelu do animacji


Prawidłowe przygotowanie modelu do animacji nie wymaga zbyt dużej ilości
pracy. Przyjmuję, że proces riggingu modelu został już zakończony. Jeżeli nie,
będzie musiał być przeprowadzony przed zaimportowaniem modelu do Unity.
W tej części lekcji zaczniesz pracę z już przygotowanym modelem i przygotu‐
jesz animację specjalnie dla tego modelu. W rzeczywistym środowisku pro‐
dukcyjnym, zanim elementy będą mogły być użyte w Unity, należy je przygo‐
tować lub zlecić to artyście 3D.
W lekcji wykorzystasz model pobrany ze sklepu Unity Asset Store. Model jest
dostarczany z wieloma różnymi elementami. Sprawdzisz je wszystkie i upew‐
nisz się, że zostały prawidłowo skonfigurowane. Aby przejść do sklepu Unity
296 Lekcja 17. Animacje

Asset Store, wybierz opcję Window/Asset Store. Możesz zostać poproszony


o zalogowanie się. W takim przypadku podaj dane uwierzytelniające do konta,
które utworzyłeś w lekcji 1. Po wczytaniu sklepu w polu wyszukiwania wpisz
Warrior (patrz rysunek 17.2).

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

Karta Model zawiera wszystkie ustawienia określające sposób importowania


modelu do Unity. W bieżącej lekcji możesz je wszystkie zignorować. Dwie inte‐
resujące karty to Rig i Animations. W karcie Rig upewnij się, że opcją wybraną
we właściwości Animation Type jest Legacy, natomiast we właściwości Gene-
ration — opcja Store in Root (New). Prawidłowe ustawienia pokazano na
rysunku 17.5.
Następnie przejdź do karty Animations. Animacje są często dostarczane jako
część modelu. To miłe, ponieważ wtedy nie trzeba zarządzać wieloma plikami
i wszystko znajduje się w pakiecie. Karta Animations zawiera wszystkie wła‐
ściwości i kontrolki wymagane do zarządzania wbudowaną animacją. W tej
lekcji oraz w celach dydaktycznych teraz je wyłączysz. W karcie Animations usuń
zaznaczenie obok pola wyboru Import Animation, a następnie kliknij przycisk
Apply. Karta powinna przedstawiać się tak, jak pokazano na rysunku 17.6.
298 Lekcja 17. Animacje

RYSUNEK 17.5.
Ustawienia
w karcie Rig

RYSUNEK 17.6.
Ustawienia
animacji

Czy model został przygotowany do animacji?


Być może zastanawiasz się, jak ustalić, czy model został przygotowany do
animacji? Najłatwiej będzie zapytać o to twórcę modelu. Jeżeli to okaże się
niemożliwe, zawsze można spojrzeć na model w panelu Hierarchy. Ogólnie
rzecz biorąc, po riggingu model będzie zawierał wiele potomnych obiektów
gry. Obiekty odpowiadają różnym złączeniom riggingu. Na rysunku 17.7
pokazano pewne obiekty potomne pozwalające na ustalenie, czy model
został poddany riggingowi.

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

Kliknij model Soldier_f_0 w katalogu Models i przeciągnij go na okno Preview,


aby zobaczyć podgląd animacji (patrz rysunek 17.9).

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

Dodanie żołnierza do sceny


Teraz dodasz do sceny model żołnierza i wypróbujesz go. Scena przygoto-
wana w tym ćwiczeniu będzie używana dalej w tej lekcji, zatem ją zapisz.
1. Utwórz nowy projekt lub scenę. Do sceny dodaj światło kierunkowe.
2. Odszukaj zasób modelu Soldier_f_0 i przeciągnij go na panel Scene.
Nowo utworzonego żołnierza umieść w położeniu (0, 0, –5) i zastosuj
rotację (0, 180, 0). Upewnij się, że żołnierz na scenie ma w panelu
Inspector zaznaczony komponent Animation. Każdy inny komponent,
np. Animator, oznacza, że poprzedni krok został wykonany
nieprawidłowo.
3. Uruchom scenę. Zauważ, że model żołnierza znajduje się na scenie,
ale pozostaje nieruchomy. To oczekiwany efekt, ponieważ jeszcze
nie zastosowałeś żadnej animacji. Zapisz scenę, w tej lekcji będziesz
z niej jeszcze korzystać.

Tabela 17.1. Właściwości komponentu Animation


Właściwość Opis
Animation To jest domyślna animacja modelu. Jeżeli nie zostanie
tutaj zdefiniowana animacja, model nie będzie
animowany.
Animations To jest lista wszystkich animacji, które mogą być
stosowane przez dany model. Dodanie animacji
odbywa się przez jej przeciągnięcie na omawianą
właściwość.
Play Automatically Jeżeli omawiana właściwość zostanie włączona,
po utworzeniu model zaczyna odtwarzać animację
domyślną.
Animate Physics Właściwość określa, czy animacja współgra z fizyką.
Culling Type Właściwość określa, kiedy animacja będzie
odtwarzana. Dostępne są następujące opcje: Always
Animate, Based on Renderer, Based on Clip Bounds
i Based on User Bounds. Ogólnie rzecz biorąc, dla
tej właściwości pozostaw wartość domyślną, o ile
nie próbujesz uzyskać określonej funkcjonalności.

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

Ten krok powoduje udostępnienie wskazanej animacji modelowi. Nie oznacza


jednak rzeczywistego animowania modelu. Przechodzenie za pomocą skryptu
między różnymi animacjami zostanie omówione dalej w tej lekcji. Obecnie
jesteś prawdopodobnie bardzo ciekawy, jak faktycznie wygląda działanie
animacji. Aby uruchomić animację modelu, przeciągnij ją na właściwość Ani-
mations komponentu Animation. W ten sposób nastąpi zdefiniowanie animacji
domyślnej dla modelu. Upewnij się również, że została ustawiona opcja Play
Automatically. Teraz po uruchomieniu sceny zobaczysz poruszający się model!

Właściwość Wrap Mode


Dotychczas zasoby animacji przeglądałeś w panelu Inspector. Być może
zwróciłeś uwagę na właściwość Wrap Mode, która wcześniej została pomi‐
nięta. Właściwość ta określa, jak zachowuje się animacja po uruchomieniu.
W tabeli 17.2 wymieniono pięć różnych trybów.

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.

Tabela 17.2. Tryby właściwości Wrap Mode


Właściwość Opis
Default Opcja pozwala animacji na domyślnie zdefiniowane
w niej zachowanie. Zwykle oznacza to jednokrotne
odtworzenie animacji.
Once Animacja jest odtwarzana tylko jednokrotnie, a następnie
się zatrzymuje.
Loop Po zakończeniu odtwarzania animacja zostaje ponownie
uruchomiona.
Ping Pong Po zakończeniu odtwarzania animacja zostaje
ponownie uruchomiona, ale jest odtwarzana wstecz.
Tak zapętlona animacja jest nieustannie odtwarzana
do przodu i wstecz.
Clamp Forever Animacja jest odtwarzana tylko jednokrotnie. Po dotarciu
do końca nieustannie odtwarza ostatnią klatkę. To odróżnia
tę opcję od Once, ponieważ Once oznacza jednokrotne
odtworzenie animacji i następnie przejście do jej pierwszej
klatki.

Wiele skomplikowanych funkcji można realizować za pomocą skryptów, ale


w tej lekcji koncentrujemy się na odtwarzaniu animacji. W kolejnej lekcji zostaną
przedstawione znacznie bardziej zaawansowane skrypty przeznaczone do
obsługi animacji.
Podsumowanie 303

 Wypróbuj samodzielnie

Użycie właściwości Wrap Mode


W tym ćwiczeniu użyjesz sceny utworzonej w poprzednim zatytułowanym
„Animacja modelu”. Jeżeli jej jeszcze nie masz, musisz wrócić do poprzed-
niego ćwiczenia i je wykonać. Tutaj zajmiesz się pracą z różnymi opcjami
właściwości Wrap Mode.
1. Otwórz poprzednio utworzoną scenę.
2. Upewnij się, że animacja Idle0 jest ustawiona jako domyślna animacja
dla modelu żołnierza. Uruchom scenę i zobacz, w jaki sposób żołnierz
się porusza.
3. W panelu Project odszukaj zasób animacji Idle0. Opcję właściwości
Wrap Mode zmień na Ping Pong. Ponownie uruchom scenę i zobacz,
jak teraz żołnierz się porusza.
4. Kontynuuj eksperymenty z różnymi animacjami i opcjami właściwości
Wrap Mode.

W celu odtworzenia animacji dla modelu trzeba użyć metody transform.


animation.Play(). Aby np. odtworzyć animację o nazwie walk, można
użyć poniższego wywołania:
transform.animation.Play("walk");
Animacje mogą być zmieniane w dowolnej chwili przez po prostu rozpoczęcie
odtwarzania innej animacji. Jeżeli dla animacji zdefiniowano pętlę, wtedy odtwa‐
rzanie w pętli odbywa się automatycznie.

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ą.

Animacja nie działa


Po ukończeniu tej lekcji być może spróbujesz animacji własnych modeli lub
innych pobranych ze sklepu Unity Asset Store. Pamiętaj, że jeśli po odpo-
wiednim zastosowaniu animacji model nadal pozostaje nieruchomy, pro-
blem niemal na pewno wiąże się z riggingiem innym niż dla animacji. Musisz
pamiętać, że model i animacja muszą mieć ten sam rigging. W przeciwnym
razie prawdopodobnie będziesz z frustracji walił głową w ścianę.

Pytanie: Czy animacje można stosować do dowolnego modelu?


Odpowiedź: Tylko wtedy, gdy mają dokładnie ten sam rigging. W przeciwnym
razie animacje mogą zachowywać się bardzo dziwnie lub w ogóle nie
działać.
Pytanie: Czy w Unity można przeprowadzić ponowny rigging modelu?
Odpowiedź: Tak. Dowiesz się o tym w następnej 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 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

3. Uruchom scenę i zobacz, że dla modelu odtwarzana jest zapętlona


animacja idle0. Naciśnij klawisz 2 i zwróć uwagę na zmianę odtwarzanej
animacji. Poeksperymentuj z klawiszami od 1 do 4, aby przekonać się,
jaką zmianę animacji powodują. Klawisze znajdujące się na klawiaturze
numerycznej nie działają, ponieważ skrypt jest specjalnie
zaprogramowany do pracy z klawiszami numerycznymi znajdującymi
się nad klawiszami liter.
Lekcja 18
Animator

W czasie tej lekcji:


 poznasz podstawy dotyczące zasobu Animator,
 dowiesz się, w jaki sposób tworzyć animatory,
 zobaczysz, jak zarządzać animatorem za pomocą skryptów.
W tej lekcji wykorzystasz wiedzę zdobytą w poprzedniej oraz użyjesz
nowego w Unity systemu animacji Mecanim i animatorów. Na początek
dowiesz się, czym są animatory i jak działają. Następnie przejdziesz do
riggingu, jego utworzenia w Unity bądź wprowadzania zmian w modelach.
Później zajmiesz się tworzeniem i konfiguracją animatorów. Na końcu
lekcji zobaczysz, jak za pomocą skryptów operować animatorem i tworzyć
interaktywne demo.

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

Podstawy zasobu Animator


W poprzedniej lekcji dowiedziałeś się, jak ręcznie kontrolować poszczególne
animacje. Za pomocą takiego systemu można przeprowadzać zaawansowane
operacje, takie jak przejścia i łączenie animacji. Jednak będzie to kłopotliwe
i żmudne. W tej lekcji zobaczysz, jak można pracować z nowym w Unity sys‐
temem animacji o nazwie Mecanim. W systemie użyty został zasób o nazwie
Animator, który zawiera kilka animacji i przejść. Tak przygotowany zasób jest
dołączany do modelu i pozwala na jego animację. Przydatną cechą omawianego
tutaj systemu jest możliwość utworzenia pojedynczego zasobu Animator,
a następnie jego zastosowanie w kilku różnych modelach, które dzięki temu
będą animowane w podobny sposób. Jednak zanim będziesz mógł przystąpić
do opracowywania zasobu animatora, musisz upewnić się, że dla modelu został
zbudowany prawidłowy rigging i skonfigurowana animacja.

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

4. Kliknij przycisk Configure…, który spowoduje uruchomienie edytora


riggingu. Jeżeli zostaniesz poproszony o zapis sceny, zrób to. W edytorze
riggingu zobaczysz model znajdujący się w tzw. pozycji T
(patrz rysunek 18.2).

RYSUNEK 18.2.
Model Jack
w pozycji T

5. Upewnij się, że wszystkie złączenia są zielone (patrz rysunek 18.3)


i kliknij przycisk Done. Jeżeli nie wszystkie złączenia są w kolorze
zielonym, przejdź do kolejnego punktu zatytułowanego „Czerwony
rigging śmierci”.
Model Jack jest teraz gotowy do animacji.

Czerwony rigging śmierci


Zapewne masz nadzieję, że powyżej wymienione kroki przebiegną zgodnie
z oczekiwaniami i wszystkie złączenia będą w kolorze zielonym. Niestety, nie
zawsze tak bywa. Unity czasami potrzebuje pewnej pomocy w ustalaniu spo‐
sobu riggingu modelu. Na rysunku 18.4 pokazano model, którego rigging jest
nieprawidłowy. W omawianym przykładzie nieprawidłowo dopasowano
złącze kręgosłupa. Aby to naprawić, wybierz opcję Mapping/Automap. Unity
przeanalizuje model i usunie problem. Jeżeli automatyczne mapowanie nie
sprawdzi się dla określonego modelu, wtedy złączenia trzeba będzie wyszu‐
kiwać i mapować ręcznie.
310 Lekcja 18. Animator

RYSUNEK 18.3.
Model
z prawidłowym
riggingiem

RYSUNEK 18.4.
Model
z nieprawidłowym
riggingiem
Podstawy zasobu Animator 311

Czasami rigging modelu jest prawidłowy, ale pewne złączenia są wyświetlane


w kolorze czerwonym (patrz rysunek 18.5). Wynikiem są ograniczenia pozy,
które można usunąć przez wybór opcji Pose/Enforce T-Pose.

RYSUNEK 18.5.
Wymuszenie
użycia pozycji T

Przedstawione proste metody pozwalają na usunięcie większości, o ile nie


wszystkich problemów związanych z riggingiem modelu.

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.

Przygotowanie animacji Idle


W celu skonfigurowania animacji Idle wykonaj wymienione poniżej kroki.
1. W katalogu Animations zaznacz plik Idles.fbx. W panelu Inspector
kliknij kartę Rig. Typ animacji zmień na Humanoid i skonfiguruj rigging
dokładnie w taki sam sposób, jak wcześniej dla modelu Jack. Być może
312 Lekcja 18. Animator

będziesz musiał powrócić do wcześniej przedstawionej procedury


i wykonać wymienione w niej kroki.
2. Po zakończeniu konfiguracji riggingu kliknij kartę Animations w panelu
Inspector. Jedynym zadaniem do wykonania jest tutaj zaznaczenie
właściwości Loop Pose. Zakładam, że zastosujesz ustawienia pokazane
na rysunku 18.6.

RYSUNEK 18.6.
Właściwości
animacji Idle

3. Na tym etapie animacja jest już poprawnie skonfigurowana. Możesz


się o tym przekonać, rozwijając plik Idles.fbx (patrz rysunek 18.7).
Upewnij się, że doskonale znasz sposób uzyskania dostępu do tej
animacji. Sam model jest nieistotny, interesuje nas animacja.

RYSUNEK 18.7.
Odszukanie
animacji
w modelu
Podstawy zasobu Animator 313

Światło czerwone, światło zielone


Być może zauważyłeś kolorowe kropki w ustawieniach animacji (patrz rysu-
nek 18.6). To są małe, sprytne narzędzia przeznaczone do wskazania, czy
animacje są dopasowane. Kropka w kolorze zielonym oznacza, że pętla
będzie płynna, bez widocznych przejść. Jeżeli którakolwiek kropka jest żółta,
wskazuje na możliwość prawie płynnego zapętlenia, choć występują drobne
różnice. Z kolei czerwona kropka znaczy, że początek i koniec animacji są
niedopasowane i przejście będzie bardzo widoczne. Jeżeli masz niedopa-
sowaną animację, możesz zmienić właściwości Start i End, aby odszukać
odpowiedni segment animacji.

Przygotowanie animacji WalkForward


W celu skonfigurowania animacji WalkForward wykonaj wymienione poniżej
kroki.
1. W katalogu Animations zaznacz plik WalkForward.fbx i wykonaj rigging
dokładnie w taki sam sposób jak dla animacji Idle.
2. W karcie Animations powinieneś mieć ustawienia, takie jak pokazano
na rysunku 18.8. Zwróć uwagę na dwie kwestie. Oto pierwsza: w sekcji
Root Transform Position (XZ) wyświetlona jest czerwona kropka. To
dobrze, bo oznacza ona, że na końcu animacji model będzie w innym
położeniu względem osi X i Z. Ponieważ animacja dotyczy chodu, jest
to oczekiwane zachowanie. A to druga: wskaźnik Average Velocity.
Powinieneś zauważyć, że wartość dla osi X wynosi -0.034, natomiast
dla osi Z wynosi 1.534. Szybkość dla osi Z jest prawidłowa, ponieważ
model ma poruszać się do przodu. Z kolei szybkość dla osi X stanowi
problem i powoduje, że podczas poruszania się model jest „ściągany”
na stronę. Dlatego też to ustawienie trzeba poprawić.

RYSUNEK 18.8.
Ustawienia
animacji
WalkForward
314 Lekcja 18. Animator

3. Aby zmodyfikować szybkość dla osi X, konieczne jest sprawdzenie


właściwości Bake into Pose dla właściwości Root Transform Rotation
i Root Transform Position (Y). Ponadto właściwości Root Transform
Rotation trzeba ustawić wartość -2.26. Na koniec sprawdź wartość
właściwości Loop Pose. Na rysunku 18.9 pokazano poprawione
ustawienia. Po zakończeniu konfiguracji kliknij przycisk Apply.

RYSUNEK 18.9.
Ustawienia
animacji
WalkForward

Przygotowanie animacji WalkForwardTurn


Animacja WalkForwardTurn pozwala modelowi na płynną zmianę kierunku
podczas poruszania się do przodu. Różni się nieco bardziej od dwóch omówio‐
nych wcześniej, ponieważ trzeba przygotować dwie animacje w jednej. Brzmi
to znacznie bardziej zawile niż faktycznie jest. Poniżej wymieniono kroki, które
należy wykonać.
1. W katalogu Animations zaznacz plik WalkForwardTurns.fbx i wykonaj
rigging dokładnie w taki sam sposób jak dla animacji Idle.
2. Domyślnie będzie to długa animacja o nazwie _7_a_U1_M_P_
WalkForwardTurnRight. Wprawdzie możesz ją zmodyfikować,
ale znacznie łatwiejszym rozwiązaniem jest jej usunięcie i od nowa
rozpoczęcie pracy nad animacją. W polu tekstowym Clip Name wpis
WalkForwardTurnRight, a następnie kliknij przycisk + (plus) i utwórz
nowy klip (patrz rysunek 18.10).

RYSUNEK 18.10.
Dodanie klipu
animacji
Podstawy zasobu Animator 315

3. Teraz możesz już usunąć stary klip animacji. Wybierz więc


_7_a_U1_M_P_WalkForwardTurnRight i naciśnij przycisk – (minus)
w celu usunięcia klipu.
4. Mając zaznaczony nowy klip WalkForwardTurnRight, ustaw jego
właściwości, tak jak pokazano na rysunku 18.11. Klip zostanie skrócony
i będzie zawierał jedynie model poruszający się w kółko w prawą
stronę. (Upewnij się, że wyświetliłeś podgląd animacji).
Po wprowadzeniu ustawień kliknij przycisk Apply.

RYSUNEK 18.11.
Ustawienia
skrętu w prawo

5. Utwórz klip animacji WalkForwardTurnLeft w dokładnie taki sam


sposób jak klip w kroku 2. Właściwości klipu skrętu w lewo są
praktycznie takie same jak WalkForwardTurnRight, ale trzeba
zaznaczyć właściwość Mirror (patrz rysunek 18.12).

RYSUNEK 18.12.
Lustrzane odbicie
animacji
316 Lekcja 18. Animator

W tym momencie wszystkie animacje są skonfigurowane i gotowe do użycia.


Możesz więc przystąpić do przygotowania zasobu animatora.

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

RYSUNEK 18.13. Dodanie animatora do modelu

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

W celu utworzenia parametru po prostu kliknij przycisk + (plus) w sekcji


Parameters panelu Animator.

 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.16. Dodawanie parametru


3. Powtórz krok 2., ale tym razem utwórz parametr o nazwie Direction.

Stan i tzw. drzewo Blend Tree


Kolejnym etapem pracy jest utworzenie nowego stanu. Ogólnie rzecz ujmując,
stan określa, który rodzaj animacji będzie aktualnie wyświetlany przez model.
Model Jack będzie miał dwa stany — Idle i Walking. Stan Idle jest już zdefi‐
niowany. Ponieważ stan Walking może być jedną z trzech animacji, konieczne
jest utworzenie stanu opartego na tzw. drzewie Blend Tree. Drzewo pozwala
na płynne przejścia i łączenie animacji na podstawie pewnych parametrów.
W celu utworzenia nowego stanu wykonaj przedstawione poniżej kroki.
1. Prawym przyciskiem myszy kliknij puste miejsce w panelu Animator
i wybierz opcję Create State/From New Blend Tree. W panelu Inspector
nowemu stanowi nadaj nazwę Walking (patrz rysunek 18.17).
2. Dwukrotnie kliknij nowy stan i rozwiń go. W panelu Inspector zmień
wartość właściwości Parameter na Direction i dodaj trzy elementy
Motion, klikając przycisk + (plus) pod sekcją Motion i wybierając Add
Motion Field (patrz rysunek 18.18).
320 Lekcja 18. Animator

RYSUNEK 18.17.
Tworzenie
i nadawanie
nazwy nowemu
stanowi

RYSUNEK 18.18.
Dodanie
Motion Field

3. Zmień wartość minimalną na –1 (patrz rysunek 18.19) i przeciągnij trzy


przygotowane wcześniej animacje ruchu na trzy nowe pola. (Pamiętaj,
że klipy animacji skrętu znajdują się w pliku WalkForwardTurns.fbx).
Upewnij się, że animacje są ułożone w następującej kolejności: Turn
Left, Straight, Turn Right. Zauważ, że animacja ruchu do przodu będzie
miała dziwną nazwę, ponieważ nigdy wcześniej jej nie zmieniałeś.
Będziesz doskonale wiedział, o którą chodzi — to jedyny klip animacji
w pliku WalkForward.fbx.
Animacja ruchu jest teraz gotowa do mieszania na podstawie parametru wska‐
zującego kierunek (Direction). Rozszerzony pogląd panelu otrzymasz po klik‐
nięciu elementu Base Layer na górze panelu Animator (patrz rysunek 18.20).

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

1. Prawym przyciskiem myszy kliknij stan Idle i wybierz opcję Make


Transition. W ten sposób zostanie utworzona biała linia podążająca
za myszą. Kliknij stan Walking , a połączysz je.
2. Powtórz krok 1., ale tym razem połączenie powinno prowadzić
od stanu Walking do Idle.
3. Przeprowadź edycję przejścia z Idle do Walking klikając białą strzałkę
łączącą oba stany. Dla właściwości Conditions wybierz Speed Greater
i podaj wartość 0.1 (patrz rysunek 18.21). To samo zrób dla przejścia
od Walking do Idle, ale tym razem wybierz Speed Less Than i podaj
wartość 0.1.
Animator został ukończony. Zwróć uwagę, że po uruchomieniu sceny nie zoba‐
czysz żadnych odtwarzanych animacji ruchu. Wynika to z faktu, że utworzone
wcześniej parametry szybkości i kierunku nigdy nie ulegają zmianie. W kolej‐
nej części lekcji dowiesz się, jak zmienić wymienione parametry z poziomu
skryptu.
322 Lekcja 18. 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.

systemie Mecanim. Po przygotowaniu niezbędnych elementów utworzyłeś


animator. Do przygotowanego animatora dodałeś parametry, stany, drzewo
łączenia i animacje. Na koniec dowiedziałeś się, jak z poziomu skryptu ope‐
rować parametrami i tym samym kontrolować animator.

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

W czasie tej lekcji dowiesz się:


 jak zaprojektować grę Gauntlet Runner,
 jak zbudować świat gry Gauntlet Runner,
 jak opracować elementy gry Gauntlet Runner,
 jak zaprojektować kontrolki gry Gauntlet Runner,
 jak jeszcze bardziej usprawnić grę Gauntlet Runner.
W tej lekcji zbudujesz trójwymiarową grę zatytułowaną Gauntlet Runner.
Pracę rozpoczniesz od zaprojektowania gry. Następnie przystąpisz do utwo-
rzenia świata, w którym toczy się akcja gry. Po przygotowaniu świata
rozpoczniesz opracowywanie poszczególnych elementów gry i obiektów
kontrolnych. Na końcu lekcji zajmiesz się analizą gry i wyszukaniem obsza-
rów, na których można ją usprawnić.

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);
}

public void SlowDown()


{
speed = speed / 2;
}

public void SpeedUp()


{
speed = speed * 2;
}
3. Uruchom scenę, a zauważysz, że droga jest przewijana. Zastosowałeś
łatwy i efektywny sposób opracowania przewijanego obiektu 3D.
W utworzonym powyżej skrypcie zauważyłeś zapewne dwie dodatkowe
metody — SlowDown() i SpeedUp(). Wprawdzie obecnie nie są używane,
ale będą niezbędne nieco później, gdy gracz zderzy się z przeszkodą. Na rysunku
19.1 pokazano efekt uruchomienia skonfigurowanej tutaj sceny.

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

mentów, które minęły gracza. Nie trzeba przygotowywać punktu tworzenia


elementów w grze. Zamiast tego poznasz różne sposoby budowania obiektów
dodatkowej energii i przeszkód przez pozostawienie tego zadania obiektowi
kontrolera gry.

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

Przedstawione poniżej kroki pozwalają na przygotowanie animacji do umiesz‐


czenia w animatorze.
1. Odszukaj katalog Animations w materiałach przeznaczonych dla
bieżącej lekcji. Przeciągnij katalog na panel Project w Unity, aby tym
samym zaimportować go do projektu.
2. W nowo zaimportowanym katalogu Animations odszukaj plik Jump.fbx
i zaznacz go. W panelu Inspector kliknij kartę Rig i zmień typ animacji
na Humanoid. Kliknij przycisk Apply.
3. W karcie Animations zmień właściwości animacji skoku w taki sposób,
aby odpowiadały pokazanym na rysunku 19.4. Zwróć uwagę, że
wartość właściwości Offset w Root Transform Rotation być może
332 Lekcja 19. Czwarta gra — Gauntlet Runner

RYSUNEK 19.4.
Właściwości
animacji Jump

będzie musiała zostać podana inna niż pokazana na rysunku. Ważne


jest, aby właściwość Average Velocity miała wartość 0 dla osi X.
Kliknij przycisk Apply.
4. W katalogu Animations zaznacz plik Runs.fbx. Ponownie wykonaj
krok 2. w celu poprawy riggingu dla modelu. W karcie Animations
zwróć uwagę na istnienie trzech klipów: RunRight, Run i RunLeft.
Wybierz Run i upewnij się, że właściwości są ustawione tak,
jak pokazano na rysunku 19.5. W tym przypadku również jest ważne,
aby wartość Average Velocity dla osi X wynosiła 0. Kliknij przycisk
Apply.
Po przygotowaniu animacji można przystąpić do pracy nad animatorem. To
będzie prosty, dwustanowy animator niewymagający żadnych drzew Blend
Tree. W celu przygotowania animatora wykonaj wymienione poniżej kroki.
1. Utwórz nowy katalog o nazwie Animators. Następnie prawym
przyciskiem myszy kliknij nowy katalog i wybierz opcję
Create/Animator Controller. Nowemu animatorowi nadaj nazwę
PlayerAnimator.
2. Dwukrotnie kliknij animator w celu przejścia do panelu Animator.
W katalogu Animations odszukaj plik Runs.fbx, klikając strzałkę
znajdującą się po prawej stronie nazwy katalogu. W rozwiniętym
modelu znajdź klip animacji Run i przeciągnij go na panel Animator
(patrz rysunek 19.6). Kliknij nowo utworzony stan Run, a następnie
w panelu Inspector zaznacz właściwość Foot IK.
Elementy gry 333

RYSUNEK 19.5.
Właściwości
animacji Run

RYSUNEK 19.6.
Dodanie klipu
animacji Run
334 Lekcja 19. Czwarta gra — Gauntlet Runner

3. W katalogu Animations odszukaj plik Jump.fbx. Wyświetl jego zawartość,


znajdź klip animacji Jump i przeciągnij ją na panel Animator. Kliknij
nowo utworzony stan Jump, przejdź do panelu Inspector, zaznacz
opcję Foot IK oraz zmień wartość właściwości Speed na 1.25.
4. Dodaj do animatora nowy parametr, klikając przycisk + (plus) w sekcji
Parameters panelu Animator. Jak pokazano na rysunku 19.7, parametr
powinien być typu Bool i mieć nazwę Jumping.

RYSUNEK 19.7.
Dodanie
parametru
Jumping

5. Prawym przyciskiem myszy kliknij stan Run w animatorze i wybierz


opcję Make Transition. Kliknij stan Jump i tym samym połącz oba stany.
Prawym przyciskiem myszy wybierz stan Jump i opcję Make Transition.
Kliknij stan Run i tym samym połącz je ze sobą.
6. Kliknij białą strzałkę oznaczającą przejście ze stanu Run do Jump.
W panelu Inspector zmień opcję Jumping na True (patrz rysunek 19.8).

RYSUNEK 19.8.
Właściwości
przejścia
ze stanu Run

7. Kliknij białą strzałkę oznaczającą przejście ze stanu Jump do Run.


W panelu Inspector zmień wartość Exit Time na 0.89
(patrz rysunek 19.9).
W ten sposób model gracza został przygotowany dla animacji. Pozostało już
tylko umieszczenie go na scenie.
1. Odszukaj plik Robot Kyle.fbx i przeciągnij go na scenę. Umieść robota
w położeniu (0, 0.25, –8.5).
2. Do modelu dodaj komponent Capsule Collider (wybierz opcję
Component/Physics/Capsule Collider). Wartość Y dla komponentu
Collider ustaw na 0.95, natomiast wysokość na 1.72.
3. Przeciągnij PlayerAnimator na właściwość Controller komponentu
Animator. Upewnij się również, że usunąłeś zaznaczenie pola Apply
Root Motion.
Obiekty kontrolne 335

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.

Skrypt strefy wyzwalacza


Pierwszy tworzony skrypt jest przeznaczony dla strefy wyzwalacza. Przy‐
pomnij sobie, że celem istnienia strefy wyzwalacza jest po prostu usuwanie
wszystkich obiektów, które miną gracza. Aby przygotować skrypt, utwórz nowy
skrypt o nazwie TriggerZoneScript i dołącz go do obiektu gry strefy wyzwa‐
lacza. Następnie w skrypcie umieść poniższy kod.
void OnTriggerEnter(Collider other)
{
Destroy (other.gameObject);
}
Skrypt jest bardzo prosty, a jego działanie polega na usuwaniu wszystkich
obiektów, które wkroczą do strefy wyzwalacza.

Skrypt obiektu kontrolnego gry


W tym skrypcie znajdzie się większość kodu tworzonego w bieżącej lekcji.
Na początek na scenie utwórz pusty obiekt gry i nadaj mu nazwę GameControl.
To jest miejsce przeznaczone dla skryptów. Następnie utwórz nowy skrypt
336 Lekcja 19. Czwarta gra — Gauntlet Runner

o nazwie GameControlScript i dołącz go do przygotowanego wcześniej obiektu


kontrolnego gry. Poniżej przedstawiono kod dla skryptu GameControlScript.
Sam skrypt jest nieco skomplikowany, dlatego przeanalizuj wszystkie wiersze,
by dokładnie poznać sposób działania. Przedstawiony poniżej kod umieść
w skrypcie.
public float objectSpeed = -.3f;
float minSpeed = -.15f;
float maxSpeed = -.3f;

public GroundScript ground;


public GroundScript wall1;
public GroundScript wall2;

float timeRemaining = 10;


float timeExtension = 1.5f;
float totalTimeElapsed = 0;

bool isGameOver = false;

void Update () {
if(isGameOver)
return;

totalTimeElapsed += Time.deltaTime;
timeRemaining -= Time.deltaTime;
if(timeRemaining <= 0)
isGameOver = true;
}

public void SlowWorldDown()


{
CancelInvoke("SpeedWorldUp");

objectSpeed = minSpeed;
ground.SlowDown();
wall1.SlowDown();
wall2.SlowDown();

Invoke ("SpeedWorldUp", 1);


}

void SpeedWorldUp()
{
objectSpeed = maxSpeed;
ground.SpeedUp();
wall1.SpeedUp();
wall2.SpeedUp();
}

public void PowerupCollected()


Obiekty kontrolne 337

{
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

wywołanie metody SpeedWorldUp(). W ten sposób szybkość wszystkich ele‐


mentów powraca do stanu początkowego i gracz może prowadzić rozgrywkę
w standardowym tempie.
Metoda PowerupCollected() jest wywoływana po zdobyciu dodatkowej
energii i powoduje wydłużenie pozostałego czasu gry.
Wreszcie w metodzie OnGUI() wyświetlane są informacje. W trakcie rozgrywki
to pozostały czas gry, natomiast po jej zakończeniu to całkowity czas ostat‐
niej gry.

Skrypt obiektu gracza


Skrypt obiektu gracza pełni dwa zadania. Pierwsze to zarządzanie ruchem
obiektu gracza i obiektów, z którymi się zderza. Drugie to zarządzanie anima‐
torem. Utwórz nowy skrypt o nazwie PlayerScript i dołącz go do znajdującego
się na scenie modelu robota. Następnie w skrypcie umieść przedstawiony
poniżej kod.
public GameControlScript control;
Animator anim;

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);
}
}

void OnTriggerEnter(Collider other)


{
if(other.gameObject.name == "Powerup(Clone)")
{
control.PowerupCollected();
}
else if(other.gameObject.name == "Obstacle(Clone)" && jumping ==
false)
{
control.SlowWorldDown();
}
Destroy(other.gameObject);
}
Dwie pierwsze zmienne przechowują odniesienia do obiektu kontrolnego gry
oraz animatora. Kolejne dwie zmienne są przeznaczone do przechowywania
informacji związanych z ruchem. Wartość zmiennej anim jest ustawiana
w metodzie Start().
Działanie metody Update() rozpoczyna się od przesunięcia gracza na pod‐
stawie otrzymanych danych wejściowych. Następnie wykonywana jest ope‐
racja sprawdzenia mająca na celu upewnienie się, że gracz nie przesunął się
dalej niż -3 lub 3 na osi X. Jeżeli gracz przesunął się bardziej, zostanie cofnięty
do pozycji -3 lub 3. Dzięki temu gracz pozostaje na wyznaczonej drodze.
W kolejnym kroku metoda Update() sprawdza, czy aktualnie obiekt gracza
odtwarza animację Jump. Jeśli tak, zmienna lokalna jumping ma przypisaną
wartość true (gracz nie zderza się z przeszkodami), a parametr Jumping
animatora ma przypisaną wartość false (animacja Jump nie będzie zapętlona).
Jeśli natomiast gracz aktualnie nie skacze, animator ustawia odpowiednie
opcje i sprawdza, czy naciśnięty został klawisz powodujący skok (domyślnie
jest to spacja).
W metodzie OnTriggerEnter() skrypt sprawdza, czy gracz zderzył się z innym
obiektem. W przypadku zderzenia z obiektem dodatkowej energii następuje
wywołanie odpowiedniej metody. Z kolei zderzenie z przeszkodą wymaga,
aby gracz nie skakał. Jeżeli faktycznie dojdzie do zderzenia z przeszkodą, nastę‐
puje wywołanie metody SlowWorldDown().

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;

public GameObject obstacle;


public GameObject powerup;

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

temp.transform.position = new Vector3(Random.Range(-3,


4), pos.y, pos.z);
}
else
{
temp = (GameObject)Instantiate(obstacle);
temp.GetComponent<ObstacleScript>().control = control;
Vector3 pos = temp.transform.position;
temp.transform.position = new Vector3(Random.Range(-3,
4), pos.y, pos.z);
}

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.

Zebranie wszystkiego w całość


Połączenie skryptów i obiektów to ostatni etap prac nad grą. Zacznij od zazna‐
czenia obiektu GameControl w panelu Hierarchy. Obiekty Ground i Wall prze‐
ciągnij na odpowiadające im właściwości w komponencie Game Control Script
(patrz rysunek 19.10). Następnie prefabrykaty Powerup i Obstacle przeciągnij
na odpowiadające im właściwości w komponencie Spawn Script.
Teraz zaznacz model Robot Kyle w panelu Hierarchy i przeciągnij obiekt
GameControl na właściwość Control w komponencie Player Script (patrz
rysunek 19.11).
I to już wszystko! Budowa gry została ukończona i można ją wypróbować.
342 Lekcja 19. Czwarta gra — Gauntlet Runner

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

W czasie tej lekcji:


 poznasz podstawy dotyczące dźwięku w Unity,
 dowiesz się, jak używać źródeł dźwięku,
 zobaczysz, jak za pomocą skryptów pracować z dźwiękiem.
W tej lekcji zajmiesz się dźwiękiem w Unity. Na początku przedstawione
zostaną podstawy dotyczące dźwięku. Następnie przejdziesz do kompo-
nentów źródła dźwięku oraz sposobów ich działania. Dowiesz się również,
jaką rolę w procesie spełniają poszczególne klipy audio. Na końcu zoba-
czysz, jak tworzyć kod pozwalający na przeprowadzanie operacji na
dźwięku.
346 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

Tabela 20.1. Właściwości komponentu Audio Source


Właściwość Opis
Audio Clip Rzeczywisty plik audio przeznaczony do odtworzenia.
Mute Właściwość określa, czy dźwięk jest wyciszony.
Bypass Effects Właściwość określa, czy efekty audio (tylko Unity Pro)
będą zastosowane w danym źródle dźwięku. Wybór
tej właściwości powoduje wyłączenie efektów.
Bypass Listener Właściwość określa, czy efekty komponentu Audio
Effects Listener (tylko Unity Pro) będą zastosowane w danym
źródle dźwięku. Wybór tej właściwości powoduje
wyłączenie efektów.
Bypass Reverb Właściwość określa, czy efekty Audio Reverb Zone
Zone (tylko Unity Pro) będą zastosowane w danym źródle
dźwięku. Wybór tej właściwości powoduje wyłączenie
efektów.
Play On Wake Właściwość określa, czy źródło dźwięku rozpocznie
odtwarzanie dźwięku natychmiast po utworzeniu
danego źródła.
Loop Właściwość określa, czy źródło dźwięku ponownie
rozpocznie odtwarzanie klipu audio po zakończeniu
jego odtwarzania.
Priority Właściwość wskazuje na wagę danego źródła dźwięku.
Wartość 0 oznacza najważniejsze, natomiast 255
oznacza najmniej ważne. Muzyka odtwarzana w tle
powinna mieć ustawioną wartość 0, aby uniknąć
nałożenia na nią innych dźwięków.
Volume Głośność danego źródła dźwięku. Wartość 1
jest odpowiednikiem 100% głośności.
Pitch Ton danego źródła dźwięku.
3D Sound Settings Ustawienia dotyczące klipów audio 3D. Ich dokładne
omówienie znajdziesz dalej w tej lekcji.
2D Sound Settings Ustawienia dotyczące klipów audio 2D. Ich dokładne
omówienie znajdziesz w dalej w tej lekcji.

Import klipów audio


Źródło dźwięku pozostaje bezczynne, jeśli nie zawiera jakiegokolwiek klipu
audio do odtworzenia. W środowisku Unity import dźwięku jest równie łatwy jak
każdego innego zasobu. Cała operacja sprowadza się do kliknięcia plików audio
i przeciągnięcia ich na panel Project. W ten sposób wskazane dźwięki zostają
dodane do zasobów. Wykorzystywane w tej lekcji klipy audio zostały wspa‐
niałomyślnie udostępnione przez Jeremiego Handela (http://handelabra.com/).
Źródła dźwięku 349

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.2. Dodanie klipu audio do źródła dźwięku


350 Lekcja 20. Dźwięk

3. Upewnij się, że zaznaczyłeś właściwość Play On Awake, 


i uruchom scenę. Zwróć uwagę na odtworzenie dźwięku.
Po upływie około 20 sekund odtwarzanie dźwięku powinno
się zakończyć, o ile nie został zapętlony.

Testowanie dźwięku w panelu Scene


Konieczność uruchomienia sceny za każdym razem, gdy trzeba przetestować
dźwięk, jest niezwykle męcząca. Wymaga to nie tylko uruchomienia sceny,
ale również przejścia do obiektu odtwarzającego dźwięk na scenie. To nie
zawsze jest łatwe, a czasem wręcz niemożliwe, dlatego też dźwięk można
przetestować w panelu Scene.
Aby przetestować dźwięk w panelu Scene, trzeba włączyć dźwięki na scenie,
co odbywa się za pomocą odpowiedniego przycisku (patrz rysunek 20.3).
Włączenie dźwięków na scenie oznacza użycie wyimaginowanego kompo‐
nentu Audio Listener. Komponent jest umieszczony w odniesieniu do klatki
w panelu Scene (nie w rzeczywistym położeniu komponentu Audio Listener).

RYSUNEK 20.3.
Włączenie
dźwięków
na scenie

 Wypróbuj samodzielnie

Dźwięk w panelu Scene


W tym ćwiczeniu zobaczysz, jak przetestować dźwięk w panelu Scene.
Wykorzystasz scenę utworzoną w poprzednim ćwiczeniu.
1. Otwórz scenę zbudowaną w poprzednim ćwiczeniu.
2. Włącz odtwarzanie dźwięków na scenie (patrz rysunek 20.3).
3. Poruszaj się po scenie. Zwróć uwagę, jak głośność dźwięku zmienia
się w zależności od Twojej odległości od sześcianu emitującego dźwięk.
Domyślnie wszystkie klipy audio są 3D i dlatego odległość między
źródłem dźwięku i słuchającym ma znaczenie.

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

Tabela 20.2. Właściwości dźwięku 3D


Właściwość Opis
Doppler Level Właściwość określa sposób, w jaki efekt Dopplera zostanie
zastosowany dla danego dźwięku. Wartość 0 wskazuje
brak efektu. Wspomniany efekt Dopplera oznacza
po prostu zniekształcenie dźwięku wraz z jego oddalaniem
się od źródła dźwięku.
Volume Rolloff Właściwość określa sposób zmiany głośności dźwięku
wraz ze wzrostem odległości od źródła dźwięku. Domyślnie
będzie logarytmiczna. Istnieje również możliwość wybrania
liniowej lub zdefiniowania własnej krzywej zmiany wraz
z własną wartością Roll off.
Min Distance Właściwość określa odległość od źródła dźwięku, zanim
uzyskamy głośność na poziomie 100%. Im większa wartość
tej właściwości, tym dalej można znajdować się od źródła
dźwięku i nadal słyszeć go na 100% głośności.
Pan Level Właściwość określa, jak duży wpływ będzie miał silnik 3D
na dźwięk. Wartość 0 oznacza to samo, co posiadanie
dźwięku 2D.
Spread Właściwość określa sposób rozproszenia dźwięku
w różnych głośnikach systemu. Wartość 0 oznacza,
że wszystkie głośniki mają to samo położenie, a sygnał
w zasadzie będzie monofoniczny. Nie zmieniaj wartości
tej właściwości, jeśli dokładnie nie rozumiesz sposobu
działania systemów audio.
Max Distance Właściwość określa maksymalną odległość od źródła
dźwięku, na jaką nadal będzie słyszany dźwięk.

RYSUNEK 20.5.
Ustawienie klipu
audio jako 2D

Użycie dźwięku za pomocą skryptów


Odtwarzanie dźwięku ze źródła dźwięku po jego utworzeniu jest przydatną
możliwością przy założeniu, że to oczekiwana funkcjonalność. Jeżeli chcesz
odtworzyć dźwięk w określonym czasie lub różne dźwięki z tego samego
Użycie dźwięku za pomocą skryptów 353

źródła dźwięku, wtedy konieczne będzie zastosowanie skryptów. Na szczę‐


ście, zarządzanie dźwiękiem z poziomu kodu nie stanowi większej trudności.
W większości przypadków sprowadza się do użycia odtwarzacza audio
w znany Ci już sposób. Po prostu wybierz dźwięk i naciśnij przycisk Play. Cała
obsługa skryptów audio odbywa się za pomocą zmiennych i metod będących
częścią obiektu audio.

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

Uruchamianie i zatrzymywanie odtwarzania klipu audio


W tym ćwiczeniu do rozpoczęcia i zakończenia odtwarzania klipu audio
użyjesz skryptu.
1. Utwórz nowy projekt lub scenę. Jeśli jeszcze tego nie zrobiłeś,
zaimportuj katalog Sounds z materiałów przeznaczonych dla bieżącej
lekcji. Do sceny dodaj sześcian, umieść go w położeniu (0, 0, 0) i dodaj
komponent Audio Source.
2. W katalogu Sound kliknij plik lopper.ogg i przeciągnij go na właściwość
Audio Clip komponentu Audio Source w sześcianie. Upewnij się, że
usunąłeś zaznaczenie opcji Play On Wake, ale zaznacz właściwość Loop
w źródle dźwięku.
3. Utwórz nowy katalog o nazwie Scripts. W katalogu utwórz nowy skrypt,
nadaj mu nazwę AudioScript i dołącz do sześcianu. W skrypcie umieść
przedstawiony poniżej kod.
void Update () {
if(Input.GetButtonDown("Jump"))
{
if(audio.isPlaying == true)
{
audio.Stop();
}
else
{
audio.Play();
}
}
}
4. Uruchom scenę. Rozpoczęcie i zakończenie odtwarzania dźwięku
odbywa się za pomocą klawisza spacji. Zwróć uwagę, jak za każdym
razem zaczyna się odtwarzanie klipu audio.

Zmiana klipu audio


Bardzo łatwo za pomocą skryptu można wskazać klip audio, który ma być
odtwarzany. Kluczem jest tutaj zmiana w kodzie właściwości Audio Clip
przed wywołaniem metody Play() w celu odtworzenia danego klipu. Zawsze
upewnij się, że zatrzymane zostało odtwarzanie bieżącego klipu, zanim przej‐
dziesz do nowego. W przeciwnym razie żądana zmiana klipu nie nastąpi.
Aby zmienić klip audio w źródle dźwięku, przypisz zmienną typu AudioClip
zmiennej klipu obiektu audio. Jeśli np. masz klip audio o nazwie newClip,
wtedy powinieneś go przypisać do źródła dźwięku i odtworzyć za pomocą
poniższego kodu:
Podsumowanie 355

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

W czasie tej lekcji dowiesz się:


 jak przygotować się do programowania na platformie
mobilnej,
 jak użyć przyśpieszeniomierza urządzenia mobilnego,
 jak korzystać z ekranu dotykowego urządzenia.
Urządzenia mobilne, takie jak smartfony i tablety, powoli stały się urzą-
dzeniami wykorzystywanymi do gier. W tej lekcji dowiesz się, jak za pomocą
środowiska Unity opracowywać projekty przeznaczone dla urządzeń
Android i iOS. Na początku przedstawione zostaną wymagania dla progra-
mowania na platformach mobilnych. Następnie zobaczysz, jak akceptować
specjalne dane wejściowe pochodzące z przyśpieszeniomierza urządzenia.
Na końcu omówiony zostanie temat danych wejściowych dostarczanych
za pomocą ekranu dotykowego.

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.

Wiele dostępnych urządzeń


Istnieje wiele rodzajów urządzeń mobilnych. W trakcie powstawania tej
książki firma Apple oferowała trzy (iPod, iPad i iPhone). Do tego mamy
niezliczoną ilość smartfonów i tabletów działających pod kontrolą systemu
Android. Każde z tych urządzeń to nieco inny sprzęt, a tym samym także
inne kroki niezbędne do jego prawidłowej konfiguracji. Dlatego też w lekcji
przedstawiono jedynie wskazówki dotyczące procesu instalacyjnego. Prak-
tycznie nie ma możliwości przygotowania dokładnej procedury, która spraw-
dzi się w każdym przypadku. W internecie można znaleźć wiele dokumen-
tów, które znacznie dokładniej omawiają konfigurację pozwalającą na
współpracę środowiska Unity i urządzeń działających pod kontrolą sys-
temów iOS i Android. Wyszukaj je, jeśli potrzebujesz pomocy w zakresie
prawidłowej konfiguracji.

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

Wymieniona witryna zawiera dokumenty dotyczące praktycznie każdego


aspektu środowiska Unity. Domyślnie wyświetla jedynie powiązane z pro‐
gramowaniem na platformach biurowych. Konieczne jest więc ręczne włą‐
czenie wyświetlania dokumentacji dotyczącej systemów iOS i Android. Stan‐
dardowo powinieneś zobaczyć czerwone znaki X na ikonach iOS i Android
(patrz rysunek 21.1).

RYSUNEK 21.1.
Wyłączone
wyświetlanie
dokumentacji
dotyczącej
urządzeń
mobilnych

Kliknięcie ikony spowoduje zmianę znaku czerwonego na zielony i włączenie


odpowiedniej dokumentacji (patrz rysunek 21.2). Jak możesz również zobaczyć
na rysunku 21.2, dokumentacja Unity zawiera artykuły pomagające w konfi‐
guracji środowiska dla systemów iOS i Android. Wspomniane dokumenty są
uaktualniane, gdy zmieniają się kroki niezbędne do konfiguracji środowiska.
Po wykonaniu kroków i skonfigurowaniu środowiska programistycznego dla
wybranego systemu platformy mobilnej (lub jeśli nie planujesz uruchamiania
gier w rzeczywistych urządzeniach) możesz przejść do kolejnej części lekcji.

RYSUNEK 21.2.
Włączone
wyświetlanie
dokumentacji
dotyczącej
urządzeń
mobilnych
362 Lekcja 21. Programowanie na platformach mobilnych

Aplikacja Unity Remote


Najprostszym sposobem na przetestowanie gry w urządzeniu jest opraco‐
wanie projektu, umieszczenie jego plików w urządzeniu, a następnie uru‐
chomienie projektu. Takie rozwiązanie jest kłopotliwe i bardzo szybko stanie
się po prostu uciążliwe. Innym sposobem na przetestowanie gier będzie
przygotowanie projektu i uruchomienie go w emulatorze urządzenia działa‐
jącego pod kontrolą systemu iOS lub Android. Takie podejście również wymaga
wykonania kilku kroków oraz konfiguracji i uruchomienia emulatora. Tego
rodzaju rozwiązanie może być użyteczne, gdy trzeba przeprowadzić rozbu‐
dowane testowanie zaawansowanych aspektów, takich jak wydajność i gene‐
rowanie. Do prostego przetestowania gry istnieje jednak znacznie lepsze
rozwiązanie w postaci aplikacji Unity Remote.
Unity Remote to aplikacja, którą można pobrać ze sklepu zawierającego opro‐
gramowanie dla urządzeń mobilnych. Unity Remote pozwala na testowanie
w urządzeniu mobilnym tworzonych aplikacji, gdy zostaną uruchomione
w edytorze Unity. W skrócie mówiąc, otrzymujesz grę działającą w czasie
rzeczywistym w urządzeniu i jednocześnie masz dostęp do środowiska pro‐
gramistycznego — urządzenie można wtedy wykorzystać w celu dostarczania do
gry danych wejściowych. Więcej informacji dotyczących aplikacji Unity Remote
znajdziesz na stronie http://docs.unity3d.com/Manual/UnityRemote4.html.
Samą aplikację Unity Remote znajdziesz w sklepach przeznaczonych do roz‐
prowadzania oprogramowania dla urządzeń mobilnych. Wystarczy przeszukać
sklep, podając wyrażenie Unity Remote. Następnie aplikację pobierasz i insta‐
lujesz dokładnie tak samo jak każdą inną (patrz rysunek 21.3).

RYSUNEK 21.3.
Różne sklepy
oferujące aplikacje
mobilne

Po instalacji aplikacja Unity Remote działa w charakterze wyświetlacza dla


gry i kontrolera. Do edytora Unity możesz więc przekazywać informacje
o kliknięciach, dane przyśpieszeniomierza, a także dane pochodzące z ekranu
dotykowego.
Przyśpieszeniomierz 363

 Wypróbuj samodzielnie

Przetestowanie konfiguracji urządzenia


Poświęć chwilę i upewnij się, że prawidłowo przygotowałeś środowisko
przeznaczone do programowania dla platform mobilnych. W tym ćwiczeniu
wykorzystasz aplikację Unity Remote do interakcji ze sceną przygotowa-
ną w Unity. Jeżeli nie masz skonfigurowanego urządzenia, nie będziesz
mógł wykonać przedstawionych tutaj kroków, ale nadal możesz się z nimi
zapoznać i zobaczyć, jak wygląda ten proces. Jeżeli wymienione poniżej
kroki nie działają, oznacza to, że masz nieprawidłowo skonfigurowane
środowisko pracy.
1. Utwórz nowy projekt lub scenę. Utwórz nowy katalog o nazwie Scripts
i skrypt o nazwie TestScript.
2. Skrypt dołącz do kamery Main Camera i umieść w nim poniższy kod.
void OnGUI()
{
if(GUI.Button(new Rect(Screen.width / 2 - 50,
Screen.height / 2 - 50, 100,
100), "Kliknij"))
{
camera.backgroundColor = new
Color(Random.Range(0f,1f),Random.Range(0f,1f),
Random.Range(0f,1f));
}
}
3. Uruchom scenę i sprawdź, czy naciśnięcie przycisku powoduje zmianę
koloru tła sceny. Zatrzymaj scenę.
4. Podłącz urządzenie mobilne do komputera. Gdy komputer rozpozna
urządzenie mobilne, uruchom aplikację Unity Remote.
5. Ponownie uruchom scenę. Po chwili na ekranie urządzenia mobilnego
powinieneś zobaczyć niebieski ekran sceny i przycisk. Naciśnięcie
przycisku powinno zmienić kolor tła sceny. Jeżeli naciśnięcie przycisku
nie przynosi żadnego efektu, kliknij dowolny panel inny niż Game.
Ta niedogodność wiąże się z pewnym niewielkim błędem, a kliknięcie
panelu lub jednego z narzędzi w Unity usuwa wspomniany błąd.

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

Jak widać na rysunku 21.4, domyślne osie urządzenia odpowiadają osiom 3D


w Unity, gdy urządzenie jest w pozycji pionowej, przodem do użytkownika.
Jeżeli obrócisz urządzenie i znajdzie się ono w innej orientacji, dane przyśpie‐
szeniomierza trzeba skonwertować na odpowiednie osie.

Programowanie dla przyśpieszeniomierza


Podczas projektowania gry wykorzystującej dane pochodzące z przyśpiesze‐
niomierza trzeba pamiętać o kilku kwestiach. Przede wszystkim w danej
chwili można używać tylko dwóch osi przyśpieszeniomierza. Powód jest
prosty: niezależnie od orientacji urządzenia, na jedną oś wpływ będzie miała
ziemska grawitacja. Spójrz na orientację urządzenia pokazaną na rysunku
21.4. Jak widać, na osie X i Z wpływ ma obracanie urządzeniem, natomiast
wartości osi Y są ujemne, ponieważ na tę oś wpływ ma grawitacja. Jeżeli poło‐
żysz urządzenie płasko i frontem do góry, możesz używać osi X i Y. W takim
przypadku grawitacja ma wpływ na wartości osi Z.
Kolejna kwestia, o której należy pamiętać podczas użycia danych przyśpie‐
szeniomierza, to fakt, że wspomniane dane nie są zbyt dokładne. Urządzenia
mobilne nie odczytują danych przyśpieszeniomierza w ustalonych odstępach
czasu i bardzo często dysponują jedynie przybliżonymi wartościami. Dlatego
też tego rodzaju dane wejściowe mogą być rwane i nierówne. Warto również
dodać, że niedokładność pozostaje niewielka. Niemniej jednak istnieje i powinna
być uwzględniona.
Przyśpieszeniomierz 365

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

Przesunięcie sześcianu dzięki potędze umysłu…


to znaczy urządzenia
W tym ćwiczeniu wykorzystasz dane przyśpieszeniomierza urządzenia
mobilnego do poruszania sześcianem po scenie. Oczywiście możliwość
wykonania tego ćwiczenia wymaga posiadania podłączonego i odpowied-
nio skonfigurowanego urządzenia mobilnego wyposażonego w przyśpie-
szeniomierz.
1. Utwórz nowy projekt lub scenę. Do sceny dodaj sześcian i umieść
go w położeniu (0, 0, 0).
2. Utwórz nowy skrypt o nazwie AccelerometerScript i dołącz do sześcianu.
Następnie w metodzie Update() skryptu umieść przedstawiony
poniżej kod.
float x = Input.acceleration.x * Time.deltaTime;
float z = -Input.acceleration.z * Time.deltaTime;
transform.Translate(x, 0f, z);
366 Lekcja 21. Programowanie na platformach mobilnych

3. Upewnij się, że podłączyłeś urządzenie mobilne do komputera. 


Umieść je w orientacji poziomej i uruchom aplikację Unity Remote.
Teraz uruchom scenę. Zwróć uwagę, że możesz poruszać
sześcianem, obracając urządzenie mobilne. Zauważ, że osie
urządzenia przesuwają sześcian wzdłuż osi X i Z.

Dane wejściowe pochodzące


z ekranu dotykowego
Większość urządzeń mobilnych można kontrolować, korzystając z ekranów
dotykowych. Tego rodzaju ekran wykrywa dotknięcie i najczęściej ma moż‐
liwość monitorowania wielu dotknięć jednocześnie. Dokładna liczba jedno‐
cześnie obsługiwanych dotknięć zależy od urządzenia.
Dotknięcie ekranu nie powoduje przekazania urządzeniu po prostu miejsca
dotknięcia. Dla każdego dotknięcia przechowywana jest całkiem spora ilość
danych. W Unity każdy ekran jest przechowywany w zmiennej typu Touch.
Oznacza to, że w trakcie każdego dotknięcia ekranu następuje wygenerowanie
zmiennej typu Touch. Zmienna istnieje dopóty, dopóki palec użytkownika
znajduje się na ekranie; zmienna śledzi ruch palca. Zmienne typu Touch są
przechowywane w kolekcji o nazwie touches będącej częścią obiektu Input.
Jeżeli aktualnie nic nie dotyka ekranu, kolekcja jest pusta. Poniżej przedsta‐
wiono polecenie pozwalające na uzyskanie dostępu do kolekcji:
Input.touches;
Za pomocą kolekcji można przeprowadzić iterację przez poszczególne
zmienne typu Touch i przetworzyć ich dane. Można to zrobić za pomocą nastę‐
pującego fragmentu kodu.
foreach(Touch touch in Input.touches)
{
// Dowolne operacje.
}
Jak wcześniej wspomniano, każdy dotyk zawiera więcej informacji, nie tylko
położenie na ekranie, w którym znajduje się palec. Wszystkie właściwości
zmiennej typu Touch wymieniono w tabeli 21.1.
Każda z tych właściwości jest użyteczna podczas zarządzania skomplikowa‐
nymi interakcjami między użytkownikiem i obiektami gry.

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

Tabela 21.1. Właściwości zmiennej typu Touch


Właściwość Opis
deltaPosition Zmiana położenia dotknięcia od chwili ostatniej
aktualizacji. Właściwość jest użyteczna podczas
wykrywania operacji przesunięcia palcem po ekranie.
deltaTime Czas, który upłynął od ostatniej zmiany dotknięcia.
fingerId Unikalny indeks dotknięcia. Jeśli np. urządzenie może
obsłużyć jednocześnie pięć dotknięć, będzie to wartość
z zakresu od 0 do 4.
phase Właściwość określa fazę dotyku. Dostępne fazy to:
Began, Moved, Stationary, Ended i Canceled.
position Dwuwymiarowe współrzędne miejsca dotknięcia ekranu.
tapCount Liczba naciśnięć ekranu w trakcie danego dotyku ekranu.
Podczas pisania tej książki właściwość była
zaimplementowana dla systemu iOS. W urządzeniach
pracujących pod kontrolą systemu Android naciśnięciami
ekranu trzeba zarządzać ręcznie.

 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";

int num = touch.fingerId;


368 Lekcja 21. Programowanie na platformach mobilnych

GUI.Label(new Rect(0 + 130 * num, 0, 120, 100), message); 


}
}
3. Upewnij się, że podłączyłeś urządzenie mobilne do komputera, i uruchom
scenę. Teraz dotknij ekranu palcem i obserwuj wyświetlane informacje
(patrz rysunek 21.5). Przeciągnij palcem po ekranie i zobacz, jak
zmieniają się dane. Następnie dotknij ekranu więcej niż tylko jednym
palcem. Przesuń je po ekranie i losowo podnieś palce. Zwróć uwagę,
jak poszczególne dotknięcia są śledzone niezależnie od siebie.
Ile jednoczesnych dotknięć obsługuje Twoje urządzenie?

RYSUNEK 21.5. Wyświetlone na ekranie dane dotyczące poszczególnych dotknięć

Zrób, jak mówię, a nie jak pokazano w ćwiczeniu!


W powyższym ćwiczeniu zaimplementowałeś metodę OnGUI() zbierającą
informacje o poszczególnych dotknięciach ekranu. Ta część kodu, gdzie ciąg
tekstowy message połączono z danymi pochodzącymi z dotknięcia, jest
wysoce niepoprawna. Nigdy nie powinieneś stosować takiego rozwiązania
w metodzie OnGUI(), ponieważ powoduje ogromny spadek wydajności
działania projektu. W ćwiczeniu zdecydowano się na takie rozwiązanie
z prostego powodu: to był najłatwiejszy sposób utworzenia przykładu bez
konieczności jego niepotrzebnego komplikowania. Ten projekt służy jedy-
nie w celach demonstracyjnych. Kod odpowiedzialny za uaktualnienia
należy umieszczać w metodzie Update().

urządzeń mobilnych działających pod kontrolą systemów iOS i Android.


Następnie przeszedłeś do pracy z przyśpieszeniomierzem. Na końcu lekcji
przeprowadziłeś eksperymenty związane ze śledzeniem dotyku w Unity.
Pytania i odpowiedzi 369

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

W czasie tej lekcji dowiesz się, jak dostosować


dla urządzeń mobilnych gry:
 Amazing Racer,
 Chaos Ball,
 Captain Blaster,
 Gauntlet Runner.
Teraz przygotujesz jeszcze więcej gier! W tej lekcji przejrzysz utworzone
dotąd gry i dostosujesz je do urządzeń mobilnych. Na początku do gry
Amazing Racer dodasz możliwość poruszania się, rozglądania i skakania.
Następnie przejdziesz do gry Chaos Ball, w której dodasz możliwość poru-
szania się i obracania. W grze Captain Blaster zmienisz orientację, aby gra
działała w urządzeniu mobilnym trzymanym pionowo. Na końcu dodasz
kontrolki danych wejściowych do gry Gauntlet Runner.

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.

Poruszanie i rozglądanie się


Pierwszym elementem przeznaczonym do zmiany jest sposób poruszania się
gracza. W omawianej grze wykorzystano kontroler First Person. Najlepszym
sposobem implementacji kontrolerów mobilnych jest otworzenie kontrolera
i modyfikacja znajdującego się w nim kodu. To nieco bardziej skomplikowane
zadanie od tych, które chciałbyś wykonywać na tym etapie. Zdecyduj się
więc na utworzenie skryptów działających na podstawie już istniejącej funk‐
cjonalności. Dane pochodzące z przyśpieszeniomierza zostaną wykorzystane
do poruszania graczem do przodu, tyłu i na boki. Z powodu stopnia skompli‐
kowania mechaniki rozglądania się operacje spoglądania w górę i w dół będą
odbywały się przez rotację kamery kontrolera, natomiast spoglądanie w lewą
i prawą stronę odbędzie się przy użyciu rzeczywistej rotacji kontrolera.
W celu skonfigurowania ruchu oraz poziomego rozglądania się wykonaj przed‐
stawione poniżej kroki.
1. Otwórz projekt ukończonej gry Amazing Racer. Do katalogu Scripts
dodaj nowy skrypt o nazwie MobileInputScript i dołącz go do obiektu
gry Player.
2. W nowym skrypcie umieść poniższy kod.
public float speed = 15;
public float jump = 3;

CharacterController control;

void Start () {
control = GetComponent<CharacterController>();
}

// Metoda wywoływana raz w trakcie każdej klatki.


void Update () {
float x = Input.acceleration.x * Time.deltaTime * speed;
float z = -Input.acceleration.z * Time.deltaTime * speed;

transform.Translate(x, 0f, z);

foreach(Touch touch in Input.touches)


Amazing Racer 373

{
// 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ę

2. W metodzie Update() skryptu umieść poniższy fragment kodu.


374 Lekcja 22. Kolejne wersje gier

foreach(Touch touch in Input.touches)


{
if(touch.position.x > Screen.width / 2)
{
transform.Rotate(-touch.deltaPosition.y, 0f, 0f);
}
}
3. Uruchom scenę. Zwróć uwagę na możliwość przesuwania palcem po
prawej stronie ekranu i tym samym rozglądania się w górę oraz w dół.
W połączeniu z MobileInputScript omawiane skrypty pozwalają na
rozglądanie się po całej scenie za pomocą tylko jednego palca.

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));
}

// Obsługa rozglądania się — punkt odniesienia.


if(touch.position.x > Screen.width / 2)
//...
3. Uruchom scenę. Zwróć uwagę, że grając na urządzeniu mobilnym,
możesz teraz skakać, poruszać się i rozglądać.
W ten sposób przeprowadziłeś konwersję gry Amazing Racer na wersję przy‐
jazną dla urządzeń mobilnych.
Chaos Ball 375

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;

transform.Translate(x, 0f, z);

foreach(Touch touch in Input.touches)


{
// Rozglądanie się.
if(touch.position.x > Screen.width / 2)
{
transform.Rotate(0f, touch.deltaPosition.x * 10, 0f);
}
}
}
376 Lekcja 22. Kolejne wersje gier

RYSUNEK 22.2. Wyłączenie komponentu Mouse Look

3. Dodaj nowy skrypt o nazwie MouseLookScript i dołącz go do kamery


Main Camera obiektu gry w postaci kontrolera First Person
(patrz rysunek 22.2). Następnie w metodzie Update() skryptu
umieść przedstawiony poniżej kod.
foreach(Touch touch in Input.touches)
{
transform.Rotate(-touch.deltaPosition.y, 0f, 0f);
}
4. Uruchom grę. Zwróć uwagę na możliwość poruszania się i rozglądania
na podstawie danych otrzymywanych z przyśpieszeniomierza i ekranu
dotykowego.
I to już wszystko, co trzeba zrobić, aby skonwertować grę Chaos Ball na postać
przyjazną dla urządzeń mobilnych (i tym samym znacznie podnieść jej poziom
trudności). W tym miejscu trzeba wspomnieć o jednej bardzo ważnej kwestii:
gracz może teraz przechodzić przez ściany i po prostu wypaść ze sceny. Wynika
to z faktu użycia wywołania Translate(), a nie kontrolera do poruszania
obiektem gracza. Istnieje kilka sposobów poprawienia wspomnianego zacho‐
wania, np. wykorzystanie istniejącego kontrolera postaci lub techniki rayca‐
stingu gracza, aby sprawdzić, czy znajduje się blisko ścian.
Captain Blaster 377

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

3. W panelu Game wybierz rozdzielczość dla gry. Najlepiej będzie, jeśli


wybierzesz rozdzielczość odpowiadającą wymiarom ekranu używanego
urządzenia mobilnego. Gdy nie znasz wymiarów, wybierz ogólną
opcję 3:2 Portrait (patrz rysunek 22.4).

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.

Teraz scena jest już gotowa do użycia. Po uruchomieniu sceny w aplikacji


Unity Remote powinieneś zobaczyć ją w odpowiedniej orientacji (pionowa).
Do zrobienia pozostało już tylko mapowanie danych przyśpieszeniomierza
i dotknięć na dane wejściowe gry. Tym razem to łatwe zadanie, ponieważ
podczas tworzenia gry nie wykorzystałeś żadnego kontrolera wbudowanego
w Unity. Przystąp zatem do modyfikacji kodu, aby gra stała się przyjazna dla
urządzeń mobilnych.
1. W katalogu Scripts odszukaj plik PlayerScript i otwórz go.
2. Implementacja ruchu wymaga umieszczenia wiersza kodu:
transform.Translate(Input.acceleration.x * speed *
Time.deltaTime, 0f, 0f);
pod wierszem:
transform.Translate(Input.GetAxis("Horizontal") * speed *
Time.deltaTime, 0f,
0f);
Gauntlet Runner 379

3. Implementacja strzelania wymaga modyfikacji wiersza:


if(Input.GetButtonDown("Jump"))
na postać:
if(Input.GetButtonDown("Jump") || Input.touches.Length > 0)
W ten sposób skonfigurowałeś pobieranie danych wejściowych gry z urzą‐
dzenia mobilnego. Prawdopodobnie zauważyłeś, że pozostało nietknięte ory‐
ginalne rozwiązanie sterowania grą. To użyteczne, ponieważ pozwala na
prowadzenie rozgrywki zarówno w komputerze, jak i urządzeniu mobilnym.
Warto również wspomnieć o jednej kwestii. Z powodu zmiany rozdzielczości
na węższą wiele meteorów powstaje poza ekranem. Aby to poprawić, należy
zmienić wymiary obszaru, na którym mogą być tworzone nowe meteory.

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);

// Jeżeli gracz dotknął ekranu.


if(Input.touches.Length > 0)
{
// Użycie położenia pierwszego dotknięcia.
transform.Translate(Input.touches[0].deltaPosition.x *
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);
}

// Sprawdzenie, czy gracz „machnął” palcem w górę.


else if(Input.touches.Length > 0)
{
if(Input.touches[0].deltaPosition.y > 2)
anim.SetBool("Jumping", true);
}
}
3. Uruchom grę. Zwróć uwagę, jak poruszanie palcem po ekranie powoduje
ruch gracza we wskazaną stronę. Zauważ także, że machnięcie palcem
w górę powoduje wykonanie skoku przez postać kierowaną przez
gracza.
W trakcie pracy nad kodem omawianej gry natkniesz się na poniższy wiersz:
if(Input.touches[0].deltaPosition.y > 2)
Być może zastanawiasz się, dlaczego użyto wartości 2? Idea polega na tym,
że choć gracz może bardzo szybko machać palcem w górę, to cykl gry wynosi
60 razy na sekundę. Dlatego też w porównaniu z grą machnięcia są wykony‐
wane całkiem wolno. Wskutek tego wartość używana od ustalenia, czy gracz
machnął palcem, jest bardzo mała. Dzięki zwiększeniu tej wartości gra może
nie rozpoznawać wolniejszych machnięć. Z kolei ustawienie niższej wartości
powoduje, że gra wykrywa machnięcia nawet wtedy, kiedy gracz ich nie wykonał.

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

lania. W ostatniej grze Gauntlet Runner zaimplementowałeś nowy system


ruchu — gracz zyskał możliwość sterowania postacią za pomocą przesuwania
i machania palcem.

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

W czasie tej lekcji dowiesz się:


 jak zarządzać scenami w grze,
 jak zachowywać dane i obiekty między scenami,
 jak przygotować różne ustawienia wybierane przez gracza,
 jak wdrożyć grę.
W tej lekcji dopracujesz grę i ją wdrożysz. Na początek poznasz sposoby
poruszania się między różnymi scenami. Następnie przejdziesz do zacho-
wywania danych i obiektów gry między poszczególnymi scenami. Później
zajmiesz się aplikacją Unity Player i jej ustawieniami. Na końcu dowiesz
się, jak skompilować i wdrożyć grę.
384 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.

Raz jeszcze, czym jest scena


Koncepcja sceny została omówiona na początku książki. Warto jednak do
niej powrócić, ponieważ Twoja wiedza jest zdecydowanie większa niż na
początku lektury. W idealnej sytuacji scena będzie poziomem w grze.
Jednak gry stają się coraz bardziej skomplikowane lub posiadają dynamicz-
nie generowane poziomy i dlatego też nie zawsze można zastosować roz-
wiązanie w postaci jednej sceny dla każdego poziomu. Warto więc uznać
scenę za listę zasobów. Gra składająca się z wielu poziomów, na których
wykorzystuje się te same obiekty, może zawierać tylko jedną scenę. Gdy tylko
trzeba pozbywać się ogromnej liczby obiektów i wczytywać wiele nowych,
koncepcja nowej sceny staje się koniecznością. Ujmując rzecz najprościej:
nie dziel poziomów na wiele różnych scen tylko dlatego, że masz taką moż-
liwość. Nowe sceny twórz tylko wtedy, gdy wymaga tego gra i zarządzanie
zasobami.

Ustalanie kolejności scen


Przejście między scenami jest łatwe i wymaga jedynie niewielkiej konfiguracji.
Przede wszystkim należy dodać wszystkie sceny do ustawień właściwości pro‐
jektu, zgodnie z przedstawionymi poniżej krokami.
1. Wyświetl okno dialogowe Build Settings, wybierając opcję File/Build
Settings.
2. Po wyświetleniu przeciągnij na okno dialogowe wszystkie sceny, które
mają znaleźć się w ostatecznej wersji projektu (patrz rysunek 23.1).
3. Szczególną uwagę zwróć na liczbę wyświetlaną obok nazwy sceny
w oknie Build Settings. Liczba ta będzie potrzebna na późniejszym
etapie. Po dodaniu wszystkich scen kliknij przycisk X w prawym
górnym rogu okna dialogowego i zamknij je. Jeżeli używasz Maca,
przycisk zamykający okno znajdziesz w prawym górnym rogu.
Teraz w projekcie można odwoływać się do scen i przechodzić pomiędzy
nimi.
Zarządzanie scenami 385

RYSUNEK 23.1. Dodanie scen do ustawień projektu

 Wypróbuj samodzielnie

Dodanie scen do okna dialogowego Build Settings


W tym ćwiczeniu dodasz sceny do okna dialogowego Build Settings w pro-
jekcie. Zachowaj ten projekt, ponieważ będziesz jeszcze z niego korzystać.
1. Utwórz nowy projekt. Do katalogu Assets dodaj podkatalog o nazwie
Scenes.
2. Wybierz opcję File/New Scene, tworząc w ten sposób nową scenę.
Następnie wybierz opcję File/Save Scene i zapisz scenę w katalogu
Scenes pod nazwę Scene1. Powtórz ten krok i utwórz scenę o nazwie
Scene2.
3. Wyświetl okno dialogowe Build Settings (wybierz opcję File/Build
Settings). Na okno najpierw przeciągnij Scene1, a dopiero później
Scene2. Scena o nazwie Scene1 powinna mieć indeks 0, natomiast
Scene2 indeks 1. Zapisz projekt, bo użyjesz go później.

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

Dlatego też w celu wczytania sceny o nazwie GameOverScene i indeksie 4 można


wykorzystać jeden z dwóch poniższych wierszy kodu:
Application.LoadLevel(4) ; // Wczytanie za pomocą indeksu sceny.
Application.LoadLevel(GameOverScene); // Wczytanie za pomocą nazwy sceny.
Wywołanie omawianej metody powoduje natychmiastowe usunięcie wszyst‐
kich obiektów gry i wczytanie wskazanej sceny. Warto pamiętać, że wykona‐
nie powyższych poleceń następuje natychmiast i jest nieodwracalne. Dlatego
przed wywołaniem musisz się upewnić, że na pewno chcesz to zrobić.

 Wypróbuj samodzielnie

Zmiana scen za pomocą przycisków


W tym ćwiczeniu będziesz przechodzić między dwoma scenami za pomocą
przycisków graficznego interfejsu użytkownika. Do wykonania tego ćwicze-
nia potrzebny jest projekt z poprzedniego. Jeżeli nie wykonałeś poprzed-
niego ćwiczenia, musisz to zrobić teraz. Zapisz projekt, ponieważ będziesz
jeszcze z niego korzystać w tej lekcji.
1. Wczytaj utworzony poprzednio projekt. Wczytaj pierwszą scenę,
odszukując plik Scene1 w katalogu Scenes i dwukrotnie go klikając.
Do sceny dodaj sześcian i umieść go w położeniu (0, 0, 0).
2. Utwórz katalog o nazwie Scripts i dodaj skrypt o nazwie LoadSceneTwo.
Dołącz skrypt do kamery Main Camera i umieść w nim poniższy kod.
void OnGUI()
{
if(GUI.Button(new Rect(5, 5, 100, 100), "Wczytaj Scene2"))
{
Application.LoadLevel(1);
}
}
3. Zapisz scenę, wybierając opcję File/Save Scene, a następnie otwórz
Scene2. (Jeżeli nie pamiętasz, jak otworzyć scenę, patrz krok 1.).
W katalogu Scripts utwórz nowy skrypt o nazwie LoadSceneOne.
Dołącz skrypt do obiektu Main Camera i umieść w nim poniższy kod.
void OnGUI()
{
if(GUI.Button(new Rect(5, 5, 100, 100), "Wczytaj Scene1"))
{
Application.LoadLevel(0);
}
}
4. Zapisz scenę i ponownie wczytaj Scene1. Uruchom scenę. Zwróć uwagę,
że między scenami możesz przechodzić, klikając przycisk wyświetlany
na każdej z nich. Zauważ, że sześcian istnieje tylko na scenie pierwszej
i jest niszczony przed przejściem do drugiej.
Zachowywanie danych i obiektów 387

Zachowywanie danych i obiektów


Umiesz już przechodzić między poszczególnymi scenami i pewnie zauważyłeś,
że dane nie są między nimi przenoszone. W rzeczywistości wszystkie sceny
są samowystarczalne i nie potrzebują zapisywania jakichkolwiek danych. Jed‐
nak w bardziej skomplikowanych grach zapis danych (co jest często nazy‐
wane trwałym przechowywaniem danych) staje się prawdziwą koniecznością.
W tej części lekcji zobaczysz, jak zachowywać obiekty między scenami oraz jak
zapisywać do pliku dane w celu ich późniejszego wykorzystania.

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

Użycie obiektu PlayerPrefs


W tym ćwiczeniu zapiszesz dane w PlayerPrefs. Do wykonania tego ćwi-
czenia potrzebny jest projekt z poprzedniego. Jeżeli nie wykonałeś tego
ćwiczenia, musisz to zrobić teraz.
1. Otwórz wcześniej utworzony projekt i upewnij się, że wczytałeś Scene1.
Do katalogu Scripts dodaj nowy skrypt SaveData i dołącz go do kamery
Main Camera. Następnie w skrypcie umieść przedstawiony poniżej kod.
string playerName = "";

void OnGUI()
{
Zachowywanie danych i obiektów 389

playerName = GUI.TextField(new Rect(5, 120, 100, 30), 


playerName);
if(GUI.Button(new Rect(5, 180, 50, 50), "Zapisz"))
{
PlayerPrefs.SetString("name", playerName);
}
}
2. Zapisz Scene1 i wczytaj Scene2. Utwórz nowy skrypt o nazwie LoadData
i dołącz do kamery Main Camera. Następnie w skrypcie umieść
przedstawiony poniżej kod.
string playerName = "";

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

Ustawienia Unity Player


Unity zawiera wiele ustawień wpływających na działanie ukończonej gry.
Ustawienia są nazywane ustawieniami gracza i pozwalają na zarządzanie
aspektami, takimi jak ikona gry i obsługiwane proporcje ekranu. Istnieje
naprawdę wiele ustawień, a część z nich nie wymaga objaśnienia. Jednak warto
się z nimi zapoznać i zobaczyć, do czego służą. Okno ustawień jest wyświetlane
w panelu Inspector po wybraniu opcji Edit/Project Settings/Player.

Ustawienia niezależne od platformy


Pierwsza grupa ustawień jest przeznaczona dla ustawień niezależnych od
platformy (patrz rysunek 23.2). Dostępnych jest wiele ustawień mających
zastosowanie dla gry niezależnie od platformy, dla której powstaje (Win‐
dows, iOS, Android, Mac itd.). Większość ustawień znajdujących się w tej
grupie nie wymaga dalszego objaśnienia. W polu Product Name należy podać
nazwę, która będzie wyświetlana jako tytuł gry. Z kolei ikona powinna być
prawidłowym plikiem graficznym. Warto pamiętać, że wymiary ikony po‐
winny być potęgą liczby 2, czyli np. 8×8, 16×16, 32×32, 64×64 itd. Jeżeli iko‐
na nie zawiera prawidłowych wymiarów, wtedy skalowanie może działać
nieprawidłowo i skutkiem będzie ikona bardzo słabej jakości. Ponadto masz
możliwość wskazania własnego kursora i określenia punktu hotspot.

RYSUNEK 23.2.
Ustawienia
niezależne
od platformy

Ustawienia dla poszczególnych platform


Druga grupa ustawień jest przeznaczona na ustawienia dla poszczególnych
platform. Mimo że w tej grupie wiele ustawień się powtarza, ale trzeba je skonfi‐
gurować dla każdej platformy, na której ma działać gra. Rezygnacja z okre‐
Kompilacja gry 391

ślonej platformy następuje po kliknięciu przedstawiającej ją ikony na pasku


wyboru (patrz rysunek 23.3).

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

Zbyt wiele ustawień


Prawdopodobnie zauważyłeś, że ogromna część ustawień dostępnych
w oknie Player Settings nie została tutaj omówiona. To prawda, ale więk-
szość z nich ma już przypisane wartości domyślne, co pozwala na szybkie
przygotowanie gry. Z kolei pozostałe umożliwiają osiągnięcie pewnych
zaawansowanych celów lub dopracowanie gry. Nie powinieneś zmieniać
większości ustawień zwłaszcza wtedy, kiedy dokładnie nie rozumiesz spo-
sobu ich działania. Błędne ustawienia prowadzą do dziwnego zachowania
gry lub wręcz uniemożliwiają jej uruchomienie. Ujmując rzecz najkrócej,
używaj jedynie podstawowych ustawień aż do chwili, gdy opanujesz kon-
cepcje związane z tworzeniem gier i będziesz musiał skorzystać z innych
dostępnych funkcji Unity.

definiujesz wynik procesu kompilacji. Natomiast drugie to Game Settings; są to


ustawienia dostępne dla gracza i pozwalają np. na wybór rozdzielczości ekranu
i konfigurację sposobu sterowania postaciami w grze.

Okno Build Settings


W oknie Build Settings znajdują się ustawienia dotyczące kompilacji gry. W tym
miejscu wskazujesz platformę, dla której jest tworzona gra, a także różne jej
sceny. Omawiane okno widziałeś już wcześniej w lekcji, ale teraz przyjrzysz
się mu nieco bliżej.
W celu wyświetlenia okna dialogowego Build Settings wybierz opcję File/
Build Settings. Po jego wyświetleniu możesz wprowadzić różne zmiany i skon‐
figurować grę wedle potrzeb. Na rysunku 23.4 pokazano przykładowe okno
dialogowe Build Settings.
W sekcji Platform określasz platformę, dla której tworzona jest dana gra. Po
wybraniu innej platformy należy nacisnąć przycisk Switch Platform, aby potwier‐
dzić zmianę. Z kolei kliknięcie przycisku Player Settings powoduje wyświe‐
tlenie w panelu Inspector okna dialogowego Player Settings. Wcześniej już
miałeś okazję zobaczyć to okno dialogowe — wskazywałeś w nim dostępne
sceny i określałeś ich kolejność. Dla wybranej platformy masz dostęp do wielu
ustawień. Ustawienia dla PC, Mac i Linux są proste i nie wymagają wyjaśnienia.
Warto w tym miejscu jedynie wspomnieć o opcji Development Build, która
pozwala na uruchomienie gry wraz z debuggerem i profilerem (tylko w wersji
Unity Pro).
Kiedy jesteś gotowy do kompilacji gry, naciśnij przycisk Build w celu tylko
kompilacji lub Build and Run w celu kompilacji i uruchomienia. Plik genero‐
wany przez Unity zależy od wybranej platformy.
Kompilacja gry 393

RYSUNEK 23.4.
Okno dialogowe
Build Settings

Okno Game Settings


Po uruchomieniu skompilowanej gry z pliku wygenerowanego przez Unity (a nie
z poziomu edytora Unity) graczowi zostanie wyświetlone okno dialogowe
Game Settings (patrz rysunek 23.5). Pozwala ono na wybór ustawień zwią‐
zanych z grą.

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ę.

Po wybraniu ustawień pozostało już tylko naciśnięcie przycisku Play!. W ten


sposób można wreszcie zacząć rozgrywkę.
Podsumowanie 395

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

4. Fałsz. Gracz może zmienić jedynie te ustawienia, które są definiowane


na podstawie osi danych wejściowych, a nie naciśnięć konkretnych
klawiszy.

Ć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

W czasie tej lekcji dowiesz się:


 co dotąd osiągnąłeś,
 co zrobić dalej,
 jakie masz dostępne zasoby.
W tej lekcji zakończysz podróż z Unity. Na początku przypomnisz sobie, co
dokładnie zrobiłeś. Następnie dowiesz się, co zrobić, aby rozwijać własne
umiejętności. Na końcu poznasz kilka różnych zasobów pomagających
w kontynuacji nauki systemu Unity.
398 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

 Dowiedziałeś się, jak kontrolować postać gracza za pomocą oferowa‐


nego przez Unity kontrolera postaci. Ponadto przygotowałeś własny
kontroler postaci 2D do wykorzystania w tworzonych projektach.
 Poznałeś sposoby budowania wspaniałych efektów cząsteczek za
pomocą różnych systemów cząsteczek. Zobaczyłeś, jak używać nowego
systemu Shuriken, a ponadto wypróbowałeś pewne starsze systemy
cząsteczek.
 Poznałeś starszy system animacji, m.in. anatomię animacji, i dowie‐
działeś się nieco o sposobach tworzenia animacji.
 Poznałeś też nowy w Unity system animacji Mecanim. Dowiedziałeś
się, jak ponownie przeprowadzić rigging modelu w celu użycia ani‐
macji, które nie zostały przygotowane specjalnie dla danego modelu.
Ponadto zobaczyłeś, jak edytować animacje i tworzyć własne klipy.
 Dowiedziałeś się, jak obsługiwać dźwięk w projektach. Zobaczyłeś,
jak wygląda praca z dźwiękiem zarówno 2D, jak i 3D. Nieobce są Ci
także tematy zapętlenia dźwięku oraz zmiany klipów audio.
 Dowiedziałeś się, jak przygotować gry do działania w urządzeniach
mobilnych. Poznałeś sposoby testowania gier z użyciem Unity Remote,
a także wykorzystania danych przyśpieszeniomierza i ekranu doty‐
kowego.
 Zobaczyłeś, jak dopracować grę przy użyciu w niej wielu scen oraz
zapewnieniu możliwości przechowywania danych. Dowiedziałeś się,
jak kompilować gry i w nie grać.
Wprawdzie to rozbudowana lista, ale na pewno niekompletna. Mam nadzieję,
że zapoznając się z powyższą listą, przypominałeś sobie to, czego się uczyłeś
wcześniej. A nauczyłeś się całkiem sporo!

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

 Amazing Racer. Trójwymiarowa gra będąca wyścigiem z czasem. W tej


grze wykorzystałeś wbudowany w Unity kontroler postaci First Per-
son, a także w pełni wyrzeźbiony i teksturowany teren. W grze poja‐
wiła się niebezpieczna woda, wyzwalacze i światło.
 Chaos Ball. Następna gra trójwymiarowa, która w pełni zasłużyła na
słowo chaos użyte w tytule. W tej grze występuje ogromna ilość
zderzeń oraz intensywnie zastosowano fizykę. Do zbudowania
powierzchni o niezwykłych właściwościach odbijania wykorzystałeś
materiał fizyczny. W grze zaimplementowałeś cele, których zdobycie
spowodowało zmianę zachowania obiektów.
 Captain Blaster. Dwuwymiarowa gra w stylu retro. To pierwsza gra,
w której zastosowałeś przewijane tło i efekty 2D. To jednocześnie była
pierwsza gra, w której gracz mógł przegrać. Opracowane przez innych
artystów modele i tekstury zapewniły grze wysokiej jakości grafikę.
 Gauntlet Runner. Kolejna gra trójwymiarowa, w której zadaniem gra‐
cza jest zbieranie dodatkowej energii i unikanie przeszkód. W grze
wykorzystałeś system animacji Mecanim, modele opracowane przez
artystów oraz sprytne manipulacje współrzędnymi tekstury w celu
uzyskania efektu przewijania w 3D.
Nie zapominaj także o przeprowadzonych modyfikacjach wszystkich wymie‐
nionych gier i przystosowaniu ich do działania w urządzeniach mobilnych.
Zdobyłeś doświadczenie w zakresie projektowania gier, ich tworzenia, testowa‐
nia i uaktualniania dla nowego sprzętu. Nieźle, naprawdę całkiem nieźle!

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

klip audio, 354 narzędzia Hand, 43


kod skryptu, 146 panelu Game, 42
kody klawiszy, 170 przyciągania, 44
kolejność scen, 384 systemu cząsteczek, 278
kolizje, 179, 182, 250 trybu Flythrough, 44
kolorowe kule, 202 kontrolowanie poślizgu, 248
komentarze, 147 kula chaos ball, 200
kompilacja gry, 391
komponent L
Animation, 300
Audio Listener, 102, 116, 347 lista
Audio Source, 348 parametrów, 163
Capsule Collider, 264 wymagań, 127
Collider, 182–184, 247 logowanie, 28
Collider Quarrel, 244 lustrzane odbicie, 315
kontrolera postaci, 245
Light, 106
Mouse Look, 376 Ł
Respawn Script, 135 łącza internetowe, 29
Rigidbody, 180, 186 łączenie
komponenty lokalne, 172 komponentów Collider, 183
koncepcja, 126, 194, 260, 326 obiektów, 135
konfiguracja stylów, 235
sceny, 316
środowiska, 360
urządzenia, 363 M
konfigurowanie ruchu, 372 malowanie
konsola, 147 drzewami, 90
konsolidacja obiektów, 196 terenu teksturą, 85
konstrukcja trawą, 92
if, 154 wzniesień, 81
if‐else, 155 mapa wysokości, 77
if‐else if, 156 materiały, 66, 68
konstrukcje warunkowe, 153 materiały fizyczne, 184
kontroler menedżer
First Person, 372 Input Manager, 167
gry, 127, 205, 266 TagManager, 122
postaci, 101, 130, 243, 248–251 menu
kontrolka Aspect, 41
etykiety, 228 Effects, 39
paska narzędziowego, 231 GameObject, 51
pola, 229 Layer, 118
pola tekstowego, 232 Layers, 42, 120
pola wyboru, 230 wyboru układu, 42
przycisku, 229 meteory, 264
przycisku powtarzającego, 230 metoda, 162
suwaka, 233 Find(), 174
kontrolki FindWithTag(), 174
efektów systemu cząsteczek, 279 Move(), 248
GUI, 227
408 Skorowidz

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

Light, 110 pole, 229


Maximize on Play, 41 tekstowe, 232
Remove Component, 37 wyboru, 230
Render Settings, 112 połączenie
Rendering/ Camera, 116 skryptów, 134
Skybox, 97 skryptu gracza, 272
Spotlight, 109 z zasobem prefabrykatu, 219
Store in Root, 297 popychanie obiektów, 254
Tags, 119 poślizg, 248
Terrain, 76 prefabrykaty, 211
opcje transformacji, 53 proces uprawnień, 127
operatory program
arytmetyczne, 151 3D Studio Max, 295
logiczne, 153, 154 Blender, 295
przypisania, 152 Maya, 295
równości, 152 MonoDevelop, 144
osiągnięcia, 398 programowanie
osie przyśpieszeniomierza, 363 dla przyśpieszeniomierza, 364
oś rotacji, 54 na platformach mobilnych, 360
oświetlenie sceny, 38 projektowanie GUI, 226
projekty, 31
proporcje ekranu, 261
P przeciążenie warstwami, 120
pakiety, 31 przejścia, 320
panel przejście ze stanu Jump, 335
Animator, 317, 318 przełączanie
Game, 39 platformy, 377
Hierarchy, 34, 35 scen, 385
Inspector, 35, 83, 143 przenoszenie zasobów, 33
Project, 32, 33 przeszkody, 330
Scene, 37, 42, 350 przewijanie drogi, 328
parametry, 163 przybliżanie, 44
parametry animatora, 318 przycisk, 229
pasek narzędziowy, 41, 42, 231 Add Component, 267
pędzel, 84 Dalej, 40
pętla Pauza, 40
for, 158 powtarzający, 230
while, 157 Start, 40
PiP, Picture in Picture, 119 Stats, 41
planowanie gry przygotowanie
koncepcja, 126, 194, 260, 326 animacji, 311
reguły, 126, 194, 260, 326 modelu, 295
wymagania, 127, 194, 260, 326 przyśpieszeniomierz, 363
platformy mobilne, 359, 360 punkt rozpoczęcia gry, 127
płynne przewijanie, 263 punkty kluczowe, 290
pobieranie modeli, 65
pociski, 265 R
początek układu współrzędnych, 49
raycasting, 187
podział ekranu, 116
reflektor, spotlight, 109, 114
reguły, 126, 194, 260, 326
410 Skorowidz

rigging, 295, 308, 309, 311 obiektu


rotacja, 54, 56 dodatkowej energii, 339
rozbieżność osi, 365 gracza, 338
rozdzielczość, 77 kontrolnego gry, 335
rozdzielczość sceny, 378 przeszkód, 339
rozglądanie się, 373 PlayerScript, 378, 379
rozpoczęcie gry, 127 pocisku, 272
rozwijane menu PrefabGenerator.cs, 222
Aspect, 41 SaveData, 388
Layers, 42, 120 SpawnScript, 340
wyboru układu, 42 strefy wyzwalacza, 335
rozwinięcie, unwrap, 67 VelocityScript.cs, 201
ruch, 378 wyzwalacza, 269
ruch gracza, 372 skrypty
rzeźbienie dla kontrolerów postaci, 245, 255
mapy wysokości, 77 do obsługi animacji, 322
terenu, 80–82, 129 do obsługi danych wejściowych, 168
do obsługi dźwięku, 352
słowo kluczowe this, 387
S spłaszczanie terenu, 81
scena, 36, 327 sterowanie postaciami, 243
SDK, Software Development Kit, 360 strefa wyzwalacza, 330
sekcja struktura
deklaracji, 146 kodu, 149
klasy, 146 prefabrykatu, 213
Using, 146 style, 238
shader, 66, 68 style GUI, 234
Bumped, 70 suwaki, 233
Diffuse, 70 symulacja nieba, 96, 97
Specular, 70 system
siatka, mesh, 61 kamer, 118
silnik gier, 401 Shuriken, 281
skalowanie, 55, 56 systemy
domyślne, 65 animacji, 293
siatki, 65 cząsteczek, 277, 278
sklep Asset Store, 65 edytor krzywych, 290
składnia, 149 moduły, 280
składniki dźwięku, 346 operacyjne, 28
skoki, 253, 374 szkielet, 294
skórki GUI, 235, 238
skrypt, 132, 141, 161 Ś
AudioScript, 356
GameControlScript, 206 ściana, 72
GoalScript.cs, 204 śledzenie dotknięć, 367
gracza, 270 środowisko, 89
LoadSceneTwo, 386 światło, 92, 106
meteoru, 267 kierunkowe, 109
MobileInputScript, 372 powierzchniowe, 110
MouseInputScript, 375 punktowe, 106
MouseLookScript, 376
Skorowidz 411

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

usuwanie niewidocznych powierzchni, 28 Limit Velocity over Lifetime, 283


użycie Renderer, 289
animacji, 299 Texture Sheet, 289
brył sztywnych, 181 Velocity over Lifetime, 283
dźwięku, 352 narzędzia Place Trees, 91
edytora krzywych, 291 osi, 168
metod, 165 przejścia ze stanu Jump, 335
obiektu PlayerPrefs, 388 shaderów, 70, 71
przyśpieszeniomierza, 365 sześcianu, 71
reflektora, 114 światła punktowego, 106, 107
warstw, 120 tekstury cookie, 113
wbudowanych metod, 148 trybu World, 287
wielu kamer, 116 zmiennej Touch, 367
właściwości Wrap Mode, 303 źródła dźwięku, 353
właściwość
Apply Root Motion, 322
W Culling Mask, 122
warstwa, 117, 120 Wrap Mode, 301, 302
warstwy gry, 38 woda, 99, 100
wartości domyślne, 392 współrzędne
warunek, 127 lokalne, 50, 51
wbudowane obiekty 3D, 63 świata, 50, 51
wdrożenie, 383 wybór
wiatr, 96 ikon pomocniczych, 38
widoczność warstw, 121 instalowanych komponentów, 27
wielkość katalogu, 27
aureoli, 112 licencji, 27
terenu, 77 platformy, 391
wierzchołek, 62 tagu, 175, 201
właściwości układu, 32
animacji wydajność, 94
Idle, 312 wygląd trawy, 94
Jump, 332 wymagania, 127, 194, 260, 326
Run, 333 dotyczące kolizji, 182
dźwięku 3D, 352 wymiar, dimension, 48, 58
kamery, 115, 251, 262 wypalanie, baking, 108
komponentu wyszukiwanie obiektów, 173
Animation, 300 wyświetlanie
Audio Source, 348 dokumentacji, 361
Collider, 183 okna Project, 30
Rigidbody, 180, 181 wywołanie kolizji cząsteczek, 287
kontrolera postaci, 245, 246 wywoływanie metod, 166
materiałów, 74 wyzwalacz, 185, 265, 269, 330
materiału fizycznego, 185
mgły, 98 Z
modułu
Collision, 286 zachowywanie
Color by Speed, 285 danych, 387
domyślnego, 282 obiektów, 387, 388
Emission, 282 zagnieżdżanie, 36
Skorowidz 413

zarządzanie zmienna, 147


projektem, 34 CollisionFlags, 249
sceną, 36, 384 GUIStyle, 235
zasięg zmiennej, 148 prywatna, 205
zasoby, 33, 102 Touch, 367
zasoby animacji, 298 Vector3, 252
terenu, 90 zmienne
zasób Animator, 308 kontrolera postaci, 247
zmiana prywatne, 150
animacji, 304 publiczne, 150
klipu audio, 354
rozdzielczości sceny, 378
scen, 386
Ź
szybkości, 137 źródła dźwięku, 347
typu kolizji, 288
właściwości, 37
wyglądu drzew, 92

You might also like