187 73 17MB
Polish Pages 448 [452] Year 2012
Tytu oryginau: Unity 3.x Game Development Essentials Tumaczenie: Jacek Janusz ISBN: 978-83-246-6761-1 Copyright © Packt Publishing 2011. First published in the English language under the title „Unity 3.x Game Development Essentials”. Polish edition copyright © 2012 by Helion S.A. All rights reserved. All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from the Publisher. Wszelkie prawa zastrzeone. Nieautoryzowane rozpowszechnianie caoci lub fragmentu niniejszej publikacji w jakiejkolwiek postaci jest zabronione. Wykonywanie kopii metod kserograficzn, fotograficzn, a take kopiowanie ksiki na noniku filmowym, magnetycznym lub innym powoduje naruszenie praw autorskich niniejszej publikacji. Wszystkie znaki wystpujce w tekcie s zastrzeonymi znakami firmowymi bd towarowymi ich wacicieli. Autor oraz Wydawnictwo HELION dooyli wszelkich stara, by zawarte w tej ksice informacje byy kompletne i rzetelne. Nie bior jednak adnej odpowiedzialnoci ani za ich wykorzystanie, ani za zwizane z tym ewentualne naruszenie praw patentowych lub autorskich. Autor oraz Wydawnictwo HELION nie ponosz równie adnej odpowiedzialnoci za ewentualne szkody wynike z wykorzystania informacji zawartych w ksice. Wydawnictwo HELION ul. Kociuszki 1c, 44-100 GLIWICE tel. 32 231 22 19, 32 230 98 63 e-mail: [email protected] WWW: http://helion.pl (ksigarnia internetowa, katalog ksiek) Drogi Czytelniku! Jeeli chcesz oceni t ksik, zajrzyj pod adres http://helion.pl/user/opinie/prgun3_ebook Moesz tam wpisa swoje uwagi, spostrzeenia, recenzj. Printed in Poland.
x Poleć książkę na Facebook.com
x Księgarnia internetowa
x Kup w wersji papierowej
x Lubię to! » Nasza społeczność
x Oceń książkę
Spis treci Przedmowa
9
O autorze
11
O recenzentach
12
Wstp
15
Rozdzia 1. Odkryj trzeci wymiar
21
Zapoznanie si z podstawami grafiki 3D Wspórzdne Przestrze modelu i przestrze wiata Wektory Kamery Wielokty, krawdzie, wierzchoki i siatki Materiay, tekstury i procedury cieniowania Fizyka bryy sztywnej Wykrywanie kolizji Podstawowe pojcia zwizane ze rodowiskiem Unity Metoda Unity — przykad Zasoby Sceny Obiekty gry Komponenty Skrypty Prefabrykaty Interfejs Widoki Scene i Hierarchy Panel Inspector
21 22 22 23 24 25 28 29 29 30 31 32 32 32 33 33 34 35 36 38
Projektowanie gier w rodowisku Unity 3.x
Okno Project Widok Game Podsumowanie
Rozdzia 2. Podstawy tworzenia prototypów i skryptów Twój pierwszy projekt w rodowisku Unity Podstawowe rodowisko prototypowe Definiowanie sceny Dodawanie prostego owietlenia Kolejna cega w cianie Zbuduj i zniszcz! Wprowadzenie do tworzenia skryptów Nowy skrypt definiujcy zachowanie lub klas Jak wyglda od rodka dziaanie skryptu w jzyku C#? Jak wyglda od rodka dziaanie skryptu w jzyku JavaScript? Atakowanie ciany Deklarowanie zmiennych publicznych Zrozumienie zasady dziaania polecenia Translate Implementacja funkcji Translate Testujemy biec wersj gry Tworzenie pocisku Przechowywanie obiektów jako prefabrykatów Wystrzelenie pocisku Uycie funkcji Instantiate() do konkretyzowania obiektów Przyoenie wektora siy do bryy sztywnej Podsumowanie
Rozdzia 3. Tworzenie rodowiska Projektowanie gry Uycie edytora terenu Opcje menu terenu Narzdzie edycji terenu Tworzenie wyspy — soce, morze i piasek Podsumowanie
Rozdzia 4. Postacie w grze i dalsze wykorzystanie skryptów Uycie panelu Inspector Znaczniki Warstwy Prefabrykaty i panel Inspector Anatomia postaci Dekonstrukcja obiektu First Person Controller Relacje midzy obiektami nadrzdnymi i podrzdnymi Obiekt First Person Controller
4
39 40 40
43 44 45 46 47 48 52 53 53 54 56 57 58 62 63 64 65 67 68 68 69 71
73 73 75 76 78 83 101
103 104 105 106 106 107 107 109 109
Spis treci
Dalsze wykorzystanie skryptów Polecenia Zmienne Kompletny przykad Funkcje Tworzenie wasnych funkcji Deklarowanie wasnej funkcji Polecenie if else Warunki wielokrotne Komunikacja midzyskryptowa oraz skadnia z kropk Dostp do innych obiektów Find() i FindWithTag() SendMessage() GetComponent Komentarze Skrypt wykonujcy operacj poruszania postaci Analiza skryptu Deklaracje zmiennych Podsumowanie
Rozdzia 5. Interakcje Zewntrzne aplikacje modelujce Ogólne ustawienia modeli Meshes Normals and Tangents Materials Animations Animation Compression Definiowanie modelu placówki Dodawanie placówki Ustalenie pooenia Obrót Dodanie zderzaczy Dodanie komponentu Rigidbody Dodanie dwiku Wyczenie automatycznej animacji Kolizje i wyzwalacze Rzucanie promieni Zgubienie klatki Wykrywanie zderzenia z przewidywaniem Otwieranie drzwi placówki Metoda 1. Wykrywanie kolizji Metoda 2. Rzucanie promieni Metoda 3. Wykrywanie kolizji wyzwalajcej Podsumowanie
119 119 120 123 123 125 127 129 131 133 133 133 134 135 138 139 139 140 145
147 147 148 148 149 150 150 151 151 152 153 153 154 156 156 156 157 160 161 162 163 164 179 185 189
5
Projektowanie gier w rodowisku Unity 3.x
Rozdzia 6. Kolekcja, inwentarz i HUD Tworzenie prefabrykatu ogniwa energetycznego Pobieranie, importowanie i umieszczanie Identyfikacja ogniwa energetycznego Skalowanie i obrót zderzacza Dodawanie komponentu Rigidbody Tworzenie skryptu dla ogniwa energetycznego Dodawanie opcji wyzwalajcego wykrywania kolizji Zapisywanie obiektu w postaci prefabrykatu Rozrzucanie ogniw energetycznych Inwentarz gracza Zapamitywanie poziomu zasilania Dodawanie funkcji CellPickup() Ograniczenie dostpu do placówki Ograniczenie dostpu do drzwi za pomoc licznika ogniw Wywietlacz HUD dla ogniwa energetycznego Importowanie ustawie tekstur GUI Tworzenie obiektu GUITexture Umieszczanie tekstury PowerGUI Skrypt do podmiany tekstury Tablice Poinformowanie o otwarciu drzwi Wskazówki dla gracza Pisanie na ekranie za pomoc komponentu GUIText Podsumowanie
Rozdzia 7. Konkretyzowanie obiektów i bryy sztywne Wykorzystywanie konkretyzacji Bryy sztywne Siy Komponent Rigidbody Tworzenie minigry Tworzenie prefabrykatu orzecha kokosowego Tworzenie obiektu Launcher Skrypt obsugujcy rzucanie orzechami kokosowymi Kocowe procedury sprawdzajce Ograniczenia konkretyzacji oraz usuwanie obiektów Dodawanie pomieszczenia przeznaczonego do rzucania kokosami Wygrywanie gry Kocowe usprawnienia Podsumowanie
191 194 194 195 195 196 197 198 199 200 200 201 202 204 204 205 206 206 208 208 209 217 221 221 227
229 230 231 232 232 233 234 236 238 247 248 251 266 271 274
Rozdzia 8. Systemy czstek
277
Co to jest system czstek? Particle Emitter Particle Animator Particle Renderer
277 278 278 279
6
Spis treci
Definiowanie zadania Uyte zasoby Tworzenie sterty gazi Tworzenie systemów czstek dla ogniska Rozpalanie ognia Testowanie i weryfikacja dziaania A wic jaki mamy problem? Podsumowanie
Rozdzia 9. Projektowanie menu Interfejsy i menu Tworzenie sceny Tworzenie menu za pomoc obiektów GUITexture i zdarze myszy Dodawanie przycisku uruchamiania gry Skrypt obsugujcy przycisk klasy GUITexture Wczytywanie scen Przypisywanie zmiennych publicznych Testowanie przycisku Dodawanie przycisku wywietlajcego instrukcje Dodawanie przycisku zakoczenia gry Testowanie skryptów przy uyciu polece debugowania Tworzenie menu za pomoc klasy GUI rodowiska Unity oraz kompozycji graficznych Wyczanie obiektów gry Tworzenie menu Podsumowanie
Rozdzia 10. Podstawy animacji Sekwencja animacji po wygraniu gry Metoda tworzenia sekwencji animacji Uruchamianie sekwencji wygrania gry Tworzenie komunikatów informujcych o wygraniu gry Animowanie przy uyciu interpolacji liniowej Tworzenie obiektu obsugujcego sekwencj zwycistwa Tworzenie skryptu wygaszania ekranu i uycie panelu Animation Wczytywanie sekwencji wygrania gry Umieszczanie obiektów GUITexture w warstwach Wyzwanie — zmiana koloru ekranu w scenie Island Podsumowanie
Rozdzia 11. Poprawa wydajnoci i kocowe modyfikacje Ulepszenie terenu i zdefiniowanie pooenia pocztkowego gracza Ulepszanie terenu Modyfikacja wzgórz i dolin oraz zastosowanie techniki przenikania tekstur Zdefiniowanie waciwej cieki Pocztkowa lokalizacja postaci gracza
280 280 281 283 292 302 303 305
307 308 310 315 315 315 318 319 320 321 321 324 326 326 326 349
351 351 352 354 354 356 358 360 372 373 374 374
375 376 376 377 378 379
7
Projektowanie gier w rodowisku Unity 3.x
Optymalizacja wydajnoci Paszczyzny odcinajce i mga Odwzorowywanie wiata Kocowe upikszenia Wulkan! Trajektorie lotu orzechów kokosowych Podsumowanie
Rozdzia 12. Budowanie i udostpnianie Opcje budowania Web Player Aplikacje samodzielne dla komputerów PC i Mac Widget aplikacji Dashboard dla OS X Ustawienia budowania Ustawienia gracza Ustawienia Cross-Platform Settings Ustawienia Per-Platform Settings Ustawienia jakoci Ustawienia wej dla gracza Budowanie gry Przystosowanie do wersji sieciowej Pierwsza kompilacja Budowanie dla sieci Udostpnianie swoich prac Udostpnianie prac na portalu Kongregate.com Podsumowanie
Rozdzia 13. Testy i dalsze zdobywanie wiedzy Nauka poprzez dziaanie Testowanie i finalizowanie Wykorzystanie uytkowników do testowania Sposoby zdobywania wiedzy Studiuj róne zagadnienia Nie odkrywaj koa na nowo Jeli czego nie wiesz, pytaj! Podsumowanie
380 380 381 391 391 397 400
401 402 402 404 404 405 406 406 407 411 413 414 414 421 423 428 428 429
431 432 432 433 437 437 438 438 439
Sowniczek
441
Skorowidz
451
8
Przedmowa Na pocztku naszej przygody z Unity bylimy po prostu trzema programistami tworzcymi niewielk, ale ciekaw gr komputerow. W tych czasach nie istnia aden interesujcy silnik gry, którego mona byoby uywa bez wysokich opat licencyjnych, wic zdecydowalimy si na stworzenie wasnego. W kocu stwierdzilimy, e bardziej interesuje nas projektowanie dobrych narzdzi ni samych gier. Po zastanowieniu zdalimy sobie spraw z tego, i uzupenienie tworzonych przez nas narzdzi o prost metod licencjonowania oraz wykorzystanie otwartej spoecznoci mog przyczyni si do zmiany sposobu konstruowania gier, ich dystrybucji oraz grania w nie przez ich projektantów. Osignicie obecnego poziomu nie byo proste. ylimy w niewygodzie, powicajc pracy cae dnie i noce, spoywajc stosy kanapek i tworzc strony internetowe dla firm prawniczych. Od jednego z potencjalnych inwestorów (który w kocu zrezygnowa z transakcji) usyszelimy kiedy, e nasze marzenie o „zdemokratyzowaniu procesu projektowania gier” ma jedn szans na sto, by si urzeczywistni . Najwaniejszym celem byo umieszczenie szalenie zoonej technologii w zgrabnym opakowaniu i sprawienie, by bya ona tak prosta w uyciu, jak to tylko moliwe. W 2009 roku z ekscytacj przyjlimy wydanie pierwszej ksiki o naszym oprogramowaniu, zatytuowanej Unity Game Development Essentials, która umoliwia wielu osobom zapoznanie si z systemem Unity. Gdy Will przekaza mi informacj, e zamierza opublikowa jej uaktualnion wersj, byem zaszczycony moliwoci napisania do niej wstpu. Will od dawna naley do spoecznoci Unity. Spotkalimy si w 2007 roku, gdy pracowa w Wielkiej Brytanii na uniwersytecie w Bournemouth i prowadzi wykady dotyczce projektowania gier przy uyciu systemu Unity. Will by twórc pierwszych poradników wideo dotyczcych Unity, które pozwoliy wielu pocztkujcym uytkownikom tego systemu zapozna si z dziaaniem wersji 1.5 oraz póniejszych. Mimo e Will pracuje obecnie w Unity Technologies, wci posiada bardzo due dowiadczenie zwizane z nauczaniem i pomaga nam we wspieraniu pocztkujcych uytkowników poprzez tworzenie materiaów szkoleniowych, prowadzenie wykadów oraz aktywne uczestnictwo w naszej spoecznoci. Kolejne wydanie ksiki Projektowanie gier w rodowisku Unity 3.x, które trzymasz w rkach (lub wywietlasz na ekranie laptopa albo komputera stacjonarnego), zostao cakowicie odnowione, jednake zachowao wszystkie elementy skadajce si na sukces
Projektowanie gier w rodowisku Unity 3.x
pierwszego wydania. Kady rozdzia ksiki zosta poszerzony, ulepszony lub uzupeniony. Obecnie zawieraj one opisy wielu opcji, które w tym czasie pojawiy si w rodowisku Unity. Mimo tego ksika nie skada si jedynie z prezentacji samych nowoci. Will dokadnie omawia podstawy uytkowania systemu oraz stosowania skryptów, a nawet próbuje rozwiza odwieczn zagadk Unity: jakiego jzyka naley uywa: C# czy JavaScript?. Dziki omówieniu w ksice obu jzyków masz moliwo wybrania tego, który bardziej Ci odpowiada. Bez wzgldu na to, czy jeste grafikiem, projektantem poziomów, czy po prostu modym czowiekiem wybierajcym dziedzin tworzenia gier komputerowych jako ciek swojej potencjalnej kariery zawodowej, ksika ta jest fascynujcym poradnikiem pozwalajcym na zdobycie wiedzy o dziaaniu rodowiska Unity. Rozpoczynajc od zapoznania si z podstawami grafiki trójwymiarowej, bdziesz móg nauczy si wszystkiego od samego pocztku. Nie jest tu wymagana adna wstpna wiedza, a mimo tego ksika zachowuje odpowiednie tempo, pozwalajc Ci na przewracanie jej kartek i tworzenie kodu! Chciabym osobicie powita Ci w spoecznoci Unity. Mam nadziej, e bdziesz mia tyle radoci z przeczytania tej ksiki, ile my mamy dziki pracy w Unity Technologies.
David Helgason Prezes i wspózaoyciel Unity Technologies
10
O autorze Will Goldstone od dawna naley do spoecznoci Unity. Pracujc w firmie Unity Technologies, oferuje wsparcie techniczne, zajmuje si zagadnieniami edukacyjnymi, kontaktami ze spoecznoci oraz udzielaniem pomocy projektantom. Stopie naukowy zwizany z kreatywn edukacj oraz wieloletnie dowiadczenie w pracy jako wykadowca wyszej uczelni pomogy mu w napisaniu pierwszej na rynku ksiki dotyczcej rodowiska Unity, zatytuowanej Unity Game Development Essentials, a take w stworzeniu odpowiednich poradników wideo. Wykorzystujc swoj stron internetow http://www.unity3dstudent.com, Will zaprasza codziennie nowych uytkowników do rozwijajcej si spoecznoci projektantów gier. Nieregularnie publikuje take swoje artykuy na stronie http://willgoldstone.com. Oto osoby, którym chciabym podzikowa za wsparcie przy tworzeniu niniejszej ksiki, jak równie za to, e byy po prostu wspaniae: Teck Lee Tan (@LoTeKk) (podzikowanie za stworzenie zasobów graficznych); wszyscy wojownicy ninja z Unity Technologies: Rune Skovbo Johansen, Nicholas Francis (@unitynich), David Helgason (@davidhelgason), Joachim Ante, Graham Dunnett, Andy Brammall (@andybrammall), Andy Stark, Charles Hinshaw, Roald Hoyer-Hansen (@brokenpoly), Carl Callewaert (@carlunity), Chris Pope (@CreativeChris1), Dave Shorter, Mark Harkness (@IAmRoflHarris), Ricardo Arango, Rob Fairchild (@robfairchild), Olly Nicholson, Cathy Yates, Adam Buckner, Richard Sykes, Emil Johansen (@AngryAnt), Ethan Vosburgh, Joe Robins (@JoeRobins)… i wiele innych wspaniaych osób, których nie mogem tu wymieni! Na licie musz si take pojawi moi przyjaciele, którzy s zwizani z Unity: Bob Berkebile (@pixelplacement), Tom Jackson (@quickfingerz), Thomas Pasieka (@thomaspasieka), Cat Burton (@catburton), Mike Renwick (@runonthespot), Mark Backler, Russ Morris (@therussmorris), Jasper Stocker (@jasperstocker), Paul Tondeur (@paultondeur), David Fugère-Lamarre, Benjamin Lee, Steffen Franz, Aaron Grove, Bastien Fontaine. Nie mog oczywicie zapomnie o Mamie, Tacie, Rach, Penny i pozostaych przyjacioach.
Projektowanie gier w rodowisku Unity 3.x
O recenzentach Rune Skovbo Johansen od 2009 roku naley do zespou projektantów w firmie Unity Technologies. Zajmuje si poszerzaniem moliwoci edytora oraz usprawnianiem interfejsu i sposobu dziaania systemu. Rune mieszka w Danii, w Kopenhadze. Oprócz zada zwizanych z edycj opracowa szereg formalnych narzdzi animacyjnych, by wspóautorem dokumentacji rodowiska Unity, a take uczestniczy w programowaniu wielu oficjalnych pakietów prezentacyjnych. Ogólnie rzecz biorc, Rune pasjonuje si tworzeniem rozwiza, które sprawiaj, e zaawansowana, a jednoczenie interesujca technologia staje si przyjazna dla uytkownika. Ukoczone studia z dziedziny tworzenia gier i multimediów pozwalaj mu stosowa twórcze i interdyscyplinarne podejcie do projektowania oprogramowania. Rune od samego dziecistwa interesuje si grafik, animacj i kodowaniem. Rune aktywnie wspiera internetow spoeczno zwizan z projektowaniem gier — udziela si na rónych forach oraz blogach, a take uczestniczy w spotkaniach i innych zdarzeniach. By prelegentem na konferencjach Game Developers Conference oraz Unity Conference oraz pomaga w zorganizowaniu spotkania Nordic Game Jam. W wolnym czasie Rune preferuje czytanie ksiek, lubi uprawia turystyk piesz w parkach i lasach oraz codziennie jedzi na rowerze. Powica take swój czas na tworzenie grafiki i animacji oraz projektowanie nieduych gier. Jest zawsze bardzo zainteresowany proceduralnym podejciem do zagadnie i wci próbuje odkry najlepszy sposób pozwalajcy zmusi komputer do wygenerowania olbrzymich, a jednoczenie nieregularnych wiatów wirtualnych. Swoje projekty prezentuje na stronie http://runevision.com. Mark Backler jest projektantem gier, który zajmuje si tym zagadnieniem od ponad piciu lat. Poprzednio pracowa w firmach EA i Kuju, a obecnie jest zatrudniony w Lionhead Studios i tworzy gr Fable. The Journey. Wspópracowa przy wielu projektach — tworzy midzy innymi gry, takie jak Harry Potter i Zakon Feniksa, Milo i Kate oraz Fable 2, która otrzymaa nagrod BAFTA. Jest dostpny na Twitterze jako @MarkBackler.
12
O recenzentach
Chciabym podzikowa Willowi za napisanie tej ksiki, która pomoga mi sprawnie rozpocz prac w rodowisku Unity, Catowi przede wszystkim za moliwo poznania Willa, utalentowanym i twórczym osobom z firmy Lionhead, od których ucz si kadego dnia, moim przyjacioom, w szczególnoci Anishowi, Tomowi oraz Chuckowi, a wreszcie mojej rodzinie za to, e jest po prostu wspaniaa.
David Fugère-Lamarre ukoczy studia informatyczne na uczelni École Polytechnique de Montréal, a take uzyska stopie naukowy w dziedzinie inynierii zarzdzania w New Jersey Institute of Technology. Jego dowiadczenie zwizane z projektowaniem gier rozpoczo si w 2004 roku, gdy zacz prac w Montrealu (Kanada) w firmie Behaviour Interactive (poprzednia nazwa: Artificial Mind & Movement) jako programista gier konsolowych. W 2007 roku pracowa na tym samym stanowisku w Lyonie (Francja) w firmie Phoenix Studio. W 2009 roku wspózaoy w Montrealu niezalen firm Illogika Studios (http://illogika.com), zajmujc si projektowaniem gier w rodowisku Unity. David prowadzi zaawansowane kursy obsugi systemu Unity w Centre Nad w Montrealu, wspópracowa równie z lokalnymi uczelniami w zakresie organizacji szkole zwizanych z programowaniem gier komputerowych. Bastien Fontaine jest dwudziestopicioletnim francuskim projektantem i twórc skryptów. Uzyska dyplom zwizany z informatyk (C++, Java, PHP, SQL itd.) na uniwersytecie w Nicei (Francja), a take studiowa w prywatnej szkole ARIES, ksztaccej przysze kadry zajmujce si projektowaniem gier wideo. Pozna takie pakiety oprogramowania, jak Virtools, Maya, 3DS Max i Photoshop. W kocu zakoczy zdobywanie wiedzy na Université Lyon 2 (Gamagora), gdzie studiowa projektowanie poziomów i nauczy si obsugi narzdzi, jak Unreal Engine, Unity oraz Sketch Up, jak równie poprawi swoje umiejtnoci projektowania gier. Bdc zatrudnionym w firmie Creative Patterns (Strasburg, Francja), Bastien uywa rodowiska Unity, aby tworzy oprogramowanie na platform iPhone. Pracowa take w firmie Illogika Studio (Montreal, Kanada), w której równie projektowa gry dla iPhone’a. Wspópracowa tam z Davidem Fugère’em-Lamarre’em, innym recenzentem niniejszej ksiki. Steffen Franz jest obecnie dyrektorem technicznym w firmie HiveMedia (http://www. hivemedia.tv), majcej swoj siedzib w rejonie San Francisco i zajmujcej si tworzeniem gier o tematyce spoecznej. Jest równie gównym projektantem dostpnej na Facebooku gry Deadliest Catch — The Social Game, która zostaa oparta na znanym programie stacji Discovery Channel. Od momentu zdobycia dyplomu w dziedzinie programowania gier w The Art Institute of California (San Francisco) Steffen uywa rodowiska Unity przez ponad trzy lata, tworzc takie tytuy, jak Globalworld (wirtualny wiat przyjazny dla dzieci), sieciowa gra Disneya TRON Legacy oraz Cordy — trójwymiarowa platformówka przeznaczona dla systemu operacyjnego Android firmy Google.
13
Projektowanie gier w rodowisku Unity 3.x
Chciabym podzikowa autorowi za moliwo udostpnienia czytelnikom mojej wiedzy oraz profesjonalnego dowiadczenia z silnikiem Unity. Przede wszystkim chciabym przekaza podzikowania mojej rodzinie, a w szczególnoci dwuletniemu brzdcowi, który dziki temu, e uwielbia spa, pozwoli mi na zrecenzowanie niniejszej ksiki. Mam nadziej, e udowodni ona, jak ambitnym, a jednoczenie ciekawym zajciem jest programowanie gier komputerowych.
Aaron Grove jest nagrodzonym szefem zespou tworzcego efekty wizualne, posiadajcym ponad dziesicioletnie dowiadczenie w swojej pracy. Tworzy najwyszej jakoci efekty wizualne dla reklam telewizyjnych oraz klipów wideo w Australii, Wielkiej Brytanii oraz Stanach Zjednoczonych Ameryki. Kreatywno Aarona i jego wiedza o grafice trójwymiarowej oraz efektach wizualnych (zarówno na poziomie technicznym, jak i artystycznym), poczone z zainteresowaniem technologi gier komputerowych, pozwalaj mu tworzy wizualnie oszaamiajce aplikacje. W 2010 roku Aaron zarzdza zespoem tworzcym efekty wizualne dla nagrodzonego klipu wideo Two Weeks zespou Grizzly Bear. Obecnie jest dyrektorem twórczym oraz wspózaoycielem firmy Blowfish Studios, która zajmuje si wycznie projektowaniem gier przy uyciu rodowiska Unity. Wicej informacji mona znale na stronie http://www.blowfishstudios.com. Ben Lee jest inynierem oprogramowania i od trzynastu lat zajmuje si zagadnieniami zwizanymi z grami komputerowymi. Realizowa projekty dla firm EA, Intel, nVidia oraz 3M. Ma bogate dowiadczenie w projektowaniu i programowaniu silników gier komputerowych, a take w innych aspektach tworzenia oprogramowania na róne platformy sprztowe. Ostatnio wspózaoy firm Blowfish Studios (http://www.blowfishstudios.com) i od tej pory skoncentrowa si wycznie na projektowaniu gier przy uyciu rodowiska Unity.
14
Wstp Silniki gier takie jak Unity s znanymi, docenianymi, a przede wszystkim potnymi narzdziami wspierajcymi tworzenie gier. rodowisko Unity jest jednym z najczciej uywanych oraz najbardziej cenionych pakietów pozwalajcych na projektowanie gier komputerowych. Moe by ono wykorzystywane przez szerokie spektrum uytkowników, poczynajc od hobbystów, a koczc na duych firmach; pozwala tworzy gry oraz interaktywne aplikacje dla przegldarek internetowych, komputerów stacjonarnych, urzdze przenonych oraz konsol. Dziki intuicyjnemu i prostemu w obsudze zestawowi narzdzi rodowiska Unity oraz niniejszej ksice moesz tak atwo jak nigdy dotd sta si twórc gier komputerowych. W ksice wykorzystano praktyczne podejcie polegajce na zaprezentowaniu podstawowych koncepcji projektowania trójwymiarowych gier wideo przed rozpoczciem procesu nauczania obsugi waciwego rodowiska Unity, na który skada si utworzenie prototypu prostego scenariusza, a nastpnie zaprojektowanie bardziej zoonej gry. Poznanie sposobów tworzenia trójwymiarowych wiatów, skryptów i mechaniki gier pozwoli Ci na zdobycie caej wiedzy, która jest niezbdna do rozpoczcia przygody z projektowaniem gier komputerowych. Ksika udostpnia szereg prostych do wykonania przykadów, których zwieczeniem jest stworzenie gry 3D wykorzystujcej perspektyw pierwszej osoby oraz interakcyjne rodowisko zdefiniowane w postaci wyspy. Wszystkie koncepcje zaprezentowane w ksice mog zosta zastosowane w innych rodzajach gier. Dziki wprowadzeniu ogólnych poj zwizanych z tworzeniem gier i rodowisk trójwymiarowych bdziesz móg uy systemu Unity w celu okrelenia poziomu interakcyjnoci gracza ze wiatem gry oraz zaplanowania zada, które powinien on rozwiza , by j ukoczy . Pod koniec ksiki bdziesz dysponowa w peni dziaajc gr trójwymiarow oraz umiejtnociami pozwalajcymi na jej rozbudow i udostpnienie kocowemu uytkownikowi, czyli graczowi, najpeniejszych wrae odbioru. Wkrótce w prosty sposób bdziesz tworzy wasne gry 3D oraz aplikacje interakcyjne!
Projektowanie gier w rodowisku Unity 3.x
Zagadnienia poruszane w ksice Rozdzia 1. „Odkryj trzeci wymiar”. W tym rozdziale zaprezentujemy podstawowe pojcia zwizane z grafik trójwymiarow oraz omówimy, w jaki sposób projektuje si gry przy uyciu systemu Unity. Nastpnie zapoznasz si z gównymi oknami interfejsu uytkownika, skadajcymi si na rodowisko Unity. Rozdzia 2. „Podstawy tworzenia prototypów i skryptów”. W tym rozdziale rozpoczniesz praktyczn nauk obsugi rodowiska Unity poprzez zaprojektowanie prototypu mechaniki dla prostej gry oraz wykorzystanie skryptów napisanych w jzykach C# (nazwa wymawiana jako „si-szarp”) oraz JavaScript, które pozwol na stworzenie prostych interakcji z systemem. Rozdzia 3. „Tworzenie rodowiska”. Gdy wiesz ju, jak naley uywa systemu Unity i jego procesów, moesz rozpocz projektowanie wiata zewntrznego za pomoc narzdzia Terrain, co umoliwi Ci utworzenie rodowiska w postaci wyspy. Rozdzia 4. „Postacie w grze i dalsze wykorzystanie skryptów”. Po zaprojektowaniu rodowiska dowiemy si, w jaki sposób w systemie Unity s konstruowane postacie gry, a nastpnie poczymy je ze skryptami. Poznamy take kolejne pojcia zwizane ze skryptami, które bd niezwykle przydatne przy tworzeniu bardziej zaawansowanych interakcji w Unity. Rozdzia 5. „Interakcje”. Z tego kluczowego rozdziau nauczysz si trzech najwaniejszych procesów zwizanych z projektowaniem gier w rodowisku Unity: interakcji przy uyciu narzdzia Collisions, wykrywania obiektów za pomoc techniki rzucania promieni (ang. Raycasting) oraz detekcji kolizji przy wykorzystaniu obszarów typu Trigger. Rozdzia 6. „Kolekcja, inwentarz i HUD”. Masz ju wiedz o procesie interakcji, ale moesz j lepiej wykorzysta , jeli nauczysz si, jak stworzy dla gracza prosty inwentarz oraz zwizany z nim przezroczysty wywietlacz (HUD), w którym bd prezentowane zgromadzone przedmioty. Rozdzia 7. „Konkretyzowanie obiektów i bryy sztywne”. Aby ponownie zastosowa interakcj w praktyce, wykorzystamy silnik fizyczny istniejcy w rodowisku Unity i nauczymy si, jak mona go poczy z animacj w celu stworzenia ministrzelanki. Rozdzia 8. „Systemy czstek”. Przerw w tworzeniu skryptów wykorzystamy w celu zapoznania si z niektórymi efektami wizualnymi dostpnymi w rodowisku Unity. Stworzymy symulacj ogniska przy uyciu systemu czstek pozwalajcego na generowanie ognia i dymu. Rozdzia 9. „Projektowanie menu”. Kada dobra gra wymaga uycia interfejsu uytkownika. W tym rozdziale zapoznamy si z dwoma sposobami tworzenia menu w rodowisku Unity: za pomoc komponentów GUI Texture oraz klasy skryptowej GUI.
16
Wstp
Rozdzia 10. „Podstawy animacji”. Dziki zastosowaniu animacji gry tworzone w rodowisku Unity staj si dynamiczne. W tym rozdziale stworzymy sekwencj kocow gry z napisami oraz dowiemy si, w jaki sposób mona j animowa , korzystajc ze skryptów, a take z okna Animation systemu Unity. Rozdzia 11. „Poprawa wydajnoci i kocowe modyfikacje”. Mimo e wane jest uzyskanie dobrej grywalnoci, przed udostpnieniem gry odbiorcom kocowym naley si upewni , i jest ona dopracowana. W tym rozdziale zajmiemy si tworzeniem kolejnych efektów wizualnych oraz zoptymalizujemy gr w taki sposób, by dobrze si prezentowaa i wydajnie dziaaa. Rozdzia 12. „Budowanie i udostpnianie”. Aby rozwija swoje umiejtnoci zwizane z projektowaniem, powiniene udostpnia swoje prace innym graczom i uzyskiwa od nich informacje zwrotne. W tym rozdziale dowiemy si, jak mona umieszcza gr w samodzielnym pliku wykonywalnym lub wykorzystywa w sieciowym odtwarzaczu gier. Rozdzia 13. „Testy i dalsze zdobywanie wiedzy”. W ostatnim rozdziale zapoznamy si z metodami pozwalajcymi na otrzymywanie informacji zwrotnej od graczy, a take przekaemy kilka porad, przydatnych projektantom chccym wykorzystywa rodowisko Unity. Zaprezentujemy równie pozycje, które warto przeczyta , aby sta si profesjonalnym projektantem gier komputerowych. Dodatek A „Sowniczek”. Sowniczek zawiera opisy czsto uywanych terminów, które moesz napotka , a take spenia funkcj porcznej bazy odnoników.
Czego potrzebujesz do przeczytania tej ksiki? Aby w peni skorzysta z tej ksiki, bdziesz musia pobra darmow wersj rodowiska Unity, dostpn pod adresem: http://www.unity3d.com/unity/download. Twój komputer powinien take spenia okrelone wymagania, zgodnie z informacjami podanymi na stronie Unity: Q Windows: wersja systemu operacyjnego XP SP2 lub nowsza. Q Mac OS X: procesor Intel, wersja systemu operacyjnego Leopard 10.5 lub nowsza. Q Karta grafiki: 64 MB pamici VRAM oraz obsuga cieniowania pikseli (pixel shader)
lub czterech jednostek mapowania tekstur. Kada karta grafiki wyprodukowana w XXI wieku spenia te wymagania. W celu zapoznania si z najnowszymi wymaganiami sprztowymi odwied stron Unity: http://unity3d.com/unity/system-requirements.html.
17
Projektowanie gier w rodowisku Unity 3.x
Dla kogo jest przeznaczona ta ksika? Czy jeste projektantem lub grafikiem, który chce stawia pierwsze kroki w dziedzinie tworzenia gier lub ich prototypów? A moe po prostu powicasz wiele godzin grom wideo i masz gow przepenion rónymi pomysami? Jeli tak jest, rodowisko Unity oraz niniejsza ksika powinny by Twoim punktem startowym. Do jej przeczytania nie jest wymagana adna wczeniejsza wiedza zwizana z projektowaniem gier — wystarczy, e zabierzesz ze sob pasj tworzenia wspaniaych gier komputerowych.
Uzyskiwanie pomocy dotyczcej ksiki i aktualizacji Ksika ta zostaa napisana i przetestowana z wykorzystaniem rodowiska Unity w wersji 3.4.2. Pomimo cisej kontroli tekstu w pewnych rzadkich przypadkach wydanie moe zawiera bdy dezorientujce czytelników. Oprócz tego, w wyniku procesu rozwojowego rodowiska Unity oraz udostpniania jego nowych wersji, pewne fragmenty ksiki bd wymaga uaktualnienia. Aby umoliwi Ci korzystanie z najnowszych informacji, udostpniamy stron internetow — pozwoli Ci ona zapozna si ze zmianami, które pojawiy si w ksice i samym rodowisku Unity. Dziki temu bdziesz pewien, e niniejsza ksika jest zawsze na bieco z najnowszymi wersjami Unity. Jeli wic napotkasz informacj, która wedug Ciebie zostaa zmodyfikowana, lub po prostu potrzebujesz pomocy w zrozumieniu ksiki, odwied nastpujcy adres: http://www.unitybook.net.
Konwencje W tej ksice napotkasz kilka rónych stylów tekstu, które pozwol na odrónienie rodzajów przekazywanych informacji. Oto kilka ich przykadów wraz z objanieniami. Kod zawarty w tekcie jest prezentowany tak: „Przypisz zmiennej fps warto zaokrglonej liczby klatek”. Blok kodu jest wyróniony nastpujco: // Zapaki private var haveMatches : boolean = false; var matchGUIprefab : GUITexture;
Niektóre polecenia kodu s tak dugie, e nie mieszcz si w jednym wierszu — upewnij si, e nie bdziesz mia do czynienia z tak sytuacj. Pamitaj, i wiersze kodu kocz si red-
18
Wstp
nikiem. Postaraj si wic, jeli to moliwe, umieszcza kod w pojedynczym wierszu. W poniszym przykadzie brak miejsca spowodowa, e kod zosta rozmieszczony w dwóch wierszach. W uywanym przez Ciebie edytorze skryptów nie powiniene jednake stosowa znaku nowego wiersza, by uzyska taki ukad: new Vector3(Mathf.Lerp(xStartPosition, xEndPosition, ´(Time.time -startTime)*speed), transform.position.y, transform.position.z);
Nowe pojcia i wane terminy zostay wyrónione pogrubion czcionk. Nazwy polece menu lub tytuy pól w oknach dialogowych s wydrukowane kursyw: „Wybierz opcj Plik/Zapisz w edytorze tekstów, a nastpnie wró do rodowiska Unity”. Uwaga Ostrzeenia lub wane uwagi pojawiaj si w takiej formie.
Wskazówka W ten sposób s podawane wskazówki.
Pomoc techniczna Jeli jeste ju dumnym posiadaczem ksiki Helionu, moemy zaoferowa Ci rónorodn pomoc, która pozwoli na jak najlepsze wykorzystanie publikacji.
Pobieranie pakietu zasobów dla tej ksiki Uaktualnione repozytorium zawierajce pakiet zasobów przygotowanych dla tej ksiki mona pobra z adresu: http://unitybook.net/book_assets.unitypackage.zip.
Pobieranie kolorowych rysunków Udostpnilimy równie kolorowe zrzuty ekranów, zaprezentowane w tej ksice. Pozwol one lepiej zrozumie dynamik dziaania systemu. Mona je pobra pod adresem: http://www. helion.pl/ksiazki/prgun3.htm.
19
Projektowanie gier w rodowisku Unity 3.x
Errata Mimo e podjlimy wszelkie kroki, aby zapewni najwysz jako treci tej ksiki, pomyki si jednak zdarzaj. Jeli znajdziesz bd w jednej z naszych ksiek — by moe w tekcie lub kodzie — bdziemy wdziczni, jeeli przelesz nam o tym informacj. Dziki temu inni czytelnicy nie bd sfrustrowani, za my bdziemy mogli poprawi kolejne wersje ksiki. Jeli znalaze jaki bd, przelij go do nas za pomoc formularza zgoszenia do erraty, który znajduje si pod adresem: http://helion.pl/user/erraty/. Po pozytywnej weryfikacji Twojego zgoszenia zostanie ono zaakceptowane, za errata pojawi si na naszej stronie pod adresem: http://helion.pl/erraty.htm.
Piractwo Piractwo internetowe materiau chronionego prawem autorskim jest cigym problemem dotykajcym wszystkie rodzaje mediów. Wydawnictwo Helion bardzo powanie traktuje ochron swoich praw autorskich oraz licencji. Jeli gdzie w internecie natkne si na nielegalne kopie naszych prac, powiadom nas o tym, przesyajc adres lub nazw strony, na której znajduj si pirackie pliki. W tym celu wykorzystaj formularz dostpny pod adresem: http://helion.pl/ piracy.html. Jestemy wdziczni za pomoc w chronieniu naszych autorów oraz wspieranie nas podczas dostarczania Ci wartociowych treci.
20
1 Odkryj trzeci wymiar Przed rozpoczciem uytkowania dowolnego pakietu grafiki trójwymiarowej niezbdne jest poznanie rodowiska, w którym zamierzasz pracowa . Poniewa rodowisko Unity jest zasadniczo narzdziem projektowania opartym na grafice trójwymiarowej, uycie wielu poj zastosowanych w tej ksice zakada pewien poziom znajomoci obsugi silników gier oraz grafiki 3D. Wane jest, aby zrozumia stosowan terminologi, zanim przejdziesz do praktycznych wicze w kolejnych rozdziaach ksiki. Postaramy si to zapewni w tym rozdziale poprzez wyjanienie niektórych wanych poj zwizanych z grafik trójwymiarow przed omówieniem zasad dziaania samego rodowiska Unity. Za chwil zostan zaprezentowane nastpujce zagadnienia: Q wspórzdne i wektory, Q formy trójwymiarowe, Q materiay i tekstury, Q dynamika bryy sztywnej, Q wykrywanie kolizji, Q obiekty gry i komponenty, Q zasoby i sceny, Q prefabrykaty, Q interfejs edytora rodowiska Unity.
Zapoznanie si z podstawami grafiki 3D Przyjrzyjmy si podstawowym elementom wiatów trójwymiarowych oraz dowiedzmy si, w jaki sposób rodowisko Unity umoliwia projektowanie gier 3D.
Projektowanie gier w rodowisku Unity 3.x
Wspórzdne Jeli uywae ju wczeniej jakiej aplikacji 3D, najprawdopodobniej znasz pojcie osi Z. Istniejce osie X i Y, okrelajce pooenie odpowiednio w poziomie i pionie, zostay uzupenione o trzeci o Z, reprezentujc gbi. Mona zauway , e w aplikacjach 3D informacje o obiekcie s wywietlane w formacie X, Y, Z — to tak zwane wspórzdne kartezjaskie. Tak mog zosta opisane wymiary, wartoci obrotu oraz pooenia w wiecie trójwymiarowym. W niniejszej ksice, tak jak w innych dokumentach zwizanych ze rodowiskiem 3D, wspórzdne 3D s zapisywane w nawiasach, na przykad: (3, 5, 3)
Taki zapis wynika przede wszystkim z koniecznoci zachowania porzdku oraz z faktu, e programowanie wymaga dokadnie takiego podania wartoci wspórzdnych. Bez wzgldu na sposób prezentacji moesz przyj , i dowolny zbiór trzech wartoci oddzielonych przecinkami bdzie reprezentowa osie X, Y, Z. Na poniszym rysunku przedstawiono szecian umieszczony w wiecie trójwymiarowym we wspórzdnych (3, 5, 3). Oznacza to, e znajduje si on w odlegoci 3 jednostek od punktu 0 na osi X, 5 jednostek od punktu 0 w gór na osi Y oraz 3 jednostek od punktu 0 w kierunku do przodu na osi Z.
Przestrze modelu i przestrze wiata Kluczowym pojciem, z którym powinnimy si zapozna , jest rónica midzy przestrzeni modelu i przestrzeni wiata. wiat w dowolnej aplikacji 3D jest technicznie nieskoczony. Powoduje to, e trudno jest w nim ustali pooenie obiektów. W kadym wiecie trójwymiaro-
22
Rozdzia 1. • Odkryj trzeci wymiar
wym zdefiniowano wic punkt pocztkowy, zwany pocztkiem lub punktem zerowym, który ma wspórzdne (0, 0, 0). Wszystkie wspórzdne obiektów w przestrzeni 3D odnosz si do punktu zerowego. Aby zdefiniowa wspórzdne danego obiektu w relacji do innego, dla uproszczenia moemy jednake uywa równie przestrzeni modelu (zwanej przestrzeni obiektu). Takie zwizki s znane pod nazw powiza typu nadrzdny – podrzdny. Powizania typu nadrzdny – podrzdny mog by ustanowione w rodowisku Unity w prosty sposób za pomoc przecignicia jednego obiektu do innego w oknie Hierarchy (hierarchia). Powoduje to, e przecigany obiekt staje si potomkiem, a jego wspórzdne s od tej pory wyznaczane wzgldem obiektu rodzica. Na przykad jeli obiekt podrzdny znajduje si w tym samym pooeniu w przestrzeni wiata co obiekt nadrzdny, wówczas jego wspórzdne wynosz (0, 0, 0), mimo e pozycja rodzica nie musi by równa punktowi zerowemu. Przestrze modelu zakada, e kady obiekt ma swój punkt zerowy, z którego rozpoczynaj si osie wspórzdnych. Jest nim zazwyczaj rodek danego obiektu. Poprzez tworzenie powiza midzy obiektami moemy porównywa ich pooenie wzgldem siebie. Oznacza to, e przy uyciu przestrzeni modelu moemy wyznacza odlegoci od innych obiektów, wykorzystujc wspórzdne obiektu nadrzdnego jako nowy punkt zerowy dla kadego z jego obiektów podrzdnych. Powysza uwaga jest szczególnie wana podczas pracy z zasobami graficznymi w narzdziach modelowania 3D, gdy zawsze powiniene upewni si, e modele tworzone w uywanym przez Ciebie pakiecie oprogramowania maj pooenie równe (0, 0, 0). Dziki temu po ich zaimportowaniu do rodowiska Unity wspórzdne zostan poprawnie odczytane. Ten proces moemy zaprezentowa w przestrzeni dwuwymiarowej, poniewa te same konwencje stosuje si w 3D. W poniszym przykadzie (patrz rysunek poniej): Q Pierwszy wykres (i) przedstawia dwa obiekty w przestrzeni wiata. Duy szecian ma wspórzdne (3, 3), natomiast mniejszy — (6, 7). Q Na drugim wykresie (ii) mniejszy szecian sta si obiektem podrzdnym wikszego szecianu. Wynika std, e wspórzdne mniejszej bryy s obecnie równe (3, 4),
poniewa jej punktem zerowym jest pooenie rodzica w przestrzeni wiata.
Wektory Bdziesz take mia do czynienia z wektorami opisanymi za pomoc wspórzdnych kartezjaskich. Wektory 3D, podobnie jak ich dwuwymiarowe odpowiedniki, s zwykymi prostymi umieszczonymi w przestrzeni trójwymiarowej, które maj kierunek i dugo . Wektory mog by przemieszczane w przestrzeni wiata, lecz same si nie zmieniaj. S one przydatne w kontekcie silnika gry, pozwalaj bowiem na wyznaczanie odlegoci, wzgldnych któw midzy obiektami oraz ich kierunków.
23
Projektowanie gier w rodowisku Unity 3.x
Kamery Kamery s niezbdne, poniewa funkcjonuj jako okno na ekranie monitora, przez które moemy obserwowa wiat trójwymiarowy. Kamery mog by umieszczane w dowolnym punkcie wiata; mog by take animowane lub przymocowane do postaci albo obiektów w zalenoci od okrelonego scenariusza gry. W danej scenie moe si znajdowa wiele kamer, lecz zakada si, e pojedyncza kamera gówna bdzie zawsze wywietla to, co widzi gracz. Dlatego te w momencie, gdy rozpoczynasz tworzenie nowej sceny, rodowisko Unity zawsze udostpnia obiekt Main Camera (kamera gówna).
24
Rozdzia 1. • Odkryj trzeci wymiar
Model projekcji — 3D kontra 2D Model projekcji dla kamery definiuje, czy obraz jest generowany w trzech (w perspektywie) lub dwóch wymiarach (w rzucie prostoktnym). Zazwyczaj kamery maj wybrany tryb projekcji perspektywicznej, co powoduje, e ich pole widzenia (ang. Field of View, w skrócie FOV) ma ksztat piramidy. Kamera w trybie projekcji perspektywicznej generuje obraz w trzech wymiarach. Jest to domylny tryb dziaania w rodowisku Unity. Kamery mog wykorzystywa take tryb projekcji prostoktnej, aby tworzy obraz w dwóch wymiarach. W tym przypadku ich pole widzenia ma ksztat prostokta. Ten tryb moe by uywany przez kamer gówn w celu tworzenia gier dwuwymiarowych lub stosowany przez dodatkow kamer, aby prezentowa na wywietlaczu póprzezroczystym (ang. Head Up Display, w skrócie HUD) takie elementy, jak mapa czy wskanik zdrowia. W silnikach gier bdziesz móg zauway , e efekty, jak owietlenie czy rozmycie ruchu, s stosowane w kamerze, aby poprawi symulacj wygldu wiata z punktu widzenia gracza. Moesz równie dodawa pewne efekty kinowe, których ludzkie oko nigdy nie zobaczy, jak odbicie wiata w soczewkach podczas spogldania na soce! Wikszo nowoczesnych gier trójwymiarowych wykorzystuje wiele kamer w celu prezentacji fragmentów wiata gry, których nie wywietla kamera gracza. Tworz one efekt „przebitek”, jak mogliby to okreli filmowcy. rodowisko Unity udostpnia z atwoci tak opcj dziki umieszczeniu w jednej scenie wielu kamer, które mog by odpowiednio obsugiwane przez skrypty, by wystpowa w roli gównej kamery w dowolnym momencie w trakcie dziaania gry. Wiele kamer moe take zosta uytych w grze jako niezaleny skadnik procesu optymalizacyjnego w celu sterowania tworzeniem okrelonych elementów dwu- lub trójwymiarowych. Na przykad obiekty mog zosta przypisane do okrelonych warstw. Te z kolei mog by przetwarzane przez odpowiednie kamery majce za zadanie generowanie obrazu tylko z danych warstw. Dziki temu uzyskujemy wicej moliwoci sterowania poszczególnymi procesami renderowania pewnych elementów w grze.
Wielokty, krawdzie, wierzchoki i siatki Obiekty trójwymiarowe s na najniszym poziomie tworzone z poczonych ze sob dwuwymiarowych ksztatów zwanych wieloktami. W przypadku modeli importowanych z aplikacji modelujcej rodowisko Unity przeksztaca wszystkie wielokty na trójkty. Poprzez czenie wielu zwizanych ze sob wieloktów aplikacje modelujce 3D umoliwiaj tworzenie zoonych ksztatów znanych jako siatki. Trójkty (zwane take powierzchniami) s z kolei zbudowane z trzech poczonych ze sob krawdzi. Miejsca, w których te krawdzie si ze sob cz, s zwane punktami lub wierzchokami. Dziki posiadanej wiedzy o pooeniu wierzchoków silniki gier mog przeprowadza obliczenia wyznaczajce punkty zderzenia zwane kolizjami. Wykrywanie kolizji przy uyciu zoonego systemu wykorzystujcego komponent Mesh Collider pozwala na przykad w strzelance wyznaczy dokadne pooenie miejsca na obiekcie, w które uderzy pocisk. Oprócz tworzenia
25
Projektowanie gier w rodowisku Unity 3.x
trójwymiarowych ksztatów, które s widoczne dla gracza, siatki mog mie wiele innych zada. Na przykad mog by uywane do zdefiniowania obiektu wykorzystywanego podczas wyznaczania kolizji, który powinien by mniej zoony od waciwego przedmiotu, lecz mie w przyblieniu taki sam ksztat jak on. Dziki temu uzyskuje si popraw wydajnoci, poniewa silnik fizyczny nie musi sprawdza zoonej siatki, aby wykry kolizj. Taki przypadek jest widoczny na poniszym rysunku, pochodzcym z podrcznika szkoleniowego tworzenia samochodu w rodowisku Unity. Sam pojazd jest bardziej zoony ni odpowiadajca mu siatka kolizji.
26
Rozdzia 1. • Odkryj trzeci wymiar
Na drugim rysunku mona zauway , e poziom szczegóowoci siatki uywanej do wykrycia kolizji jest duo mniejszy ni w przypadku siatki widocznej.
Przy tworzeniu gier kluczowe dla projektanta staje si zrozumienie wanoci parametru liczby wieloktów. Liczba wieloktów jest sum wieloktów w uywanych modelach, ale czasem równie w rekwizytach czy te na caym poziomie gry (w rodowisku Unity zwanym scen). Im wiksza jest liczba wieloktów, tym wicej pracy musi powici sprzt komputerowy, by wygenerowa obiekty na ekranie. Dlatego te moemy zauway rónic w poziomie szczegóowoci midzy wczesnymi grami 3D a obecnymi. Na przykadzie gier takich jak Quake (1996) firmy id Software oraz Gears Of War (2006) firmy Epic zwró uwag na to, jak w cigu jednej dekady zmieni si ten poziom. W wyniku postpu technologicznego projektanci mog obecnie modelowa postacie i wiaty trójwymiarowe dla gier, które zawieraj duo wicej wieloktów, a dziki temu maj odpowiednio lepszy poziom realizmu. Ta tendencja bdzie aktualna równie w kolejnych latach. Poniewa coraz wicej platform staje si mobilnych i sieciowych, gry dostpne kiedy na dedykowane konsole mog dziki rodowisku Unity by teraz uruchamianie w przegldarce internetowej. W tym przypadku ograniczenia sprztowe s obecnie równie wane jak kiedy, poniewa sprzt z niszej póki, taki jak telefony komórkowe i tablety, staje si zdolny do uruchamiania gier trójwymiarowych. Z tego powodu podczas modelowania dowolnego obiektu dla tworzonej gry powiniene bra pod uwag jego szczegóowo oraz obszary, w których jest ona najbardziej wymagana.
27
Projektowanie gier w rodowisku Unity 3.x
Materiay, tekstury i procedury cieniowania Materiay s powszechnie uywanym pojciem we wszystkich aplikacjach 3D, poniewa umoliwiaj zdefiniowanie wizualnego wygldu trójwymiarowego modelu. Materiay mog przyjmowa dowoln posta — od podstawowych kolorów do odbijajcych powierzchni wykorzystujcych obrazy. Rozpocznijmy od zwykego koloru oraz moliwoci uycia jednego obrazu zwanego tekstur lub wikszej ich liczby. Pojedynczy materia wspópracuje z procedur cieniowania, która jest skryptem definiujcym sposób jego renderowania. Na przykad w czasie procedury cieniowania odbijajcego na materiale zostan utworzone odbicia otaczajcych go obiektów, lecz zachowa on swój kolor lub wygld obrazu uytego jako tekstura. Uycie materiaów w rodowisku Unity jest prost czynnoci. Dowolne materiay stworzone w uywanym przez Ciebie pakiecie modelowania trójwymiarowego zostan zaimportowane i automatycznie odtworzone przez silnik, a nastpnie przeksztacone na zasoby, które mog by wielokrotnie wykorzystywane. Moesz take tworzy wasne materiay od samego pocztku, przypisujc obrazy do tekstur i wybierajc odpowiedni procedur cieniowania z obszernej biblioteki, która jest dostarczana razem z programem. Istnieje równie moliwo napisania wasnych skryptów cieniowania lub skopiowania i wklejenia tych, które zostay stworzone przez projektantów w ramach spoecznoci Unity. Dziki temu uzyskujesz wiksz swobod dziaania, przekraczajc granice zdefiniowane przez domylny zestaw zasobów. Podczas tworzenia tekstur dla gry przy uyciu pakietu graficznego takiego jak Photoshop czy GIMP powiniene zwraca uwag na rozdzielczoci tych tekstur. Wiksze tekstury umoliwi uzyskanie wyszego poziomu szczegóowoci modeli, lecz bd trudniejsze do renderowania. Tekstury importowane do rodowiska Unity zostan odpowiednio przeskalowane do rozdzielczoci bdcej potg liczby 2. Na przykad: Q 64 piksele × 64 piksele, Q 128 pikseli × 128 pikseli, Q 256 pikseli × 256 pikseli, Q 512 pikseli × 512 pikseli, Q 1024 piksele × 1024 piksele.
Tworzenie tekstur o powyszych rozmiarach z zawartoci, która mieci si w ich obszarze, bdzie skutkowa tym, e zostan one poprawnie zaimportowane do rodowiska Unity. Oczywicie moesz równie uywa tekstur o rozmiarach, które nie s wielokrotnociami liczby 2, lecz w wikszoci przypadków s one wykorzystywane w graficznych elementach interfejsu uytkownika, o czym bdziesz móg si przekona w dalszej czci tej ksiki.
28
Rozdzia 1. • Odkryj trzeci wymiar
Fizyka bryy sztywnej Projektanci uywajcy silników gier korzystaj take z pomocy silników fizycznych, które udostpniaj dodatkowe moliwoci symulacji zachowania si obiektów gry w wiecie rzeczywistym. Silnik gry w rodowisku Unity wykorzystuje system PhysX firmy nVidia, który jest popularnym i bardzo dokadnym komercyjnym silnikiem fizycznym. W silnikach gier nie istnieje zaoenie, i obiekty powinny podlega prawom fizyki — po pierwsze dlatego, e wymagaoby to duej mocy obliczeniowej, a po drugie, e po prostu nie ma takiej potrzeby. Na przykad w grze wycigowej 3D samochody powinny by przetwarzane przez silnik fizyczny, lecz nie dotyczy to samego toru czy otaczajcych go obiektów, takich jak drzewa, ciany itp., które pozostaj nieruchome w trakcie caej rozgrywki. Z tego powodu podczas tworzenia gier w rodowisku Unity komponent fizyki bryy sztywnej jest przydzielany do kadego obiektu, który powinien pozostawa pod kontrol silnika fizycznego — w idealnym przypadku wszystkim poruszajcym si obiektom. Dziki temu silnik fizyczny obsuguje tylko obiekty w ruchu, przez co poprawia si wydajno dziaania aplikacji. Silniki fizyczne dla gier uywaj systemu dynamiki bryy sztywnej do tworzenia realistycznego ruchu. Oznacza to po prostu, e obiekty w wiecie trójwymiarowym nie s statyczne, lecz charakteryzuj si takimi parametrami, jak masa, ciar, prdko i tarcie. Poniewa moc przetwarzania sprztu i oprogramowania wzrasta, fizyka bryy sztywnej znajduje coraz szersze zastosowanie w grach, gdy pozwala uzyska bardziej urozmaicon i realistyczn symulacj. Dynamik bryy sztywnej bdziemy wykorzystywa jeszcze w tym rozdziale podczas tworzenia prototypu, a take w gównej grze w rozdziale 7. zatytuowanym „Konkretyzowanie obiektów i bryy sztywne”.
Wykrywanie kolizji Wykrywanie kolizji jest w silnikach gier zagadnieniem waniejszym od animacji trójwymiarowej. Jest to metoda analizy naszego wiata 3D pod ktem detekcji kolizji zachodzcych midzy obiektami. Poprzez przypisanie obiektowi komponentu zderzacza tworzymy w rzeczywistoci wokó niego niewidzialn sie . Zazwyczaj odzwierciedla ona jego ksztat i wykrywa dowolne kolizje z innymi zderzaczami, co powoduje, e silnik gry odpowiednio na nie reaguje. W rodowisku Unity istniej dwa zasadnicze rodzaje zderzaczy (ang. collider): podstawowe (ang. primitives) i siatkowe (ang. meshes). Ksztaty podstawowe w rodowisku 3D s prostymi geometrycznymi obiektami, takimi jak skrzynki (ang. box), kule (ang. sphere) i kapsuy (ang. capsule). Wynika std, e prosty zderzacz, na przykad typu skrzynkowego, ma w rodowisku Unity taki wanie ksztat bez wzgldu na to, jak wyglda rzeczywisty obiekt 3D, któremu zosta on przypisany. Podstawowe zderzacze s czsto wykorzystywane, poniewa atwiej je przetworzy . Uywa si ich take w przypadkach, gdy nie zachodzi potrzeba uzyskania duej dokadnoci dziaania. Zderzacz siatkowy jest bardziej kosztowny, wykorzystuje bowiem ksztat obiektu, do którego zosta przypisany. Wynika std, e im bardziej zoona jest siatka, tym bardziej
29
Projektowanie gier w rodowisku Unity 3.x
szczegóowy i dokadny bdzie zderzacz, ale równoczenie stanie si on trudniejszy do przetworzenia. Jak zaprezentowano we wczeniejszym przykadzie dotyczcym tworzenia samochodu, mona jednake utworzy mniej zoon siatk ni ta, która bdzie renderowana, aby uzyska prostszy i bardziej wydajny zderzacz siatkowy. Na poniszym rysunku przedstawiono róne typy i podtypy zderzaczy:
Na przykad w grze w krgle prosty zderzacz kulisty bdzie otacza kul, natomiast same krgle bd wykorzystywa prosty zderzacz kapsuowy lub (w celu uzyskania bardziej realistycznej kolizji) zderzacz siatkowy, którego ksztat bdzie odpowiada trójwymiarowej siatce krgla. Podczas uderzenia zderzacze biorcych w nim udzia obiektów poinformuj o tym zdarzeniu silnik fizyczny, który wygeneruje odpowiedni reakcj opart na kierunku uderzenia, prdkoci i innych czynnikach. Zastosowanie zderzacza siatkowego, który w powyszym przypadku dokadnie odpowiadaby ksztatowi modelu krgla, byoby bardziej precyzyjne, lecz jednoczenie kosztowniejsze w sensie przetwarzania. To oznacza po prostu, e wymagaoby wikszej mocy obliczeniowej komputera, co mogoby mie wpyw na uzyskanie gorszej wydajnoci, a w zwizku z tym by kosztowne.
Podstawowe pojcia zwizane ze rodowiskiem Unity rodowisko Unity upraszcza proces tworzenia gier komputerowych przez udostpnienie szeregu logicznych etapów pozwalajcych na zbudowanie dowolnego scenariusza moliwego do wymylenia. System Unity nie jest zwizany z okrelonym typem gier i oferuje moliwo stworzenia projektu od samego pocztku dziki zestawowi spójnych procedur, co pozwala na maksymalne wykorzystanie Twojej twórczej wyobrani. Korzystajc z koncepcji obiektu gry, moesz podzieli projekt na atwo zarzdzane elementy, które skadaj si z wielu pojedynczych komponentów (ang. components). Dziki udostpnieniu obiektom okrelonej funkcjonalnoci poprzez wybór komponentów moesz wci rozwija swoj gr. Komponent z kolei skada si ze zmiennych (ang. variables), które zasadniczo opisuj jego waciwoci lub zawieraj ustawienia pozwalajce nim sterowa . Dziki modyfikacji zmiennych moesz mie pen kontrol nad tym, jaki wpyw wywiera komponent na dany obiekt. Na poniszym rysunku zaprezentowano omówione przed chwil powizania:
30
Rozdzia 1. • Odkryj trzeci wymiar
Na kolejnym rysunku widzimy interfejs rodowiska Unity zawierajcy obiekt gry z komponentem owietlenia.
Teraz przyjrzymy si, w jaki sposób przedstawiona powyej metoda moe zosta uyta w prostym kontekcie rozgrywki.
Metoda Unity — przykad Jeli w grze chcielibymy wykorzystywa odbijajc si pik, musielibymy rozpocz dziaania od utworzenia kuli. Mona to szybko zrobi za pomoc odpowiedniego menu rodowiska Unity, co pozwoli na uzyskanie nowego obiektu gry (waciwego ksztatu 3D) z siatk kulist. Zostanie on automatycznie uzupeniony o komponent renderowania, co sprawi, e bdzie widoczny. Nastpnie moemy doda komponent bryy sztywnej. Dziki temu system Unity zastosuje silnik fizyczny dla danego obiektu. Komponent ten charakteryzuje si takimi waciwociami, jak masa, ciar, rozciganie, a take zdolnoci do uycia okrelonych si na obiekcie. Moe to mie miejsce zarówno w przypadku, gdy gracz wykonuje pewne dziaania, jak i podczas kolizji z innymi obiektami.
31
Projektowanie gier w rodowisku Unity 3.x
W tej chwili kula bdzie w trakcie gry spadaa na ziemi. Jak jednak spowodowa , by si od niej odbijaa? To proste! Komponent zderzacza zawiera zmienn zwan Physic Material (materia fizyczny). Jest to ustawienie uywane przez silnik fizyczny, definiujce sposób oddziaywania na powierzchnie innych obiektów. W naszym przypadku moemy wybra warto Bouncy (odbijanie) — gotowy materia fizyczny udostpniany w rodowisku Unity jako element pakietu do zaimportowania — i to wszystko! Odbijajca si pika jest gotowa zaledwie po kilku klikniciach mysz. Ta uproszczona metoda, uywana w wikszoci prostych przypadków, takich jak cho by powyszy przykad, wydaje si na pierwszy rzut oka nieciekawa. Wkrótce jednake zauwaysz, e jej uycie w bardziej zoonych zadaniach powoduje, i staj si one atwiejsze do wykonania. Poniej zaprezentowano inne kluczowe pojcia stosowane w rodowisku Unity, które powiniene pozna przed rozpoczciem jego uywania.
Zasoby Zasoby s elementami skadajcymi si na kady projekt utworzony w rodowisku Unity. Mog to by tekstury w postaci plików graficznych, modele trójwymiarowe dla siatek oraz pliki z efektami dwikowymi. W rodowisku Unity zaoono, e kady plik uywany w grze bdzie zasobem. Std te wszystkie pliki kadego folderu odpowiadajcego projektowi w rodowisku Unity s przechowywane w podrzdnym katalogu zwanym Assets (zasoby). Folder Assets jest odwzorowany w interfejsie Unity w panelu projektu (patrz podrozdzia „Interfejs” znajdujcy si w dalszej czci tego rozdziau).
Sceny Pracujc w rodowisku Unity, powiniene traktowa sceny jako pojedyncze poziomy lub obszary zawierajce treci gry. Bywa te tak, e projektanci umieszczaj ca gr (np. ukadank) w jednej scenie poprzez dynamiczne adowanie treci za pomoc kodu. Dziki zastosowaniu wielu scen bdziesz móg usprawni adowanie zasobów i oddzielnie przetestowa kad z czci gry. Nowe sceny s czsto wykorzystywane niezalenie od tej, nad któr trwaj prace projektowe, by utworzy prototyp lub przetestowa ewentualn rozgrywk. Kada otwarta scena staje si t, nad któr pracujesz, poniewa w systemie nie mona jednoczenie projektowa wikszej ich liczby. Sceny mog by modyfikowane i tworzone przy uyciu widoków Hierarchy (hierarchia) i Scene (scena).
Obiekty gry Aktywny obiekt w otwartej scenie ma nazw GameObject (obiekt gry). Pewne zasoby, pobrane z panelu Project (projekt), takie jak modele i prefabrykaty, staj si obiektami gry przez ich umieszczenie (lub „konkretyzowanie”) w biecej scenie. Inne obiekty, takie jak systemy czstek i ksztaty podstawowe, mog by umieszczane w scenie za pomoc przycisku Create (utwórz)
32
Rozdzia 1. • Odkryj trzeci wymiar
znajdujcego si w widoku Hierarchy lub przy uyciu opcji menu gównego GameObject. Wszystkie nowo tworzone obiekty gry zawieraj przynajmniej jeden skadnik — jest nim komponent Transform (transformacja). Komponent Transform przekazuje po prostu silnikowi Unity pooenie, obrót i skal obiektu. Kady z tych parametrów jest opisany za pomoc trzech wspórzdnych X, Y, Z (w przypadku skali zawieraj one rozmiary). Z kolei ten komponent moe zosta uyty w skrypcie w celu zdefiniowania pooenia, obrotu lub skali danego obiektu. Obiekty gry moesz uzupenia o nastpne komponenty, dodajc wymagane funkcjonalnoci i tworzc kolejne fragmenty gry zgodnie ze scenariuszem, jaki sobie tylko moesz wyobrazi . Na poniszym rysunku moesz zauway najbardziej podstawow posta obiektu gry, widoczn w panelu Inspector (inspektor):
Obiekty gry mog by równie zagniedone w widoku Hierarchy, co pozwala na tworzenie powiza nadrzdny – podrzdny, o których wspominalimy wczeniej.
Komponenty Komponenty przyjmuj róne postacie. Mog definiowa zachowanie obiektu poprzez okrelanie wygldu oraz wpywanie na inne aspekty jego funkcjonowania w grze. Doczanie komponentów pozwala na uywanie okrelonych skadników silnika gry w danym obiekcie. Najczciej uywane komponenty zwizane z tworzeniem gier s ju wbudowane do systemu Unity. Mona wród nich wymieni wspomniany wczeniej komponent fizyki bryy sztywnej, a take prostsze elementy, takie jak wiata, kamery, emitery czstek i wiele innych. Aby dodawa do gry kolejne interaktywne skadniki, bdziesz pisa skrypty, które równie s rozpoznawane przez rodowisko Unity jako komponenty. Potraktuj skrypt jako co, co poszerza lub modyfikuje istniejc funkcjonalno , moliw do uzyskania w Unity, albo generuje odpowiedni sposób zachowania si obiektu przy uyciu dostpnych klas skryptowych.
Skrypty Skrypty nale do komponentów rodowiska Unity. S uwaane za kluczowy skadnik wykorzystywany w procesie produkcji gier. W tej ksice bdziemy tworzy skrypty w jzykach C Sharp (czciej zapisywanym jako C#) oraz JavaScript. Powiniene by take wiadomy tego, e
33
Projektowanie gier w rodowisku Unity 3.x
Unity oferuje moliwo uycia jzyka Boo (pochodzcego od jzyka Python). Zamierzamy si jednak skoncentrowa na C# i JavaScript, poniewa s one dwoma podstawowymi jzykami stosowanymi przez uytkowników rodowiska Unity. Poza tym Boo nie mona wykorzystywa do oskryptowania urzdze przenonych. Z tego powodu nie jest on zalecany do nauki pisania skryptów w rodowisku Unity. Podczas uywania systemu Unity nie jest wymagane zrozumienie, w jaki sposób zosta zakodowany jego wasny silnik czy te jak mona go zmodyfikowa , jednake skrypty bd przez Ciebie wykorzystywane praktycznie podczas tworzenia kadego scenariusza gry. Prostota uycia skryptów w rodowisku Unity polega na tym, i kady z nich bdzie zrozumiay dla Ciebie po przeanalizowaniu zaledwie kilku przykadów. Wynika to std, e Unity zawiera wasn klas typu Behaviour o nazwie Monobehaviour. Jest to zestaw skryptowych polece, które moesz wykorzystywa . Dla wielu pocztkujcych projektantów nauka tworzenia skryptów moe by do zniechcajc perspektyw, która moe spowodowa , e uytkownicy przyzwyczajeni do projektowania mog zrezygnowa z uywania rodowiska Unity. Jeli nie masz dowiadczenia w tworzeniu gier ani programowaniu, nie martw si. Wprowadzimy Ci bardzo agodnie w zagadnienie pisania skryptów, pamitajc jednoczenie o tym, aby przedstawia nie tylko znaczenie, lecz równie si tkwic w sprawnym tworzeniu skryptów dla gier projektowanych przy uyciu rodowiska Unity. Do tworzenia skryptów bdziesz uywa oddzielnego edytora zwanego Monodevelop, który jest dostpny w rodowisku Unity. Ta niezalena aplikacja znajduje si w folderze instalacyjnym Twojego komputera typu PC lub Mac. Zostanie ona uruchomiona za kadym razem, gdy bdziesz chcia utworzy nowy skrypt lub przeprowadzi edycj istniejcego. Modyfikacja i zapamitanie skryptu za pomoc edytora spowoduj, e zostanie on natychmiast uaktualniony w rodowisku Unity. Jeli chcesz, w ustawieniach systemu moesz take wskaza wasny edytor skryptowy, taki jak Visual Studio. Zalecamy jednak uywanie aplikacji Monodevelop, poniewa oferuje ona automatyczne uzupenianie kodu, a poza tym zostaa stworzona i jest wspierana przez firm Unity Technologies.
Prefabrykaty Projektowanie w rodowisku Unity opiera si nie tylko na zastosowaniu obiektów gry, lecz równie pozwala przechowywa je w postaci zasobów moliwych do ponownego uycia w rónych czciach aplikacji. Mog by one konkretyzowane (inaczej mówic, „mnoone” lub „klonowane”) w dowolnym momencie. Poprzez tworzenie zoonych obiektów, zawierajcych róne komponenty i ustawienia, moesz sprawnie konstruowa szablon sucy do wygenerowania jego wielu egzemplarzy (std te pochodzi pojcie „konkretyzacja”), z których kady moe by nastpnie indywidualnie modyfikowany. Wemy pod uwag skrzynk — mógby zdefiniowa dla niej okrelon mas, a póniej napisa skrypty obsugujce jej niszczenie. Prawdopodobnie jednak bdziesz chcia uy tego obiektu wielokrotnie w tej samej grze, a by moe innych ni ta, dla której zosta zaprojektowany.
34
Rozdzia 1. • Odkryj trzeci wymiar
Prefabrykaty pozwalaj na przechowywanie kompletnego obiektu razem z jego komponentami i biec konfiguracj. Porównujc prefabrykaty z klas MovieClip uywan w systemie Adobe Flash, moesz je sobie wyobrazi jako puste pojemniki, które zostaj wypenione obiektami dziki utworzeniu szablonu danych do wielokrotnego wykorzystania.
Interfejs Interfejs systemu Unity, podobnie jak wielu innych rodowisk, ma ukad, który moe zosta dopasowany do potrzeb uytkownika. Poniewa skada si on z kilku zadokowanych widoków, moesz zdecydowa , które z nich powinny znajdowa si w okrelonych miejscach. Spójrzmy na typowy ukad interfejsu Unity:
Moe on zosta utworzony poprzez wybranie opcji menu gównego Window/Layouts/2 by 3 (okno/ukady/2 na 3). Jak wida na powyszym rysunku (wykonanym w wersji dla komputera typu Mac), znajduje si tam pi rónych paneli lub widoków, z których bdziesz korzysta : 1. Scene (scena) — w tym obszarze jest tworzona gra. 2. Game (gra) — okno podgldu, aktywne jedynie w trybie gry. 3. Hierarchy (hierarchia) — lista obiektów gry zawartych w scenie.
35
Projektowanie gier w rodowisku Unity 3.x
4. Project (projekt) — lista zasobów zawartych w projekcie; inaczej mówic, jest to biblioteka zasobów. 5. Inspector (inspektor) — biece ustawienia dla wybranego zasobu lub obiektu.
Widoki Scene i Hierarchy Panel Scene w rodowisku Unity umoliwia tworzenie projektu gry. Okno udostpnia widok perspektywiczny (peny 3D), który mona zmieni na rzuty paskie (z góry, boku i przodu). Obrót widoku w przypadku korzystania z rzutu paskiego pozwala na wywietlenie sceny w postaci izometrycznej. Panel Scene moe by uwaany za w peni renderowany widok „edycji” gry, któr tworzysz. Przeciganie zasobu do tego okna (lub widoku Hierarchy) spowoduje powstanie jego konkretyzacji w postaci obiektu gry. Widok Scene jest zwizany z panelem Hierarchy, który zawiera list (posortowan w rosncym porzdku alfabetycznym) wszystkich obiektów gry nalecych do biecej sceny.
Narzdzia sterujce Z oknem Scene s zwizane cztery przydatne narzdzia sterujce, które zaprezentowano na poniszym rysunku.
S one dostpne za pomoc skrótów klawiaturowych Q, W, E oraz R i oferuj nastpujce funkcje: Q Narzdzie Hand (rka) (klawisz Q): To narzdzie pozwala na poruszanie si po oknie
Scene. Po naciniciu lewego przycisku myszy, a nastpnie jej przemieszczeniu, umoliwia zmian widoku prezentowanego w panelu Scene. Przytrzymanie klawisza Alt przy jednoczesnym wybraniu narzdzia Hand i naciniciu lewego przycisku myszy pozwala na obracanie widoku wokó punktu centralnego, na który spogldasz. Z drugiej strony, naciskajc prawy klawisz myszy, uzyskujemy moliwo przybliania i oddalania widoku, podobnie jak w przypadku obracania kókiem myszy. Nacinicie klawisza Shift przyspiesza wykonywanie powyszych dwóch operacji. Q Narzdzie Translate (translacja) (klawisz W): Jest to Twoje aktywne narzdzie selekcji.
Dziki temu, e masz moliwo penej interakcji z oknem Scene, wybieranie obiektów w nim, a take w panelu Hierarchy oznacza, i potrafisz zaznaczy i „chwyci ” obiekt w celu jego przemieszczenia. Q Narzdzie Rotate (obrót) (klawisz E): Dziaa ono podobnie jak narzdzie Translate,
wykorzystujc widoczne „uchwyty”, pozwalajce na obracanie obiektu wokó kadej osi.
36
Rozdzia 1. • Odkryj trzeci wymiar
Q Narzdzie Scale (skala) (klawisz R): Równie jego funkcjonalno jest podobna do
dziaania narzdzi Translate i Rotate. Pozwala ono na zmian rozmiaru lub skalowanie obiektu przy uyciu widocznych uchwytów. Po wybraniu obiektów w jednym z paneli Scene lub Hierarchy zostan one automatycznie zaznaczone w drugim panelu. Pozwala to na wywietlenie waciwoci obiektu w oknie Inspector. Jeli w oknie Scene nie jeste w stanie zobaczy obiektu, który zosta wybrany w panelu Hierarchy, moesz nacisn klawisz F, co spowoduje, e obiekt zostanie umieszczony na rodku okna. Po prostu zaznacz obiekt w panelu Hierarchy, przemie kursor myszy nad okno Scene, a nastpnie nacinij klawisz F. Taki sam rezultat moesz osign poprzez dwukrotne kliknicie nazwy obiektu gry w panelu Hierarchy.
Poruszanie si po oknie Scene w trybie Flythrough Aby porusza si po oknie Scene za pomoc myszy i klawiszy, moesz uy trybu Flythrough (inspekcja dynamiczna). Po prostu przytrzymaj nacinity lewy klawisz myszy, a nastpnie zacznij ni porusza , dziki czemu uzyskasz widok z perspektywy pierwszej osoby. Moesz take wykorzysta klawisze W, A, S i D, by przesuwa obiekty, natomiast Q i E, eby je podnosi i obnia .
Pasek sterujcy Oprócz samych narzdzi sterujcych jest dostpny take pasek zawierajcy dodatkowe opcje, które wspieraj Ci podczas pracy ze scenami w rodowisku Unity. Zosta on przedstawiony na poniszym rysunku:
Jest to pasek sterujcy dla widoku sceny, który zawiera nastpujce opcje (od lewej do prawej): Q Tryb rysowania — domylnie jest wybrana opcja Textured (z teksturami). Q Tryb renderowania — domylnie jest wybrana opcja RGB. Q Wczanie i wyczanie owietlenia sceny. Q Wczanie i wyczanie nakadek — pokazuje i ukrywa elementy graficznego interfejsu
uytkownika (GUI) oraz opcj skybox, a take siatk trójwymiarow. Q Wczanie i wyczanie trybu odsuchiwania — pozwala na odsuchiwanie róde dwiku znajdujcych si w biecej scenie. Q Gizmos (gadety) — uyj tego menu rozwijanego, aby wywietli lub ukry gadety,
czyli dwuwymiarowe ikony reprezentujce kamery, róda wiate i inne komponenty znajdujce si w biecej scenie.
37
Projektowanie gier w rodowisku Unity 3.x
Pole wyszukiwania Mimo e widok Scene jest wewntrznie zwizany z panelem Hierarchy, czsto moesz mie potrzeb znalezienia jakiego elementu lub jego typu poprzez przeprowadzenie operacji wyszukiwania. W tym przypadku po prostu wprowad nazw obiektu lub jego typ danych (inaczej mówic, nazw przypisanego komponentu) w polu wyszukiwania, co spowoduje, e wszystkie inne obiekty w widoku Scene zostan wywietlone w kolorze szarym, aby uwydatni ten, który chciae znale . Jest to bardzo przydatna operacja podczas pracy ze zoonymi scenami i powinna by uywana w powizaniu z klawiszem F, który aktywuje podwietlony obiekt w oknie Scene.
Przycisk Create Poniewa wiele zasobów gry, których bdziesz uywa w rodowisku Unity, zostanie zbudowanych w samym edytorze, panel Hierarchy zawiera przycisk Create (stwórz) pozwalajcy na tworzenie obiektów. Opcje z nim zwizane s take dostpne w menu GameObject. Dziaaj podobnie jak przycisk Create, umoliwiajc utworzenie obiektu i jego natychmiastowe zaznaczenie. Dziki temu moesz przydzieli mu inn nazw lub rozpocz edycj w panelach Scene albo Inspector.
Panel Inspector Przyjmij, e panel Inspector (inspektor) jest czym w rodzaju Twojego osobistego zestawu narzdzi, dziki któremu moesz modyfikowa kady parametr obiektu gry lub zasobu w Twoim projekcie. Ma on podobn zasad dziaania do rozwizania Property Inspector, stosowanego przez firm Adobe w produktach Flash i Dreamweaver, które polega na uyciu okna o zawartoci zalenej od biecego kontekstu. Oznacza to po prostu, e panel Inspector bdzie wywietla waciwoci wybranego przez Ciebie obiektu. Analizuje on kontekst tego, nad czym obecnie pracujesz. Widok Inspector bdzie prezentowa wszystkie komponenty, nalece do dowolnego obiektu wybranego przez Ciebie, i pozwoli na modyfikacje ich zmiennych przy uyciu prostych kontrolek, takich jak pola edycji, suwaki, przyciski i rozwijane menu. Wiele tych zmiennych jest zwizanych z systemem przecigania i upuszczania, stosowanym w rodowisku Unity. Oznacza to, e zamiast wskazywa wartoci z menu rozwijanego, atwiej bdzie przecign i upuci zmienn w celu wybrania odpowiedniego ustawienia lub przypisania jej okrelonej waciwoci. Okno Inspector nie suy jedynie do inspekcji obiektów. Umoliwia równie wprowadzanie zmian, by prezentowa róne opcje dostpne dla Twojego projektu podczas wybierania ich z menu Edit (edycja). Jest ono take idealnym miejscem pozwalajcym na wywietlanie waciwoci komponentu, gdy tylko zostanie wybrany okrelony obiekt lub zasób.
38
Rozdzia 1. • Odkryj trzeci wymiar
Na powyszym rysunku widzimy panel Inspector prezentujcy waciwoci obiektu target zawartego w projekcie gry. Obiekt ten skada si z dwóch komponentów: Transform (transformacja) i Animation (animacja). Okno Inspector pozwoli na modyfikacj ich ustawie. Zauwa, e w celu tymczasowego zablokowania dowolnego z komponentów, co stanie si bardzo przydatne w trakcie testowania i eksperymentowania, moesz po prostu odznaczy pole wyboru znajdujce si po lewej stronie jego nazwy. Podobnie te, jeli chciaby wyczy cay obiekt, moesz odznaczy pole wyboru wywietlone obok jego nazwy na samej górze okna Inspector.
Okno Project Okno Project (projekt) jest bezporednim widokiem folderu Assets Twojego projektu. Kady projekt tworzony w rodowisku Unity skada si z folderu nadrzdnego, zawierajcego trzy podfoldery: Assets (zasoby), Library (biblioteka) oraz — w czasie, gdy jest aktywny edytor Unity — folder Temp (tymczasowy). Umieszczenie zasobów w folderze Assets oznacza, e bdziesz móg je od razu zobaczy w oknie Project i zostan one automatycznie zaimportowane do Twojego projektu Unity. Podobnie te, w przypadku zmiany dowolnego zasobu umieszczonego w folderze Assets i zapisania go z poziomu innej aplikacji, takiej jak Photoshop, rodowisko Unity raz jeszcze dokona jego importu, natychmiast uwzgldniajc wprowadzone zmiany w projekcie oraz aktywnych scenach, które go wykorzystuj. Zarzdzanie zasobami Powiniene pamita, e moesz zmienia nazwy i pooenie zasobów, uywajc w tym celu jedynie okna Project. Wykorzystanie do tego aplikacji Finder (Mac) lub Eksploratora Windows (PC) moe uszkodzi odpowiednie poczenia z Twoim projektem Unity. Aby wic przemieszcza lub zmienia nazwy obiektów w folderze Assets, zamiast systemu operacyjnego uywaj okna Project, dostpnego w rodowisku Unity.
39
Projektowanie gier w rodowisku Unity 3.x
Okno Project, podobnie jak Hierarchy, zawiera przycisk Create. Pozwala on na tworzenie dowolnych zasobów w rodowisku Unity, takich jak skrypty, prefabrykaty czy materiay.
Widok Game Widok Game (gra) jest aktywowany poprzez nacinicie przycisku Play (granie) i pozwala na wykonanie realistycznego testu Twojej gry. Zawiera on take ustawienia umoliwiajce zdefiniowanie wspóczynnika proporcji ekranu. Ta opcja jest przydatna podczas sprawdzania, czy widok prezentowany graczowi bdzie ograniczony w porównaniu z ekranem panoramicznym, na przykad dla wspóczynnika proporcji równego 4:3. Po naciniciu przycisku Play powiniene zawsze pamita o poniszej wskazówce: Tryb grania — wycznie do testowania! W trybie grania dowolne modyfikacje gry wprowadzone przez Ciebie s jedynie tymczasowe. Oznacza to, e powinien on by trybem stosowanym wycznie do testowania. Ponowne nacinicie przycisku Play w celu zatrzymania gry spowoduje, i zmiany wprowadzone w aktywnych obiektach gry zostan wycofane. Takie zachowanie moe czasami dziwi pocztkujcych uytkowników, dlatego nie zapomnij o tej wskazówce!
Poprzez wczenie opcji Maximize on Play (powikszenie przy graniu) widok Game moe zosta powikszony w trakcie rozpoczynania trybu grania, dziki czemu uzyskujesz lepszy widok gry zajmujcej obszar równy prawie caemu ekranowi. Okno zostaje poszerzone do rozmiaru caego interfejsu rodowiska Unity. Mona take powiksza obszar kadego panelu, umieszczajc nad nim mysz, a nastpnie naciskajc klawisz spacji. Oprócz przycisku Play, który suy do uruchomienia cigego trybu testowania, moesz wykorzysta przycisk Pause (zatrzymanie) znajdujcy si obok niego. Jego uycie spowoduje zatrzymanie gry. Do chwilowego uruchomienia aplikacji suy wówczas trzeci przycisk Advance Frame (chwilowe uruchomienie), znajdujcy si obok przycisku Pause. Jest on przydatny podczas uruchamiania gry w celu wyszukiwania i rozwizywania problemów lub bdów zawartych w Twojej aplikacji.
Podsumowanie W tym rozdziale zapoznae si z gównymi koncepcjami niezbdnymi do zrozumienia i wykonania wicze zawartych w tej ksice. Grafika trójwymiarowa jest jednak bardzo zoonym przedmiotem, którego bdziesz si uczy nie tylko podczas korzystania ze rodowiska Unity, ale równie przy innych okazjach. Wynika std, e w celu uzupenienia wiedzy zwizanej z projektowaniem gier trójwymiarowych powiniene dokadniej pozna zagadnienia przedstawione w tym rozdziale. Kady rodzaj oprogramowania uywanego przez Ciebie bdzie udo-
40
Rozdzia 1. • Odkryj trzeci wymiar
stpnia wasne poradniki i zasoby przeznaczone do szkolenia. Jeli zamierzasz nauczy si tworzenia grafiki trójwymiarowej, aby uzupeni swoj wiedz zwizan ze rodowiskiem Unity, powiniene dokadnie przeanalizowa list narzdzi wspópracujcych z nim, a nastpnie wybra to, które Ci najbardziej odpowiada. Po krótkim przegldzie koncepcji zwizanych z grafik 3D oraz zapoznaniu si z procesami wykorzystywanymi przez rodowisko Unity w celu tworzenia gier moesz wykona prostsze wiczenie, zanim rozpoczniesz tworzenie bardziej zaawansowanej gry przedstawionej w tej ksice. W nastpnym rozdziale zaprezentujemy wiczenie, w którym bdziesz tworzy prototyp prostej mechaniki gry przy uyciu ksztatów podstawowych, wygenerowanych przez sam silnik. Zaczniesz take kodowa , aby zapozna si z jzykami C# i JavaScript. Wane jest, aby rozpocz nauk obsugi rodowiska Unity, wykorzystujc w tym celu prosty przykad i ksztaty podstawowe, poniewa w przyszoci w taki wanie sposób bdziesz czsto tworzy prototypy swoich pomysów zwizanych z grami. Wystarczy, e opanujesz obsug systemu Unity i poczujesz si w nim bardziej komfortowo. Nastpnie zajmiemy si bardziej powanym przykadem. Przyjrzymy si rodowiskom gry i zapoznamy si z dziaaniem edytora powierzchni. Dziki zastosowaniu metody interakcyjnego definiowania wysokoci terenu edytor powierzchni jest prostym w uyciu narzdziem, pozwalajcym na projektowanie gier wykorzystujcych rodowiska zewntrzne. Uyjemy go do zbudowania wyspy, któr w kolejnych rozdziaach uzupenimy o dodatkowe opcje, tworzc w rezultacie niewielk gr. Jej celem bdzie rozpalenie przez gracza ogniska zapakami wyniesionymi z zamknitego posterunku. Rozpocznijmy wic nasze dziaania!
41
Projektowanie gier w rodowisku Unity 3.x
42
2 Podstawy tworzenia prototypów i skryptów Jedn z najlepszych metod zdobywania wiedzy i dowiadczenia podczas stawiania pierwszych kroków w dziedzinie projektowania gier jest tworzenie prototypów wasnych pomysów. rodowisko Unity przoduje w tym zagadnieniu, udostpniajc wizualny edytor sceny oraz publiczne zmienne skadowe, które widniej na panelu Inspector (inspektor) w postaci odpowiednich ustawie. Zapoznanie si z dziaaniem edytora Unity rozpoczniemy od wygenerowania prototypu prostej mechaniki gry, wykorzystujc w tym celu ksztaty podstawowe oraz tworzenie elementarnych skryptów. W tym rozdziale zostan przedstawione nastpujce zagadnienia: Q tworzenie nowego projektu w rodowisku Unity, Q importowanie pakietów z zasobami, Q praca z obiektami gry w widokach Scene (scena) i Hierarchy (hierarchia), Q dodawanie materiaów, Q tworzenie skryptów w jzykach C Sharp (C#) oraz JavaScript, Q zmienne, funkcje i polecenia, Q uycie polecenia Translate() w celu przemieszczenia obiektów, Q uycie prefabrykatów do przechowywania obiektów, Q uycie polecenia Instantiate() w celu konkretyzacji obiektów.
Projektowanie gier w rodowisku Unity 3.x
Twój pierwszy projekt w rodowisku Unity rodowisko Unity jest oferowane w dwóch wersjach: standardowej (darmowej) oraz patnej (licencjonowanej) dla profesjonalnych projektantów. W niniejszej ksice bdziemy omawia opcje, do których maj dostp uytkownicy wersji darmowej. Jeli uruchomisz rodowisko Unity po raz pierwszy, zostanie do niego wczytany przykadowy projekt. Zapoznawanie si z najlepszymi wzorami, stosowanymi w najwyszej jakoci projektach, jest bardzo przydatne. Jednake w przypadku pocztkujcych uytkowników przegldanie profesjonalnie utworzonych zasobów i skryptów mogoby by deprymujce, dlatego te pominiemy projekt przykadowy i rozpoczniemy prace od samego pocztku! W menu gównym rodowiska Unity wybierz opcj File/New Project (plik/nowy projekt), co spowoduje wywietlenie okna dialogowego Project Wizard (kreator projektu — na poniszym rysunku przedstawiono wersj dla komputera typu Mac). Kliknij zakadk Create new Project (stwórz nowy projekt). Uwaga Jeli chciaby, by za kadym razem po uruchomieniu rodowiska Unity okno dialogowe Project Wizard byo automatycznie wywietlane, powiniene wywoywa aplikacj z nacinitym klawiszem Alt (Mac i PC). Taki sposób dziaania mona równie skonfigurowa w opcji menu File/Preferences (plik/ustawienia).
44
Rozdzia 2. • Podstawy tworzenia prototypów i skryptów
Kliknij przycisk Set1 (umie ), aby zdefiniowa lokalizacj folderu dla nowego projektu Unity. W niniejszej ksice zosta on nazwany UGDE i umieszczony na pulpicie, by mie do niego atwy dostp. Kreator projektu pozwala take na zaimportowanie wielu pakietów z zasobami, które s udostpnione za darmo przez firm Unity Technologies. Zawieraj one zoone skrypty, gotowe obiekty i inne elementy graficzne, które s przydatne podczas rozpoczynania pracy z rónymi rodzajami projektów. Te pakiety moesz take zaimportowa w kadej chwili, wybierajc opcj menu Assets/Import Package (zasoby/import pakietu), a nastpnie odpowiedni pozycj z dostpnej listy. Wybierajc opcj Assets/Import Package/Custom Package (zasoby/import pakietu/pakiet uytkownika), mógby równie zaimportowa pakiet znajdujcy si w dowolnej lokalizacji na Twoim dysku twardym. Taka funkcjonalno pozwala wspódzieli zasoby z innymi uytkownikami oraz umoliwia instalacj pakietów, które uzyskae poprzez wybranie opcji Window/Asset Store (okno/sklep z zasobami). Z listy pakietów, które mona zaimportowa , wybierz nastpujce (jak zaprezentowano na powyszym rysunku): Q Character Controller (kontroler postaci), Q Skyboxes (skybox — symulacja nieba i horyzontu), Q Terrain Assets (zasoby terenu), Q Water (Basic) (woda — wersja podstawowa).
Po zaznaczeniu pakietów kliknij przycisk Create Project (stwórz projekt), znajdujcy si w dolnej czci okna dialogowego. Spowoduje to rozpoczcie procesu tworzenia nowego projektu, podczas którego bdziesz móg obserwowa paski postpu, reprezentujce import poszczególnych pakietów.
Podstawowe rodowisko prototypowe Aby stworzy proste rodowisko, w którym zostanie wygenerowany prototyp okrelonej mechaniki gry, dziaania powinnimy rozpocz od zdefiniowania podstawowej listy obiektów — zostanie im przypisana funkcjonalno pozwalajca graczowi celowa i strzela do ciany skadajcej si z prostych szecianów. Po zakoczeniu pracy rodowisko prototypowe bdzie si skada z powierzchni zbudowanej z prostych szecianów, kamery pozwalajcej na obserwowanie wiata gry w trzech wymiarach oraz róda wiata punktowego, umoliwiajcego podwietlenie obszaru, w którym bdzie si toczy akcja gry. Wygenerowany wiat powinien wyglda tak jak na poniszym rysunku:
1
W wersji dla PC przycisk nazywa si Browse (przegldaj) — przyp. tum.
45
Projektowanie gier w rodowisku Unity 3.x
Definiowanie sceny Poniewa kada nowa scena zawiera domylnie obiekt Main Camera (gówna kamera), dziaania rozpoczniemy od utworzenia powierzchni dla rodowiska prototypowego. W panelu Hierarchy (hierarchia) kliknij przycisk Create (stwórz), a nastpnie z rozwijanego menu wybierz opcj Cube (szecian). Elementy znajdujce si na licie s take dostpne w opcji GameObject/Create Other (obiekt gry/stwórz inny) menu gównego aplikacji. Obecnie moesz zauway obiekt o nazwie Cube, znajdujcy si w panelu Hierarchy. Wybierz go, a póniej nacinij klawisz F2 (PC) lub Return (Mac) albo dwukrotnie z opónieniem kliknij nazw obiektu, eby j zmieni . Wprowad sowo Floor (powierzchnia), a nastpnie nacinij klawisz Enter (PC) lub Return (Mac), by zatwierdzi wprowadzenie zmian. Ze wzgldu na konieczno zapewnienia zgodnoci rozpoczniemy tworzenie obiektów w punkcie zerowym wiata, czyli centrum trójwymiarowego rodowiska, w którym pracujemy. Aby upewni si, e szecian bdcy powierzchni zosta umieszczony dokadnie w tym miejscu, sprawd, czy w dalszym cigu jest wybrany w panelu Hierarchy. Nastpnie zaznacz komponent Transform na panelu Inspector (inspektor) i zwró uwag na to, czy wszystkie wartoci wspórzdnych X, Y i Z s równe zeru. Jeli tak nie jest, wprowad zera w odpowiednich polach edycji lub kliknij ikon w ksztacie kóka zbatego, a potem wybierz z menu podrcznego opcj Reset Position (wyzeruj pooenie). W dalszej kolejnoci powinnimy przeksztaci szecian na powierzchni, odpowiednio powikszajc go w osi X i Y. W komponencie Transform przejd do grupy Scale (skala), a nastpnie w polach edycji X i Z wprowad wartoci 100, pozostawiajc pole Y równe 1.
46
Rozdzia 2. • Podstawy tworzenia prototypów i skryptów
Dodawanie prostego owietlenia Postaramy si teraz owietli obszar powierzchni prototypowej poprzez dodanie róda wiata punktowego. Kliknij przycisk Create w panelu Hierarchy (lub wybierz opcj menu gównego GameObject/Create Other), a nastpnie wybierz pozycj Point Light (wiato punktowe). Umie ródo wiata w pooeniu (0, 20, 0), uywajc w tym celu odpowiednich wartoci Position (pozycja) zawartych w komponencie Transform, dziki czemu bdzie si ono znajdowa 20 jednostek nad powierzchni. Jak zapewne zauwaye, oznacza to, e wiato nie dociera do caej powierzchni. Przecignij wic óty punkt, który znajduje si na przeciciu linii tworzcych zarys wiata punktowego w widoku Scene, by uzyska warto parametru Range (zasig) równ 40. Parametr ten jest elementem komponentu Light (wiato) dostpnego w widoku Inspector. Wykonane przez Ciebie dziaanie spowoduje, e na obiekcie tworzcym powierzchni pojawi si lekka powiata.
47
Projektowanie gier w rodowisku Unity 3.x
Wskazówka Pamitaj, e wikszo komponentów jest powizana z odpowiednimi narzdziami, sucymi do wizualnej edycji i znajdujcymi si w widoku Scene. Modyfikacja wartoci takich jak Range w komponencie Light, dostpnym w panelu Inspector, spowoduje uaktualnienie wygldu obiektu w widoku Scene w trakcie wprowadzania zmian. Zostan one zatwierdzone po naciniciu klawisza Return (Enter).
Kolejna cega w cianie Utworzymy cian zoon z szecianów, która bdzie celem dla pocisków. Najpierw utworzymy pierwsz ceg, uzupenion w razie koniecznoci o komponenty, a nastpnie powielimy j w tylu egzemplarzach, a bdziemy dysponowali gotow cian.
Tworzenie wzorcowej cegy Aby uzyska szablon, pozwalajcy na wygenerowanie wszystkich cegie, musimy utworzy wzorcowy obiekt, który bdzie mona póniej klonowa . Procedura jest nastpujca: 1. Kliknij przycisk Create, znajdujcy si w górnym obszarze panelu Hierarchy, a nastpnie wybierz opcj Cube. Uywajc wartoci Position w komponencie Transform, umie obiekt w pooeniu (0, 1, 0). Upewnij si, czy wci jest wybrany w panelu Hierarchy, a nastpnie przybli jego widok przez przemieszczenie kursora myszy nad okno Scene i nacinicie klawisza F. 2. Uzupenij obiekt Cube o parametry fizyczne, wybierajc opcj menu gównego Component/Physics/Rigidbody (komponent/parametry fizyczne/brya sztywna). Oznacza to, e Twój obiekt bdzie od tej pory bry sztywn, charakteryzujc si takimi parametrami, jak masa czy ciar. Moe take oddziaywa na inne obiekty dziki wykorzystaniu silnika fizycznego w celu uzyskania realistycznych wyników w wiecie 3D. 3. Wreszcie stwórzmy kolor dla obiektu poprzez wygenerowanie odpowiedniego materiau. Materiay su do uzupeniania obiektów trójwymiarowych o kolor i tekstur. Aby utworzy nowy materia, kliknij przycisk Create, znajdujcy si w panelu Project, a nastpnie z menu rozwijanego wybierz opcj Material (materia). Nacinij klawisz F2 (PC) lub Return (Mac), aby zmieni jego domyln nazw New Material (nowy materia) na Red (czerwony). 4. Gdy materia zostanie wybrany, jego waciwoci s wywietlane w panelu Inspector. Kliknij pole koloru (1), znajdujce si po prawej stronie etykiety Main Color (gówny kolor), aby otworzy okno dialogowe Color Picker (wybór koloru) (2). Bdzie ono róni si wygldem w zalenoci od tego, czy uywasz komputera typu Mac lub PC. Po prostu wybierz jaki odcie koloru czerwonego, a nastpnie zamknij okno. Pole koloru Main Color powinno zosta odpowiednio zaktualizowane.
48
Rozdzia 2. • Podstawy tworzenia prototypów i skryptów
5. Aby uy stworzonego materiau, przecignij go z panelu Project i upu na szecian znajdujcy si w widoku Scene lub nazw obiektu w oknie Hierarchy. Materia zostanie uyty w komponencie Mesh Renderer (renderer siatki) dla danego obiektu oraz natychmiast zaprezentowany innym jego komponentom w panelu Inspector. Najwaniejsze jest jednak to, e Twój szecian powinien by teraz czerwony! Modyfikacja parametrów materiau przy uyciu opcji Preview (podgld), zastosowanej do dowolnego obiektu, spowoduje wprowadzenie rzeczywistych zmian tylko w oryginalnym elemencie, poniewa poprzez t operacj odwoujemy si do waciwego zasobu, a nie do nowo utworzonej instancji. 6. Poniewa szecian ma ju kolor i waciwoci fizyczne, wynikajce z uycia komponentu Rigidbody (brya sztywna), moe zosta sklonowany i utworzy cian zoon z cegie. Zanim jednak tego dokonamy, przyjrzyjmy si przez chwil prawom fizycznym dziaajcym w przestrzeni 3D. Upewnij si, e szecian zosta wybrany, a nastpnie przypisz parametrowi Y Position (pooenie Y) warto 15, za X Rotation (rotacja X) warto 40. Obie te waciwoci nale do komponentu Transform w widoku Inspector. Nacinij przycisk Play (lub skrót klawiszowy Ctrl+P dla PC albo Command+P dla komputerów Mac), znajdujcy si w górnej czci interfejsu Unity. Powiniene zobaczy spadajcy szecian, który pod ktem uderza o powierzchni i po wykonaniu póobrotu zatrzymuje si.
49
Projektowanie gier w rodowisku Unity 3.x
7. Nacinij przycisk Play ponownie, aby zatrzyma symulacj. Nie naciskaj przycisku Pause, poniewa spowodowaoby to tylko tymczasowe zatrzymanie animacji, natomiast póniejsze zmiany w scenie nie zostayby zapamitane. 8. Przywró poprzednie ustawienia dla szecianu: parametrowi Y Position przypisz warto 1, a X Rotation — warto 0. Sprawdzie, e cega zostaa poprawnie zdefiniowana i dziaa zgodnie z oczekiwaniami. Moesz wic rozpocz tworzenie rzdu cegie, z których bdzie si skada nasza ciana.
I pstryk! Mamy rzd Aby uatwi rozmieszczanie obiektów, rodowisko Unity pozwala na uycie opcji przycigania. Parametry opcji przycigania mog by modyfikowane w opcji menu Edit/Snap Settings (edycja/ustawienia opcji przycigania). Aby zastosowa opcj przycigania, przytrzymaj nacinity klawisz Control (PC) lub Command (Mac) podczas uywania narzdzia Translate (W) w celu rozmieszczenia obiektów w widoku Scene. By rozpocz budow ciany, przy uyciu skrótu klawiszowego Ctrl+D (PC) lub Command+D (Mac) skopiuj obiekt cegy, którym ju dysponujemy. Nastpnie przecignij go, chwytajc za uchwyt czerwonej osi i jednoczenie trzymajc wcinity klawisz Control (PC) lub Command (Mac). Dziki temu obiekt bdzie si przemieszcza skokowo po siatce przycigania. Przesuwaj ceg w osi X, a znajdzie si w bezporednim ssiedztwie innej, tak jak przedstawiono na poniszym rysunku:
50
Rozdzia 2. • Podstawy tworzenia prototypów i skryptów
Powtarzaj procedur kopiowania i rozmieszczania przy uyciu siatki przycigania a do momentu, gdy bdziesz dysponowa rzdem dziesiciu cegie. Aby przyspieszy tworzenie konstrukcji, umiecimy go w pustym obiekcie nadrzdnym, który nastpnie sklonujemy. Przyciganie do wierzchoków Podstawowa procedura przycigania, której uylimy wczeniej, dziaaa poprawnie, poniewa nasze szeciany charakteryzuj si ogóln skal o wielkoci 1. Jednake podczas skalowania obiektów o bardziej zoonych ksztatach powiniene zastosowa opcj przycigania do wierzchoków. Aby jej uy, upewnij si, e wybrae narzdzie Translate, a nastpnie wcinij i przytrzymaj klawisz V. Gdy umiecisz kursor myszy nad punktem wybranego wierzchoka, przecignij cay element do wierzchoka nalecego do innego obiektu.
Grupowanie i duplikacja przy uyciu pustych obiektów Stwórz pusty obiekt, wybierajc opcj menu gównego GameObject/Create Empty (obiekt gry/stwórz pusty). Nastpnie umie go w pooeniu (4.5, 0.5, -1) przy uyciu komponentu Transform z panelu Inspector. Zmie jego nazw na CubeHolder. Zaznacz wszystkie szeciany w panelu Hierarchy: wybierz szecian znajdujcy si najwyej, przytrzymaj klawisz Shift, a nastpnie wybierz szecian najniszy. W dalszej kolejnoci przecignij zaznaczony zbiór szecianów do pustego obiektu CubeHolder, znajdujcego si w panelu Hierarchy, aby uczyni go obiektem nadrzdnym. Po wykonaniu tej operacji widok Hierarchy powinien si przedstawia nastpujco:
Moesz zauway , e obok nazwy obiektu nadrzdnego pojawia si ikona w postaci strzaki. Oznacza to, e moesz j klikn , co spowoduje rozwinicie i zwinicie listy z obiektami podrzdnymi. Aby zaoszczdzi miejsce w panelu Hierarchy, kliknij strzak, by ukry wszystkie obiekty podrzdne, a nastpnie ponownie wybierz CubeHolder. Gdy cay rzd cegie zosta utworzony i przyporzdkowany do obiektu nadrzdnego, moemy go w prosty sposób zduplikowa poprzez przecignicie z uyciem opcji przycigania w osi Y. Tak jak poprzednio uyj skrótu klawiszowego sucego do klonowania (PC: Ctrl+D, Mac:
51
Projektowanie gier w rodowisku Unity 3.x
Command+D), a nastpnie wybierz narzdzie Translate (W) i zastosuj technik przecigania z przyciganiem (PC: Ctrl, Mac: Command), by przemieci rzd cegie w gór o jedn jednostk za pomoc zielonego uchwytu osi Y. Powtarzaj powysz procedur, a utworzysz osiem rzdów cegie umieszczonych jeden nad drugim. ciana powinna wyglda jak na poniszym rysunku. Zwró uwag na to, e zostay na nim zaznaczone wszystkie obiekty CubeHolder znajdujce si w panelu Hierarchy.
Zbuduj i zniszcz! Gdy zbudowalimy cian z cegie, nadszed czas na stworzenie prostej mechaniki gry, w której gracz moe przemieszcza kamer i wystrzeliwa pociski w kierunku ciany, by j zburzy .
Definiowanie widoku Ustaw kamer w taki sposób, by bya skierowana na cian. W tym celu zaznacz obiekt Main Camera, znajdujcy si w panelu Hierarchy, a nastpnie w komponencie Transform zdefiniuj jego pozycj równ (4, 3, -15). Upewnij si take, e wszystkie parametry zwizane z obrotem s równe zeru.
52
Rozdzia 2. • Podstawy tworzenia prototypów i skryptów
Wprowadzenie do tworzenia skryptów Aby rozpocz nauk programowania, przyjrzymy si prostemu przykadowi, definiujcemu t sam funkcjonalno w jzykach C Sharp (C#) oraz JavaScript, podstawowych dla projektantów wykorzystujcych rodowisko Unity. Mona równie tworzy skrypty oparte na jzyku Boo, lecz s one rzadko uywane, pomijajc osoby, które go dobrze znaj. Uwaga Kolejne wiczenia moesz wykonywa, uywajc zarówno jzyka JavaScript, jak i C#. Jednake w dalszej czci ksiki powiniene zdecydowa si na ten jzyk, który bardziej Ci odpowiada.
Rozpocznij od kliknicia przycisku Create (stwórz), znajdujcego si w panelu Project (projekt), a nastpnie wybrania opcji Javascript lub C# Script. Twój skrypt zostanie umieszczony w panelu Project pod nazw NewBehaviourScript, obok której widnieje niewielka ikona w ksztacie strony z napisem JS lub C#. W trakcie dokonywania wyboru skryptu masz dostp do podgldu jego kodu w oknie Inspector (inspektor). Znajduje si tam take przycisk Open (otwórz), którego kliknicie powoduje otwarcie skryptu w domylnym edytorze o nazwie Monodevelop. Moesz go take otworzy , klikajc dwukrotnie jego ikon w panelu Project.
Nowy skrypt definiujcy zachowanie lub klas Bez wzgldu na to, czy zdecydujesz si na jzyk C#, czy JavaScript, przydatne bdzie przeczytanie obu dalszych fragmentów, poniewa zawieraj on ogólne informacje o tworzeniu skryptów i mog równie pomóc w podjciu decyzji o wyborze okrelonego jzyka. W terminologii rodowiska Unity kady nowo utworzony skrypt odpowiada zdefiniowaniu nowej klasy. Jeli jeste pocztkujcym programist, potraktuj klas jako zbiór dziaa, waciwoci i innych zapamitanych informacji, do których mona mie dostp poprzez jej nazw. Na przykad klasa o nazwie Pies mogaby zawiera takie waciwoci, jak kolor, rasa, rozmiar i pe. Oprócz nich istniayby takie dziaania, jak biegnij czy przynie patyk. Waciwoci mog by opisane jako zmienne, natomiast dziaania mog zosta zdefiniowane w postaci funkcji, zwanych take metodami. Aby odwoa si do zmiennej rasa, która jest waciwoci klasy Pies, moglibymy poda nazw klasy, nastpnie uy znaku kropki, a wreszcie wprowadzi nazw zmiennej: Pies.rasa;
Do wywoania funkcji klasy Pies moglibymy zastosowa poniszy zapis: Pies.przyniesPatyk();
53
Projektowanie gier w rodowisku Unity 3.x
Funkcje moemy równie wywoywa z argumentami — nie maj one jednak nic wspólnego z tymi, których uywamy codziennie podczas dyskusji z innymi osobami! Przyjmij zaoenie, e argumenty pozwalaj na modyfikowanie dziaania funkcji. Na przykad w przypadku funkcji przyniesPatyk moglibymy uy argumentu, który definiuje, jak szybko pies powinien przynie patyk. Jej wywoanie mogoby wyglda tak: Pies.przyniesPatyk(25);
Mimo e zaprezentowane wyej przykady s abstrakcyjne, czsto pozwalaj odwzorowa kod programu na sytuacje wzite z ycia, co sprawia, e nabieraj sensu. Podczas czytania tej ksiki postaraj si do nich wraca . Moesz take tworzy wasne odwzorowania, co pozwoli Ci lepiej zrozumie dziaanie klas informacji oraz ich waciwoci. W czasie pisania skryptu w jzyku C# lub JavaScript tworzysz now klas (lub klasy) zawierajc waciwoci (zmienne) oraz polecenia (funkcje), których moesz uy w okrelonym miejscu w swojej grze.
Jak wyglda od rodka dziaanie skryptu w jzyku C#? Gdy w rodowisku Unity utworzysz nowy skrypt w jzyku C#, od razu otrzymasz pewien kod, którego moesz uy : using UnityEngine; using System.Collections; public class NewBehaviourScript : MonoBehaviour { // Use this for initialization void Start () { } // Update is called once per frame void Update () { } }
Kod rozpoczyna si od dwóch niezbdnych wierszy, zawierajcych odwoania do samego silnika Unity: using UnityEngine; using System.Collections;
Nastpnie jest tworzona nazwa klasy, zgodna z nazw skryptu. W jzyku C# musisz zdefiniowa tak nazw skryptu, która bdzie odpowiada nazwie zadeklarowanej w nim klasy. Na pocztku dokumentu widzimy zapis public class NewBehaviourScript : MonoBehaviour {, poniewa NewBehaviourScript jest domyln nazw, nadawan przez rodowisko Unity kademu nowo utworzonemu skryptowi. Jeli w panelu Project zmienisz nazw skryptu, system Unity automatycznie zmieni take nazw zdefiniowanej w nim klasy.
54
Rozdzia 2. • Podstawy tworzenia prototypów i skryptów
Kod skadajcy si z klas Podczas pisania kodu wikszo funkcji, zmiennych i innych skadników skryptu bdzie umieszczana wewntrz klasy jzyka C#. Wewntrz w tym kontekcie oznacza, e musi wystpi po deklaracji klasy i koczy si zamykajcym nawiasem klamrowym }, znajdujcym si na kocu skryptu. Podczas analizowania polece zawartych w tej ksice moesz zaoy, e Twój kod powinien zosta umieszczony wewntrz klasy zdefiniowanej w skrypcie. Kady wyjtek od tej reguy zostanie jawnie wskazany. Ta zasada nie jest tak rygorystycznie przestrzegana w jzyku JavaScript, poniewa cay skrypt jest w nim definiowany jako oddzielna klasa. Aby zapozna si ze szczegóami, przeczytaj podrozdzia zatytuowany „Jak wyglda od rodka dziaanie skryptu w jzyku JavaScript?”.
Funkcje podstawowe rodowisko Unity zawiera wiele wasnych funkcji, które mog by uywane w celu uruchomienia rónych opcji silnika gry. Dwie z nich s szczególnie wane podczas tworzenia nowego skryptu w jzyku C#. Uwaga Funkcje jzyka C# (zwane równie metodami) najczciej rozpoczynaj si od sowa void. Uyta nazwa okrela typ wartoci, która jest zwracana przez funkcj, czyli danej otrzymanej po jej wywoaniu. Poniewa wikszo funkcji jest tworzona wycznie w celu wykonania okrelonych instrukcji, a nie zwracania jakich informacji, na pocztku ich deklaracji bdziesz czsto spotyka sowo void. Oznacza ono po prostu, e wywoanie funkcji nie zwróci adnych wartoci.
Funkcje te s nastpujce: Q Start(): Zostaje ona wywoana przy pierwszym uruchomieniu sceny, dlatego jest
czsto uywana (jak wynika z sugestii zawartej w kodzie) w celach inicjalizacyjnych. Na przykad mógby dysponowa zmienn przechowujc wynik, której musi zosta przypisana warto 0 podczas rozpoczynania gry. W funkcji Start() mogaby take zosta wywoana procedura, która umieszcza posta gracza we waciwym miejscu gry na pocztku danego poziomu. Q Update(): Poniewa stany rónych elementów gry mog si zmienia w trakcie jej
trwania, funkcja ta jest wywoywana w kadej iteracji podczas dziaania Twojego programu i jest odpowiedzialna za ich sprawdzanie.
Zmienne w jzyku C# Aby zapamita informacj w zmiennej jzyka C#, naley uy nastpujcej skadni: typDanych nazwaZmiennej = warto; Na przykad: int currentScore = 5;
55
Projektowanie gier w rodowisku Unity 3.x
lub: float currentVelocity = 5.86f;
Zwró uwag na to, e w powyszych przykadach uyto danych numerycznych: int oznacza liczb cakowit, natomiast float liczb zmiennoprzecinkow. Ten drugi przypadek wymaga dodatkowo w jzyku C# umieszczenia litery f po wartoci samej liczby. Róni si to w pewien sposób od skadni uywanej w jzyku JavaScript. Wicej szczegóów zostanie zaprezentowanych w kolejnym punkcie „Zmienne w jzyku JavaScript”.
Jak wyglda od rodka dziaanie skryptu w jzyku JavaScript? Nowo utworzony plik w jzyku JavaScript zawiera mniej danych ni odpowiadajcy mu plik jzyka C#, poniewa cay skrypt jest uwaany za definicj klasy. Zakada si, e znajdujce si w nim treci zawieraj si midzy niewidocznymi dla uytkownika znacznikami otwierajcymi i zamykajcymi klas, gdy sama jej deklaracja jest ukryta. Moesz take zauway , e wiersze using UnityEngine; i using System.Collections; s równie niewidoczne w pliku jzyka JavaScript, dlatego nowo utworzony skrypt zawiera tylko funkcj Update(): function Update() { }
Deklaracja funkcji w jzyku JavaScript wyglda inaczej i wymaga uycia sowa kluczowego function przed jej nazw. Deklaracje zmiennych i innych elementów skryptu s take zapisywane w odmienny sposób — w kolejnych punktach zapoznamy si z odpowiednimi przykadami.
Zmienne w jzyku JavaScript Skadnia suca do deklarowania zmiennych w jzyku JavaScript wyglda nastpujco: var nazwaZmiennej : TypDanych = warto;
Jak wida , deklaracja jest zawsze poprzedzona sowem kluczowym var. Na przykad: var currentScore : int = 0;
lub: var currentVelocity : float = 5.86;
Jak zapewne zauwaye, typ float, inaczej ni w jzyku C#, nie wymaga podania litery f wystpujcej za wartoci. Podczas analizy kolejnych skryptów napisanych w dwóch rónych jzykach bdziesz take móg stwierdzi , e jzyk C# ma czsto bardziej rygorystyczne reguy, okrelajce sposób tworzenia programów, szczególnie w przypadku niejawnie deklarowanych typów danych, które maj by uywane.
56
Rozdzia 2. • Podstawy tworzenia prototypów i skryptów
Komentarze Zarówno w jzyku C#, jak i w JavaScript moesz tworzy komentarze za pomoc nastpujcych konstrukcji: // dwa ukoniki oznaczaj pojedynczy wiersz komentarza
lub: /* ukonik i gwiazdka rozpoczynaj komentarz zawierajcy si w wielu wierszach. Jego zakoczeniem s gwiazdka i ukonik */
Podczas czytania tej ksiki komentarze mog pomóc Ci przypomnie sobie zasad dziaania tworzonych przez Ciebie fragmentów kodu. Pamitaj, e komentarze nie wykonuj si, dlatego moesz w nich umieszcza dowolne teksty, wczajc w to równie wiersze kodu. Dopóki bd si one zawiera w komentarzu, nie zostan potraktowane jako dziaajcy kod.
Atakowanie ciany A teraz zastosujmy zdobyt wiedz w praktyce i zamiemy istniejc scen w prototyp interakcyjnej fabuy. W panelu Project zmie nazw nowo utworzonego skryptu poprzez jego wybranie, nacinicie klawisza F2 (PC) lub Return (Mac), a nastpnie wprowadzenie tekstu skryptu Shooter. Jeli wykorzystujesz jzyk C#, pamitaj o upewnieniu si, e Twoja deklaracja klasy znajdujca si wewntrz skryptu odpowiada jego nazwie: public class Shooter : MonoBehaviour {
Jak wczeniej wspomniano, uytkownicy wykorzystujcy jzyk JavaScript nie bd musieli stosowa si do powyszej reguy. By zastosowa w praktyce wiedz o korzystaniu ze skryptów w rodowisku Unity, napiszemy skrypt sterujcy kamer i pozwalajcy na strzelanie pociskami w kierunku postawionej przez nas ciany. Na pocztku utworzymy trzy zmienne: Q bullet: ta zmienna jest typu Rigidbody, poniewa przechowuje odwoanie do obiektu
o waciwociach fizycznych, który zostanie przez nas utworzony; Q power: jest to zmienna o typie zmiennoprzecinkowym, któr wykorzystamy w celu ustalenia siy strzau; Q moveSpeed: kolejna zmienna o typie zmiennoprzecinkowym, której uyjemy,
by zdefiniowa prdko poruszania kamer za pomoc klawiszy strzaek. Powysze zmienne musz by skadowymi z dostpem publicznym, co pozwoli je wywietli w panelu Inspector w postaci modyfikowanych ustawie. Za chwil zobaczysz, jak to dziaa!
57
Projektowanie gier w rodowisku Unity 3.x
Deklarowanie zmiennych publicznych Wane jest, by zrozumie dziaanie zmiennych o dostpie publicznym, poniewa pozwala on na odwoywanie si do nich z innych skryptów. Ma to znaczenie podczas projektowania gier, gdy umoliwia definiowanie prostszej komunikacji midzyobiektowej. Zmienne publiczne s take przydatne z tego wzgldu, e wystpuj w postaci ustawie, które mona wizualnie modyfikowa w panelu Inspector, gdy tylko skrypt zostanie przypisany do obiektu. Zmienne prywatne zachowuj si przeciwnie — zostay zaprojektowane, by by dostpne tylko z poziomu skryptu, klasy lub funkcji, w których s zdefiniowane. Nie pojawiaj si równie w postaci ustawie w panelu Inspector. Jzyk C#: Zanim rozpoczniemy dziaania, usuniemy funkcj Start() ze skryptu, poniewa nie bdziemy jej uywa . W tym celu po prostu skasuj tekst void Start { }. Aby stworzy wymagane zmienne, umie poniszy fragment kodu w swoim skrypcie poniej wiersza otwierajcego klas: using UnityEngine; using System.Collections; public class Shooter : MonoBehaviour { public Rigidbody bullet; public float power = 1500f; public float moveSpeed = 2f; void Update () { } }
Zwró uwag na to, e w powyszym przykadzie usunlimy domylne komentarze, by zaoszczdzi miejsce. Jzyk JavaScript: Aby stworzy zmienne o dostpie publicznym w jzyku JavaScript, musisz si upewni , e zostan one zadeklarowane poza istniejcymi funkcjami. Naley je po prostu umieci na samej górze skryptu. Zadeklaruj wic trzy wymagane zmienne, wstawiajc poniszy kod na pocztku skryptu Shooter: var bullet : Rigidbody; var power : float = 1500; var moveSpeed : float = 5; function Update () { }
Przypisywanie skryptów do obiektów Aby skrypt móg zosta uyty w grze, musi by przypisany jako komponent do jednego z obiektów gry znajdujcych si w istniejcej scenie.
58
Rozdzia 2. • Podstawy tworzenia prototypów i skryptów
Zapisz skrypt, wybierajc z gównego menu edytora opcj File/Save (plik/zapisz), a nastpnie wró do rodowiska Unity. Oferuje ono kilka sposobów przypisywania skryptu do obiektu: 1. Przecignij go z panelu Project i upu na nazwie obiektu w panelu Hierarchy. 2. Przecignij go z panelu Project i upu na wizualn reprezentacj obiektu w panelu Scene. 3. Wybierz obiekt, dla którego chcesz przypisa skrypt. Nastpnie przecignij i upu skrypt w niezajtym obszarze w widoku Inspector tego obiektu. 4. Wybierz obiekt, do którego chcesz przypisa skrypt. Wybierz opcj menu gównego Component/Scripts (komponent/skrypty), a nastpnie nazw swojego skryptu. Najczciej jest stosowana pierwsza metoda. W naszym przypadku bdzie to rzeczywicie najlepszy wybór, poniewa przeciganie skryptu do kamery w widoku Scene mogoby by uciliwe z tego powodu, e nie zawiera ona wyranego obszaru, na którym mona by go upuci . Przecignij wic nowy skrypt Shooter z panelu Project i upu go na nazwie Main Camera, znajdujcej si w panelu Hierarchy, co spowoduje jego przypisanie. Bdziesz móg zauway , e skrypt zostanie wywietlony jako nowy skadnik poniej istniejcego komponentu Audio Listener. W panelu Inspector stwierdzisz take istnienie trzech zmiennych publicznych: Bullet, Power i Move Speed:
Jak moesz zauway , rodowisko Unity zmodyfikowao nazwy zmiennych, rozpoczynajc je od wielkiej litery. Dodatkowo, w przypadku zmiennej moveSpeed, wielka litera wewntrz jej nazwy zostaa potraktowana jako pocztek nowego sowa. Dziki temu uzyskano dwa wyrazy oddzielone spacj, które s widoczne w panelu Inspector jako jedna zmienna publiczna. Mona równie stwierdzi , e zmienna Bullet nie zostaa jeszcze zainicjalizowana, lecz oczekuje si, i obiekt, który zostanie do niej przypisany, bdzie uywa komponentu bryy sztywnej (Rigidbody). Czsto zwany jest on po prostu obiektem typu Rigidbody. Pomimo tego, e w rodowisku Unity wszystkie elementy w scenie mog by traktowane jako obiekty gry, podczas definiowania w skrypcie obiektu o typie Rigidbody bdziemy mogli si odwoywa jedynie do waciwoci i funkcji klasy o tej wanie nazwie. Nie stanowi to jednak problemu — po prostu sprawia, e skrypt staje si bardziej efektywny ni w przypadku, gdybymy odwoywali si do caej klasy GameObject. Aby dowiedzie si wicej na ten temat, zapoznaj si z dokumentacj zwizan z oprogramowaniem skryptowym dotyczcym wspomnianych klas: Q GameObject: http://unity3d.com/support/documentation/ScriptReference/GameObject.html, Q RigidBody: http://unity3d.com/support/documentation/ScriptReference/Rigidbody.html.
59
Projektowanie gier w rodowisku Unity 3.x
Uwaga Pamitaj, e podczas modyfikowania zmiennych publicznych, dostpnych w panelu Inspector, dowolna ich zmiana zamiast zastpi wartoci, które zostay zapisane w skrypcie, po prostu je przesoni.
Kontynuujmy prace zwizane z tworzeniem skryptu i uzupenijmy go o pewn interaktywno . Wró wic z powrotem do edytora, do którego zosta on wczytany.
Poruszanie kamer Teraz wykorzystamy zmienn moveSpeed oraz odczytamy stan klawiatury, aby porusza kamer i faktycznie stworzy prosty mechanizm celowania dla strzau. Bdzie on polega na ustawianiu kamery w kierunku miejsca, w które bdziemy strzelali. Poniewa chcielibymy uywa klawiszy strzaek na klawiaturze, musimy si najpierw dowiedzie , w jaki sposób w kodzie mona si do nich odwoywa . rodowisko Unity wykorzystuje wiele sygnaów wejciowych, które mona obserwowa i modyfikowa przy uyciu menedera wej (Input Manager) — patrz menu Edit/Project Settings/Input (edycja/ustawienia projektu/wejcie). Jak wida na poniszym rysunku, istniej dwa domylne parametry typu Input (wejcie): Horizontal (poziomy) i Vertical (pionowy). Wykorzystuj one zasad dziaania osi wspórzdnych, dziki czemu naciskanie przycisku Positive Button (przycisk dodatni) generuje warto równ 1, natomiast naciskanie przycisku Negative Button (przycisk ujemny) tworzy warto -1. Zwolnienie dowolnego przycisku oznacza, e warto typu Input ponownie staje si równa 0, podobnie jak miaoby to miejsce podczas uywania sprystego joysticka analogowego, znajdujcego si w urzdzeniu typu gamepad. Poniewa typ Input jest równie nazw klasy, a wszystkie nazwane elementy w menederze wej s osiami lub przyciskami, w skrypcie moemy uy nastpujcego zapisu: Input.GetAxis("Horizontal");
Powyszy wiersz pozwala na odczytanie biecej wartoci przycisków poziomych, zawierajcej si w zakresie od -1 do 1 w zalenoci od tego, co jest naciskane przez uytkownika. Zastosujmy go w naszym skrypcie, uywajc zmiennych lokalnych do reprezentowania osi. Dziki temu moemy póniej zmodyfikowa warto zmiennej, uywajc operacji mnoenia, dziki czemu uzyskamy maksymaln warto wiksz od 1. Pozwoli nam to na przemieszczanie kamery z prdkoci wiksz ni jedna jednostka na iteracj. Dostpu do tej zmiennej nie musimy mie w panelu Inspector, poniewa samo rodowisko Unity bdzie przypisywa jej odpowiednie wartoci w zalenoci od stanu sygnaów wejciowych. Wynika std, e powinna ona zosta zdefiniowana jako zmienna lokalna.
60
Rozdzia 2. • Podstawy tworzenia prototypów i skryptów
Zmienne lokalne, prywatne i publiczne Zanim bdziemy kontynuowa prace zwizane z tworzeniem skryptu, zapoznajmy si ze zmiennymi lokalnymi, prywatnymi i publicznymi: Q Zmienne lokalne. S to zmienne tworzone wewntrz funkcji. Nie bd prezentowane
w panelu Inspector i s dostpne wycznie dla funkcji, w której si znajduj. Q Zmienne prywatne. S tworzone na zewntrz funkcji i dlatego dostp do nich maj
wszystkie funkcje danej klasy. Nie s one jednak widoczne w panelu Inspector. Q Zmienne publiczne. S tworzone na zewntrz funkcji, dostp do nich maj wszystkie
funkcje danej klasy, a take inne skrypty. Zmienne publiczne s widoczne w panelu Inspector i mog by tam modyfikowane.
Zmienne lokalne i odczytywanie wej Tworzenie zmiennych lokalnych w jzykach C# i JavaScript zostao przedstawione w poniszych fragmentach kodu:
61
Projektowanie gier w rodowisku Unity 3.x
Jzyk C#: void Update () { float h = Input.GetAxis("Horizontal") * Time.deltaTime * moveSpeed; float v = Input.GetAxis("Vertical") * Time.deltaTime * moveSpeed;
Jzyk JavaScript: function Update () { var h : float = Input.GetAxis("Horizontal") * Time.deltaTime * moveSpeed; var v : float = Input.GetAxis("Vertical") * Time.deltaTime * moveSpeed;
Zadeklarowane zmienne: h dla osi poziomej i v dla osi pionowej mogyby zosta dowolnie nazwane, jednake uywanie pojedynczych liter jest po prostu szybsze. Ogólnie mówic, zazwyczaj powinno si tworzy standardowe nazwy, poniewa niektóre pojedyncze litery nie mog by uywane. Na przykad nazwy zmiennych x, y i z s uywane do przechowywania wartoci wspórzdnych i dlatego te zarezerwowano je wycznie do tych zastosowa. Poniewa wartoci osi mog zawiera si w przedziale od -1 do 1, zmienne s liczbami dziesitnymi i musimy je deklarowa z uyciem typu zmiennoprzecinkowego. Mnoy si je nastpnie za pomoc symbolu gwiazdki * przez parametr Time.deltaTime. Oznacza to, e wyznaczana warto jest dzielona przez liczb klatek na sekund (parametr deltaTime jest czasem tworzenia kolejnych klatek lub czasem liczonym od ostatniego wywoania funkcji Update()). Wynika std, i warto osiga pewn spójn wielko na sekund, niezalenie od szybkoci klatek. W kolejnym kroku zwikszamy warto wynikow, mnoc j przez zmienn publiczn, któr utworzylimy wczeniej, czyli moveSpeed. Oznacza to, e mimo i wartoci h i v s zmiennymi lokalnymi, moemy wci na nie wpywa poprzez modyfikowanie zmiennej publicznej moveSpeed, dostpnej w panelu Inspector, poniewa jest ona skadnikiem uywanego przez nas równania. Jest to czsto spotykane rozwizanie podczas tworzenia skryptów, gdy wykorzystuje ono zalet uycia publicznie dostpnych ustawie poczonych z okrelonymi wartociami generowanymi przez funkcj.
Zrozumienie zasady dziaania polecenia Translate Aby rzeczywicie uy stworzonych zmiennych w celu przemieszczenia obiektu, musimy zastosowa polecenie Translate. Podczas implementowania dowolnego fragmentu kodu musisz by pewien, e rozumiesz jego dziaanie. Translate jest poleceniem pochodzcym z klasy Transform: http://unity3d.com/support/
documentation/ScriptReference/Transform.html.
62
Rozdzia 2. • Podstawy tworzenia prototypów i skryptów
Jest to klasa informacji przechowujca waciwoci pooenia, obrotu i skali danego obiektu. Zawiera ona równie funkcje, które mog by uywane w celu jego przemieszczania lub obracania. Oczekiwane uycie funkcji Translate wyglda nastpujco: Transform.Translate(Vector3);
Istnienie parametru Vector3 oznacza, e funkcja Translate wymaga jego uycia w formie gównego argumentu. Dane reprezentowane przez Vector3 s po prostu informacjami zawierajcymi wartoci wspórzdnych X, Y i Z. W naszym konkretnym przypadku oznaczaj koordynaty przesunicia obiektu.
Implementacja funkcji Translate Zaimplementujmy polecenie Translate, uywajc utworzonych przez nas wartoci wejciowych h i v i umieszczajc je w parametrze Vector3. Jzyki C# i JavaScript: Umie poniszy wiersz kodu wewntrz funkcji Update() w Twoim skrypcie, a dokadniej pomidzy jej otwierajcym { i zamykajcym } nawiasem klamrowym. Zwró uwag na to, e zapis wyglda identycznie w obu jzykach: transform.Translate(h, v, 0);
Moemy tu skorzysta ze sowa transform, poniewa wiemy, e dowolny obiekt, któremu udostpnimy skrypt, bdzie wykorzystywa komponent Transform. Przyczone komponenty danego obiektu mog by adresowane poprzez uycie ich nazw zapisanych maymi literami, natomiast dostp do komponentów innych obiektów wymaga zastosowania polecenia GetComponent i odpowiedniej nazwy zaczynajcej si od wielkiej litery, na przykad: GameObject.Find("NazwaInnegoObiektu").GetComponent.Translate(h,v,0);
W naszym przypadku nie musimy wykorzystywa powyszej formy zapisu. Dostp do komponentów przyczonych do innych obiektów zosta dokadniej opisany w podrozdziale rozdziau 4., zatytuowanym „Komunikacja midzyskryptowa oraz skadnia z kropk”. W skrypcie uyjemy biecej wartoci zmiennej h dla osi X oraz v dla osi Y, natomiast osi Z przekaemy po prostu warto 0, poniewa nie chcemy si przesuwa do przodu ani do tyu. Zapisz teraz swój skrypt, uywajc opcji menu gównego File/Save (plik/zapisz), a nastpnie wró do rodowiska Unity. Zapamitaj tworzon scen za pomoc opcji File/Save Scene As (plik/zapisz scen jako) i nazwij j Prototype. rodowisko Unity zaproponuje zapisanie jej w domylnym folderze Assets (zasoby). Powiniene zawsze si upewnia , e zapamitujesz sceny w tym folderze, poniewa w przeciwnym razie
63
Projektowanie gier w rodowisku Unity 3.x
nie bdziesz mia do nich dostpu z panelu Project (projekt). By zapewni idealny porzdek, moesz take utworzy podkatalog wewntrz folderu Assets, w którym bdziesz przechowywa swoje sceny. Takie dziaanie nie jest jednak wymagane, lecz ogólnie uwaa si je za dobry wzorzec postpowania.
Testujemy biec wersj gry W rodowisku Unity moesz testowa gr w kadym momencie, przy zaoeniu, e skrypty nie zawieraj adnych bdów. Jeli w skryptach wykryto jakie problemy, bdziesz musia je rozwiza przed uyciem trybu grania. Gdy bdy zostan naprawione, pasek Console (konsola), znajdujcy si na dolnej krawdzi interfejsu Unity, nie bdzie zawiera adnych informacji. Pasek Console wywietla najnowsze wpisy pojawiajce si w konsoli Unity. Moesz j wywietli , wybierajc opcj menu Window/Console (okno/konsola) (skrót klawiszowy to Ctrl+Shift+C dla PC lub Command+Shift+C dla komputerów Mac). Kady bd zostanie wywietlony na czerwono. Dwukrotne jego kliknicie umoliwi wywietlenie odpowiedniego fragmentu skryptu, który spowodowa pojawienie si problemu. Wikszo bdów polega na pominiciu jakiego znaku lub bdnym zapisie, dlatego te zawsze dokadnie sprawdzaj, co napisae. Jeli Twoja gra jest wolna od bdów, kliknij przycisk Play (granie), znajdujcy si w górnej czci okna Unity, aby przej do trybu grania. Bdziesz móg porusza obiektem Main Camera za pomoc klawiszy strzaek góra, dó, lewo i prawo lub ich odpowiedników: W, A, S i D, tak jak zaprezentowano na poniszym rysunku. Gdy przetestowae ju gr i upewnie si, e dziaa poprawnie, ponownie nacinij przycisk Play, aby opuci tryb grania. Uwaga Opuszczenie trybu grania przed kontynuowaniem pracy jest wane, poniewa podczas jego wyczania wszystkie zmodyfikowane ustawienia komponentów i obiektów uywanych w biecej scenie nie zostan zapamitane. Pozostawienie rodowiska Unity w trybie grania i wprowadzanie dalszych modyfikacji bdzie oznaczao, e po prostu utracisz wyniki swojej pracy.
Ukoczmy prototyp mechaniki gry poprzez uzupenienie go o moliwo wystrzeliwania pocisków w kierunku ciany, aby j zburzy .
64
Rozdzia 2. • Podstawy tworzenia prototypów i skryptów
Tworzenie pocisku Aby wystrzeli pocisk w kierunku ciany, musimy w ramach biecej sceny najpierw go utworzy , a nastpnie zapamita w postaci prefabrykatu. Uwaga Prefabrykat jest obiektem gry, przechowywanym w projekcie w postaci zasobu. Zasób ten moe by konkretyzowany, czyli tworzony w trakcie dziaania gry, a nastpnie przetwarzany poprzez uycie kodu.
Tworzenie prefabrykatu pocisku Rozpocznij od kliknicia przycisku Create (stwórz), znajdujcego si na górnej krawdzi panelu Hierarchy (hierarchia). Nastpnie z podrcznego menu wybierz opcj Sphere (kula). Jak wczeniej wspomniano, dostp do tworzenia ksztatów podstawowych jest równie moliwy za pomoc opcji menu gównego GameObject/Create/Other (obiekt gry/utwórz/inny). Teraz upewnij si, e utworzona przez Ciebie kula zostaa zaznaczona w panelu Hierarchy, a póniej przemie kursor myszy na widok Scene (scena) i nacinij klawisz F, by skoncentrowa si na wybranym obiekcie.
65
Projektowanie gier w rodowisku Unity 3.x
Uwaga Jeli Twoja kula ma takie samo pooenie, jak który z innych obiektów, moesz w prosty sposób przej do narzdzia translacji (W), a nastpnie przecign uchwyt odpowiedniej osi, aby odsun j od zasaniajcego elementu. Po tej operacji ponownie skoncentruj widok na kuli poprzez nacinicie klawisza F.
Spogldajc na panel Inspector (inspektor), moesz zauway , e podczas dodawania nowych obiektów o ksztatach podstawowych rodowisko Unity oprócz istniejcego komponentu Transform automatycznie przypisuje im trzy nowe komponenty. S to: 1. Mesh Filter (filtr siatki). Suy do modyfikowania ksztatu. 2. Renderer (renderer). Suy do modyfikowania wygldu. 3. Collider (zderzacz). Suy do zarzdzania interakcjami (zwanymi kolizjami) z innymi obiektami.
Tworzenie i przypisywanie materiau Wygld pocisku da si zmodyfikowa poprzez stworzenie materiau, który moemy przekaza do renderera. Gdy chcesz zmieni wygld obiektu, powiniene najczciej odszuka odpowiednie ustawienia zwizane z jakim komponentem typu Renderer. W przypadku obiektów 3D bdzie to Mesh Renderer (renderer siatki), a dla systemów czstek bdzie to Particle Renderer (renderer czstek) itd. Aby zachowa porzdek, utworzymy nowy podkatalog wewntrz folderu Assets. Bdziemy w nim przechowywa wszystkie materiay uywane w biecym projekcie. W panelu Project kliknij przycisk Create, a nastpnie z podrcznego menu wybierz opcj Folder (katalog). Zmie jego nazw na Materials poprzez nacinicie klawisza F2 (PC) lub Return (Mac). Teraz umie w nim materia czerwonej cegy, który zosta wczeniej przez Ciebie stworzony. Uwaga Aby w panelu Project utworzy nowy zasób w istniejcym folderze, po prostu go wybierz, a nastpnie rozpocznij operacj tworzenia poprzez kliknicie przycisku Create.
Teraz utworzymy potrzebny materia i zastosujemy go w naszym obiekcie: 1. Upewnij si, e folder Materials jest zaznaczony, a nastpnie kliknij przycisk Create, znajdujcy si w panelu Project. Z wywietlonego menu podrcznego wybierz opcj Material (materia). Spowoduje to utworzenie zasobu New Material, którego nazw powiniene zmieni na bulletColor lub podobn, przypominajc Ci, e powinien on zosta przypisany do pocisku. 2. Majc zaznaczony nowo utworzony materia, kliknij obszar koloru, aby otworzy okno Color Picker. Póniej wybierz jaki odcie koloru niebieskiego i zamknij to okno.
66
Rozdzia 2. • Podstawy tworzenia prototypów i skryptów
3. Po wybraniu koloru przecignij materia bulletColor z panelu Project i upu go na nazwie kuli w panelu Hierarchy. Spowoduje to przypisanie materiau do interesujcego Ci obiektu. Uwaga Jeli chcesz sprawdzi, jak bdzie wyglda materia przypisany do trójwymiarowego obiektu w rodowisku Unity, moesz go przecign do widoku Scene, a nastpnie umieci kursor myszy nad okrelon siatk. System Unity zaprezentuje podgld obiektu w wybranym kolorze. Aby uniewani wybór, moesz przesun kursor poza obszar widoku lub nacisn klawisz Esc. By zastosowa materia, zwalniasz po prostu przycisk myszy.
Dodawanie parametrów fizycznych za pomoc komponentu Rigidbody Poprzez dodanie komponentu Rigidbody musimy zapewni to, e silnik fizyczny bdzie móg sterowa pociskiem Sphere. Wybierz obiekt Sphere z panelu Hierarchy, a nastpnie opcj Component/Physics/Rigidbody (komponent/parametry fizyczne/brya sztywna) z menu gównego. Komponent bryy sztywnej zosta dodany, a jego parametry mog by modyfikowane w panelu Inspector. Na potrzeby obecnego prototypu nie musimy jednak niczego zmienia .
Przechowywanie obiektów jako prefabrykatów Poniewa powinnimy wystrzeliwa pocisk w chwili, gdy gracz nacinie jaki klawisz, nie chcemy, aby znajdowa si on cay czas w scenie. Zamiast tego powinien by przechowywany i konkretyzowa si dopiero podczas naciskania klawisza. Z tego powodu bdziemy zapisywa nasz obiekt w postaci prefabrykatu, a nastpnie uywa skryptu w celu jego konkretyzacji (to znaczy tworzenia jego instancji) w momencie naciskania klawisza. Uwaga Prefabrykaty w rodowisku Unity pozwalaj na przechowywanie obiektów gry, które zostay zdefiniowane w okrelony sposób. Na przykad moesz odpowiednio skonfigurowa obiekt wrogiego onierza, zawierajcy pewne skrypty i waciwoci, które definiuj jego zachowanie. Nastpnie moesz zapisa ten obiekt w postaci prefabrykatu i w razie koniecznoci konkretyzowa go. Podobnie mógby uywa innego onierza, zachowujcego si odmiennie, który byby kolejnym prefabrykatem. Mógby take utworzy instancj pierwszego obiektu, a pó niej zmodyfikowa ustawienia jego komponentów, aby po konkretyzacji porusza si wolniej lub szybciej. System prefabrykatów udostpnia szeroki zakres swobody w tym wzgldzie.
67
Projektowanie gier w rodowisku Unity 3.x
Kliknij przycisk Create (stwórz), znajdujcy si na górze panelu Project (projekt), a nastpnie wybierz opcj Folder (folder). Zmie nazw nowo utworzonego katalogu na Prefabs. W kolejnym kroku przecignij obiekt Sphere z panelu Hierarchy (hierarchia) i upu go na folder Prefabs w panelu Project. Przecignicie obiektu gry w dowolny obszar panelu Project spowoduje, e zostanie on zapamitany jako prefabrykat. Folder Prefabs zosta przez nas utworzony jedynie w celu zapewnienia porzdku i stosowania si do dobrych wzorców postpowania. Zmie nazw nowo utworzonego prefabrykatu na Projectile. Moesz ju usun oryginalny obiekt Sphere z panelu Hierarchy: wybierz go, a nastpnie nacinij klawisz Delete (PC) lub Command+Backspace (Mac). Alternatyw dla tego rozwizania jest kliknicie prawym klawiszem myszy obiektu w panelu Hierarchy i wybranie opcji Delete (usu) z menu podrcznego.
Wystrzelenie pocisku Wró my do skryptu Shooter, który wanie tworzymy. W tym celu kliknij dwukrotnie jego ikon, znajdujc si w panelu Project, lub wybierz go, a nastpnie kliknij przycisk Open (otwórz), wywietlany na górze okna Inspector (inspektor). Uyjemy wczeniej zadeklarowanej zmiennej bullet, bdcej odwoaniem do okrelonego obiektu, który zamierzamy skonkretyzowa . Gdy tylko obiekt zostanie utworzony z prefabrykatu, zastosujemy odpowiednie dziaanie, aby wystrzeli go w kierunku ciany znajdujcej si w scenie. W funkcji Update() po wierszu transform.Translate(h, v, 0) dodaj nastpujcy kod, niezalenie od tego, jakiego jzyka programowania uywasz: if(Input.GetButtonUp("Fire1")){ }
Polecenie if sprawdza, czy klawisz przypisany do wejciowego przycisku Fire1 zosta zwolniony. Domylnie jest on odwzorowany na lewy klawisz Ctrl lub lewy przycisk myszy. Moesz go jednak przypisa do innego klawisza, wprowadzajc odpowiedni modyfikacj w menederze wej , co mona zrobi przez wybranie opcji menu gównego Edit/Project Settings/Input (edycja/ustawienia projektu/wejcia).
Uycie funkcji Instantiate() do konkretyzowania obiektów Wewntrz polecenia if (to znaczy pomidzy otwierajcym i zamykajcym nawiasem klamrowym) umie nastpujcy wiersz kodu:
68
Rozdzia 2. • Podstawy tworzenia prototypów i skryptów
Jzyk C#: Rigidbody instance = Instantiate(bullet, transform.position, ´transform.rotation) as Rigidbody;
Jzyk JavaScript: var instance: Rigidbody = Instantiate(bullet, transform.position, ´transform.rotation);
Jak wida , stworzylimy now zmienn zwan instance. Przechowujemy w niej referencj do funkcji tworzcej nowy obiekt o typie Rigidbody. Polecenie Instantiate wymaga podania trzech parametrów: Instantiate(co naley stworzy, gdzie naley stworzy, wielko obrotu);
W naszym przypadku chcemy, aby zostaa utworzona instancja obiektu lub prefabrykatu, który zosta przypisany do zmiennej publicznej bullet. Pooenie i obrót instancji pobierzemy z komponentu transform, uywanego w obiekcie, do którego zosta przydzielony skrypt, czyli Main Camera. Dlatego te w skryptach bdziesz móg czsto zauway zapis transform.position, odnoszcy si do ustawie zwizanych z komponentem transform i dotyczcy pooenia obiektu, do którego zosta przyczony dany skrypt. Zauwa, e w jzyku C# musisz umieci sowo Rigidbody za wywoaniem funkcji Instantiate, aby jawnie wskaza typ danych.
Przyoenie wektora siy do bryy sztywnej Po utworzeniu obiektu musimy go natychmiast wystrzeli , uywajc w tym celu polecenia AddForce(). Dziaa ono tak: Rigidbody.AddForce(kierunek i wielko wektora siy podane jako typ Vector3);
Zanim wic przyoymy wektor siy, musimy stworzy referencj do kierunku, w którym chcemy strzela . Kamera jest zwrócona w stron ciany z cegie, wic sensowne jest, by oddawa strzay w tym wanie kierunku. Poniej wiersza zawierajcego funkcj Instantiate(), a jednoczenie wci w obrbie polecenia if, umie nastpujcy kod: Jzyk C#: Vector3 fwd = transform.TransformDirection(Vector3.forward);
Jzyk JavaScript: var fwd: Vector3 = transform.TransformDirection(Vector3.forward);
Utworzylimy zmienn fwd o typie Vector3 i przypisalimy jej kierunek do przodu dla komponentu transform w obiekcie, do którego jest przyczony nasz skrypt.
69
Projektowanie gier w rodowisku Unity 3.x
Polecenie TransformDirection moe zosta uyte w celu przeksztacenia lokalnego kierunku — w naszym przypadku kierunku wskazywania kamery — na kierunek wiata. Obiekty oraz wiat maj wasne systemy wspórzdnych, wic moe si zdarzy , e kierunek wskazywania do przodu dla jakiego obiektu nie musi koniecznie odpowiada waciwemu kierunkowi wiata. Wynika std, i w takich przypadkach konwersja jest niezbdna. Konstrukcja Vector3.forward, uyta w powyszym kontekcie, jest zwykym uproszczeniem zapisu Vector3(0, 0, 1). Wystpuje w nim warto jednostkowa dugoci dla osi Z. Wreszcie bdziemy mogli wystrzeli pocisk przez odwoanie si do naszej zmiennej, która reprezentuje nowo utworzony obiekt instance, a nastpnie uycie polecenia AddForce() w celu przyoenia siy w kierunku zdefiniowanym w zmiennej fwd, mnoc j przez wczeniej utworzon zmienn publiczn power. Dodaj poniszy wiersz kodu bezporednio pod tym, który poprzednio umiecie w skrypcie: Jzyki C# i JavaScript: instance.AddForce(fwd * power);
Zapamitaj skrypt i wró do rodowiska Unity. Zanim przetestujemy dziaanie ukoczonej mechaniki gry, musimy przypisa prefabrykat Projectile do zmiennej publicznej Bullet. W tym celu wybierz obiekt Main Camera w panelu Hierarchy, aby wywietli skrypt Shooter w postaci komponentu w panelu Inspector. Nastpnie przecignij prefabrykat Projectile z panelu Project i upu go na zmienn Bullet w panelu Inspector w miejscu, w którym znajduje si napis None (Rigidbody), jak przedstawiono na poniszym rysunku:
Po wykonaniu tej czynnoci bdziesz móg zobaczy nazw Projectile w obszarze zmiennej Bullet. Zapisz scen za pomoc opcji File/Save Scene (plik/zapisz scen), a póniej przetestuj gr, naciskajc przycisk Play znajdujcy si w górnej czci interfejsu. Teraz bdziesz móg przemieszcza kamer i strzela pociskami za pomoc lewego klawisza Ctrl na klawiaturze. Jeli chcesz zmieni si wystrzau pocisku, po prostu zmodyfikuj zmienn
70
Rozdzia 2. • Podstawy tworzenia prototypów i skryptów
publiczn Power poprzez wybranie obiektu Main Camera, a nastpnie wprowadzenie innej wartoci w miejsce liczby 1500 przypisanej do komponentu Shooter (Script). Pamitaj, aby zawsze nacisn przycisk Play w celu zakoczenia testowania.
Podsumowanie Gratulacje! Wanie stworzye swój pierwszy prototyp w rodowisku Unity. W tym rozdziale poznae zasady uywania interfejsu Unity, obiektów gry i komponentów, a take podstawy tworzenia skryptów. Miejmy nadziej, e wiedza ta bdzie solidnym fundamentem, na którym zostanie zbudowane dalsze dowiadczenie w tworzeniu gier komputerowych w rodowisku Unity. A teraz chwila odpoczynku. Zagraj w stworzony przez siebie prototyp gry, a moe stwórz kolejny w oparciu o informacje zaprezentowane w tym rozdziale. By moe jeste jednak dny wiedzy — jeli tak, kontynuuj czytanie ksiki! Skoro poznae ju podstawowe operacje dostpne w rodowisku projektowym Unity, zajmijmy si waciw gr, która bdzie omawiana w dalszych rozdziaach tej ksiki. W nastpnym rozdziale rozpoczniemy tworzenie gry zwanej Survival Island (wyspa przetrwania). Poznasz, w jaki sposób mona bdzie wykorzysta narzdzia tworzenia terenu, aby uksztatowa tropikaln wysp, która ma nawet swój wulkan! W dalszej kolejnoci umiecisz na niej prefabrykat postaci gracza i zwiedzisz nowo utworzony raj tropikalny!
71
Projektowanie gier w rodowisku Unity 3.x
72
3 Tworzenie rodowiska Podczas budowania trójwymiarowego wiata bdziesz wykorzystywa dwie odmienne geometrie rodowiska — budynki, sceneria oraz rekwizyty zostan utworzone w dodatkowym narzdziu modelowania 3D, natomiast teren bdzie wygenerowany przy uyciu dedykowanego edytora, dostpnego w rodowisku Unity. W tym rozdziale zapoznamy si z dziaaniem edytora terenu, a take dowiemy si, w jaki sposób moemy wykorzysta jego zestaw narzdzi, aby stworzy rodowisko gry. Odpowiednie aplikacje do projektowania rzeby terenu, geometrii oraz malowania za pomoc tekstur pozwol na wygenerowanie caego terenu wyspy. Szczególnie dokadnie zostan omówione nastpujce zagadnienia: Q obsuga narzdzi edytora terenu, pozwalajcych na zbudowanie wyspy, Q sceny zawierajce owietlenie, Q uycie dwiku, Q importowanie spakowanych zasobów.
Zanim uyjemy narzdzi edytora terenu do zbudowania wyspy, spróbujmy zastanowi si, co zamierzamy stworzy , aby podczas czytania tej ksiki pamita o naszym celu.
Projektowanie gry By waciwie przygotowa si do zrealizowania zadania polegajcego na stworzeniu wikszej gry, zastanówmy si dobrze, co waciwie zamierzamy zbudowa . Dziki temu bdziesz móg lepiej zrozumie sens nastpnych dziaa i ich odpowiednie zalenoci od siebie. Gra, któr chcemy zaprojektowa , bdzie si nazywa Survival Island. Oczywicie moesz wymyli dowoln nazw i jej uy ! Podstawowa koncepcja gry polega na tym, e posta sterowana
Projektowanie gier w rodowisku Unity 3.x
przez Ciebie pojawia si na bezludnej wyspie, gdzie znajduje si aktywny wulkan i barak zbudowany przez jak firm. Twoim celem jest przetrwanie nocy na wyspie dziki rozpaleniu ognia, który oprócz tego, e bdzie Ci ogrzewa , pozwoli na wezwanie pomocy. Aby rozpali ogie, potrzebujesz zapaek, lecz one znajduj si w zamknitym baraku. By otworzy barak, gracz musi znale kilka ogniw pozwalajcych zasili generator sterujcy drzwiami baraku. Ostatnie ogniwo bdzie dostpne w minigrze, w któr bdziesz musia zagra . Bdzie ona polega na rzucaniu orzechami kokosowymi do celów w strzelnicy. Jeli uda Ci si je wszystkie zaliczy , wygrasz najwaniejsz i ostatni bateri! Gracz rozpocznie gr na play i bdzie musia znale budynki, wdrujc po ciece na wyspie. Oto ogólny szkic wyspy — oczywicie budynki, ognisko i wulkan nie zostay przedstawione we waciwej skali!
Dziaania rozpoczniemy od wykorzystania narzdzia tworzenia terenu w celu zaprojektowania i zbudowania wyspy (patrz pierwszy rysunek na nastpnej stronie). Nastpnie zaimportujemy pozostae elementy gry: barak, ogniwa oraz inne skadniki. Bd one dostpne w pakiecie zasobów przygotowanym specjalnie dla tej ksiki. W dalszych rozdziaach uzupenimy teren wyspy o dodatkowe szczegóy; bdzie on wyglda podobnie jak drugi rysunek na nastpnej stronie Scena z prototypem moe si przyda do póniejszego wykorzystania, dlatego powiniene j zachowa w biecym projekcie, ale nie wiza jej z waciw gr. Upewnij si, e scena prototypu zostaa zapamitana, a nastpnie przejd do opcji menu gównego File/New Scene (plik/nowa scena). W dalszej kolejnoci wybierz opcj File/Save Scene As (plik/zapisz scen jako) i zapisz scen w folderze Assets (zasoby) pod nazw Island. Konwencje nazewnicze Pamitaj o tym, by nazywajc elementy, zwraca uwag na wielko liter, poniewa podczas tworzenia kodu dotyczcego przykadowo nowej sceny bdziemy uywa nazwy „Island” zaczynajcej si od wielkiej litery.
74
Rozdzia 3. • Tworzenie rodowiska
Uycie edytora terenu Edytor terenu jest niezbdnym narzdziem dla projektanta podczas tworzenia dowolnej gry, w której planuje si uycie rodowiska zewntrznego. System Unity zawiera wasny edytor terenu, pozwalajcy na szybkie i atwe tworzenie zoonych rodowisk. W rodowisku Unity teren jest po prostu obiektem gry, który zawiera doczony komponent ze specjalnymi narzdziami. Tworzenie terenu rozpoczynasz od wygenerowania zwykej paszczyzny, czyli jednostronnego i paskiego trójwymiarowego ksztatu. Moe by on nastpnie szybko przeksztacony na zoony zestaw realistycznych obiektów geometrycznych uzupenionych o szczegóy, takie jak drzewa, skay, roliny, a nawet efekty atmosferyczne, np. wiatr.
75
Projektowanie gier w rodowisku Unity 3.x
Opcje menu terenu Aby zapozna si z opcjami zaprezentowanymi w kolejnym podrozdziale, bdziesz musia utworzy teren. Rozpocznijmy wic od wygenerowania nowego obiektu terenu w naszej grze. Jest to zasób, który moe zosta utworzony w rodowisku Unity przez wybranie opcji menu gównego Terrain/Create Terrain (teren/stwórz teren). Zanim zaczniesz modyfikowa swój teren, powiniene zdefiniowa okrelone parametry charakteryzujce jego rozmiar i poziom szczegóowoci. Gówna opcja menu Terrain (teren) pozwala nie tylko na tworzenie terenu dla gry, lecz równie umoliwia przeprowadzenie operacji omówionych w poniszych punktach (teraz zostan one zaprezentowane ogólnie; dokadny opis pojawi si w dalszej czci ksiki).
Importowanie i eksportowanie map wysokociowych Mapy wysokociowe s dwuwymiarowymi obiektami graficznymi, zawierajcymi jasne i ciemne obszary. Reprezentuj one topografi terenu i mog zosta zaimportowane jako alternatywne rozwizanie dla odpowiednich narzdzi wystpujcych w rodowisku Unity. Mapy wysokociowe mog by tworzone w programach graficznych takich jak Photoshop, a nastpnie zapisywane w formacie RAW. S one czsto wykorzystywane podczas projektowania gier, gdy mog by w prosty sposób eksportowane i przesyane midzy aplikacjami graficznymi i rodowiskami projektowymi, takimi jak Unity. Do wygenerowania rodowiska uyjemy narzdzi edycji terenu dostpnych w systemie Unity, dlatego nie bdziemy wykorzystywa map wysokociowych stworzonych w zewntrznych programach. Uwaga Podczas uywania narzdzi Paint Tools w rodowisku Unity jest w rzeczywistoci tworzona niewidoczna dla uytkownika mapa wysokociowa. Narzdzia te pozwalaj na prostsz jej obsug, ni ma to miejsce w innych aplikacjach. Czytelnicy, którzy zajmuj si grafik, mog wykorzysta t moliwo w celu zaimportowania lub wyeksportowania istniejcych map stworzonych przez siebie przy uyciu innych pakietów.
Ustalanie rozdzielczoci Zaprezentowane niej okno dialogowe pozwala na zdefiniowanie szeregu waciwoci dla kadego nowo utworzonego obiektu terenu. Ustawienia te powinny zosta zdefiniowane zawsze przed stworzeniem topografii terenu. Ich póniejsza zmiana moe spowodowa , e wprowadzone przez Ciebie modyfikacje zostan uniewanione.
76
Rozdzia 3. • Tworzenie rodowiska
Q Terrain Width (szeroko obszaru terenu), Terrain Height (wysoko obszaru terenu)
Q
Q
Q Q
Q
i Terrain Length (dugo obszaru terenu). Wielkoci te s wyraone w metrach. Zwró uwag na to, e parametr Terrain Height oznacza maksymaln wysoko , jak moe osign topografia terenu. Heightmap Resolution (rozdzielczo mapy wysokociowej). Jest to rozdzielczo tekstury, któr przechowuje rodowisko Unity w celu reprezentowania topografii za pomoc pikseli. Pomimo tego, e wikszo tekstur terenów w systemie Unity ma rozmiary równe potdze dwójki (128×128, 256×256, 512×512 itd.), rozdzielczoci mapy wysokociowej wymagaj uwzgldnienia dodatkowego piksela. Wynika to std, i kady piksel definiuje punkt wierzchoka, dlatego na przykad dla terenu o rozmiarze 4×4 istniej cztery wierzchoki, które s obecne w kadym rzdzie siatki. Mimo tego liczba punktów, w których te wierzchoki si cz (wliczajc w to krawdzie terenu), wynosi 5. Detail Resolution (rozdzielczo szczegóów). Rozdzielczo grafiki, znana jako mapa rozdzielczoci szczegóów, któr rodowisko Unity przechowuje w metadanych projektu. Definiuje ona poziom dokadnoci szczegóów terenu. Szczegóami s dodatkowe skadniki terenu, takie jak roliny, skay czy krzewy. Im wysza jest warto parametru, tym dokadniej moesz rozmieci szczegóy na terenie, biorc pod uwag ich lokalizacj. Detail Resolution Per Patch (rozdzielczo szczegóów dla fragmentu). Rozdzielczo kadego fragmentu terenu. Control Texture Resolution (rozdzielczo tekstury sterujcej). Jest to rozdzielczo tekstur podczas ich nakadania na powierzchni terenu. Inna nazwa tego parametru w rodowisku Unity to tekstury Splatmap. Definiuje on szczegóy gradientów przej midzy teksturami umieszczanymi na powierzchni terenu. Podobnie jak w przypadku kadej rozdzielczoci tekstur jest zalecane, aby warto tego parametru bya niewielka, gdy poprawia to sprawno dziaania systemu. Pamitajc o tym, dobrze jest zachowa jego domyln warto równ 512. Im parametr jest wyszy, tym dokadniej mona poczy krawdzie wielu tekstur znajdujcych si na tym samym obszarze. Base Texture Resolution (rozdzielczo tekstury podstawowej). Rozdzielczo tekstury uywanej przez rodowisko Unity podczas renderowania obszarów terenu, które s odpowiednio odlege od wykorzystywanej przez gr kamery, lub w przypadku sprztu o gorszej wydajnoci.
77
Projektowanie gier w rodowisku Unity 3.x
Hurtowe rozmieszczanie drzew Opcja menu Mass Place Trees (hurtowe rozmieszczanie drzew) wykonuje dokadnie to, co oznacza jej nazwa — umieszcza na terenie okrelon liczb drzew, biorc pod uwag zdefiniowane dla tej czynnoci parametry (wysoko , grubo , gsto rozmieszczania oraz poziom zmiennoci), które s dostpne w obszarze Place Trees (rozmieszczanie drzew), przeznaczonym dla komponentu skryptu w panelu Inspector (inspektor). Funkcji tej nie powinno si uywa w kadym przypadku, poniewa nie pozwala ona kontrolowa pooenia drzew, lecz jedynie wpywa na gsto ich rozmieszczenia, a take grubo i wysoko pni, co wynika z parametrów samego komponentu. Zaleca si, aby zamiast tej funkcji uywa narzdzia Place Trees (rozmieszczanie drzew), które pozwala na samodzielne definiowanie bardziej realistycznej metody rozmieszczania drzew.
Wyrównanie mapy wysokociowej Opcja menu Flatten Heightmap (wyrównanie mapy wysokociowej) pozwala na wyrównanie terenu do okrelonej wysokoci. Domylnie poziom terenu znajduje si na wysokoci równej zeru, tak wic jeli chcesz umieci go wyej (np. w przypadku naszej wyspy), moesz zdefiniowa odpowiedni warto omawianego parametru.
Aktualizacja prototypów drzew i szczegóów Jeli zmodyfikujesz zasoby tworzce drzewa i szczegóy, które zostay ju umieszczone na terenie, moesz wybra opcj Refresh Tree and Detail Prototypes (aktualizacja prototypów drzew i szczegóów), aby zaktualizowa ich wygld.
Narzdzie edycji terenu Zanim rozpoczniemy budow wyspy, przyjrzyjmy si narzdziom edycji terenu, aby zapozna si z ich funkcjami. Stworzye ju wasny teren, wic powinien on by widoczny w panelu Hierarchy (hierarchia). Jeli nie zosta jeszcze wybrany, zrób to teraz, aby wywietli jego waciwoci w panelu Inspector.
Skrypt terenu Zestaw narzdzi edycji terenu widoczny w panelu Inspector jest dostpny w postaci komponentu o nazwie Terrain (Script) (skrypt terenu). Komponent ten pozwala na wykorzystanie rónych narzdzi i zdefiniowanie ustawie terenu, poniewa jest uzupenieniem wczeniej omówionych funkcji, dostpnych w menu gównym aplikacji. Komponent Terrain (Script) zosta podzielony na kilka sekcji, które s atwo dostpne dziki widocznym ikonom. Poniej zaprezentujemy krótki przegld ich moliwoci w dziedzinie tworzenia terenów.
78
Rozdzia 3. • Tworzenie rodowiska
Zwikszanie/zmniejszanie wysokoci terenu Opcja ta pozwala na zwikszenie wysokoci terenu za pomoc narzdzia Transform (skrót klawiszowy W).
Masz równie moliwo okrelenia stylów pdzli, a take rozmiaru i stopnia przezroczystoci (skutecznoci) deformacji, któr tworzysz. Nacinicie i przytrzymanie klawisza Shift podczas uywania tego narzdzia powoduje efekt przeciwny, czyli obnienie wysokoci, co zaprezentowano na poniszym rysunku.
Ustalanie wysokoci Narzdzie to dziaa podobnie jak wczeniej omówiona opcja zwikszania wysokoci, pozwala jednak ustali t wysoko .
79
Projektowanie gier w rodowisku Unity 3.x
Oznacza to, e moesz zdefiniowa poziom wysokoci, który nie zostanie przekroczony. Jeli na przykad definiowany przez Ciebie obszar terenu osignie okrelon wysoko , zostanie spaszczony, co pozwoli na utworzenie paskowyu. Przedstawiono to na poniszym rysunku.
Wygadzanie powierzchni Ta opcja jest uywana przede wszystkim w celu uzupenienia dziaania pozostaych narzdzi, takich jak definiowanie wysokoci, aby wygadzi strome obszary topografii.
Krawdzie przykadowego paskowyu, omawianego w poprzednim punkcie, s bardzo strome. Jeli chciaby je zmodyfikowa , powiniene uy narzdzia wygadzania powierzchni, tak jak zaprezentowano na rysunku na nastpnej stronie.
Nakadanie tekstur Narzdzie to jest uywane do nakadania tekstur (zwanych w rodowisku Unity Splats) na powierzchni terenu (patrz drugi rysunek na nastpnej stronie).
80
Rozdzia 3. • Tworzenie rodowiska
Aby móc umieci tekstur na terenie, musi ona zosta najpierw dodana do palety dostpnej w obszarze Textures (tekstury) tego narzdzia. Tekstury mog by dodawane poprzez kliknicie przycisku Edit Textures (edycja tekstury), a nastpnie wybranie opcji Add Texture (dodaj tekstur). Pozwala to na uycie w projekcie dowolnego pliku graficznego, a take zdefiniowanie parametrów okrelajcych jego podzia na mniejsze elementy. Pierwsza tekstura, jak dodasz do palety, bdzie domylnie umieszczona na caej powierzchni terenu. Dziki poczeniu kilku tekstur o rónych poziomach przezroczystoci, które samodzielnie naoysz na teren, bdziesz móg uzyska realistycznie wygldajce obszary o takim typie powierzchni, jaki sobie zayczysz. Aby wybra tekstur, któr chcesz umieci na terenie, po prostu kliknij jej miniaturk widoczn na palecie Textures. Uywana tekstura jest wyróniona niebieskim prostoktem.
Umieszczanie drzew Oto kolejne narzdzie, które wykonuje czynno zgodn z jego nazw. Poprzez malowanie przy uyciu myszy lub zastosowanie pojedynczych klikni mona za jego pomoc umieszcza drzewa na terenie, okrelajc jednoczenie, jaki zasób naley w tym celu wykorzysta .
81
Projektowanie gier w rodowisku Unity 3.x
Równie tutaj, podobnie jak w przypadku narzdzia nakadania tekstur, masz dostp do przycisku Edit Trees (edycja drzew), pozwalajcego na dodawanie, edycj i usuwanie zasobów z palety. S one prefabrykatami drzew bdcych obiektami gry. Podczas projektowania gry bdziesz wykorzystywa prefabrykat drzewa palmowego, który zosta zaimportowany razem z innymi zasobami terenu w trakcie tworzenia nowego projektu na samym pocztku ksiki. W grupie Settings (ustawienia) s dostpne nastpujce opcje: Q Brush Size (rozmiar pdzla): liczba drzew, które s umieszczane na terenie
pojedynczym klikniciem mysz; Q Tree Density: odlego midzy kolejnymi drzewami podczas ich umieszczania
na terenie; Q Color Variation (poziom zmiennoci koloru): poziom losowej zmiennoci koloru
drzew podczas generowania kilku obiektów jednoczenie; Q Tree Width/Height (grubo /wysoko drzewa): rozmiary drzew umieszczanych
na terenie; Q Tree Width/Height Variation (poziom zmiennoci gruboci i wysokoci drzewa):
poziom losowej zmiennoci gruboci i wysokoci drzew, pozwalajcy na uzyskanie bardziej realistycznych obszarów zalesionych. Mona równie wykorzysta klawisz Shift, by odwróci efekty dziaania tego narzdzia. W tym przypadku uycie klawisza Shift usuwa istniejce drzewa z terenu. Dodatkowe wcinicie klawisza Ctrl pozwala na usuwanie drzew o typie, który jest wybrany w palecie.
Umieszczanie szczegóów Opcja ta jest podobna w dziaaniu do narzdzia umieszczania drzew, lecz uywa si jej dla mniejszych obiektów, takich jak kwiaty, roliny czy skay.
Ustawienia terenu Opcja ustawie terenu dostpna w palecie ikon Terrain (Script) zawiera róne parametry zwizane z generowaniem terenu przez procesor karty graficznej (GPU).
82
Rozdzia 3. • Tworzenie rodowiska
Moesz tu zmodyfikowa ustawienia wpywajce na poziom szczegóowoci gry. Poziom szczegóowoci podczas projektowania gier definiuje liczba szczegóów dostpnych w okrelonej odlegoci od gracza. W naszym przypadku, czyli gdy chodzi o teren, musimy mie moliwo modyfikowania takich ustawie, jak odlego rysowania obiektów. Jest to koncepcja czsto uywana w grach 3D, która pozwala na renderowanie mniejszej liczby szczegóów obiektów znajdujcych si w wikszej odlegoci od gracza, przez co uzyskuje si lepsz wydajno . W ustawieniach terenu moesz przykadowo zmodyfikowa parametr Base Map Distance (odlego mapy podstawowej), aby zdefiniowa , w jakiej odlegoci od gracza grafika o wysokiej jakoci powinna zosta zastpiona teksturami o mniejszej rozdzielczoci. Dziki temu generowanie odlegych obiektów bdzie mniej kosztowne. Szczegóami zwizanymi z powyszymi ustawieniami zajmiemy si póniej, ju po rozpoczciu tworzenia terenu.
Tworzenie wyspy — soce, morze i piasek A teraz uyjmy zestawu narzdzi i stwórzmy wysp!
Etap 1. Definiowanie terenu Skoro zapoznalimy si ju z powyszymi narzdziami, rozpocznijmy dziaania od upewnienia si, e teren jest wci wybrany w panelu Hierarchy. Jeli tak, przejd do opcji menu gównego Terrain/Set Resolution (teren/definiowanie rozdzielczoci). Przy tworzeniu pierwszego projektu nie chcemy, aby wyspa bya zbyt rozlega, dlatego zdefiniuj parametry Terrain Width (szeroko ) i Terrain Length (dugo ) równe 500 jednostkom. Pamitaj, by naciska klawisz Enter po wprowadzeniu kadej z wartoci. Dziki temu bdziesz móg je skutecznie zapamita po klikniciu przycisku Set Resolution (ustaw rozdzielczo ). Poziom wyspy powinien si znajdowa na wysokoci ziemi, a nie w pooeniu zerowym, które jest domylnie przyjmowane dla kadego nowo tworzonego terenu. Jeli zakadasz, e pooenie zerowe wyspy powinno by równe poziomowi morza, wówczas poziom ziemi powinien zosta podwyszony i sta si wysokoci, na której znajduje si powierzchnia wyspy. Przejd do opcji menu Terrain/Flatten Heightmap (teren/wyrównanie mapy wysokociowej). Kliknij mysz wewntrz pola edycji Height (wysoko ), a nastpnie wprowad warto 30 metrów i zatwierd j klawiszem Enter. Kliknij przycisk Flatten (wyrównanie), by zapamita zmiany.
83
Projektowanie gier w rodowisku Unity 3.x
Powysza modyfikacja wprowadza bardzo niewielk rónic w widoku Scene (scena), poniewa to, co zrobilimy, byo tylko niewielkim podniesieniem terenu w gór. Jednake powodem wprowadzenia tej modyfikacji bdzie due zaoszczdzenie czasu w przyszoci, gdy moemy teraz obniy krawdzie terenu przy uyciu odwróconej opcji zwikszania wysokoci, co pozwoli na uzyskanie podwyszonej wyspy porodku tworzonego obszaru. Ta metoda jest bardziej wydajna czasowo ni tworzenie terenu o wysokoci zerowej, a nastpnie podwyszanie jego centralnego miejsca.
Etap 2. Tworzenie zarysu wyspy W panelu Inspector dla komponentu terenu Terrain (Script) wybierz narzdzie Raise/Lower Terrain (zwikszanie/zmniejszanie wysokoci terenu), czyli pierwsz ikon po lewej stronie. Wybierz pierwszy pdzel z palety i ustaw jego parametr Brush Size (rozmiar pdzla) na warto 100. Przypisz parametrowi Opacity (nieprzezroczysto ) warto 75. Klikajc o Y (zielony stoek) w gadecie znajdujcym si w prawym górnym naroniku okna, zmie widok w panelu Scene, co umoliwi spogldanie z góry na tworzony teren.
Uywajc klawisza Shift w celu obnienia wysokoci, rozpocznij rysowanie ksztatu terenu: stwórz lini brzegow, która opada do poziomu zerowego. atwo poznasz, e osigna ona minimaln wysoko , poniewa teren zostanie automatycznie wyrównany na tej wysokoci. Mimo e nie musimy dokadnie odwzorowywa wyspy zaprezentowanej na pocztku tego rozdziau, postaraj si nie tworzy zbyt dziwnego ksztatu, poniewa bdziesz potrzebowa wikszego obszaru paskiego terenu, eby umieci na nim budynki. Jeli potrzebujesz pomocy, spójrz na poniszy szkic lub skorzystaj z rysunku przedstawionego we wczeniejszej czci tego rozdziau. Po zakoczeniu pracy powiniene uzyska ksztat podobny do tego, który wida na poniszym rysunku. Klikniciem centralnego szecianu w gadecie znajdujcym si w prawym górnym naroniku panelu Scene zmie z powrotem widok na perspektyw trójwymiarow i rozpocznij podziwianie swojej pracy. Powi troch czasu, aby utworzy dodatkowe elementy topograficzne. W tym celu uyj narzdzia Raise/Lower Terrain. Moesz take zastosowa klawisz Shift, by utworzy jezioro. Nastpnie wykorzystaj narzdzie Smooth Height (wygadzanie powierzchni) do wyrównania zbyt ostrych krawdzi. Pozostaw paski obszar w poudniowo-zachodniej czci terenu (lewy dolny naronik na powyszym rysunku), na którym umiecimy wulkan!
84
Rozdzia 3. • Tworzenie rodowiska
Etap 3. Wulkan! A teraz stwórzmy wulkan! W tym celu musisz zastosowa kombinacj narzdzi Paint Height (ustalanie wysokoci), Raise/Lower Terrain oraz Smooth Height. Najpierw jednak uyj opcji Paint Height. Wybierz pierwszy pdzel z palety, a nastpnie ustal warto parametru Brush Size na 75, Opacity na 50, a Height (wysoko ) na 100. Ponownie zmie widok w panelu Scene, co umoliwi spogldanie z góry na tworzony teren. Rozpocznij rysowanie na paskowyu w poudniowo-zachodniej czci wyspy, któr pozostawie niezmienion podczas tworzenia terenu. Pamitaj, e narzdzie przestanie dziaa po osigniciu wysokoci równej 100 jednostek. Twoja wyspa w widoku perspektywicznym powinna wyglda jak na poniszym rysunku. Paskowy wyglda do surowo — poprawimy go poprzez zastosowanie opcji wygadzania. Na razie jednak musimy utworzy krater wulkanu. W tym celu, uywajc narzdzia Paint Height, przypisz parametrowi Height warto 20, a Brush Size — 30. Nastpny krok bdzie atwiejszy do wykonania, jeli zastosujemy widok z góry: kliknij o Y (zielony stoek) w gadecie znajdujcym si w prawym górnym naroniku panelu Scene. A teraz, trzymajc wcinity przycisk myszy, rozpocznij rysowanie: zacznij od rodka paskowyu z wulkanem i kieruj si równomiernie w stron jego krawdzi. Wykonuj dziaanie dopóty, dopóki nie uzyskasz odpowiedniego wydrenia oraz wskich cian wokó niego, tak jak zaprezentowano na drugim rysunku na nastpnej stronie.
85
Projektowanie gier w rodowisku Unity 3.x
Wci jednak krawdzie wierzchoka s zbyt ostre. Gdy wybierzesz widok perspektywiczny, sam bdziesz móg si przekona , e wulkan nie wyglda zbyt adnie. Aby go poprawi , powiniene uy narzdzia Smooth Height. Wybierz je, a nastpnie przypisz parametrowi Brush Size warto 30, a Opacity — warto 100. Trzymajc nacinity klawisz myszy, staraj si przemieszcza pdzlem po wierzchoku i wygadzaj jego krawdzie a do momentu, gdy uzyskasz agodny grzbiet, tak jak przedstawiono na poniszym rysunku:
86
Rozdzia 3. • Tworzenie rodowiska
Wreszcie powi troch czasu na stworzenie kilku nierównoci na caym terenie, pamitaj jednak o pozostawieniu cieki wiodcej z poudniowej czci wyspy (dolnego fragmentu ksztatu widocznego na powyszym rysunku) do miejsca, gdzie umiecisz budynki pokazane na mapie zaprezentowanej wczeniej w tym rozdziale. Gdy wulkan uzyska ju odpowiedni ksztat, moemy si zaj nakadaniem tekstur na wysp w celu uzyskania wikszego realizmu.
Etap 4. Dodawanie tekstur Podczas nakadania tekstur na teren wane jest pamitanie o tym, e pierwsza z nich przykryje cakowicie dany obszar. Biorc to pod uwag, powiniene upewni si, e pierwsza tekstura, któr dodasz do palety, bdzie definiowa podstawowy charakter Twojego terenu. W pakiecie Terrain Assets (zasoby terenu), który dodalimy podczas rozpoczynania projektu, znajdziesz róne zasoby pozwalajce na dopasowanie terenu do wasnych potrzeb. W panelu Project odszukaj folder o nazwie Standard Textures (standardowe tekstury), który z kolei zawiera podfolder Terrain Assets. Rozwi go, klikajc szar strzak po lewej stronie jego nazwy, a nastpnie otwórz podkatalog Terrain Textures (tekstury terenu). Tam znajdziesz niezbdne pliki graficzne z teksturami. W folderze Terrain Textures zawarto cztery tekstury, których uyjesz podczas tworzenia terenu wyspy. Rozpocznijmy od dodania ich do palety. Upewnij si, e obiekt gry Terrain jest wci aktywny w panelu Hierarchy, a nastpnie wybierz narzdzie Paint Texture (nakadanie tekstur) z komponentu Terrain (Script), dostpnego w obszarze Inspector.
87
Projektowanie gier w rodowisku Unity 3.x
Procedura nakadania tekstur Aby umieci cztery tekstury na naszym terenie, rozpocznij od kliknicia przycisku Edit Textures (edycja tekstur), a nastpnie wybierz opcj Add Textures (dodaj tekstury) z menu podrcznego. Zostanie wywietlone okno dialogowe Add Terrain Texture (dodaj tekstur terenu), w którym bdziesz móg wybra dowoln tekstur obecn w Twoim projekcie. Kliknij ma ikon w ksztacie okrgu, znajdujc si po prawej stronie ustawienia Splat (patrz rysunek poniej), by otworzy okno dialogowe Select Texture 2D (wybierz tekstur dwuwymiarow) prezentujce list dostpnych tekstur. W kolejnym kroku wybierz tekstur zwan Grass (Hill) (trawa na wzgórzu). Okno dialogowe jest wyposaone w opcj wyszukiwania, dziki czemu po wprowadzeniu nazwy grass (trawa) moesz ograniczy zestaw wywietlonych tekstur.
Pozostaw niezmienione wartoci parametrów Tile Size X (rozmiar X kafla) i Tile Size Y (rozmiar Y kafla) równe 15. Poniewa uyta tekstura pokryje ca map, taka niewielka warto parametrów pozwoli na uzyskanie odwzorowania o wikszej liczbie szczegóów. Parametry Tile Offset (przesunicie kafla) powinny by równe 0, gdy tekstura jest zaprojektowana do standardowego kafelkowania i nie musi zosta przesunita. Kliknij przycisk Add (dodaj), aby zakoczy . Cay teren zosta automatycznie przykryty trawiast tekstur, poniewa wybrano j jako pierwsz. Kada kolejna tekstura dodana do palety bdzie musiaa zosta naoona przez Ciebie samodzielnie. Powtarzaj powysz czynno , by doda jeszcze trzy tekstury do palety: wybierz nazwy Grass&Rock (trawa i skay), GoodDirt (solidny kurz) oraz Cliff (Layered Rock) (warstwowa ciana skalna). Dla ostatniej tekstury ustal warto parametrów Tile Size X i Tile Size Y na 70, poniewa zostanie ona uyta w rozcignitym obszarze mapy. Gdyby rozmiar kafli by nieduy, tekstura mogaby wydawa si znieksztacona.
Obszary piasku W palecie znajduj si teraz cztery tekstury. Wybór tekstury o nazwie GoodDirt powinien spowodowa , e bezporednio pod ni ukae si niebieska linia. Wartoci parametrów powinny by nastpujce: Brush Size — 60, Opacity — 50, a Target Strength (natenie) — 1. Moesz zacz malowa wybrzee wyspy, uywajc widoku z góry lub perspektywicznego.
88
Rozdzia 3. • Tworzenie rodowiska
Uwaga Jeli do nakadania tekstur uywasz widoku perspektywicznego, dobrze jest pamita o tym, e w celu obrócenia makiety moesz podczas przecigania myszy uy klawisza Alt. Ta metoda dziaa, gdy zostao wybrane narzdzie Hand (skrót klawiszowy Q) lub Transform (skrót klawiszowy W). Moesz take powiksza rozmiar dowolnego panelu nalecego do interfejsu Unity poprzez umieszczenie kursora myszy nad nim, a nastpnie nacinicie klawisza spacji.
Po zakoczeniu pracy powiniene uzyska widok zbliony do tego z poniszego rysunku.
Jeli podczas malowania popenisz jaki bd, moesz usun rezultat pojedynczego uycia pdzla (czyli jednorazowego ruchu myszy przy wcinitym jej przycisku), wybierajc opcj menu Edit/Undo (edycja/wycofanie zmian). Moesz take wybra tekstur z palety i uy jej do ponownego pomalowania terenu.
Trawa i skay Wybierz tekstur Grass&Rock poprzez kliknicie drugiej miniaturki znajdujcej si na palecie. Ustaw nastpujce wartoci parametrów: Brush Size — 25, Opacity — 30 i Target Strength — 0,5. Pomaluj obszary pagórkowate oraz górn cz wierzchoka wulkanu.
89
Projektowanie gier w rodowisku Unity 3.x
Wulkan jak prawdziwy Teraz musimy sprawi , by wygld wulkanu sta si bardziej realistyczny. W tym celu dodamy do niego tekstur Cliff (Layered Rock). Wybierz odpowiedni tekstur z palety i wprowad nastpujce wartoci parametrów: Brush Size — 20, Opacity — 100 i Target Strength — 1. Pomaluj górn zewntrzn cz wierzchoka oraz cay wewntrzny obszar stoka nalecy do wulkanu. Nastpnie powoli zmniejszaj warto parametrów Opacity i Brush Size w miar malowania coraz niszych partii terenu. Dziki temu tekstura skay bdzie pynnie przeksztaca si w tekstur trawy. Uywajc niszych wartoci nieprzezroczystoci, moesz take pomalowa inne wysze wzniesienia na wyspie. Jeli powicisz troch czasu na eksperymenty, docelowy wygld Twojego wulkanu powinien by podobny do tego, który zosta przedstawiony na poniszym rysunku.
Etap 5. Czas na drzewa Po naoeniu tekstur na wysp nadszed czas na uzupenienie jej o drzewa. W pakiecie Terrain Assets znajduje si drzewo, którego moesz uy z edytorem terenu. Na szczcie dla nas jest to zasób definiujcy drzewo palmowe. rodowisko Unity dysponuje take edytorem drzew, który powiniene przetestowa po zakoczeniu czytania tej ksiki i zdobyciu wikszego dowiadczenia. Aby uzyska o nim wicej informacji, odwied stron internetow http://unity3d.com/ support/documentation/Components/class-Tree.html.
90
Rozdzia 3. • Tworzenie rodowiska
Teraz uyjemy jednak drzewa palmowego, które zostao dla nas wykonane. Wybierz narzdzie Place Trees (umieszczanie drzew), a nastpnie kliknij przycisk Edit Trees (edycja drzew). Z menu podrcznego wybierz opcj Add Tree (dodaj drzewo). Pojawi si okno Add Tree (dodaj drzewo). Tak jak ma to miejsce w przypadku innych narzdzi edycji terenu, to okno dialogowe pozwala na wybranie z folderu Assets obiektu o odpowiednim typie. Dla zasobów terenu nie istniej ograniczenia dotyczce drzew. Oznacza to, e moesz doda modele wasnych drzew poprzez skopiowanie ich do folderu Assets (w celu dokadniejszego zapoznania si z tym zagadnieniem przeczytaj odpowiedni dokumentacj dotyczc obiektów drzew). My jednak bdziemy uywa drzewa palmowego dostarczonego razem z zasobami terenu. Kliknij ikon koa znajdujc si po prawej stronie ustawienia Tree (drzewo). Podobnie jak w przypadku omówionej wczeniej opcji nakadania tekstur, równie i tutaj spowoduje to otwarcie okna dialogowego Select GameObject (wybór obiektu gry), w którym moesz wybra obiekt Palm (drzewo palmowe). Atrybut Bend Factor (wspóczynnik uginania) umoliwia uzyskanie efektu uginania drzew pod wpywem wiatru. Jest on jednak wymagajcy obliczeniowo i kada jego warto róna od zera moe spowodowa ograniczenie wydajnoci dziaania aplikacji podczas testowania gry. Jeli to zauwaysz, przypisz parametrowi Bend Factor ponownie warto 0. W celu uzyskania niewielkiego ugicia drzew uyjemy niskiej wartoci atrybutu równej 2. Po jej wprowadzeniu nie zapomnij o naciniciu klawisza Enter. Jeli stwierdzisz, e podany parametr wpywa na nisk wydajno dziaania programu, moesz zawsze wprowadzi warto 0. Kliknij przycisk Add (dodaj), by zapamita dokonane zmiany. Moesz zobaczy drzewo palmowe na niewielkim obrazku otoczonym niebiesk ramk, która oznacza, e zostao ono wybrane. Ustal nastpujce wartoci parametrów: Brush Size — 15 (rysowanie pitnastu drzew za jednym razem), Tree Density (gsto drzew) — 40 (szeroki rozrzut drzew), Color Variation (poziom zmiennoci koloru) — 0,4, a take Tree Height (wysoko drzewa) — 50, Tree Width (grubo drzewa) — 50 i towarzyszce im atrybuty Variation (poziom zmiennoci) — 30, dziki czemu uzyskamy rónorodny zestaw drzew. Uywajc pojedynczych klikni mysz, umieszczaj drzewa na wybrzeu wyspy niedaleko obszarów piaszczystych, tam gdzie w rzeczywistoci powinny si one pojawia . Nastpnie, aby uzupeni wygld terenu, umie jeszcze troch drzew palmowych w przypadkowych miejscach na samej wyspie. Pamitaj, e za kadym razem, gdy bdnie umiecisz drzewa, moesz je usuwa poprzez nacinicie i przytrzymanie klawisza Shift oraz malowanie (przeciganie) mysz.
91
Projektowanie gier w rodowisku Unity 3.x
Etap 6. Trawa jest zawsze bardziej zielona Gdy mamy ju na naszej wyspie drzewa, powinnimy doda troch terenów trawiastych, aby uzupeni tekstur trawy pokrywajc cay teren. W komponencie Terrain (Script) wybierz ikon Paint Details (umieszczanie szczegóów), a nastpnie kliknij przycisk Edit Details (edycja szczegóów). Wybierz opcj Add Grass Texture (dodaj tekstur trawy) z menu podrcznego. Pakiet zasobów terenu zawiera gotow tekstur trawy, dlatego kliknij ma ikon w ksztacie koa, znajdujc si po prawej stronie ustawienia Detail Texture (tekstura szczegóów), aby wywietli okno dialogowe Select Texture 2D (wybierz tekstur dwuwymiarow). Nastpnie wybierz w nim tekstur nazwan po prostu Grass (trawa). Po jej wybraniu pozostaw niezmienione wartoci parametrów Width (grubo ) i Height (wysoko ) oraz upewnij si, e zostaa zaznaczona najniej pooona opcja Billboard. Poniewa tekstury definiujce szczegóy trawy s dwuwymiarowe, moemy uy techniki billboardingu, wykorzystywanej podczas projektowania gier. Polega ona na tym, i dana tekstura jest zawsze odwrócona przodem w stron kamery, co sprawia, e robi wraenie przestrzennej. Jeli uywasz okien wyboru koloru, upewnij si, e atrybuty Healthy Color (kolor ywej roliny) i Dry Color (kolor wyschnitej roliny) maj odcienie podobne do tekstury naoonej na teren. Wybór zbyt jaskrawego koloru spowoduje, e tekstura bdzie wyglda sztucznie.
Kliknij przycisk Add (dodaj), znajdujcy si w dolnej czci okna dialogowego, aby potwierdzi dodanie tekstury do palety. By umieci na mapie traw, moemy ponownie uy funkcji malowania z wykorzystaniem myszy, tak jak w przypadku innych narzdzi edycji terenu. Najpierw musimy wybra rodzaj pdzla i takie ustawienia, eby uzyska obszerne, a jednoczenie nierównomierne nakadanie szczegóów trawy na teren. Poniewa renderowanie trawy take wpywa na wydajno dziaania komputera, zdefiniujemy minimalne parametry: warto Brush Size bdzie, co prawda, równa 100,
92
Rozdzia 3. • Tworzenie rodowiska
lecz atrybutowi Opacity przypiszemy warto 0,1, a Target Strength — 0,3. Dziki temu uzyskamy duy obszar pokrycia przy niewielkiej iloci trawy. Wybierajc pdzel punktowy (patrz poniszy rysunek), moemy stworzy niejednolite obszary pokryte traw.
Przybli powierzchni terenu poprzez wybranie narzdzia Hand, a nastpnie przytrzymanie wcinitego klawisza Ctrl (PC) lub Command (Mac) podczas przecigania myszy w kierunku prawym. Gdy uzyskasz ju odpowiednie powikszenie, ponownie wybierz w edytorze terenu narzdzie Paint Details i klikajc mysz, namaluj kilka obszarów trawiastych. Ze wzgldów wydajnociowych postaraj si nie stworzy ich zbyt wiele. Zawsze moesz wróci do tej opcji edytora w przyszoci i doda wicej trawy, jeli gra dziaa odpowiednio szybko. Uwaga Przyblienie powierzchni terenu podczas rysowania szczegóów w widoku Scene jest niezbdne, poniewa z powodu oszczdzania pamici nie s one wywietlane przy zbyt duej skali mapy. Bdziesz móg czsto zauway, e podczas oddalania si trawa i inne szczegóy nagle znikaj. Ale nie przejmuj si, one wci znajduj si na swoim miejscu!
Etap 7. Niech pojawi si wiato! Mimo e wyspa jest ju gotowa do eksploracji, musimy jeszcze do sceny doda owietlenie. Poniewa jest to Twoje pierwsze podejcie do zagadnienia obsugi owietlenia w rodowisku Unity, byoby dobrze, gdyby wiedzia, w jakich przypadkach wykorzystuje si trzy ponisze rodzaje wiate:
93
Projektowanie gier w rodowisku Unity 3.x
1. Owietlenie kierunkowe. Uywane jako gówne ródo wiata, czsto symuluje wiato soneczne. Nie promieniuje ono z jednego punktu, lecz zamiast tego równomiernie owietla scen z okrelonego kierunku. 2. Owietlenie punktowe. To wiato promieniuje z pojedynczego punktu przestrzeni trójwymiarowej i symuluje pozostae róda, takie jak owietlenie wewntrz budynków, ogie, wiecce obiekty itd. 3. Owietlenie reflektorowe. wiato to take pochodzi z jednego punktu, lecz charakteryzuje si tym, e ma okrelony kierunek i rozproszenie, którego promie mona modyfikowa , podobnie jak ma to miejsce w przypadku reflektora.
Tworzenie wiata sonecznego Do utworzenia gównego róda wiata uyjemy owietlenia kierunkowego. Kliknij przycisk Create w panelu Hierarchy lub wybierz opcj menu gównego GameObject/Create Other (obiekt gry/stwórz inny). Nastpnie z menu podrcznego wybierz pozycj Directional Light (owietlenie kierunkowe). wiato kierunkowe nie promieniuje z jednego punktu, wic jego pooenie jest zupenie nieistotne, poniewa i tak nie moe by widoczne dla gracza. Widzimy jedynie generowane wiato. Jednake w niniejszym poradniku zamierzamy uy owietlenia kierunkowego, które bdzie reprezentowao soce. W tym celu zastosujemy efekt odbicia wiata w obiektywie kamery (tzw. flar). Aby zasymulowa soce, umiecimy ródo wiata wysoko nad wysp. By upewni si, e odpowiada ono kierunkowi wysyanych promieni wietlnych, dodatkowo zdefiniujemy jego pooenie na osi Z w duej odlegoci od pocztku ukadu wspórzdnych. Umie ródo wiata w pooeniu (0, 250, -200) poprzez wprowadzenie odpowiednich wartoci dla komponentu Transform w panelu Inspector. Parametr X rotation (obrót w osi X) ustaw na warto 15, aby nachyli promienie w dó wzgldem osi X. Spowoduje to zwikszenie stopnia owietlenia terenu wyspy. Teraz musimy sprawi , by wiato stao si widzialne. W tym celu uyjemy efektu flary. rodowisko Unity udostpnia go w standardowym pakiecie, który moemy zaimportowa . Zauwa, e nie poprosiem Ci, aby doczy ten efekt na samym pocztku tworzenia naszego projektu. Zrobiem to specjalnie, by móg teraz przetestowa czynno importowania nowego pakietu zasobów. Wczytajmy interesujcy nas pakiet, wybierajc opcj menu gównego Assets/Import Package/Light Flares (zasoby/import pakietu/flary wietlne). Pojawi si okno dialogowe Importing Package (importowanie pakietu), w którym moesz po prostu klikn przycisk Import (importuj) w celu potwierdzenia wczytania pakietu. Jak widzisz, nie jest to skomplikowane.
94
Rozdzia 3. • Tworzenie rodowiska
W tym momencie moesz klikn przycisk w ksztacie maego koa, znajdujcy si po prawej stronie ustawienia Flare (flara) w komponencie Light (owietlenie). Spowoduje to otwarcie okna dialogowego Select Flare (wybór flary), które zawiera kilka rodzajów wanie zaimportowanych efektów flar. Wybierz t o nazwie Sun (soce), a nastpnie zamknij okno. W rozdziale 10. wykorzystamy narzdzie odwzorowania wiata, które poczy ze rodowiskiem wyspy owietlenie stworzone przed chwil, a take w dalszej czci tej ksiki. Dziki temu uzyskamy wysokiej jakoci cienie oraz du sprawno dziaania samej gry.
Etap 8. A co z d wikami? Dwik jest czsto pomijanym zagadnieniem podczas projektowania gier. Aby uzyska naprawd gbok immersj, gracz musi nie tylko widzie otoczenie, które mu udostpniasz, ale take je sysze . Dwik w rodowisku Unity jest obsugiwany za pomoc dwóch komponentów — róda audio i odbiornika audio. Potraktuj ródo audio jako co w rodzaju gonika znajdujcego si w Twoim wiecie gry, za odbiornik audio — jako mikrofon lub ucho gracza. Obiekt kamery ma w rodowisku Unity domylnie doczony komponent odbiornika audio. Zakadajc wic, e w swojej grze zawsze uywasz kamery, prawdopodobnie bdziesz musia jedynie zdefiniowa róda dwiku. Dodatkowo komponent odbiornika audio nie wymaga adnych ustawie — po prostu dziaa. Unity poinformuje Ci o bdzie, jeli przypadkowo usuniesz jedyny odbiornik audio z danej sceny lub skorzystasz w danej chwili z wicej ni jednego aktywnego odbiornika.
D wiki — paskie czy przestrzenne? rodowisko Unity zakada, e domylnie Twoje dwiki bd traktowane jako przestrzenne, czyli takie, które brzmi realistycznie w przestrzeni trójwymiarowej: staj si coraz bardziej ciche, gdy si od nich oddalasz i gdy przemieszczasz si od jednego gonika do drugiego podczas zbliania si do nich z rónych kierunków. Oznacza to, e rodowisko Unity bdzie automatycznie modyfikowao si dwików przy oddalaniu si od ich róde, co jednak w przypadku dwiku otaczajcego nie jest podan opcj. Dwik, nad którym pracujemy, powinnimy wic zmieni na paski — pozwoli nam to na uzyskanie staego poziomu sygnau bez wzgldu na to, gdzie znajduje si odbiornik, czyli ucho gracza. Przykadowo: Q Dwik paski jest najlepsz opcj dla muzyki w grze, poniewa jej sia powinna
by staa bez wzgldu na to, w którym miejscu wiata gry znajduje si gracz. Q Dwik przestrzenny jest najlepszym wyborem w celu zdefiniowania efektu szafy
grajcej wewntrz budynku. Chocia efekt dwikowy moe odtwarza muzyk, uycie dwiku przestrzennego sprawi, e stanie si ona goniejsza dla gracza zbliajcego si do szafy grajcej, a take bdzie si przemieszcza midzy gonikami w odpowiedzi na konkretne ruchy odbiornika, co docelowo spowoduje uzyskanie wyszej immersji.
95
Projektowanie gier w rodowisku Unity 3.x
Formaty plików d wikowych rodowisko Unity pozwala na uycie najbardziej popularnych formatów audio: WAV, MP3, AIFF i OGG. Po rozpoznaniu skompresowanego pliku, takiego jak MP3, nastpuje jego konwersja do formatu OggVorbis. Klipy nieskompresowane (np. WAV) nie s przeksztacane. Pamitaj, e ustawienia zwizane z kompresj danego zasobu, wybranego w panelu Project, mog zosta zmienione w panelu Inspector. Podobnie jak ma to miejsce w przypadku innych rodzajów importowanych zasobów, równie pliki dwikowe s poddawane konwersji w momencie, gdy przeczasz si midzy aplikacj Unity a innym programem. Za kadym razem, gdy chcesz wywietli zawarto folderu Assets, nastpuje odczytanie jego zawartoci w celu wyszukania nowych plików. Opcja pozwalajca na kompresj w innym formacie nie jest jednak dostpna dla plików ju skompresowanych (np. MP3), które chciaby umieci w swoim projekcie.
Wzgórza yj! Aby uczyni wysp bardziej realistyczn, umiecimy w niej ródo audio odtwarzajce cige odgosy otoczenia przy uyciu dwików paskich. Rozpocznij od wybrania obiektu terenu w panelu Hierarchy. Przejd do opcji menu Component/ Audio/Audio Source (komponent/audio/ródo audio). Spowoduje to dodanie komponentu Audio Source (ródo audio) do obiektu Terrain. W przypadku dwików paskich ich poziom pozostaje niezmienny, za pooenie nie jest istotne, dlatego moemy umieci ródo audio w dowolnym obiekcie. Sensowne jest wic poczenie dwiku otoczenia z obiektem terenu wyspy. W panelu Inspector przy terenie moemy teraz zauway obecno komponentu Audio Source, dla którego moesz wybra okrelony plik do odtwarzania lub pozostawi opcj niezmienion w przypadku, gdy planujesz odtwarzanie dwików za pomoc skryptu. Zanim przypiszesz dwik, musimy jednak dysponowa odpowiednim klipem oraz innymi zasobami niezbdnymi, by korzysta z tej ksiki.
Importowanie pakietu zasobów utworzonego dla ksiki By zrealizowa ten punkt, musisz pobra pakiet zasobów utworzony specjalnie dla tej ksiki. Jest on dostpny pod adresem http://www.packtpub.com/support. Odwied t stron i z dostpnej listy wybierz tytu Unity 3.x Game Development Essentials. Aby uzyska cze do zestawu zasobów, podaj adres swojej poczty elektronicznej. Po otrzymaniu cza kliknij je, a nastpnie zapisz na dysku skompresowany plik. Rozpakuj go, a otrzymasz docelowy plik z rozszerzeniem .unitypackage. Wró do rodowiska Unity i wybierz opcj menu gównego Assets/Import Package/ Custom Package (zasoby/importuj pakiet/pakiet uytkownika). Pojawi si okno dialogowe Import Package (import pakietu), w którym bdziesz móg wybra rozpakowany plik zasobów. Nastpnie kliknij przycisk Open (otwórz), aby go otworzy .
96
Rozdzia 3. • Tworzenie rodowiska
Kliknij przycisk Import (importuj), eby potwierdzi dodanie wszystkich plików do projektu. Po krótkiej chwili powiconej na ich wczytanie powiniene je zobaczy w swoim projekcie. Bd dostpne w folderze o nazwie Book Assets (zasoby ksiki). Nastpnie, klikajc szary trójkt obok nazwy Sounds (dwiki), powiniene otworzy odpowiedni podfolder z plikami dwików. Wybierz nazw hillside, co spowoduje pojawienie si grupy Audio Importer (importowanie audio) w panelu Inspector. Odznacz opcj wyboru 3D Sound (dwik przestrzenny), aby zmieni typ dwiku na paski. Nastpnie kliknij przycisk Apply (zastosuj), znajdujcy si w dolnej czci obszaru Audio Importer, by zatwierdzi wprowadzenie zmian. Bdziesz móg zauway pasek postpu w czasie ponownego importowania pliku dwikowego z nowymi ustawieniami. Plik hillside moe ju zosta uyty w komponencie Audio Source do terenu. Kliknij ikon w ksztacie koa, znajdujc si po prawej stronie ustawienia Audio Clip (klip audio) w komponencie Audio Source dla obiektu terenu. Zostanie wywietlone okno dialogowe Select AudioClip (wybór klipu audio) prezentujce list dostpnych w Twoim projekcie plików dwikowych. Wybierz plik hillside, a nastpnie zamknij okno.
Kolejne ustawienia d wiku Komponent Audio Source zawiera róne ustawienia, pozwalajce modyfikowa sposób odtwarzania klipu dwikowego. W przypadku dwiku otoczenia po prostu upewnij si, e zaznaczone s opcje wyboru Play On Awake (uruchom przy starcie) oraz Loop (w ptli). Pozwoli to na automatyczne odtwarzanie dwiku w ptli, gdy gracz pojawi si w scenie (lub uruchomi kolejny poziom). Twój komponent Audio Source powinien wyglda tak jak na poniszym rysunku.
97
Projektowanie gier w rodowisku Unity 3.x
Etap 9. Spójrz w gór, na niebo! Podczas tworzenia rodowiska trójwymiarowego pojcia horyzontu lub odlegoci s wyraane dziki wykorzystaniu opcji zwanej skybox1. Skybox jest szecianem, którego wewntrzne ciany s wypenione szecioma teksturami, symulujcymi w trakcie operacji renderowania niebo i horyzont. Mieci si w nim cay wiat 3D. Podobnie jak ma to miejsce w przypadku prawdziwego horyzontu, gracz nie moe zbliy si do cianek szecianu skybox. Aby uy szecianu skybox w naszej scenie, wybierz opcj menu Edit/Render Settings (edycja/ustawienia renderowania). Obszar Inspector zostanie odpowiednio zmodyfikowany, by wywietli waciwoci renderowania sceny. Kliknij ikon w ksztacie koa, znajdujc si po prawej stronie ustawienia Skybox Material (materia opcji skybox), co spowoduje otwarcie okna dialogowego Select Material (wybierz materia). Technicznie skybox jest pewnym rodzajem materiau — metod umieszczania w grze tekstur na trójwymiarowej siatce. Z otwartego okna wybierz pozycj Sunny 2 Skybox, a wybrany materia zostanie uyty w szecianie skybox. Wane jest, aby pamita, e kady skybox, który utworzysz, bdzie domylnie widoczny jedynie w panelu Game View, chyba e klikniesz przycisk Game Overlay (nakadka gry), znajdujcy si nad górn krawdzi widoku Scene. Jest to rodkowy przycisk, tak jak przedstawiono na poniszym rysunku.
Etap 10. Zbiornik wodny Poniewa stworzylimy teren wyspy, wynika std, e powinna by ona otoczona wod. Woda w darmowej wersji rodowiska Unity jest tworzona za pomoc animowanego materiau, zastosowanego do powierzchni obiektu. Uytkownicy wersji profesjonalnej mog korzysta z bardziej realistycznego pakietu Pro Water. Mimo e przy zastosowaniu systemu czstek jest moliwe stworzenie bardziej dynamicznych efektów symulujcych wod, najlepsz metod pozwalajc na dodanie obszernego zbiornika wodnego jest uycie jednego z odpowiednich materiaów, dostarczanych przez system Unity. Pakiet Water (basic) assets (podstawowe zasoby wody) udostpnia dwie gotowe powierzchnie, zawierajce materiay symulujce wod. S one zapamitane jako prefabrykaty i mog by atwo uyte z poziomu panelu Project. Po prostu otwórz podfolder Water Basic (podstawowe zasoby wody) w folderze Standard Assets. 1
Dosowne tumaczenie to „pudeko nieba” — przyp. tum.
98
Rozdzia 3. • Tworzenie rodowiska
Przecignij prefabrykat Daylight Simple Water na scen i umie go w pooeniu (250, 4, 250) poprzez wprowadzenie odpowiednich wartoci w polach X, Y i Z dla parametru Position komponentu Transform, zawartego w panelu Inspector. Aby powikszy skal prefabrykatu wody w celu utworzenia morza otaczajcego wysp, atrybutom X i Z parametru Scale przypisz po prostu wartoci równe 1600. Dziki temu uzyskasz obszar wodny w samym rodku mapy, którego powierzchnia znajdzie si cztery metry powyej dna morskiego. Woda przykryje naroniki wyspy i ukryje jej prawdziw natur opart na siatkach 3D. Cay teren powinien wyglda tak jak na poniszym rysunku.
Etap 11. Spacer po wyspie W panelu Project rozwi folder Standard Assets, a nastpnie jego podfolder Character Controllers (kontrolery postaci). Znajdziesz tam dwa prefabrykaty — gotowe obiekty First Person Controller (kontroler perspektywy pierwszej osoby) oraz 3rd Person Controller (kontroler perspektywy trzeciej osoby). Poniewa tworzymy gr w perspektywie pierwszej osoby, wybierz prefabrykat First Person Controller. W aktywnym panelu Scene przybli ten fragment wyspy, na którym chciaby umieci obiekt gracza wykorzystujcy perspektyw pierwszej osoby. Twój widok powinien by podobny do przedstawionego na poniszym rysunku. Przecignij prefabrykat First Person Controller z panelu Project na widok Scene. Moesz zauway , e rodowisko Unity próbuje umieci prefabrykat nad napotkanym obiektem zderzacza — w naszym przypadku jest to wbudowany zderzacz terenu. Po zwolnieniu przycisku myszy skoncentruj widok na nowo utworzonym kontrolerze poprzez przemieszczenie kursora nad okno Scene i nacinicie klawisza F.
99
Projektowanie gier w rodowisku Unity 3.x
By moe stwierdzisz, e obiekt jest po prostu do poowy zakopany w ziemi. Wynika to std, i rodowisko Unity umieszcza rodek obiektu (lub punkt jego pocztku wspórzdnych) na powierzchni zderzacza, na który go upuszczasz. To zjawisko zostao zaprezentowane na poniszym rysunku.
Stwarza to pewien problem, gdy podczas rozpoczynania sceny zderzacze nie powinny by ze sob poczone. rodowisko Unity musi wówczas podj decyzj, co naley zrobi , by zlikwidowa poczenie, natomiast zderzacz dla kontrolera perspektywy pierwszej osoby moe by nieaktywny do momentu, a znajdzie si we waciwym pooeniu. Do obiektu stosuj si równie prawa grawitacji, dlatego moe on po prostu upa na powierzchni terenu. Aby unikn takiej sytuacji, wybierz narzdzie Translate (klawisz W), a nastpnie przecignij zielony uchwyt osi Y, by upewni si, e zielona kapsua zarysu zderzacza znajduje si nad powierzchni terenu.
100
Rozdzia 3. • Tworzenie rodowiska
Gdy kontroler perspektywy pierwszej osoby jest ju aktywnym obiektem w grze, moesz zobaczy go w panelu Hierarchy, a jego komponenty w panelu Inspector. A teraz nacinij przycisk Play, aby przetestowa gr. Bdziesz móg porusza si po terenie swojej wyspy! Domylne elementy sterujce postaci s nastpujce: Q strzaka w gór lub klawisz W: do przodu, Q strzaka w dó lub klawisz S: do tyu, Q strzaka w lewo lub klawisz A: krok w lewo, Q strzaka w prawo lub klawisz D: krok w prawo, Q mysz: rozgldanie si lub zmiana kierunku ruchu podczas chodzenia.
Gdy pospacerowae ju po wyspie, moesz wyj z trybu testowania, ponownie naciskajc przycisk Play.
Etap 12. Kocowe ulepszenia Poniewa do gry dodalimy kontroler perspektywy pierwszej osoby, z naszej sceny moemy usun domylny obiekt, czyli gówn kamer (Main Camera). rodowisko Unity przypomina o tym komunikatem wywietlanym w obszarze podgldu konsoli w dolnej czci interfejsu.
Aby rozwiza ten problem, po prostu usu obiekt Main Camera, poniewa ju go nie potrzebujemy. W tym celu zaznacz go w panelu Hierarchy, a nastpnie nacinij klawisze Delete (PC) lub Command+Backspace (Mac). W przypadku innej platformy kliknij prawym klawiszem myszy nazw obiektu w panelu Hierarchy i wybierz opcj Delete (usu) z menu podrcznego. Teraz budowa wyspy jest ju zupenie ukoczona. Wybierz opcj menu File/Save Scene (plik/zapisz scen) i zapamitaj swoj scen, aby nie utraci danych. Gratulacje! Teren Twojej wyspy jest gotowy do eksploracji, wic ponownie nacinij przycisk Play i j rozpocznij! Pamitaj, aby po zakoczeniu ponownie nacisn przycisk Play w celu wyjcia z trybu testowania.
Podsumowanie W tym rozdziale zapoznalimy si z podstawami projektowania Twojego pierwszego rodowiska gry. Rozpoczynalimy od zwykej paszczyzny, lecz po krótkim czasie dysponujemy terenem wyspy cakowicie gotowym do eksploracji. Przyjrzelimy si take zagadnieniom zwizanym
101
Projektowanie gier w rodowisku Unity 3.x
z owietleniem i dwikiem, które s dwoma gównymi skadnikami wykorzystywanymi w kadym typie projektów gier, z którymi bdziesz mia do czynienia. Pamitaj, e zawsze moesz uy narzdzi edycji terenu omówionych w tym rozdziale, aby umieci na wyspie wicej szczegóów. To wanie uczynimy w rozdziale 11., zatytuowanym „Poprawa wydajnoci i kocowe modyfikacje”. Gdy dokadniej poznasz system obsugi dwiku, uyjemy go w dalszej czci ksiki, by doda kolejne róda audio do gry. Podczas czytania ksiki bdziesz odkrywa kolejne elementy, które pozwol na takie uzupenienie rodowiska gry, aby jeszcze bardziej „zawiesi niewiar” gracza i zwikszy poziom jego immersji. Postaramy si zwikszy poziom dynamizmu wyspy: uyjemy systemu czstek, dodamy efekt ognia, a nawet ozdobimy wulkan pióropuszem z dymu i popiou! W kolejnych rozdziaach umiecimy w scenie budynek placówki, a nastpnie dowiemy si, w jaki sposób mona uruchomi animacj otwieranych drzwi w momencie zbliania si do nich przez gracza. Aby zrealizowa to zadanie, pogbimy najpierw nasz wiedz o tworzeniu skryptów w rodowisku Unity, a take uczynimy pierwszy krok do projektowania prawdziwych interakcji w grze.
102
4 Postacie w grze i dalsze wykorzystanie skryptów W tym rozdziale poszerzymy scenariusz wyspy stworzony przez nas w poprzedniej czci ksiki. W tym celu zapoznamy si z konstruowaniem postaci gracza, którego obiekt dodalimy ju do sceny. Obiekt ten jest przykadem postaci wykorzystujcej perspektyw pierwszej osoby. W jaki jednak sposób zestaw jego komponentów pozwala na uzyskanie takiego rezultatu? Podczas analizy poszczególnych skadników tworzcych posta gracza zapoznamy si dokadnie ze sposobem wykonania jego prefabrykatu. Poniewa w scenie gry umiecilimy ju prefabrykat, moglibymy zaakceptowa to, e dziaa on prawidowo, i kontynuowa projekt, lecz byoby to jednak zbyt proste. W kadym przypadku, gdy wykorzystujesz dowolne zasoby nieutworzone przez Ciebie, powiniene upewni si, e rozumiesz zasad ich dziaania, nawet jeli jeszcze sam nie potrafisz ich zaprojektowa . W przeciwnym razie, jeeli cokolwiek si nie powiedzie, bdziesz mia duy problem, w którym nie pomog nawet proby o pomoc kierowane do innych osób. Pamitajc o powyszym, aby zrozumie , w jaki sposób poczenie dosownie kilku obiektów i komponentów moe spowodowa utworzenie penowartociowej postaci, zapoznamy si z nastpujcymi zagadnieniami: Q uycie panelu Inspector (inspektor), Q anatomia postaci — przegld, Q powizania nadrzdny – podrzdny w obiektach, Q komponent Character Controller, Q dopasowywanie zmiennej o dostpie publicznym w panelu Inspector, Q uycie kamer w celu stworzenia widoku,
Projektowanie gier w rodowisku Unity 3.x
Q dalsze wykorzystanie skryptów, Q uycie skryptów w celu uzyskania ruchu gracza.
Uycie panelu Inspector Aby przeanalizowa szczegóy definicji obiektu w panelu Inspector (inspektor), rozpocznijmy od przyjrzenia si tym opcjom, które s wspólne dla obiektów w aktywnej scenie oraz prefabrykatów w projekcie. Na samym szczycie panelu Inspector znajduje si nazwa wybranego obiektu, a take ikona reprezentujca obiekt lub prefabrykat (odpowiednio szecian o cianach w kolorach czerwonym, zielonym i niebieskim lub jasnoniebieskim). Na przykad dla nowo utworzonego obiektu gry (niepochodzcego z istniejcego prefabrykatu) Directional light górny obszar panelu Inspector wyglda nastpujco:
Moesz zauway ikon w ksztacie szecianu o cianach w kolorach czerwonym, zielonym i niebieskim, która reprezentuje standardowy obiekt gry. Naley równie wspomnie , e lokalizacja obiektu w tym miejscu panelu Inspector moe zosta uyta do zmiany jego nazwy poprzez jej zwyke kliknicie i wprowadzenie nowej. Jest to alternatywa dla tego typu operacji, wykonywanych przez nas do tej pory w panelu Hierarchy (hierarchia). Po prawej stronie pola z nazw widnieje opcja wyboru Static (statyczny). Wybranie jej informuje rodowisko Unity o tym, e dany obiekt w scenie nie bdzie si porusza w trakcie trwania gry i mona go wykorzysta do utworzenia odwzorowania wiata na jego powierzchni. Narzdzie Lightmapping (odwzorowywanie wiata) zostanie zaprezentowane w dalszej czci tej ksiki, aby poprawi estetyk sceny. Opcja Static pozwala na uycie opcji Bake (wypalanie) — pótrwaego renderingu owietlenia sceny na jej teksturach, aby zwikszy gbi widoku i jego realizm. Zaznacz opcj wyboru Static dla obiektu Directional light, poniewa póniej uyjemy go w narzdziu Lightmapping. Oprócz ikony, opcji wyboru informujcej o uyciu obiektu oraz jego nazwy moesz zauway pola Tag (znacznik) i Layer (warstwa).
104
Rozdzia 4. • Postacie w grze i dalsze wykorzystanie skryptów
Znaczniki Znaczniki s zwykymi sowami kluczowymi, które mog zosta przypisane do obiektu gry. Do utworzenia znacznika moesz wykorzysta sowo lub zwrot opisujce dany obiekt (lub obiekty) w skryptach gry (jeden znacznik moe by wykorzystywany wiele razy). Jeli uywae wczeniej aplikacji Adobe Flash, moesz potraktowa znaczniki jako co w rodzaju nazwy instancji. Oba pojcia bazuj na sowach kluczowych reprezentujcych obiekty w scenie. Dodawanie znacznika do obiektu gry jest procedur dwustopniow. Najpierw Twój znacznik musi zosta umieszczony na licie przy uyciu menedera znaczników, a nastpnie zastosowany w wybranym przez Ciebie obiekcie. Aby prze wiczy t procedur, stwórzmy i dodajmy pierwszy znacznik do obiektu Directional light. Zaznacz go w panelu Hierarchy, a nastpnie kliknij menu podrczne Tag w miejscu, w którym jest wywietlona nazwa Untagged (bez znaczników). Spowoduje to wywietlenie listy istniejcych znaczników. Moesz wybra znacznik z listy lub utworzy nowy. Wybierz opcj Add Tag (dodaj znacznik), znajdujc si w dolnej czci menu, aby doda znacznik do listy w menederze znaczników.
W panelu Inspector bdzie mona teraz zobaczy opcj Tag Manager (meneder znaczników), a nie parametry komponentów wybranego przez Ciebie obiektu. Meneder znaczników wywietla zarówno znaczniki, jak i warstwy. Aby doda nowy znacznik, musisz klikn szar strzak znajdujc si po lewej stronie nazwy Tags. Spowoduje to wywietlenie pól Size (rozmiar) i Element (element). W tym momencie bdziesz móg wprowadzi nazw znacznika w obszarze znajdujcym si po prawej stronie pozycji Element 0. Podaj nazw Sunlight (wiato soneczne) (znaczniki mog przyjmowa dowolne nazwy), a nastpnie nacinij klawisz Enter lub Return w celu potwierdzenia. Zauwa, e po naciniciu klawisza warto pola Size wzrosa o jeden. Oprócz tego pojawio si nowe pole o nazwie Element 1. Nie musisz go wypenia , poniewa jest ono po prostu przeznaczone dla kolejnego znacznika. Atrybut Size jest zwykym licznikiem zdefiniowanych znaczników. rodowisko Unity wykorzystuje parametry Size i Element w wielu rónych sytuacjach. Bdziesz to móg zauway w trakcie uywania panelu Inspector.
105
Projektowanie gier w rodowisku Unity 3.x
Wanie umiecie nowy znacznik na licie. Jednake nie zosta on jeszcze przypisany do obiektu Directional light. W tym celu ponownie wybierz ten obiekt w panelu Hierarchy i kliknij nazw Untagged, znajdujc si obok pola Tag w panelu Inspector. Bdziesz móg zobaczy , e dodany przez Ciebie znacznik o nazwie Sunlight znajduje si na dole wywietlanej listy. Aby go uy , po prostu wybierz go z menu, jak przedstawiono na poniszym rysunku.
Warstwy Warstwy s dodatkowym sposobem podzielenia obiektów na kategorie w celu zastosowania w odniesieniu do nich okrelonych regu. S one najczciej uywane, by przydziela odpowiednim grupom obiektów reguy renderowania dotyczce wiata i kamer. Jednake mog by take wykorzystane w metodzie rzucania promieni (ang. Raycasting), co umoliwia selektywne ignorowanie okrelonych obiektów. T metod zajmiemy si w nastpnym rozdziale przy okazji omawiania interakcji. Inne znane zastosowanie warstw w obszarze fizycznym polega na umieszczaniu na tej samej warstwie takich obiektów, które powinny oddziaywa na siebie, czyli w praktyce na tworzeniu warstw kolizji obiektów mogcych si ze sob zderza . Na przykad umieszczenie obiektów na warstwie umoliwia ich odseparowanie za pomoc parametru Culling Mask (maska selektywna) zwizanego ze wiatem, dziki czemu nie bd one brane pod uwag podczas renderowania z uyciem owietlenia. Warstwy s tworzone podobnie jak znaczniki. S take dostpne z omówionego wczeniej menedera znaczników.
Prefabrykaty i panel Inspector Jeli aktywny obiekt gry, który wybierasz w panelu Hierarchy, zosta utworzony z prefabrykatu, wówczas w oknie pojawi si dodatkowe ustawienia, tak jak przedstawiono na poniszym rysunku.
106
Rozdzia 4. • Postacie w grze i dalsze wykorzystanie skryptów
Poniej pól Tag i Layer moesz zauway trzy dodatkowe przyciski, pozwalajce na dostp do prefabrykatu, z którego pochodzi dany obiekt: 1. Select (wybierz). Przycisk pozwala na zlokalizowanie i podwietlenie w panelu Project prefabrykatu, z którego pochodzi dany obiekt. 2. Revert (wycofaj). Umoliwia przywrócenie ustawie komponentów aktywnego obiektu do takich, które s uywane w prefabrykacie wywietlanym w panelu Project. 3. Apply (zastosuj). Zmienia ustawienia prefabrykatu na takie, które s uywane w aktualnie wybranej jego instancji. Umoliwia to uaktualnienie dowolnych instancji lub „klonów” tego prefabrykatu, bez wzgldu na to, czy istniej one w aktywnej scenie lub innych scenach. Poniewa zdobye ju wiedz o dodatkowych ustawieniach dostpnych w panelu Inspector, uyjmy go do przeanalizowania postaci gracza.
Anatomia postaci Aby móc przeglda postacie dostpne w pakiecie Character Controllers (kontrolery postaci), który zaimportowalimy do naszego projektu, przyjrzyjmy si, w jaki sposób — z punktu widzenia rodowiska Unity — funkcjonuj prefabrykaty wykorzystujce perspektyw pierwszej i trzeciej osoby. Na poniszym diagramie (patrz nastpna strona) zaprezentowano podstawowe komponenty, które skadaj si na te postacie.
Dekonstrukcja obiektu First Person Controller Zanim zapoznamy si z komponentami tworzcymi First Person Controller (kontroler perspektywy pierwszej osoby, w skrócie FPC), sprawdmy najpierw, z jakich obiektów si on skada. Kliknij ikon szarej strzaki, znajdujc si po lewej stronie obiektu First Person Controller w panelu Hierarchy (hierarchia), aby wywietli jego skadowe. Gdy mamy do czynienia z takim zagniedeniem obiektów, mówimy, e wystpuje midzy nimi powizanie nadrzdny – podrzdny. W naszym przypadku First Person Controller jest obiektem nadrzdnym (rodzicem), za Graphics (grafika) i Main Camera (kamera gówna) s obiektami podrzdnymi (potomkami). Obiekty podrzdne, wywietlane w panelu Hierarchy, ujawniaj swoj przynaleno do rodziców, tak jak zaprezentowano na kolejnym rysunku (patrz strona 111).
107
Projektowanie gier w rodowisku Unity 3.x
108
Rozdzia 4. • Postacie w grze i dalsze wykorzystanie skryptów
Relacje midzy obiektami nadrzdnymi i podrzdnymi Podczas uywania zagniedonych lub podrzdnych obiektów powiniene pamita o kilku gównych zasadach. Jak ju napisano w rozdziale 1., powizania nadrzdny – podrzdny s istotne w zoonych obiektach, które charakteryzuj si okrelon hierarchi. W przypadku kontrolerów perspektywy pierwszej osoby s one szczególnie wane, gdy podczas przemieszczania si i obracania obiektu nadrzdnego jego obiekty podrzdne — szczególnie Main Camera — poruszaj si razem z nim. W celu uzyskania dokadniejszych informacji zapoznaj si z rozdziaem 1., zatytuowanym „Odkryj trzeci wymiar”. Pooenie i obrót obiektu podrzdnego s wzgldne w odniesieniu do jego obiektu nadrzdnego. S definiowane jako pooenie lokalne i obrót lokalny. Na przykad mógby przyj , e Twój obiekt nadrzdny znajduje si we wspórzdnych wiata równych (500, 35, 500). Jednake gdy wybierzesz obiekt podrzdny, bdziesz móg zauway , e jego pooenie jest duo blisze wartoci (0, 0, 0), chocia znajduje si on w przyblieniu w tym samym miejscu co jego rodzic. Na tym polega dziaanie wzgldnoci pooenia. Poprzez umieszczenie obiektu podrzdnego we wspórzdnych (0, 0, 0) sprawiamy, e znajduje si on w pooeniu bezwzgldnym wzgldem swojego obiektu nadrzdnego lub wzgldnym do jego lokalizacji. W panelu Hierarchy kliknij obiekt Graphics, znajdujcy si poniej obiektu nadrzdnego FPC, a zobaczysz, jak dziaa relacja powizania. Mimo e kontroler perspektywy pierwszej osoby znajduje si na wyspie w zupenie przypadkowych wspórzdnych wiata, to jednak obiekt Graphics ma wartoci pooenia równe (0, 0, 0). Z przedstawionej relacji wzgldnoci wynika równie regua polegajca na tym, e ruch obiektu nadrzdnego bdzie naladowany przez obiekt podrzdny przy jednoczesnym dopasowaniu lokalnego pooenia i obrotu do odpowiedniej pozycji i obrotu rodzica w wiecie gry.
Obiekt First Person Controller Obiekt kontrolera perspektywy pierwszej osoby skada si z trzech elementów: 1. First Person Controller. Jest to podstawowy obiekt kontrolera perspektywy pierwszej osoby — inaczej mówic, rodzic caej grupy. Wykorzystuje skrypty oraz zderzacz Character Controller, co pozwala na sterowanie jego zachowaniem. Skrypty umoliwiaj poruszanie obiektu przy uyciu klawiatury oraz jego obracanie za pomoc przesuwania myszy w lewo i prawo.
109
Projektowanie gier w rodowisku Unity 3.x
2. Graphics. Podstawowy ksztat kapsuy, który pozwala projektantowi na wizualne ustalenie lokalizacji obiektu FPC. 3. Main Camera. Kamera gówna jest umiejscowiona w pooeniu, w którym oczekiwaby oczu gracza. Pozwala ona na stworzenie widoku i wykorzystuje skrypty umoliwiajce spogldanie do góry i w dó. Pamitajc o zwizku nadrzdny – podrzdny, moemy teraz powiedzie , e dowolny ruch lub obrót obiektu FPC jest naladowany przez obiekty Graphics i Main Camera. Wybierz obiekt First Person Controller w panelu Hierarchy. Nastpnie po umieszczeniu kursora myszy w oknie Scene (scena) nacinij klawisz F, aby skoncentrowa widok na tym obiekcie. Powiniene ju widzie bia kapsu z zielonym zarysem zderzacza. Przycinij przycisk Play (granie), kliknij w dowolnym miejscu okna Game (gra) i zacznij porusza postaci, spogldajc jednoczenie na okno Scene. Moesz zauway , e w trakcie poruszania postaci za pomoc klawiszy i jej obracania przy uyciu myszy obiekty podrzdne równie si przemieszczaj. Jeli ukad okien w rodowisku Unity nie pozwala Ci na jednoczesne obserwowanie widoków Game i Scene, uyj ustawienia 2 by 3 (2 na 3), wybierajc opcj menu gównego Window/Layouts/2 by 3 (okno/ukad okien/2 na 3).
Obiekt 1. First Person Controller (rodzic) Jeli obiekt First Person Controller jest wci wybrany w oknie Hierarchy, przyjrzyj si jego komponentom, widocznym w panelu Inspector. Bdziesz móg zauway pi elementów, tworzcych obiekt nadrzdny FPC: Transform, Character Controller, Mouse Look (Script), Character Motor (Script) oraz FPSInput Controller (Script).
Transform Kontroler perspektywy pierwszej osoby zawiera komponent Transform, który wywietla informacje o pozycji, obrocie i skalowaniu wybranego obiektu i pozwala na modyfikowanie ich parametrów.
Character Controller Ten skadnik dziaa jako zderzacz, czyli komponent umoliwiajcy naszemu obiektowi osignicie fizycznej obecnoci, dziki czemu bdzie on w stanie oddziaywa na inne obiekty. Zosta specjalnie zaprojektowany w celu przemieszczania postaci i sterowania ni w wiecie gry. Komponent zawiera nastpujce parametry: Q Height (wysoko ). Jest to parametr, który definiuje, jak wysoka powinna by posta ,
czyli okrela zarazem wysoko zderzacza w ksztacie kapsuy. Q Radius (promie). Grubo zderzacza w ksztacie kapsuy. Domylnie promie kapsuy odpowiada promieniowi obiektu podrzdnego Graphics . Jednake powiniene zwikszy t warto , jeli chcesz uczyni posta szersz, by ograniczy jej ruchy lub aby wykrywa zderzenia przy uyciu obszerniejszego zderzacza.
110
Rozdzia 4. • Postacie w grze i dalsze wykorzystanie skryptów
Q Slope Limit (ograniczenie nachylenia). Parametr ten jest brany pod uwag podczas
Q
Q
Q
Q
wspinania si postaci. Pozwala okreli , jak pochyy powinien by stok, by posta nie moga si ju na niego wspi . Dziki uyciu tego parametru komponent Character Controller nie pozwala graczowi na wspinanie si po pionowych cianach lub stromych zboczach terenu, co rzeczywicie byoby nierealne w prawdziwym wiecie. Step Offset (wysoko stopnia). Poniewa w grze moesz uy schodów, ten parametr pozwoli Ci na okrelenie wysokoci, na jak posta moe podnie nog. Im wiksza warto , tym wysze mog by stopnie schodów. Skin Width (grubo skóry). Posta moe zderza si z innymi obiektami w scenie z okrelon prdkoci. Ten parametr pozwala na wskazanie, jak gboko inne obiekty mog oddziaywa na zderzacz postaci bez wyzwalania reakcji. Zosta on utworzony w celu zminimalizowania takich konfliktów z obiektami, czego rezultatem moe by fluktuacja pooenia postaci (drobne, lecz cige drgania obiektu) lub jej zablokowanie w cianie. Taka sytuacja zdarza si, gdy dwa zderzacze nagle spotykaj si ze sob i nie pozwalaj silnikowi gry na odpowiedni reakcj. Zamiast oczekiwanej obsugi procesu zderzenia silnik wyczy oba zderzacze w celu przejcia kontroli lub wymusi zupenie przypadkowe ich zachowanie. Zgodnie z zaleceniami Unity Technologies parametr Skin Width powinien osiga warto do 10% wielkoci parametru Radius postaci. Min Move Distance (minimalna warto przemieszczenia). Jest to najmniejsza warto przemieszczenia obiektu. Zwykle wynosi ona 0. Wprowadzenie wielkoci wikszej od zera oznacza, e posta nie bdzie moga si porusza , chyba e zostanie przeniesiona o odcinek duszy ni warto parametru. Parametr ten jest uywany przede wszystkim do zredukowania fluktuacji pooenia postaci, lecz w wikszoci przypadków jego warto jest równa 0. Center (rodek postaci). Parametr typu Vector3 (skadajcy si z 3 wartoci: x, y i z). Pozwala na zdefiniowanie pooenia zderzacza postaci w miejscu innym ni jej rodek. Warto tego parametru wynosi zazwyczaj 0 i jest on czciej uywany przy postaciach z perspektyw trzeciej osoby, które maj bardziej zoony wygld ni prosta kapsua. Na przykad poprzez modyfikacj wspórzdnej Y moesz zdefiniowa , w którym miejscu stopa postaci powinna dotyka powierzchni gruntu. Wpyw na to ma wanie zderzacz Character Collider, a nie sam ksztat siatki trójwymiarowej tworzcej stop.
Zderzacz Character Collider (podobnie jak inne tego typu obiekty w rodowisku Unity) jest reprezentowany w widoku Scene przez zielony obrys w ksztacie kapsuy.
Mouse Look (Script) Skrypt ten zosta napisany w jzyku C# i odpowiada za obracanie postaci w czasie poruszania mysz. Dziki temu klawisze strzaek poziomych s wykorzystywane do przemieszczania postaci w lewo i prawo bez potrzeby jej obracania. Skrypt zawiera kilka zmiennych o dostpie publicznym, które mona modyfikowa :
111
Projektowanie gier w rodowisku Unity 3.x
Q Axes (osie). Domylna warto zmiennej jest równa MouseX. Dostpnymi opcjami s wartoci MouseX, MouseY i MouseXAndY. Instancja skryptu Mouse Look, wykorzystywana przez obiekt FPC (inna jego instancja jest komponentem obiektu podrzdnego Main Camera), musi zawiera w parametrze Axes tylko o X, poniewa pozwala to na
poruszanie mysz w lewo i prawo, by uzyska obrót caej postaci, wcznie z obiektem podrzdnym Main Camera. Moesz si dziwi , dlaczego po prostu nie wybralimy wartoci obu osi (czyli MouseXAndY) w komponencie Mouse Look obiektu Main Camera. Problem polega na tym,
e jeli pozwolilibymy kamerze na przesuwanie si w obu osiach, posta nie patrzyaby w kierunku, w którym si przemieszcza. Kamera po prostu obracaaby si w miejscu. W wyniku tego moglibymy si rozglda , lecz w czasie poruszania postaci za pomoc klawiszy utracilibymy waciwy kierunek przemieszczania si do przodu, przy zaoeniu, e odpowiada on kierunkowi spogldania samej kamery. Uywajc instancji skryptu Mouse Look w obiekcie nadrzdnym (First Person Controller), pozwalamy na obracanie postaci, co z kolei odpowiednio porusza kamer, gdy jest ona obiektem podrzdnym, który dopasowuje si do obrotu rodzica. Q Sensitivity X, Sensitivity Y (czuo w osi X, czuo w osi Y). Poniewa w skrypcie wykorzystujemy tylko o X, zmienna ta bdzie okrela , jak bardzo ruch myszy w lewo i prawo wpynie na obrót obiektu. Jeli zmiennej Axes zostaaby przypisana o Y, za pomoc tego parametru mona by okrela wpyw ruchu myszy w gór i w dó na obrót kamery w osi pionowej. Zwró uwag na to, e zmienna Sensitivity Y ma warto 0, poniewa nie jest uywana, natomiast zmiennej Sensitivity X zostaa przypisana warto 15 — im wysza warto , tym szybszy obrót. Q Minimum X, Maximum X (minimalny kt osi X, maksymalny kt osi X). Ten parametr
pozwala na ograniczenie kta obrotu, poniewa zadaniem skryptu jest zarzdzanie obracaniem postaci. Odpowiednie wartoci wynosz -360 i 360, co pozwala na wykonanie penego obrotu obiektu wokó wasnej osi. Q Minimum Y , Maximum Y (minimalny kt osi Y, maksymalny kt osi Y). Poniewa nie wykorzystujemy osi Y, warto zmiennej wynosi 0. Mógby jednak wykorzysta ten parametr, jeli chciaby ograniczy kt spogldania postaci w gór i w dó, podobnie jak w przypadku instancji skryptu uywanej w obiekcie podrzdnym Main Camera.
Character Motor (Script) Skrypt ten, napisany w jzyku JavaScript, dostarcza podstawowych funkcji pozwalajcych na stosowanie rónego rodzaju metod sterowania postaci w rodowisku Unity. Jest on udostpniany w pakiecie Character Controllers assets, który zosta przez nas wczeniej zaimportowany. Skrypt dziaa jak silnik, który porusza oboma prefabrykatami kontrolerów pierwszej i trzeciej osoby. Jest on bardzo zoony, lecz zawiera komentarze umieszczone w kodzie przez projektantów z firmy Unity. Zalecamy, aby po przeczytaniu niniejszej ksiki powróci do tego skryptu i przeanalizowa go. Bdziesz zdziwiony, jak wiele zagadnie zaczniesz rozumie !
112
Rozdzia 4. • Postacie w grze i dalsze wykorzystanie skryptów
Gówne zmienne o dostpie publicznym pozwalaj na modyfikacj poniszych ustawie w panelu Inspector lub w samym kodzie: Q Can Control (moe uywa sterowania). Ta prosta zmienna logiczna, przyjmujca
Q
Q
Q
Q
wartoci prawdy lub faszu, pozwala ustali , czy sterowanie ma by wczone, czy wyczone. Powinna by uywana na przykad wtedy, gdy aktywowane jest menu, dziki czemu gracz moe uywa klawiszy sterujcych, aby si w nim porusza . Mona take wykorzystywa t zmienn do zabezpieczenia przed przypadkowym poruszaniem postaci. Use Fixed Update (uyj funkcji FixedUpdate). Funkcja FixedUpdate() jest podobna do funkcji Update(), której uywalimy ju wczeniej, lecz zamiast przeprowadza aktualizacj co klatk, Fixed Update czyni to po kadym kroku fizycznym. Oznacza to, e funkcja ta jest bezporednio zwizana z silnikiem fizycznym. Kady skadnik, który wykorzystuje bry sztywn lub realistyczn symulacj ruchu, powinien uywa funkcji Fixed Update. Dlatego te w naszym przypadku opcja ta jest domylnie zaznaczona. Movement (ruch). Jest to zastosowana w skrypcie instancja klasy CharacterMotorMovement, która zawiera zmienne sterujce bezwadnoci przy poruszaniu si, spadaniu i zatrzymywaniu w powietrzu, jak równie na gruncie. Jumping (skakanie). Jest to uyta w skrypcie instancja klasy CharacterMotorJumping. Zawiera ona zmienne pozwalajce ustali , jak posta ma si zachowywa podczas wykonywania skoków. Dostarcza równie zmiennej logicznej, umoliwiajcej zupene zablokowanie opcji skakania. Moving Platform (poruszajca si platforma). Gdy obiekt Character Controller nie jest typu Rigidbody, wówczas w skrypcie najczciej obsuguje si grawitacj, tak jak ma to miejsce w przypadku komponentu Character Motor . Wymaga to dodatkowego kodowania w celu zaprogramowania reakcji na spotkania z innymi obiektami, takimi jak poruszajce si platformy. Jeli chciaby, by Twoja posta przemieszczaa si za pomoc platform lub wind, wówczas mógby zastosowa zmienn Moving Platform, by wykorzysta odpowiedni fragment skryptu. Pozwala on poruszajcym si obiektom oddziaywa na posta dziki przenoszeniu ruchu z tych obiektów, z którymi kontaktuje si komponent Character Controller.
Q Sliding (lizganie si). Poniewa kontroler postaci ma ksztat kapsuy i zosta
zaprojektowany po to, by odpowiednio reagowa na stopnie schodów i nachylenie terenu, moemy oczekiwa , e przemieszczanie si w dó po nierównym zboczu moe przebiega w formie lizgania si. Odpowiedni zestaw parametrów pozwala na rozwinicie umiejtnoci posiadanych przez posta i zapewnienie pynnego ruchu lizgowego. Opcj lizgania moesz wyczy w prostszych grach platformowych, w których naley zapewni dokadne wykonywanie skoków midzy pókami. Pamitaj równie, e lizganie pojawia si wówczas, gdy posta znajduje si na powierzchni, której kt nachylenia jest wikszy od parametru Slope Limit w komponencie Character Controller. Zabezpiecza to przed wspinaniem si na strome powierzchnie powtarzajcymi si skokami.
113
Projektowanie gier w rodowisku Unity 3.x
FPSInput Controller (Script) Skrypt ten, napisany w jzyku JavaScript, umoliwia postaci poruszanie si do przodu i do tyu, jeli uyjemy klawiszy osi pionowej (strzaka w gór, strzaka w dó lub W, S), przemieszczanie si w kierunkach bocznych za pomoc klawiszy osi poziomej (strzaka w lewo, strzaka w prawo lub A, D), a take skakanie po naciniciu przez nas klawisza skoku, którym jest domylnie spacja. Skrypt dziaa w powizaniu ze skryptem Character Motor i dostarcza mu niezbdnych informacji o stanie wej . Tak te mona wyjani istnienie w skrypcie zmiennych wykorzystujcych klas Input, której uylimy w rozdziale 2., zatytuowanym „Podstawy tworzenia prototypów i skryptów”, w naszym przykadzie zwizanym z tworzeniem prototypu. Moesz tam zauway midzy innymi nastpujcy fragment kodu: var directionVector = new Vector3(Input.GetAxis("Horizontal"), 0, ´Input.GetAxis("Vertical"));
Powyszy przykad wykorzystuje parametr tekstowy "Horizontal" (ruch w poziomie) dla wspórzdnej X oraz "Vertical" (ruch w pionie) dla wspórzdnej Z w celu zdefiniowania zmiennej Vector3. Dziki temu moemy uywa klawiszy strzaek w gór i w dó (lub W i S), aby porusza postaci do przodu i do tyu, za strzaek w lewo i w prawo (lub A i D), by przemieszcza j w kierunkach bocznych. Pamitaj jednak, e obracanie postaci realizowane jest za pomoc myszy i odpowiada za nie inny element, Mouse Look (Script). Skrypt FPSInput Controller równie zawiera komentarze stworzone przez jego projektantów, dlatego moesz go przeanalizowa , aby dowiedzie si, jak dziaa. eby go dobrze zrozumie , powiniene jednak najpierw przeczyta t ksik i zdoby wicej dowiadczenia.
Obiekt 2. Graphics (potomek) Ze wzgldu na to, e uyto perspektywy pierwszej osoby, gracz nigdy nie zobaczy obiektu postaci. Jest ona i tak reprezentowana przez kapsu, która zostaa utworzona wycznie po to, aby projektant móg atwo znale obiekt w oknie Scene podczas testowania gry. Czsto projektanci wyczaj opcj renderowania kapsuy poprzez dezaktywacj komponentu Mesh Renderer w panelu Inspector. Sprawia to, e kapsua bdzie niewidoczna, szczególnie w grach, w których posta gracza jest prezentowana z innych uj w czasie przerywników. Wybierz obiekt podrzdny Graphics w panelu Hierarchy, a nastpnie przyjrzyj si panelowi Inspector, który wywietli odpowiednie komponenty. Przyjmijmy bez udowadniania, e obiekt zawiera komponent Transform, którego pooenie jest równe (0, 0, 0). Znajduje si on w centralnym punkcie obiektu nadrzdnego, czyli First Person Controller. Poniewa jedynym zadaniem obiektu Graphics jest wizualne reprezentowanie gracza, zawiera on po prostu dwa kluczowe komponenty, czynice gracza widocznym. S to Mesh Filter i Mesh Renderer. Co robi te komponenty?
114
Rozdzia 4. • Postacie w grze i dalsze wykorzystanie skryptów
Mesh Filter Mesh Filter jest komponentem zawierajcym siatk, czyli trójwymiarowy ksztat. Jest wykorzy-
stywany przez renderer grafiki w celu wywietlenia powierzchni zdefiniowanej przez siatk. W naszym przypadku powierzchnia nazywa si polySurface2. Nazwa komponentu Mesh Filter dla dowolnego ksztatu 3D jest zazwyczaj taka sama jak nazwa zasobu siatki, któr on reprezentuje. Dlatego te podczas wykorzystywania modeli utworzonych poza rodowiskiem Unity bdziesz móg zauway , e kady komponent Mesh Filter ma nazw pochodzc z tego fragmentu modelu, w którym si znajduje.
Mesh Renderer Gównym zadaniem komponentu Mesh Renderer jest narysowanie i wywietlenie powierzchni na siatce trójwymiarowego obiektu. Oprócz tego zarzdza on take: Q sposobem reagowania siatki 3D na owietlenie, Q materiaami uywanymi na powierzchni w celu zaprezentowania okrelonego koloru
lub tekstury. Komponenty Mesh Renderer charakteryzuj si nastpujcymi parametrami: Q Cast Shadows (rzucanie cieni). Owietlony obiekt bdzie rzuca cie na inne
powierzchnie (opcja dostpna jedynie w wersji Unity Pro). Q Receive Shadows (przyjmowanie cieni). Cienie rzucane przez inne obiekty bd wywietlane na danym obiekcie (opcja dostpna jedynie w wersji Unity Pro). W przypadku kapsuy Graphics adna z powyszych opcji nie zostaa zaznaczona. Po pierwsze dlatego, e kapsua i tak nie bdzie nigdy widoczna. Nie musimy wic wywietla cieni na postaci. Po drugie gracz nie wie, e jego posta w grze jest kapsu, dlatego cie w tym ksztacie wygldaby do dziwnie. Q Materials (materiay). Ten parametr wykorzystuje system Size/Element, uywany
ju w omawianym wczeniej menederze znaczników. Dziki temu mona wybra co najmniej jeden materia, a nastpnie od razu zmodyfikowa jego ustawienia bez potrzeby wyszukiwania, a nastpnie wprowadzania zmian w panelu Project. Poniewa obiekt Graphics udostpnia wycznie funkcje i nie potrzebuje adnego koloru ani tekstury, nie ma w jego przypadku podgldu adnego materiau. Zosta mu wic przydzielony wygld Default Diffuse, który wykorzystuje prosty materia uywany przez nowo tworzone obiekty o ksztatach podstawowych.
Obiekt 3. Main Camera (potomek) Obiekt Main Camera jest Twoim widokiem na wiat gry. W prefabrykacie First Person Controller znajduje si on na wysokoci oczu postaci (na szczycie kapsuy Graphics) i jest sterowany za pomoc skryptów, co pozwala graczowi przemieszcza go niezalenie od caego obiektu nadrzdnego. Dziki temu gracz moe jednoczenie rozglda si i chodzi .
115
Projektowanie gier w rodowisku Unity 3.x
Zazwyczaj obiekty kamery zawieraj oprócz standardowego komponentu Transform jeszcze trzy inne elementy: Camera, GUILayer i FlareLayer. Wykorzystuj take komponent Audio Listener w celu odbierania dwików, lecz jest on zwykle uywany jedynie w gównej kamerze, poniewa rodowisko Unity wymaga, aby w scenie by aktywny tylko jeden odbiornik audio. Kamera wykorzystuje instancj skryptu Mouse Look, któr omawialimy wczeniej. Pozwala ona na obrót kamer w osi pionowej, sterowany za pomoc myszy. Aby lepiej zrozumie dziaanie kamery, przyjrzyjmy si, w jaki sposób dziaaj jej podstawowe komponenty.
Camera Komponent Camera, któremu zwykle towarzysz skadniki GUILayer i FlareLayer, jest najwaniejszym elementem, odpowiedzialnym za tworzenie widoku. Aby zrozumie , jak komponent Camera generuje widok, przeanalizujemy jego parametry, które zostay zaprezentowane na poniszym rysunku.
Q Clear Flags (znaczniki czyszczenia obszaru ekranu). Zazwyczaj opcja ta bdzie domylnie równa wartoci Skybox, co pozwoli kamerze na renderowanie materiau
uytego w skyboksie w biecej scenie. Aby jednak umoliwi projektantowi zarzdzanie wieloma kamerami w celu wywietlania wiata gry, stworzono parametr Clear Flags . Pozwala on na definiowanie okrelonych kamer, jak równie renderowanie tylko pewnych fragmentów wiata gry. Jednake jest mao prawdopodobne, by zacz uywa takich zaawansowanych opcji, zanim nie zapoznasz si dokadnie z podstawami obsugi rodowiska Unity. Q Background (to). Kolor ta jest kolorem generowanym za wszystkimi istniejcymi obiektami gry, jeli nie zosta zdefiniowany materia dla opcji skybox w biecej scenie. Kliknicie bloku koloru pozwoli na jego zmian w oknie wyboru, podobnie jak zrobilimy to z materiaem na prototyp z wczeniejszego rozdziau. Moesz take uy ikony pipety, znajdujcej si po prawej stronie bloku koloru, aby pobra przykadow próbk z dowolnego miejsca ekranu.
116
Rozdzia 4. • Postacie w grze i dalsze wykorzystanie skryptów
Q Normalized View Port Rect (obszar prostoktny znormalizowanego widoku). Ten
parametr pozwala na specyficzne okrelenie rozmiarów i pooenia widoku kamery. Zazwyczaj umoliwia uycie caego ekranu do wywietlania wiata gry. Jest to równie prawda w przypadku komponentu Main Camera umocowanego do gracza. Wspórzdne X i Y maj warto 0, co oznacza, e prostokt reprezentujcy widok kamery ma wspórzdne rozpoczynajce si w lewym dolnym naroniku ekranu. Jeli parametry W (szeroko ) i H (wysoko ) s równe 1, widok wypeni cay ekran, poniewa system wspórzdnych uywany w rodowisku Unity dopuszcza wartoci od 0 do 1. System ten jest uywany w przypadku innych elementów dwuwymiarowych, wród których mona wymieni Graphical User Interface (graficzny interfejs uytkownika, w skrócie GUI). Moliwo zdefiniowania rozmiaru i pooenia widoku pozwala nam na uywanie wicej ni jednej kamery w grze. Na przykad w grze wycigowej chciaby uywa mniejszego widoku kamery umieszczonego w jednym z naroników ekranu, aby obserwowa to, co dzieje si za Twoim samochodem. Dziki temu gracz mógby dostrzec kierowców, którzy zbliaj si do niego. Q Clipping Planes (Near/Far). Paszczyzny odcinajce s w rzeczywistoci odlegociami
ograniczajcymi rysowanie wiata gry. Paszczyzna przednia definiuje najmniejsz odlego , poniej której elementy wiata nie bd generowane. Podobnie paszczyzna tylna okrela najwiksz odlego , przy której koczy si renderowanie obiektów. Paszczyzn odcinajcych uywa si czsto, aby zminimalizowa wykorzystanie pamici w buforze grafiki (czyli obszarze przeznaczonym do przechowywania informacji o elementach wizualnych wiata gry). Pozwalaj one na pomijanie scenerii, która znajduje si zbyt daleko od gracza. W starszych grach 3D stosowanie tej techniki byo bardziej oczywiste, poniewa komputery miay do dyspozycji mniejsze iloci pamici. Aby uzyska pynne dziaanie aplikacji, naleao oszczdza pami poprzez uycie bliej pooonych tylnych paszczyzn odcinajcych. Ogólnie mówic, w razie koniecznoci naley modyfikowa tyln paszczyzn odcinajc. Q Field of view (pole widzenia). Ten parametr definiuje wielko pola widzenia kamery w stopniach. W obiekcie gównej kamery zostaa mu przypisana warto 60. Jest on odpowiedzialny za symulowanie widoku uzyskiwanego przez ludzkie oko. Q Projection (rzut). Zmiana tego ustawienia spowoduje aktywowanie w kamerze widoku rzutu prostoktnego, w przeciwiestwie do standardowego widoku trójwymiarowego zwanego perspektywicznym. Kamery rzutu prostoktnego s uywane przede wszystkim w grach strategicznych czasu rzeczywistego lub prawdziwych platformówkach 2D. Q Depth (gboko ). Ten parametr moe by uywany podczas wykorzystywania wielu kamer. Pozwala na okrelenie priorytetów lub warstw widoków kamer. Oznacza to, e widok kamery z wiksz wartoci parametru Depth bdzie renderowany przed obrazem kamery o mniejszej wartoci tego parametru. Wspópracuje on take z ustawieniem Normalized View Port Rect, aby umoliwi umieszczanie mniejszych widoków kamer w gównym widoku wiata gry. We wspomnianym przykadzie lusterka
117
Projektowanie gier w rodowisku Unity 3.x
wstecznego w grze wycigowej odpowiedzialna za jego dziaanie kamera musiaaby uywa parametru Depth o wikszej wartoci ni kamera gówna. Dziki temu widok z kamery tylnej byby poprawnie renderowany przed widokiem uzyskiwanym z kamery gównej. Q Culling Mask (maska selektywna). Jak wczeniej wspomniano, parametr ten dziaa z warstwami rodowiska Unity i pozwala na uycie selektywnego renderingu. Umieszczajc okrelone elementy gry na odpowiedniej warstwie, a nastpnie waciwie zaznaczajc t opcj na licie wyboru Culling Mask, moesz j wyczy z operacji renderingu. Teraz obiekt Main Camera renderuje wszystkie elementy, poniewa jest jedyn kamer w grze.
GUILayer i Flare Layer Te dwa komponenty nie maj parametrów, lecz po prostu pozwalaj na renderowanie dodatkowych elementów wizualnych. Komponent GUILayer umoliwia rendering elementów dwuwymiarowych, takich jak obiekty GUI Text i GUI Texture. Komponent Flare Layer pozwala kamerze na wywietlanie flar wietlnych, takich jak ta, której uylimy w skadniku Directional light w rozdziale 3., zatytuowanym „Tworzenie rodowiska”.
Mouse Look (Script) Jest to druga instancja komponentu Mouse Look (Script), któr do tej pory widzielimy. Pierwsza z nich jest uywana przez obiekt rodzica, czyli First Person Controller. Jednake w tym przypadku parametr Axes zawiera warto MouseY, co w rezultacie powoduje, e obiekt kamery gównej mona za pomoc myszy obraca wokó osi X i uzyskiwa efekt spogldania do góry i w dó. Poczenie tej funkcjonalnoci z inn instancj skryptu Mouse Look, która umoliwia obracanie obiektu nadrzdnego, udostpnia moliwo cakowicie dowolnego manipulowania widokiem za pomoc myszy, gdy podczas obracania obiektu rodzica kamera gówna równie naladuje jego ruchy.
Audio Listener Komponent Audio Listener dziaa jak nasze uszy i pozwala sysze dwiki generowane przez róda audio umieszczone w grze. Umieszczenie go w kamerze gównej w grze wykorzystujcej perspektyw pierwszej osoby sprawia, e dwiki trójwymiarowe pojawiajce si przykadowo po lewej stronie gracza bd syszane w jego lewym uchu, co pozwoli na stworzenie otoczenia cile naladujcego wiat rzeczywisty. Poniewa poznae ju skadniki obiektu First Person Controller, moemy si dokadniej przyjrze skryptom, zanim bdziesz móg je wykorzysta w nastpnym rozdziale, zatytuowanym „Interakcje”. Pozwoli on na poszerzenie i utrwalenie wiedzy, któr zdobye podczas wczeniejszym wicze z tworzeniem prototypu.
118
Rozdzia 4. • Postacie w grze i dalsze wykorzystanie skryptów
Dalsze wykorzystanie skryptów Sprawne uycie skryptów jest jedn z najwaniejszych umiejtnoci w ciece rozwoju projektanta gier. rodowisko Unity pozwala na tworzenie gier osobom nieposiadajcym rozlegej wiedzy o kodzie ródowym silnika. Jednake wci musisz wiedzie , w jaki sposób napisa kod sterujcy tym silnikiem. Kody tworzone w tym celu wykorzystuj zestaw gotowych klas, które moesz potraktowa jako biblioteki lub instrukcje sterujce dziaaniem. Gdy piszesz skrypty, tworzysz wasne klasy, uywajc w tym celu polece istniejcego silnika Unity. W tej ksice zostan zaprezentowane podstawy tworzenia skryptów w jzyku C# oraz JavaScript. Oprócz tego bardzo zalecamy przeczytanie dodatkowej dokumentacji Scripting Reference. Jest ona dostpna jako element instalacji pakietu Unity i znajduje si w podkatalogu documentation, a take w internecie pod adresem: http://unity3d.com/support/documentation/ScriptReference/. Problemy napotykane podczas tworzenia skryptów mog by czsto rozwizywane przy uyciu powyszej dokumentacji. Jeli to nie pomoe, istnieje moliwo przeszukania bazy odpowiedzi dotyczcych rodowiska Unity, znajdujcej si pod nastpujcym adresem: http://answers.unity3d.com. Moesz take poprosi o pomoc na forach Unity: http://forum.unity3d.com. Inn metod uzyskiwania wsparcia jest dedykowany kana Internet Relay Chat (IRC). Aby dowiedzie si o nim wicej, odwied nastpujc stron: http://unity3d.com/support/community. Nowo tworzony lub modyfikowany skrypt staje si aktywny dopiero wówczas, gdy zostaje doczony do obiektu gry w biecej scenie. Jednake takie skrypty mog wywoywa statyczne (globalne) funkcje zawarte w innych skryptach, niedoczonych do adnych obiektów. Skrypt doczony do obiektu gry staje si jego komponentem. W tym obiekcie zostaje take zastosowany okrelony sposób dziaania, który definiuje skrypt. Mimo tego skrypty nie ograniczaj si jedynie do narzucania sposobu dziaania obiektowi gry, do którego nale, poniewa mog by w nich uywane i inne obiekty, jeli pojawi si odwoanie do ich nazw lub znaczników. Aby lepiej zrozumie dziaanie skryptów, które zamierzamy przetestowa , zapoznajmy si z kilkoma gównymi zasadami ich tworzenia.
Polecenia Polecenia s instrukcjami zapisanymi w skrypcie. Mimo e mog si one znajdowa w dowolnym jego miejscu, powiniene je umieszcza w jakiej funkcji, aby uzyskiwa wiksz kontrol nad sposobem ich wykonywania. Wszystkie polecenia w obu jzykach musz by zakoczone znakiem rednika: speed = 5;
119
Projektowanie gier w rodowisku Unity 3.x
Dziki temu interpreter wie, e powinien oczekiwa nastpnego polecenia lub fragmentu innego skryptu.
Zmienne Zmienne s po prostu kontenerami na informacje. Mog przyjmowa dowolne nazwy przy zaoeniu, e: Q Nazwa nie koliduje z istniejcym sowem w kodzie silnika rodowiska Unity. Q Nazwa zmiennej zawiera wycznie znaki alfanumeryczne oraz podkrelenie i nie
rozpoczyna si od liczby. Na przykad sowo transform istnieje ju w systemie Unity i reprezentuje komponent Transform obiektu gry. Wynika std, e nie moesz go uy jako nazwy zmiennej, poniewa wywoa to konflikt. Zmienne mog zawiera acuchy tekstowe, liczby i odwoania do obiektów, zasobów lub komponentów. Oto przykad deklaracji zmiennej: Jzyk C#: float speed = 9.0f;
Jzyk JavaScript: var speed = 9.0;
Zmiennej speed przyporzdkowano okrelon warto przy uyciu pojedynczego znaku równoci. Caa instrukcja zostaa zakoczona znakiem rednika.
Typy danych zmiennych Podczas deklarowania zmiennych w jzyku JavaScript powiniene take okreli , jaki rodzaj informacji bdzie w nich przechowywany. Robi si to poprzez zdefiniowanie typu danych. Wykorzystujc nasz poprzedni przykad, moemy poniej zaprezentowa t sam deklaracj zmiennej, lecz przy uwzgldnieniu jej typu danych: var speed : float = 9.0;
Przed poleceniem przypisania wartoci do zmiennej uylimy znaku dwukropka, by okreli typ danych. W powyszym przykadzie zmiennej zostaa przypisana liczba dziesitna. Ten typ zdefiniowalimy za pomoc sowa float (skrót od floating point, czyli liczby dziesitnej). Pamitaj, e w jzyku C# informacj o typie danych (w naszym przypadku sowo float) umieszcza si przed nazw zmiennej zamiast sowa var (stosowanego w JavaScript). Pozwala to na jawne przyporzdkowanie typu danych do nowo tworzonej zmiennej. Poprzez okrelenie typu danych w deklarowanej zmiennej moemy sprawi , e skrypt bdzie sprawniej dziaa , poniewa silnik gry nie bdzie musia okrela typu na podstawie odczyty-
120
Rozdzia 4. • Postacie w grze i dalsze wykorzystanie skryptów
wanej wartoci. Poniej przedstawiono kilka powszechnie uywanych typów danych, z jakimi bdziesz mia do czynienia po rozpoczciu tworzenia skryptów w rodowisku Unity (zaznaczono rónice w wielkoci liter w kadym z jzyków): Q String (js) / string (C#): poczenie tekstu i liczb, przechowywane w cudzysowach, np. "to jest string"; Q int: skrót od sowa integer, czyli liczby cakowitej bez przecinka; Q float: warto numeryczna zmiennoprzecinkowa lub dziesitna; Q boolean (js) / bool (C#): warto true lub false (prawda lub fasz), najczciej uywana
jako przecznik; Q Vector3: zbiór wartoci X, Y i Z, czyli wektor o trzech wymiarach; skada si z trzech wartoci typu float, a nowe typy danych s czsto tworzone na podstawie innych typów danych.
Uycie zmiennych Informacja zawarta w zmiennych po ich zadeklarowaniu moe zosta odczytana lub zmodyfikowana. Wystarczy uy nazwy zmiennej. Na przykad, jeli chcielibymy zdefiniowa warto zmiennej speed, uylibymy poniszego zapisu: speed = 20;
W naszym skrypcie moemy take odczyta lub uy wartoci zmiennej. Na przykad, jeli chcielibymy zapamita warto , która jest równa poowie obecnej wartoci zmiennej speed, moglibymy utworzy now zmienn, jak zaprezentowano w poniszym przykadzie (jzyk C#): float speed = 9.0f; float halfSpeed; halfSpeed = speed/2.0f;
Zauwa, e w wierszu odpowiadajcym za deklaracj zmiennej halfSpeed nie przypisuje si jej adnej wartoci. Wynika to std, i przypisanie pojawia si w nastpnym wierszu, w którym dzielimy warto istniejcej zmiennej przez dwa. Zwró uwag na to, e ze wzgldów wydajnociowych moglibymy przypisa zmiennej warto ju podczas jej tworzenia, tak jak zaprezentowano w poniszym fragmencie kodu: float speed = 9.0f; float halfSpeed = speed/2.0f;
Zmienne publiczne i prywatne Zmienne mog by publicznymi lub prywatnymi elementami skryptu. Jednak wycznie publicznie dostpne zmienne mog si automatycznie pojawia w postaci parametrów skryptu, prezentowanego jako komponent w panelu Inspector (inspektor). Zazwyczaj takie zmienne powinny by uywane tylko wówczas, gdy konieczne jest wykonanie w panelu Inspector pewnych modyfikacji. W przeciwnym razie wartoci zmiennych bd zsynchronizowane
121
Projektowanie gier w rodowisku Unity 3.x
z danymi wprowadzonymi w panelu Inspector, a nie zostan zapisane w skrypcie. Jeli wic warto zmiennej powinna by widoczna jedynie w skrypcie, idealnym rozwizaniem jest zdefiniowanie jej z dostpem prywatnym. Konflikty zmiennych publicznych Warto zauway, e gdy tworzysz zmienn publiczn, jej warto jest kontrolowana przez odpowiedni parametr, dostpny w panelu Inspector. Jeli pó niej zmienisz swój skrypt i zmodyfikujesz warto wewntrz skryptu, wówczas powiniene si upewni, e warto widoczna w panelu Inspector nie przykrywa wartoci w skrypcie. Aby unikn konfliktu, mógby zachowa publiczny dostp do tej zmiennej lub po prostu uaktualni reprezentujcy j parametr w panelu Inspector. Jeeli chcesz zdefiniowa zmienn publiczn w celu umoliwienia dostpu do niej z poziomu innych skryptów, powiniene ukry j w panelu Inspector, czyli zabroni systemowi jej serializacji. Oznacza to umieszczenie nastpujcego wiersza przed deklaracj zmiennej: Jzyk C#: [System.NonSerialized] public float runSpeed = 8.0f; Jzyk JavaScript: @System.NonSerialized var runSpeed : float = 8.0;
Deklarowanie zmiennych publicznych i prywatnych W tym podpunkcie zaprezentowano, w jaki sposób mona deklarowa publiczne i prywatne zmienne w jzykach C# i JavaScript. Jzyk C#: Zmienna w jzyku C# jest prywatna bez wzgldu na to, czy zostaa zadeklarowana wewntrz, czy te na zewntrz funkcji. Aby mona j byo zobaczy i zmodyfikowa z poziomu panelu Inspector, powinna zosta poprzedzona prefiksem public. public float gravity = 20.5f; // ta zmienna jest publiczna private float gravity = 20.5f; // ta zmienna jest prywatna float gravity = 20.5f; // ta zmienna jest równie prywatna w jzyku C#
Jzyk JavaScript: Jzyk JavaScript dziaa troch inaczej. Gdy zmienna jest deklarowana wewntrz funkcji, staje si prywatna i jest dostpna tylko wewntrz niej. Jeli jednak zmienna zostanie zadeklarowana poza funkcj, jest od razu publiczna i wymagany jest prefiks private, aby ukry j w panelu Inspector. public var gravity : float = 20.0; // ta zmienna jest publiczna var gravity : float = 20.0; // ta zmienna jest równie publiczna w jzyku JavaScript private var gravity : float = 20.0; // ta zmienna jest prywatna
122
Rozdzia 4. • Postacie w grze i dalsze wykorzystanie skryptów
Kompletny przykad Na poniszym rysunku przedstawiono skrypt napisany w jzyku C# i zastosowany w obiekcie. W klasie Rocket zadeklarowano zmienn publiczn moveSpeed oraz zmienn prywatn blastSpeed. Zmiennej prywatnej nie przypisano wartoci podczas jej deklarowania, lecz zrobiono to w funkcji Update(). Uzyskuje tam ona warto równ zmiennej moveSpeed pomnoonej przez 2. Warto tej zmiennej prywatnej jest nastpnie uywana jako wspórzdna Z w zmiennej typu Vector3, która z kolei jest wykorzystywana w celu ustalenia prdkoci obiektu typu Rigidbody.
Uwaga Pamitaj, e kady parametr zmodyfikowany w panelu Inspector przykryje oryginaln warto przypisan zmiennej w skrypcie. Nie zostanie zmodyfikowany kod skryptu, lecz zmienna zostanie po prostu podmieniona po uruchomieniu gry. Warto zadeklarowana w skrypcie moe zosta przywrócona poprzez kliknicie ikony kóka zbatego, znajdujcej si po prawej stronie komponentu, i wybranie opcji Reset (przywró warto pocztkow) z menu podrcznego.
Funkcje Funkcje lub inaczej metody mog by zdefiniowane jako zestaw instrukcji, który jest wywoywany w okrelonym momencie w trakcie dziaania gry. Skrypt moe zawiera wiele funkcji, a kada z nich moe wywoywa dowoln funkcj, znajdujc si w nim lub w innych skryptach
123
Projektowanie gier w rodowisku Unity 3.x
zewntrznych. Skrypty rodowiska Unity pozwalaj na wywoywanie wielu gotowych ju funkcji, które mog by uruchamiane w okrelonych momentach lub reagowa na dziaania uytkownika. Moesz take tworzy wasne funkcje, a nastpnie wywoywa je, by uruchamia okrelone zestawy polece. W jzyku JavaScript wszystkie funkcje s deklarowane prefiksem function. W jzyku C# najczciej uywa si prefiksu void. Po nim wystpuj nazwa funkcji oraz nawiasy, wewntrz których projektant moe w razie potrzeby umieszcza dodatkowe parametry. Nastpnie pojawia si wntrze funkcji, zawierajce si midzy nawiasami klamrowymi { oraz }. Przyjrzyjmy si teraz kilku przykadom istniejcych funkcji, które moesz w przyszoci wykorzystywa .
Update() Jak mona byo zauway we wczeniejszych przykadach, nowo utworzony plik jzyków C# lub JavaScript w rodowisku Unity rozpoczyna si od funkcji Update(): Jzyk C#: void Update(){ }
Jzyk JavaScript: function Update(){ }
Gry dziaaj z okrelon prdkoci klatek na sekund (ang. Frames Per Second, w skrócie FPS). Funkcja Update() jest wywoywana podczas renderowania kadej klatki. W wyniku tego jest ona uywana przede wszystkim w poleceniach, które musz wykonywa si przez cay czas lub wykrywa zmiany zachodzce w czasie rzeczywistym w wiecie gry. Takie zmiany to na przykad naciskanie klawiszy lub klikanie mysz. Jak zaprezentowano w skrypcie CharacterMotor, podczas obsugi polece zwizanych ze zdarzeniami fizycznymi powinna by uywana alternatywna funkcja FixedUpdate(). Jest ona zsynchronizowana z silnikiem fizycznym, natomiast sama funkcja Update() moe by wywoywana z czstotliwoci zalen od szybkoci klatek.
OnMouseDown() OnMouseDown() jest przykadem funkcji wywoywanej w okrelonym momencie. Jest ona uruchamiana jedynie wówczas, gdy gracz klika mysz zderzacz obiektu gry lub element graficznego interfejsu uytkownika.
Funkcja ta jest najczciej uywana w grach sterowanych mysz lub podczas wykrywania klikni w menu programu. Oto prosty przykad uycia funkcji OnMouseDown() (w jzyku JavaScript) — zakoczy on gr po klikniciu obiektu, do którego podczono poniszy kod:
124
Rozdzia 4. • Postacie w grze i dalsze wykorzystanie skryptów
function OnMouseDown(){ Application.Quit(); }
Istnieje równie wiele podobnych funkcji zwizanych z obsug myszy, takich jak OnMouseUp(), OnMouseEnter() itd. Poszukaj nazwy Mouse w dokumentacji tworzenia skryptów, aby si z nimi zapozna .
Tworzenie wasnych funkcji Podczas tworzenia wasnych funkcji bdziesz móg okreli zestaw polece, które powinny zosta wywoane z dowolnego miejsca Twojego skryptu. Jeli chcielibymy uy pewnych instrukcji w celu przemieszczenia obiektu w okrelone miejsce w wiecie gry, wówczas moglibymy stworzy wasn funkcj, zawierajc odpowiednie polecenia, co pozwolioby na jej wywoanie z innych obszarów naszego skryptu.
Warto zwracana Funkcje, które maj okrelone zadanie, mog nie tylko wykonywa polecenia, ale take zwraca pewn informacj. Na przykad, jeli chcielibymy stworzy funkcj, która wykonywaaby jakie dziaania arytmetyczne i zwracaaby ich wynik, wówczas moglibymy napisa co podobnego do poniszego fragmentu kodu: Jzyk C#: float currentAmount; float DoSums(){ float amount = 5.0f + 55.8f; return amount; } void Update () { if(Input.GetButtonUp("Jump")){ currentAmount = DoSums(); } }
Jzyk JavaScript: private var currentAmount : float; function DoSums() : float{ var amount : float = 5.0 + 55.8; return amount; }
Stworzylimy wasn funkcj DoSums(), która zwraca warto o okrelonym typie. Jest to typ takiego samego rodzaju, jak w przypadku deklaracji zmiennej. W naszym przykadzie jest
125
Projektowanie gier w rodowisku Unity 3.x
zwracana warto o typie float. Aby funkcja moga j zwraca , zdefiniowalimy jej typ oraz uylimy polecenia return. Oznacza ono, e jeli funkcja jest wykorzystywana w innym obszarze skryptu, jej warto wynikowa zostaje zwrócona w podobny sposób, jak gdybymy uywali zmiennej. W tym przypadku jednak mamy wiksze moliwoci, poniewa warto zwracana moe si zmienia i zalee od przebiegu kodu wewntrz funkcji. W powyszym przykadzie jest wyliczana suma skadników, a nastpnie przypisywana do zmiennej currentAmount w momencie, gdy gracz zwalnia klawisz spacji (domylny klawisz dla sygnau wejciowego "Jump"). Tak wic zmienna currentAmount bdzie równa 60,8, poniewa taka warto jest zwracana przez funkcj DoSums(). Wskazówka Aby stworzy wasn funkcj w jzyku C#, jej deklaracj powiniene rozpocz od nazwy zwracanego typu, a nie sowa void. W jzyku JavaScript typ danych jest umieszczany po nazwie funkcji — w taki sam sposób, jak w przypadku deklaracji zmiennej.
Argumenty Argumenty s zmiennymi wewntrz funkcji, które pozwalaj na przesyanie do niej rónych informacji w celu zmodyfikowania jej zachowania. Oznacza to, e nie musisz tworzy kolejnych funkcji zawierajcych odmienne polecenia. Na przykad w przypadku schwytania w puapk posta gracza musi zosta przeniesiona na pocztek poziomu, jeli zginie. Zamiast tworzy oddzielne zestawy polece dla wszystkich czci gry, w których gracz moe zgin , wystarczy zawrze odpowiednie instrukcje w pojedynczej funkcji, wielokrotnie wywoywanej. Zalet takiego rozwizania jest to, e moemy modyfikowa dziaanie funkcji przez zwyke sterowanie ni za pomoc argumentów. Zazwyczaj argumenty s deklarowane w funkcji tak: Jzyk C#: void FunctionName(DataType argument1, DataType argument2){ // tu wystpuj polecenia, które mog wykorzystywa argumenty funkcji }
Jzyk JavaScript: function FunctionName(argument1 : DataType, argument2 : DataType){ // tu wystpuj polecenia, które mog wykorzystywa argumenty funkcji }
Kady z argumentów jest deklarowany wewntrz nawiasów i oddzielany od kolejnego przecinkiem. Jest to podobne do deklarowania zmiennej przy uyciu jej nazwy oraz typu danych.
126
Rozdzia 4. • Postacie w grze i dalsze wykorzystanie skryptów
Deklarowanie wasnej funkcji Aby zilustrowa nasze rozwaania, moglibymy utworzy funkcj zwan SpawnEnemy(), która wygldaaby tak jak w poniszym fragmencie kodu: Jzyk C#: void SpawnEnemy(GameObject enemy, Transform spawnTrans, string enemyName){ GameObject newEnemy = Instantiate(enemy, spawnTrans.position, ´spawnTrans.rotation) as GameObject; newEnemy.name = enemyName; }
Jzyk JavaScript: function SpawnEnemy(enemy : GameObject, spawnTrans : Transform, enemyName : String){ var newEnemy : GameObject = Instantiate(enemy, spawnTrans.position, ´spawnTrans.rotation); newEnemy.name = enemyName; }
Wywoywanie wasnej funkcji Aby wywoa stworzon funkcj, naley poda jej nazw, a nastpnie w nawiasach zestaw danych, które odpowiadaj argumentom zawartym we wczeniejszej deklaracji: Jzyk C#: public GameObject enemyPrefab1; public Transform spawn1; public Transform spawn2; int enemyCount = 0; void Update(){ if(enemyCount < 1){ SpawnEnemy(enemyPrefab1, spawn1, "Ogre"); enemyCount++; } }
Jzyk JavaScript: var var var var
enemyPrefab1 : GameObject; spawn1 : Transform; spawn2 : Transform; enemyCount : int = 0;
function Update(){ if(enemyCount < 1){ SpawnEnemy(enemyPrefab1, spawn1, "Ogre");
127
Projektowanie gier w rodowisku Unity 3.x
enemyCount++; } }
W powyszym przykadzie jest wywoywana funkcja SpawnEnemy(), a jej argumentom s przypisywane nastpujce wartoci: Q enemy: Ten argument jest typu GameObject. Przypisujemy mu warto zmiennej publicznej enemyPrefab, która z kolei zawiera dowolny obiekt gry. W tym przypadku
taki sam rezultat moglibymy osign w panelu Inspector, poniewa zmienna jest publiczna i moemy po prostu przecign prefabrykat na jej nazw. Q spawnTrans: Ten argument jest typu Transform. Uywa si go do deklarowania pooenia
i obrotu w odniesieniu do wykonywanego polecenia (patrz deklaracja zaprezentowana we wczeniejszym podpunkcie). Temu argumentowi przypisujemy warto zmiennej publicznej spawn1, dlatego moglibymy take przecign komponent Transform dla niezainicjalizowanego obiektu gry, aby osign ten sam wynik. Q enemyName: W tym argumencie przekazujemy po prostu warto "Ogre" jako typ danych string.
Argumenty musz zosta podane w odpowiedniej kolejnoci. Jeli przekazalibymy je w niewaciwym porzdku, wówczas otrzymalibymy komunikat, e poniszy wiersz kodu zawiera bdne argumenty: SpawnEnemy("Ogre", enemyPrefab1, spawn1);
Oznacza to po prostu, e przekazalimy dane do funkcji, które nie odpowiadaj temu, czego ona oczekuje w swojej deklaracji (zapisanej poniej w pseudokodzie): SpawnEnemy(enemy – obiekt gry, spawnTrans – obiekt transformacji, ´enemyName – cig znaków zawierajcy informacj);
Niewaciwa kolejno argumentów powoduje, e kompilacja skryptu zatrzymuje si na pierwszym napotkanym problemie, czyli próbie przekazania wartoci typu string zamiast GameObject. Jako podsumowanie powyszych rozwaa poniej prezentujemy kod penego skryptu zapisany w obu jzykach. Jzyk C#: using UnityEngine; using System.Collections; public class test : MonoBehaviour { public GameObject enemyPrefab1; public Transform spawn1; public Transform spawn2;
128
Rozdzia 4. • Postacie w grze i dalsze wykorzystanie skryptów
int enemyCount = 0; void Update(){ if(enemyCount < 1){ SpawnEnemy(enemyPrefab1, spawn1, "Ogre"); enemyCount++; } } void SpawnEnemy(GameObject enemy, Transform spawnTrans, string enemyName){ GameObject newEnemy = Instantiate(enemy, spawnTrans.position, ´spawnTrans.rotation) as GameObject; newEnemy.name = enemyName; } }
Jzyk JavaScript: var enemyPrefab1 : GameObject; var spawn1 : Transform; var spawn2 : Transform; private var enemyCount : int = 0; function Update(){ if(enemyCount < 1){ SpawnEnemy(enemyPrefab1, spawn1, "Ogre"); enemyCount++; } } function SpawnEnemy(enemy : GameObject, spawnTrans : Transform, ´enemyName : String){ var newEnemy : GameObject = Instantiate(enemy, spawnTrans.position, spawnTrans.rotation); newEnemy.name = enemyName; }
Polecenie if else Polecenie if jest uywane w skryptach w celu sprawdzenia warunków. Jeli warunki s spenione, wówczas polecenie if wykonuje zestaw zagniedonych w nim instrukcji. Jeli nie, wykonywane s polecenia w grupie zwanej else. W poniszych przykadach polecenie if sprawdza, czy zmienna grounded typu boolean jest równa true. Jzyk C#: bool grounded = false; float speed;
129
Projektowanie gier w rodowisku Unity 3.x
void Update(){ if(grounded==true){ speed = 5.0f; } }
Jzyk JavaScript: var grounded : boolean = false; var speed : float; function Update(){ if(grounded==true){ speed = 5.0; } }
Jeli warunek zdefiniowany w nawiasach polecenia if jest speniony, to znaczy warto zmiennej grounded jest równa true (co moe by rezultatem wykonania innej funkcji w tym skrypcie), wówczas zmiennej speed zostaje przypisana warto 5. W przeciwnym razie nie uzyska ona adnej wartoci. Poniewa sprawdzamy, czy zmienna typu boolean jest równa true, moglibymy zapisa to w prostszy sposób: if(grounded){}
Powyszy zapis jest identyczny z wczeniejszym if(grounded == true). Aby sprawdzi , czy zmienna grounded zawiera warto false, wystarczy napisa : if(!grounded){}
Poniewa uycie znaku wykrzyknika oznacza zaprzeczenie, moemy teraz sprawdzi warunek, gdy zmienna grounded nie jest równa true. Uwaga Pamitaj, e podczas przypisywania wartoci do zmiennej jest uywany pojedynczy znak równoci '=', natomiast podczas sprawdzania jej stanu wykorzystujemy dwa znaki równoci '=='. S one inaczej nazywane porównawczymi znakami równoci — porównujemy informacje znajdujce si po obu ich stronach. Jeli chciaby wprowadzi zapis oznaczajcy „NIE jest równy”, wówczas powiniene zastpi pierwszy znak równoci znakiem wykrzyknika, jak przedstawiono poniej: if(grounded != true){}
Jeli chcielibymy zdefiniowa warunek awaryjny, moglibymy uy polecenia else, znajdujcego si po instrukcji if. Oznacza ono, e jeli warunki okrelone w poleceniu if nie zostan spenione, powinno si wykona co innego.
130
Rozdzia 4. • Postacie w grze i dalsze wykorzystanie skryptów
Jzyki C# i JavaScript: if(grounded==true){ speed = 5.0f; }else{ speed = 0.0f; }
Jeli zmienna grounded bdzie równa true, zmiennej speed zostanie przypisana warto 0. Aby wykorzysta dodatkowy potencja tkwicy w poleceniach sprawdzajcych warunki, moemy uy zapisu else if przed kocow instrukcj else. Jeli chcielibymy sprawdza wartoci, moglibymy uy poniszego fragmentu kodu: if(speed >= 6){ // wykonaj jakie polecenia } else if(speed >= 3){ // wykonaj inne polecenia } else{ // jeli aden z powyszych warunków nie jest równy true, wykonaj te polecenia }
Pamitaj, e dwa ukoniki // oznaczaj, i kod znajdujcy si za nimi nie jest wykonywany. S one wic pocztkiem komentarza (kodu niewykonywalnego).
Warunki wielokrotne W pojedynczym poleceniu if moemy równie sprawdza wicej ni jeden warunek, uywajc do ich poczenia dwóch znaków &&. Na przykad moglibymy sprawdzi warunki od razu dla dwóch zmiennych i wykonywa instrukcje jedynie wówczas, gdyby miay one okrelone wartoci. W tym celu uylibymy poniszego fragmentu kodu: if(speed >= 3 && grounded == true){ // wykonaj jakie polecenia }
Jeli chcemy sprawdzi , czy który z warunków jest speniony, powinnimy uy dwóch pionowych znaków || oznaczajcych sowo LUB. Nasz kod zapisalibymy w poniszy sposób: if(speed >= 3 || grounded == true){ // wykonaj jakie polecenia }
131
Projektowanie gier w rodowisku Unity 3.x
Oznacza to, e polecenia w instrukcji if zostan wykonane, jeli przynajmniej jeden z warunków bdzie speniony.
Ptle for Podczas pisania skryptów bdziesz czsto musia wielokrotnie wykonywa ten sam zestaw instrukcji, a do momentu, gdy zostan spenione pewne warunki. W tych przypadkach najlepszym rozwizaniem jest uycie ptli for. Ptla for zawiera trzy parametry umieszczone wewntrz nawiasów: for(deklaracja zmiennej cakowitej; warunek kontynuacji ptli; ´instrukcja do wykonania pod koniec kadej iteracji ptli)
W przeciwiestwie do argumentów funkcji parametry ptli for s oddzielone od siebie znakami rednika. Na przykad prosta ptla for zwikszajca licznik wygldaaby nastpujco: Jzyk C#: public int counter = 0; void Start() { for(int i=0; i doorOpenTime){ ShutDoor(currentDoor); doorTimer = 0.0f; } } }
Jzyk JavaScript: function Update(){ if(doorIsOpen){ doorTimer += Time.deltaTime; if(doorTimer > doorOpenTime){
175
Projektowanie gier w rodowisku Unity 3.x
ShutDoor(currentDoor); doorTimer = 0.0f; } } }
Stwórz teraz funkcj ShutDoor() poniej istniejcej funkcji OpenDoor(). W tym celu umie kursor po prawej stronie zamykajcego nawiasu klamrowego } i nacinij Enter. Poniewa dziaa ona podobnie jak funkcja OpenDoor(), nie bdziemy jej dokadnie analizowa . Po prostu zwró uwag na to, e uywamy innej animacji, a take przypisujemy zmiennej doorIsOpen ponownie warto false, dziki czemu caa procedura moe si zacz od pocztku: Jzyk C#: void ShutDoor(GameObject door){ doorIsOpen = false; door.audio.PlayOneShot(doorShutSound); door.transform.parent.animation.Play("doorshut"); }
Jzyk JavaScript: function ShutDoor(door : GameObject){ doorIsOpen = false; door.audio.PlayOneShot(doorShutSound); door.transform.parent.animation.Play("doorshut"); }
Nadszed czas na test! W edytorze MonoDevelop wybierz opcj menu File/Save (plik/zapisz), a nastpnie wró do rodowiska Unity i przetestuj gr, tak jak poprzednio. Licznik czasu spowoduje, e otwarte drzwi zamkn si automatycznie po upywie trzech sekund. Pielgnacja kodu Jeli utworzylimy skrypt, który obsuguje otwieranie i zamykanie drzwi, moemy si zastanowi , w jaki sposób moglibymy wykorzysta nasz wiedz o konstruowaniu funkcji w celu usprawnienia istniejcego kodu. Mamy teraz dwie wasne funkcje — OpenDoor() i ShutDoor(). Wykonuj one te same trzy zadania: odtwarzaj dwik, modyfikuj zmienn logiczn oraz wywietlaj animacj. Dlaczego nie moglibymy stworzy pojedynczej funkcji z odpowiednimi argumentami, które pozwalayby na odtwarzanie rónych dwików, przypisywanie do zmiennej logicznej wartoci true lub false, a take wywietlanie okrelonych animacji? Przypisanie trzech zada do odpowiednich argumentów pozwoli nam na rozwizanie powyszego problemu. Po zamykajcym nawiasie klamrowym funkcji ShutDoor() umie nastpujcy kod:
176
Rozdzia 5. • Interakcje
Jzyk C#: void Door(AudioClip aClip, bool openCheck, string animName, GameObject thisDoor){ thisDoor.audio.PlayOneShot(aClip); doorIsOpen = openCheck; thisDoor.transform.parent.animation.Play(animName); }
Jzyk JavaScript: function Door(aClip : AudioClip, openCheck : boolean, animName : String, thisDoor : GameObject){ thisDoor.audio.PlayOneShot(aClip); doorIsOpen = openCheck; thisDoor.transform.parent.animation.Play(animName); }
Moesz zauway , e powysza funkcja jest podobna do istniejcych funkcji OpenDoor i ShutDoor, lecz w swojej deklaracji zawiera cztery argumenty: aClip, openCheck, animName i thisDoor. S one w rzeczywistoci zmiennymi, które zostaj przypisane podczas wywoywania funkcji, a ich wartoci s uywane wewntrz niej. Na przykad, jeli chcielibymy przesa wartoci odpowiadajce otwarciu drzwi, wywoalibymy funkcj z nastpujcymi parametrami: Door(doorOpenSound, true, "dooropen", currentDoor);
Powyszy kod przekazuje zmienn doorOpenSound do argumentu aClip, warto true do argumentu openCheck, acuch tekstowy dooropen do argumentu animName, a take przypisuje obiekt gry (GameObject), zawarty w zmiennej currentDoor, do argumentu thisDoor. Teraz moesz zmieni wywoanie funkcji OpenDoor(), znajdujce si wewntrz kodu wykrywajcego kolizj. Najpierw usu poniszy wiersz, który wywouje funkcj OpenDoor() w funkcji OnControllerColliderHit(): OpenDoor(currentDoor);
W jej miejsce wstaw poniszy kod: Jzyk C# i JavaScript: Door(doorOpenSound, true, "dooropen", currentDoor);
Dziki temu uzyskalimy pojedyncz funkcj, która jest wywoywana z czterema argumentami: Q doorOpenSound — dwik do odtworzenia; Q true — warto przekazana do zmiennej doorIsOpen; Q dooropen — animacja do wywietlenia; Q currentDoor — obiekt, który uczestniczy w kolizji.
177
Projektowanie gier w rodowisku Unity 3.x
Poniewa wykorzystujemy powysz metod nie tylko do otwierania, ale równie do zamykania drzwi, powinnimy poprawi odpowiedni kod w funkcji Update(). Zlokalizuj instrukcj if, która sprawdza, czy zmienna doorTimer jest wiksza od wartoci doorOpenTime. Wewntrz tej instrukcji zamie wywoanie ShutDoor(currentDoor) na poniszy kod: Jzyk C# i JavaScript: Door(doorShutSound, false, "doorshut", currentDoor);
Moesz ju usun dwie pierwotne funkcje OpenDoor() i ShutDoor(), poniewa nowa funkcja Door() cakowicie je zastpuje. Jeli tworzymy funkcj w opisany wyej sposób, nie stosujemy powtarzajcego si kodu w skryptach, a przez to czynimy go bardziej zwizym, prostszym do odczytania i debugowania. Poza tym oszczdzamy czas, który musielibymy powici na napisanie dwóch rónych funkcji. Jeli chciaby zachowa te dwie funkcje, by przypominay Ci, co zrobie, moesz je po prostu zawrze w komentarzu — nie bd one ju wówczas wykonywalnym elementem skryptu. Umie wic znaki /* przed pocztkiem funkcji OpenDoor(), a */ po zamykajcym nawiasie klamrowym funkcji ShutDoor(). W edytorze bdziesz móg zauway , e kod, zamieniony w wielowierszowy komentarz, zmieni swój kolor. Nastpnie upewnij si, e korzystajc z odpowiedniej opcji menu programu MonoDevelop, zapisae swój skrypt. Wró do rodowiska Unity i kliknij przycisk Play (granie), aby przetestowa gr. Powiniene teraz widzie animacj otwierania i zamykania drzwi. Wci jednak istnieje problem zwizany z uderzaniem w powikszony zderzacz. Wady procedury wykrywania kolizji Nasza pierwsza implementacja otwierania drzwi jest gotowa. Funkcja OnControllerColliderHit() dziaa prawidowo, lecz jej uycie nie jest najlepsz metod tworzenia mechaniki otwierajcej drzwi. Gówne wady zastosowanej metody s nastpujce: Q Kod jest przechowywany w obiekcie gracza, co oznacza, e w przypadku rozbudowy
kodu zwizanego z interakcj skrypt bdzie si powiksza i stanie si trudny do pielgnacji. Q Powikszenie zderzacza powoduje, e gracz uderza w niewidoczn przeszkod, która
co prawda otwiera drzwi, lecz powoduje jednoczenie jego zatrzymanie, co spowalnia rozgrywk. Teraz zajmiemy si drugim z trzech zaplanowanych sposobów otwierania drzwi i uyjemy rzucania promieni.
178
Rozdzia 5. • Interakcje
Metoda 2. Rzucanie promieni W tym punkcie zaimplementujemy drug metod pozwalajc na otwarcie drzwi. Mimo e wykrywanie kolizji z kontrolerem postaci moe by uwaane za poprawne rozwizanie, jednak stosujc koncepcj rzucania promieni, moemy wypróbowa sposób, dziki któremu gracz otwiera drzwi wycznie wtedy, gdy jest ustawiony naprzeciwko nich. Wynika to std, e promie bdzie zawsze rzucany w kierunku spogldania obiektu First Person Controller i nie spotka si z drzwiami, jeli gracz bdzie si przykadowo wycofywa .
Wyczanie procedury wykrywania kolizji przy uyciu komentarzy Aby unikn koniecznoci tworzenia dodatkowego skryptu, po prostu umiecimy w komentarzu, czyli tymczasowo wyczymy, ten fragment kodu, który zawiera funkcj wykrywania kolizji. Aby to zrobi , umiecimy w odpowiednich miejscach znaki zamieniajce dziaajcy kod w komentarz. Upewnij si, e w edytorze jest otwarty skrypt PlayerCollisions, i zlokalizuj nastpujcy wiersz: Jzyk C#: void OnControllerColliderHit(ControllerColliderHit hit){
Jzyk JavaScript: function OnControllerColliderHit(hit: ControllerColliderHit){
Przed powyszym wierszem umie dwa znaki /*. Pamitaj, e umieszczenie w skrypcie znaku ukonika i gwiazdki rozpoczyna komentarz wielowierszowy (w przeciwiestwie do dwóch ukoników, które po prostu tworz komentarz w biecym wierszu). Po zamykajcym nawiasie klamrowym w funkcji wykrywajcej kolizj umie te same znaki, ale w odwrotnej kolejnoci, czyli gwiazdk, po której wystpuje ukonik: */. Caa funkcja powinna zmieni kolor skadni w edytorze, co oznacza, e zostaa zakomentowana.
Przenoszenie kodu — tworzenie skryptu DoorManager Poniewa zamierzamy uy promienia w celu otwarcia drzwi, powinnimy si zastanowi , gdzie umiecimy kod wykonujcy t czynno . Kod otwierajcy drzwi jest teraz przypisany do postaci gracza. Gracz moe spotka wiele rónych obiektów w trakcie gry, dlatego lepiej bdzie przechowywa logik otwierajc i zamykajc drzwi w nich samych. Oznacza to, e drzwi bd „znay” jedynie wasne funkcje oraz wymagania zwizane z ich otwieraniem przez gracza. Dziki temu metoda rzucania promieni oraz wykorzystujca wyzwalacz bd uywa kodu zawartego w obiekcie drzwi. W rodowisku Unity kliknij przycisk Create, znajdujcy si w panelu Project. Nastpnie wybierz odpowiadajcy Ci jzyk programowania. Zmie nazw nowo utworzonego skryptu na DoorManager i wczytaj go do edytora MonoDevelop.
179
Projektowanie gier w rodowisku Unity 3.x
Zamierzamy teraz wykorzysta wikszo naszej logiki, zwizanej z obsug drzwi, ze skryptu PlayerCollisions. Poniewa znamy ju zasad jego dziaania, umie jedynie cay poniszy kod w nowym skrypcie DoorManager. Nastpnie omówimy istniejce rónice i zobaczymy, co zmienio si w samym skrypcie PlayerCollisions. Jzyk C#: using UnityEngine; using System.Collections; public class DoorManager : MonoBehaviour { bool doorIsOpen = false; float doorTimer = 0.0f; public float doorOpenTime = 3.0f; public AudioClip doorOpenSound; public AudioClip doorShutSound; void Start(){ doorTimer = 0.0f; } void Update(){ if(doorIsOpen){ doorTimer += Time.deltaTime; if(doorTimer > doorOpenTime){ Door(doorShutSound, false, "doorshut"); doorTimer = 0.0f; } } } void DoorCheck(){ if(!doorIsOpen){ Door(doorOpenSound, true, "dooropen"); } } void Door(AudioClip aClip, bool openCheck, string animName){ audio.PlayOneShot(aClip); doorIsOpen = openCheck; transform.parent.gameObject.animation.Play(animName); } }
Jzyk JavaScript: private var doorIsOpen : boolean = false; private var doorTimer : float = 0.0f; var doorOpenTime : float = 3.0f; var doorOpenSound : AudioClip;
180
Rozdzia 5. • Interakcje
var doorShutSound : AudioClip; function Start(){ doorTimer = 0.0f; } function Update(){ if(doorIsOpen){ doorTimer += Time.deltaTime; if(doorTimer > doorOpenTime){ Door(doorShutSound, false, "doorshut"); doorTimer = 0.0f; } } } function DoorCheck(){ if(!doorIsOpen){ Door(doorOpenSound, true, "dooropen"); } } function Door(aClip : AudioClip, openCheck : boolean, animName : String){ audio.PlayOneShot(aClip); doorIsOpen = openCheck; transform.parent.gameObject.animation.Play(animName); }
Kluczow zmian w porównaniu z kodem ze skryptu PlayerCollisions jest dodanie funkcji Door ´Check(). Dziki temu mamy procedur, która moe by w prosty sposób wywoywana i nie wymaga przekazywania dodatkowego argumentu, sprawdzajcego, czy drzwi nie s otwarte: if(!doorIsOpen){ Door(doorOpenSound, true, "dooropen"); }
Powyszy kod wywouje funkcj Door() i przekazuje jej odpowiednie argumenty, pozwalajce na otwarcie drzwi. Licznik czasu w funkcji Update() umoliwia zamknicie drzwi i powrót do stanu pierwotnego. Teraz powinnimy usun niepotrzebny kod ze skryptu PlayerCollisions, a nastpnie zaimplementowa metod rzucania promieni.
Porzdkowanie skryptu PlayerCollisions Dysponujemy ju skryptem DoorManager, który zarzdza stanem drzwi, wic moemy usun wikszo kodu ze skryptu PlayerCollisions. Poniewa wci uczysz si obsugi rodowiska Unity, moesz (podobnie jak wczeniej) jedynie zakomentowa odpowiedni kod, zamiast go usuwa . W poniszym przykadzie zaprezentowalimy jednak wycznie te wiersze, które pozostay, dlatego od Ciebie zaley, czy zbdny kod zostanie usunity, czy tylko ujty w znaki komentarza.
181
Projektowanie gier w rodowisku Unity 3.x
Bez wzgldu na decyzj powiniene usun lub umieci w komentarzu takie fragmenty kodu w skrypcie PlayerCollisions, aby pozostay tylko ponisze wiersze: Jzyk C#: using UnityEngine; using System.Collections; public class PlayerCollisions : MonoBehaviour { GameObject currentDoor; void Update () { } }
Jzyk JavaScript: private var currentDoor : GameObject; function Update(){ }
Teraz mamy jedynie funkcj Update()— umiecimy w niej kod wykonujcy operacj rzucania promieni, a take zmienn prywatn, przechowujc odwoanie do drzwi, na które oddziaujemy. Dodajmy kod odpowiedzialny za rzucanie promieni, który bdzie wywoywany w funkcji Door ´Check(), zawartej w skrypcie DoorManager.
Rzucanie promienia Bdc w dalszym cigu w skrypcie PlayerCollisions, umie kursor wewntrz funkcji Update(). Kod odpowiedzialny za rzucanie promieni umiecimy w funkcji Update(), poniewa musimy z powodów technicznych wykonywa t operacj w kadej klatce. Wynika to std, e pooenie i kierunek spogldania gracza mog si w kadej chwili zmieni . Dodaj do funkcji Update() poniszy kod: Jzyk C#: RaycastHit hit; if(Physics.Raycast (transform.position, transform.forward, out hit, 3)) { if(hit.collider.gameObject.tag=="playerDoor"){ currentDoor = hit.collider.gameObject; currentDoor.SendMessage("DoorCheck"); } }
182
Rozdzia 5. • Interakcje
Jzyk JavaScript: var hit : RaycastHit; if(Physics.Raycast (transform.position, transform.forward, hit, 3)) { if(hit.collider.gameObject.tag=="playerDoor"){ currentDoor = hit.collider.gameObject; currentDoor.SendMessage("DoorCheck"); } }
Na pocztku powyszego kodu nastpuje utworzenie promienia przez zadeklarowanie lokalnej zmiennej hit o typie RaycastHit. Zauwa, e nie musi by ona prywatna, by nie bya widoczna w panelu Inspector — wystarczy, e jest lokalna (zadeklarowana wewntrz funkcji). Zmienna ta bdzie wykorzystywana do przechowywania informacji o promieniu podczas jego przecinania si ze zderzaczami. Gdy bdziemy chcieli uy promienia, odwoamy si do zmiennej hit. Nastpnie pojawiaj si dwie instrukcje if. Nadrzdna instrukcja if jest odpowiedzialna za rzucanie promienia oraz uycie zmiennej, któr stworzylimy. Poniewa operacja rzucania promienia (czyli funkcja Physics.Raycast()) bdzie wykonywana w nadrzdnym poleceniu if, dostp do podrzdnej instrukcji if bdzie moliwy jedynie wówczas, gdy promie uderzy w obiekt. Dziki temu poprawimy wydajno skryptu. Nasza pierwsza instrukcja if zawiera funkcj Physics.Raycast(), która przeprowadza operacj rzucania promienia. Ma ona cztery parametry: Q Pooenie, w którym nastpuje tworzenie promienia (transform.position — pooenie obiektu, który jest obsugiwany przez skrypt, czyli First Person Controller). Q Kierunek promienia ( transform.forward — kierunek spogldania obiektu,
który jest obsugiwany przez skrypt). Q Struktura danych RaycastHit, przechowywana w zmiennej hit. Zawiera ona informacje o rzucanym promieniu. Q Dugo promienia (3 — odlego w jednostkach uywanych w grze, czyli metrach). Zauwa, e w jzyku C# musimy uy sowa kluczowego out, umieszczonego przed zmienn hit, aby odzyska warto , któr otrzymaa ona wewntrz funkcji Physics.Raycast(). W jzyku JavaScript taka funkcjonalno jest domylna i wystarczy uy samej nazwy zmiennej. Nastpnie mamy zagniedone polecenie if, które sprawdza przy uyciu zmiennej hit, czy istniej jakie aktywne kolizje ze zderzaczami w wiecie gry, a dokadniej, czy zderzylimy si ze zderzaczem, nalecym do obiektu charakteryzujcego si znacznikiem playerDoor: hit.collider.gameObject.tag == "PlayerDoor"
183
Projektowanie gier w rodowisku Unity 3.x
Jeli oba warunki if s spenione, przypisujemy zmiennej currentDoor warto obiektu przechowywanego w zmiennej hit, a nastpnie poleceniem systemowym SendMessage() wywoujemy funkcj DoorCheck(). Poleceniem SendMessage moemy wywoa dowoln funkcj dla obiektu, nie odwoujc si jednoczenie do okrelonego skryptu, lecz uywajc jedynie jej nazwy: currentDoor.SendMessage("DoorCheck");
Powyszy kod po prostu przeszukuje wszystkie skrypty, doczone do obiektu wskazywanego przez zmienn currentDoor, znajduje funkcj DoorCheck(), a nastpnie j uruchamia. Uwaga Aby uzyska wicej informacji o funkcji SendMessage(), zapoznaj si z dokumentacj tworzenia skryptów w rodowisku Unity, znajdujc si pod adresem: http://unity3d.com/support/documentation/ ScriptReference/GameObject.SendMessage.html.
Zapisz zmodyfikowany skrypt i wró do rodowiska Unity. Musimy jeszcze przypisa skrypt DoorManager do drzwi. W tym celu upewnij si, i struktura obiektu nadrzdnego outPost jest wywietlona w panelu Hierarchy, co powoduje, e widzimy obiekt podrzdny door. Przecignij skrypt DoorManager z panelu Project na obiekt potomka door, znajdujcy si w panelu Hierarchy. Podobnie jak zrobie to wczeniej w przypadku skryptu PlayerCollisions, przypisz klipy audio door_open i door_shut do zmiennych publicznych komponentu skryptu DoorManager w panelu Inspector.
Resetowanie zderzacza Poniewa uywamy teraz metody rzucania promieni w kierunku spogldania gracza, nie potrzebujemy powikszonego zderzacza drzwi. Moemy mu wic przywróci standardowe rozmiary, które odpowiadaj zawierajcej go siatce trójwymiarowej. Aby to zrobi , po prostu wybierz obiekt podrzdny door w panelu Hierarchy, a nastpnie w komponencie Box Collider kliknij ikon kóka zbatego, znajdujc si po prawej stronie. Z wywietlonego menu podrcznego wybierz opcj Reset (resetuj). A teraz przetestujmy gr w dziaaniu! Nacinij przycisk Play, znajdujcy si w górnej czci interfejsu Unity, aby rozpocz test. Bdziesz móg zauway , e podczas zbliania si do drzwi otwieraj si one nie tylko bez potrzeby uderzania w nie, ale równie wtedy, gdy zwracasz si twarz do nich. Wynika to std, e promie wykrywajcy drzwi jest rysowany w tym samym kierunku, w którym spoglda gracz. Rzucanie promieni moe by uywane w rónych mechanikach gier w celu wykrywania, czy jakie obiekty znajduj si w bliskiej odlegoci od zderzaczy lub le na ich linii widoku. Zalecamy, aby po przeczytaniu tej ksiki spróbowa stworzy kilka prototypów gier na podstawie
184
Rozdzia 5. • Interakcje
pomysów zwizanych z wykorzystaniem tej techniki, poniewa praktyczne jej zastosowanie pozwoli Ci na zdobycie wikszego dowiadczenia. Jednake, jak wspomniano wczeniej, powyszy sposób dziaania drzwi nie jest taki, jakiego oczekujemy, gdy drzwi powinny po prostu wykrywa osob znajdujc si w ich pobliu. Dobrymi przykadami takiego zachowania s cho by czujnik ruchu lub sensor antywamaniowy. Z tego powodu zajmiemy si teraz rozwizaniem trzecim, które jest najbardziej odpowiednie, by osign nasz cel, czyli otworzy drzwi. Bdzie to zastosowanie zderzacza wyzwalajcego.
Metoda 3. Wykrywanie kolizji wyzwalajcej Poniewa dwie pierwsze metody miay pewne wady (uderzanie w zderzacz przy zastosowaniu standardowej funkcji OnControllerColliderHit() oraz — w przypadku rzucania promieni — otwieranie drzwi zaraz po ustawieniu si naprzeciwko nich), uycie zderzacza wyzwalajcego powinno by uwaane za najlepszy sposób implementowania mechaniki otwierania drzwi. Wynika to std, e nie mamy potrzeby tworzenia fizycznego zderzacza, z którym musielibymy si zderza , a oprócz tego obecno gracza bdzie wykrywana bez wzgldu na to, w jakim kierunku si on porusza. Jak wspomniano wczeniej, w drzwiach pozostawimy zderzacz skrzynkowy, poniewa dziki jego fizycznej obecnoci obiekty w razie koniecznoci bd mogy si z nim zderza . Oznacza to, e powinnimy w innym obiekcie utworzy nowy zderzacz skrzynkowy z wczon opcj wyzwalania. Jest to równie wane z tego powodu, i nasze drzwi zawieraj animacj ruchu i nie chcielibymy, by obszar wyzwalania przemieszcza si podczas ich otwierania. Dlatego moglibymy doczy zderzacz skrzynkowy do obiektu nadrzdnego, czyli outPost, a nastpnie po prostu zdefiniowa jego obszar wyzwalania w pobliu drzwi, jak zaprezentowano na rysunkach na pocztku tego rozdziau. Po zdefiniowaniu pooenia zderzacza moemy zastosowa niewielki skrypt, który uywa funkcji OnTriggerEnter(). Jest ona odpowiedzialna za wykrywanie obiektów, pojawiajcych si w pobliu
zderzacza z aktywnym trybem wyzwalania. Moemy z niej skorzysta w celu wywoania tej samej funkcji DoorCheck(), której uylimy w drugim rozwizaniu. Powysze dziaania spowoduj, e skrypt PlayerCollisions stanie si bezuyteczny. Caa logika obsugujca drzwi bdzie zawarta w obiekcie, który je reprezentuje. Takie rozwizanie jest uwaane za waciwy wzorzec postpowania w trakcie projektowania gier.
Tworzenie i skalowanie obszaru wyzwalania W panelu Hierarchy wybierz obiekt nadrzdny, zwany outPost, a nastpnie uruchom opcj menu gównego Component/Physics/Box Collider (komponent/parametry fizyczne/zderzacz skrzynkowy). Twój zderzacz skrzynkowy bdzie mia standardowy rozmiar zwykego szecianu (1, 1, 1). W widoku Scene powinnimy uy metody przecigania z wykorzystaniem klawisza Shift, aby
185
Projektowanie gier w rodowisku Unity 3.x
zmieni jego wielko i pooenie. Moesz take zauway , e zosta on utworzony wewntrz modelu outPost, a dokadniej na jego podstawie. Wynika to std, i w tym miejscu rozpoczynay si osie wspórzdnych modelu w zewntrznej aplikacji, w której zosta on zaprojektowany.
Upewnij si, e wybrae narzdzie reprezentowane przez ikon rki (skrót klawiszowy Q), poniewa pozwala ono na ukrycie uchwytów osi obiektu, co z kolei uatwia modyfikacj wielkoci zderzacza. Przytrzymaj wcinity klawisz Shift, a nastpnie przecigaj punkty, znajdujce si w widoku Scene na krawdziach zderzacza skrzynkowego, dopóki nie osigniesz rezultatu przedstawionego na nastpnym rysunku. Aby go uzyska , pomocne bdzie wybranie widoku prostoktnego (z góry i z boku). Teraz powinnimy zmodyfikowa sposób dziaania zderzacza. W tym celu w widoku Inspector dla wybranego obiektu outPost zaznacz opcj Is Trigger (jest wyzwalaczem) w komponencie Box Collider.
Skrypt obsugujcy zderzenia z trybem wyzwalania Gdy zderzacz wyzwalajcy znajduje si ju we waciwym miejscu, wystarczy tylko wykry obecno gracza w obszarze wyzwalania (zwanym czasem stref wyzwalania). W panelu Project kliknij przycisk Create, a nastpnie stwórz nowy skrypt w jzyku C# lub JavaScript. Zmie jego nazw na TriggerZone i otwórz w edytorze MonoDevelop. Nasz kod zostanie zastosowany w obiekcie nadrzdnym outPost i bdzie bardzo prosty, poniewa musimy wykona tylko ponisze czynnoci: Q wykry obecno gracza, Q wyszuka obiekt podrzdny o nazwie door, nalecy do obiektu outPost, Q wysa komunikat do znalezionego obiektu w celu wywoania funkcji DoorCheck().
186
Rozdzia 5. • Interakcje
Widok z boku:
Widok perspektywiczny:
Rozpocznijmy od utworzenia w naszym skrypcie funkcji OnTriggerEnter(): Jzyk C#: void OnTriggerEnter(Collider col){ }
187
Projektowanie gier w rodowisku Unity 3.x
Jzyk JavaScript: function OnTriggerEnter(col : Collider){ }
Powyszy kod wyglda znajomo, dziaa bowiem podobnie jak napisana wczeniej funkcja OnControllerColliderHit(). Jednake odpowiednie informacje o obiekcie, z którym wystpuje interakcja (zderzenie lub przecicie si zderzaczy), s przechowywane w zmiennej typu Collider. T zmienn nazwalimy po prostu col. Dziki temu moemy sprawdzi rodzaj obiektu, wykorzystujc instrukcj if. Dodaj poniszy kod do funkcji OnTriggerEnter(): Jzyk C# i JavaScript: if(col.gameObject.tag == "Player"){ transform.FindChild("door").SendMessage("DoorCheck"); }
W powyszym kodzie sprawdzamy, czy zderzacz naley do obiektu gry zawierajcego znacznik Player1. Znacznik ten znajduje si w prefabrykacie First Person Controller, zaimportowanym do rodowiska Unity. Powyszy kod moglibymy równie zapisa , wykorzystujc nazw hierarchiczn: if(col.gameObject.name == "First Person Controller"){
Jednake uycie znacznika jest szybsze i bdzie poprawne nawet wówczas, gdy zmienimy nazw prefabrykatu First Person Controller. Gdy warunek if jest speniony, odszukujemy obiekt podrzdny door przy uyciu polecenia transform.FindChild(). Jest ono sprawniejsze od instrukcji gameObject.Find(), poniewa przeszukuje wycznie obiekty podrzdne wobec obiektu, do którego jest przypisany skrypt. Funkcja gameObject.Find() dziaa duej, gdy przeszukuje ca hierarchi obiektów. Uycie polecenia transform.FindChild() jest równie zalecane, w scenie mog si bowiem mieci take inne budynki z drzwiami. Musimy by wic pewni, e wysyamy komunikat jedynie do tego obiektu drzwi, w którego obszarze wyzwalania znajduje si gracz. Wreszcie, podobnie jak poprzednio, wykorzystujemy funkcj SendMessage(), aby wywoa procedur DoorCheck(), zawart w doczonym do obiektu drzwi skrypcie DoorManager.
1
Z powodu bdu w kodzie dostarczonym przez firm Unity Technologies prefabrykat First Person Controller, który jest wykorzystywany w tej ksice, nie zawiera znacznika Player. Aby skrypt TriggerZone dziaa prawidowo, w panelu Project przejd do katalogu Standard Assets/Character Controllers (standardowe zasoby/kontrolery postaci) i kliknij prefabrykat First Person Controller, a nastpnie wybierz opcj Player z menu Tag, znajdujcego si w panelu Inspector — przyp. tum.
188
Rozdzia 5. • Interakcje
Zapisz skrypt z poziomu edytora MonoDevelop, a nastpnie wró do rodowiska Unity, aby doczy skrypt TriggerZone do obiektu outPost: przecignij go z panelu Project i upu na nazwie outPost w panelu Hierarchy.
Usunicie skryptu PlayerCollisions Nowo utworzony wyzwalacz jest gotowy do dziaania. Powinnimy jednak ze skryptu PlayerCollisions usun kod, który wykorzystywa pierwsz metod wykrywania kolizji. Oczywicie moesz zachowa sam skrypt do póniejszych zastosowa, ale teraz nie musi on by ju przypisany do obiektu gracza. Wybierz obiekt First Person Controller w panelu Hierarchy, a nastpnie odszukaj komponent PlayerCollisions (script). Aby go usun , kliknij ikon w ksztacie kóka zbatego, znajdujc si po prawej stronie nazwy komponentu, oraz wybierz opcj Remove (usu) w menu podrcznym. A teraz zagrajmy w gr! Wybierz opcj File/Save Scene (plik/zapisz scen) z menu gównego i kliknij przycisk Play, aby przetestowa nowo utworzony obszar wyzwalania. Drzwi obiektu outPost powinny si otwiera bez wzgldu na kierunek spogldania gracza, gdy tylko pojawi si on w strefie wyzwalania. Jest to wic idealna metoda otwierania drzwi w naszej grze. W sensie projektowym moemy j równie uwaa za poprawn, poniewa nie wykorzystuje ona gracza do sprawdzania obiektów, z którymi si zderza. Obiekt outPost po prostu „wie”, e gdy gracz zblia si do niego, musi otworzy drzwi.
Podsumowanie W tym rozdziale przeanalizowalimy trzy metody, pozwalajce na wykrywanie interakcji zachodzcych midzy obiektami w grach trójwymiarowych: Q wykrywanie kolizji, Q rzucanie promieni, Q wyzwalajce wykrywanie kolizji.
Powysze trzy sposoby maj okrelone zastosowania, a ich znajomo jest podstawow umiejtnoci, której powiniene móc uywa w czasie przyszej pracy w rodowisku Unity. W nastpnym rozdziale w dalszym cigu bdziemy wykorzystywa wyzwalacze. Stworzymy gr polegajc na znalezieniu ogniw energetycznych w celu wczenia generatora i otwarcia drzwi placówki. Napiszemy take kod, który bdzie zabrania dostpu do placówki a do momentu, gdy generator uzyska pene zasilanie.
189
Projektowanie gier w rodowisku Unity 3.x
190
6 Kolekcja, inwentarz i HUD W tej czci ksiki bdziemy wykorzystywa dowiadczenia zdobyte w poprzednim rozdziale, uywajc metody wyzwalanego wykrywania kolizji. Zastosujemy j w celu podnoszenia rónych obiektów. Nastpnie zapoznamy si z tworzeniem dwuwymiarowego wywietlacza póprzezroczystego (HUD) oraz dowiemy si, w jaki sposób mona nim sterowa za pomoc kodu. Wywietlacze póprzezroczyste typu HUD maj róne zastosowanie w grach w zalenoci od ich typu. Na przykad w grze wycigowej wywietlacz póprzezroczysty bdzie prezentowa takie informacje, jak prdko , pooenie, liczba pozostaych okre itd. (patrz pierwszy rysunek na nstpnej stronie). W strzelance z perspektyw pierwszej osoby wywietlacz póprzezroczysty skada si najczciej z takich elementów, jak poziom zdrowia, ilo amunicji i zawarto inwentarza (patrz drugi rysunek na nstpnej stronie). Poniewa dysponujemy ju placówk z otwieranymi drzwiami, powinnimy ograniczy graczowi dostp do niej. Zrobimy to poprzez zmuszenie go do zgromadzenia okrelonych obiektów, co dopiero pozwoli na otwarcie drzwi. Wywietlajc instrukcj na ekranie po pojawieniu si gracza w strefie wyzwalania zderzacza drzwi, bdziemy mogli go poinformowa , e ich otwarcie wymaga dziaajcego róda zasilania. Nastpnie umiecimy na ekranie dwuwymiarowy wywietlacz póprzezroczysty, prezentujcy rozadowane ogniwo energetyczne. Bdzie to zachca gracza do poszukiwania kolejnych ogniw energetycznych, rozrzuconych w pobliu placówki, aby uzyska odpowiednie zasilanie, pozwalajce na otwarcie drzwi. W tym celu umiecimy w trójwymiarowym wiecie model generatora, który bdzie si znajdowa obok drzwi. Bdzie on wyposaony we wskanik prezentujcy biecy poziom zasilania. Zarówno
Projektowanie gier w rodowisku Unity 3.x
(Wipeout Pure © SCEE 2005)
(Half-Life 2: Episode Two © Valve Software 2007)
192
Rozdzia 6. • Kolekcja, inwentarz i HUD
wskanik, jak i wywietlacz HUD bd sterowane skryptem Inventory, zawierajcym zestawy rónych tekstur, które powinny by odpowiednio prezentowane w zalenoci od tego, ile ogniw energetycznych zostao ju zgromadzonych. Wreszcie nad drzwiami placówki umiecimy ródo wiata, które zmieni kolor z czerwonego na zielony, gdy po zgromadzeniu odpowiedniej liczby ogniw energetycznych, pozwalajcych na zasilenie generatora, drzwi zostan otwarte przez gracza.
Dziki stworzeniu opisanej wyej amigówki poznasz nastpujce zagadnienia: Q gromadzenie obiektów przy uyciu prefabrykatów i wyzwalaczy, Q liczenie przy wykorzystaniu zmiennych cakowitych, Q obsuga komponentu GUITexture w celu utworzenia wywietlacza HUD, Q wywietlanie tekstu na ekranie przy uyciu komponentu GUIText, Q sterowanie teksturami i wiatami za pomoc skryptów, Q tworzenie kolekcji i sterowanie wywietlaczem HUD dziki wykorzystaniu typu
tablicowego.
193
Projektowanie gier w rodowisku Unity 3.x
Tworzenie prefabrykatu ogniwa energetycznego W tym podrozdziale uyjemy modelu ogniwa energetycznego, znajdujcego si w folderze Book Assets (zasoby ksiki), który zosta wczeniej zaimportowany do rodowiska Unity. Zmodyfikujemy go w widoku Scene (scena), a nastpnie przeksztacimy w prefabrykat, czyli szablon danych, pozwalajcy na tworzenie instancji lub klonów danego obiektu. Jeli znasz rodowisko Adobe Flash, moesz porówna t ide z koncepcj MovieClip, dziki której w czasie wykonywania programu potrafisz tworzy wiele identycznych instancji wczeniej przygotowanego szablonu, a take je modyfikowa .
Pobieranie, importowanie i umieszczanie Aby rozpocz tworzenie amigówki, bdziesz musia umieci ogniwa energetyczne w folderze Book Assets, znajdujcym si w panelu Project (projekt). W tym celu udostpnilimy nastpujce zasoby: Q Model powerCell w folderze Models (modele). Q Pi plików tekstur dla wywietlacza póprzezroczystego, reprezentujcego poziom naadowania ogniwa energetycznego, o nazwach zaczynajcych si od sowa hud_charge.
Pliki znajduj si w folderze Book Assets/Textures (zasoby ksiki/tekstury). Q Pi plików tekstur dla panelu wywietlacza generatora, prezentujcego poziom zasilania, o nazwach od meter_charge0 do meter_charge4. Pliki te równie znajduj si w folderze Book Assets/Textures. Q Klip dwikowy o nazwie cell_collected, który zostanie odtworzony po zgromadzeniu przez gracza odpowiedniej liczby ogniw. Znajduje si on w folderze Book Assets/Sounds (zasoby ksiki/dwiki). Przecignij model powerCell z folderu Models, znajdujcego si w panelu Project, na widok Scene. Nastpnie przemie kursor myszy nad widok Scene i nacinij klawisz F, aby przybliy obiekt powerCell. Twoje ogniwo energetyczne mogo zosta umieszczone w dowolnym miejscu. Zdefiniujemy dla niego waciwe pooenie, gdy tylko ukoczymy tworzenie prefabrykatu. Oczywicie, jeli przecigne model powerCell na widok Scene w ten sposób, e koliduje on z drzwiami, po prostu uyj narzdzia Translate (skrót klawiszowy W), aby przemieci go na obszar, w którym moesz go dobrze widzie . Pamitaj, e zawsze masz moliwo nacinicia klawisza F w celu przyblienia widoku wybranego obiektu.
194
Rozdzia 6. • Kolekcja, inwentarz i HUD
Identyfikacja ogniwa energetycznego Poniewa musimy wykrywa kolizje z obiektem powerCell, powinnimy go wyposay w znacznik, pozwalajcy na jego identyfikacj w skrypcie, który wkrótce napiszemy. Obiekty mog by identyfikowane dziki ich nazwom, wywietlanym w panelu Hierarchy (hierarchia), lecz przypisywanie znaczników do elementów o zblionych typach moe by przydatne podczas implementacji mechaniki gry, takiej jak kolekcja. Kliknij menu rozwijane Tag (znacznik), a nastpnie wybierz ostatni opcj Add Tag (dodaj znacznik). Panel Inspector (inspektor) zmieni wygld i wywietli obszar menedera znaczników. Jeli nie widzisz listy znaczników, po prostu kliknij szar strzak, znajdujc si po lewej stronie nazwy Tags. W pierwszym dostpnym polu Element umie znacznik o nazwie cell (ogniwo), jak przedstawiono na poniszym rysunku:
Nacinij klawisz Enter, aby zatwierdzi wprowadzenie nazwy, ponownie zaznacz obiekt powerCell w panelu Hierarchy, a wreszcie wybierz nazw cell z menu podrcznego Tag, znajdujcego si w górnej czci widoku Inspector.
Skalowanie i obrót zderzacza Teraz przypiszemy obiektowi powerCell odpowiednie komponenty i zmodyfikujemy ich ustawienia, a nastpnie zamienimy go w prefabrykat.
Powikszanie ogniwa energetycznego Poniewa tworzymy przedmiot, który powinien by gromadzony przez gracza, powinnimy si upewni , e ma on odpowiedni rozmiar, by mona go byo dostrzec w grze. Wczeniej zapoznalimy si z metod skalowania obiektów przy uyciu komponentu FBXImporter, nalecego do danego zasobu. Teraz przeprowadzimy prost operacj zmiany rozmiaru za pomoc komponentu Transform w panelu Inspector. Jeli obiekt powerCell jest wybrany w panelu Hierarchy, wprowad w polach Scale (skala) w panelu Inspector wartoci komponentu Transform równe 1,6.
Dodawanie zderzacza wyzwalajcego Nastpnie do obiektu powerCell powinnimy doda prosty zderzacz, aby pozwoli graczowi na interakcj z nim. Wybierz opcj menu gównego Component/Physics/Capsule Collider (komponent/parametry fizyczne/zderzacz kapsuowy). Wybralimy ten rodzaj zderzacza, poniewa
195
Projektowanie gier w rodowisku Unity 3.x
ma on ksztat przypominajcy obiekt powerCell. Nie chcemy jednak, aby gracz uderza w niego podczas jego zbierania, wic powinnimy wczy w nim tryb wyzwalania. W tym celu w nowo utworzonym komponencie Capsule Collider zaznacz opcj Is Trigger (jest wyzwalaczem).
Skalowanie zderzacza Dowolny zderzacz prosty, przypisany w rodowisku Unity do obiektu, nie musi mie od razu ustalonego rozmiaru lub pooenia. Te parametry mog zosta zmodyfikowane w widoku Scene przy uyciu klawisza Shift podczas przecigania za pomoc myszy punktów, które znajduj si na obrysie zderzacza, a take za pomoc ustawie jego komponentu w panelu Inspector. Zderzacz kapsuowy, ze wzgldu na swój ksztat, zawiera dwa ustawienia: Radius (promie) i Height (wysoko ). Pozwalaj one na jego lepsze dopasowanie do ksztatu obiektu powerCell. W polu edycji Radius wprowad warto 0,3. Zderzacz wci bdzie wikszy ni obiekt powerCell, lecz jest to waciwe rozwizanie, gdy uatwi ono podniesienie obiektu. Moesz zauway , e kierunek pooenia zderzacza jest niewaciwy. Da si to naprawi , zmieniajc warto Direction (kierunek) i przypisujc do niej o X, poniewa jest to kierunek, w którym zosta zorientowany sam model (wzgldem dugoci). Innym parametrem, pozwalajcym na zmian skali, jest Height (wysoko ). Domylna warto 1 jest wiksza od dugoci obiektu powerCell, lecz ponownie zakadamy, i jest to poprawne rozwizanie, które uatwi podniesienie ogniwa energetycznego. Wynika to std, e zanim gracz zbliy si odpowiednio blisko do ogniwa, nastpi zetknicie jego zderzacza ze zderzaczem obiektu powerCell. Po ukoczeniu dziaa Twój zderzacz powinien wyglda tak jak na poniszym rysunku:
Dodawanie komponentu Rigidbody Wkrótce napiszemy kod, który spowoduje obracanie si obiektu powerCell. Wynika std, e nie bdzie on ju statyczny. Jak wiemy z wczeniejszych dowiadcze z animowanymi drzwiami, poruszanie obiektami w rodowisku Unity jest moliwe, gdy zastosujemy komponent Rigidbody.
196
Rozdzia 6. • Kolekcja, inwentarz i HUD
Dziki temu uzyskujemy du sprawno dziaania, poniewa danym obiektem zarzdza silnik fizyczny. Jeli obiekt powerCell jest wci aktywny w panelu Hierarchy (hierarchia), wybierz opcj menu gównego Component/Physics/Rigidbody (komponent/parametry fizyczne/brya sztywna). W dodanym komponencie odznacz opcj wyboru Use Gravity (uyj grawitacji), a zaznacz Is Kinematic (uyj kinematyki).
Tworzenie skryptu dla ogniwa energetycznego Teraz napiszemy skrypt, który bdzie realizowa kilka zada, niezbdnych do obsugi ogniwa energetycznego w trakcie dziaania gry. Bd to: Q Efekt obracania, by ogniwo energetyczne byo lepiej widoczne dla gracza. Q Funkcja OnTriggerEnter(), która bdzie wykrywa gracza, chccego podnie ogniwo
energetyczne. Funkcja ta wyle komunikat do skryptu Inventory, przypisanego do gracza, co spowoduje uaktualnienie jego kolekcji elementów. Kliknij folder Scripts (skrypty) w panelu Project (projekt), aby upewni si, e nowo tworzony skrypt zostanie umieszczony dokadnie w tym miejscu. W panelu Project kliknij przycisk Create (stwórz), a nastpnie wybierz jzyk C# lub JavaScript. Zmie nazw nowo utworzonego pliku na PowerCell. Dwukrotnie kliknij jego ikon, by wczyta go do edytora.
Obracanie obiektu Na samym pocztku skryptu, powyej funkcji Update(), stwórz zmienn rotationSpeed o typie zmiennoprzecinkowym i przypisz jej warto 100,0. W tym celu wprowad poniszy kod: Jzyk C#: public float rotationSpeed = 100.0f;
Jzyk JavaScript: var rotationSpeed : float = 100.0;
Uyjemy tej zmiennej w celu zdefiniowania prdkoci obracania si obiektu powerCell. Jest ona publiczna, dlatego po przypisaniu skryptu do obiektu powerCell bdziemy mogli j modyfikowa w panelu Inspector (inspektor). Jako projektant lub grafik moesz mie do niej dostp ju po napisaniu skryptu. Wewntrz funkcji Update() umie ponisz instrukcj, która bdzie obraca obiektem powerCell wokó osi Y z prdkoci obrotow równ wartoci zmiennej rotationSpeed: Jzyk C#: transform.Rotate(new Vector3(0,rotationSpeed * Time.deltaTime ,0));
197
Projektowanie gier w rodowisku Unity 3.x
Jzyk JavaScript: transform.Rotate(Vector3(0,rotationSpeed * Time.deltaTime,0));
Polecenie Rotate() oczekuje parametru typu Vector3(X, Y, Z). Osiom X i Y przypisujemy warto 0, natomiast osi Y zmienn rotationSpeed. Poniewa polecenie zostao umieszczone w funkcji Update(), bdzie wywoywane w kadej klatce, przez co obiekt moe si obraca za kadym razem o 100 stopni. Jednake dodatkowo mnoymy zmienn przez warto Time. ´deltaTime, co oznacza, e obrót nie bdzie zalea od prdkoci klatek, lecz zostanie ograniczony do takiego poziomu, jaki jest nam potrzebny. W edytorze skryptu wybierz opcj File/Save (plik/zapisz), a póniej wró do rodowiska Unity. Aby przypisa skrypt do obiektu powerCell, po prostu przecignij go z panelu Project i upu na odpowiedni nazw w panelu Hierarchy (hierarchia). Nastpnie wybierz obiekt, by upewni si, czy skrypt pojawi si w obszarze Inspector. Kliknij przycisk Play (granie), znajdujcy si w górnej czci interfejsu, i obserwuj obiekt powerCell w widoku Scene (scena) lub Game (gra), jeli kamera obiektu First Person Controller jest skierowana na niego, aby sprawdzi , e si obraca. Jeeli obracanie obiektu nie dziaa, wró do edycji skryptu i upewnij si, e nie popenie adnych bdów. Oprócz tego sprawd, czy przypisae skrypt do waciwego obiektu. Pamitaj, aby ponownie nacisn przycisk Play w celu zakoczenia testów i powrotu do projektowania.
Dodawanie opcji wyzwalajcego wykrywania kolizji Teraz postaramy si wykry sytuacj, w której zderzacz wyzwalajcy obiektu powoduje kolizj ze zderzaczem gracza. Wró do skryptu i poniej prawego nawiasu klamrowego, koczcego funkcj Update(), umie taki kod: Jzyk C#: void OnTriggerEnter(Collider col){ if(col.gameObject.tag == "Player"){ col.gameObject.SendMessage("CellPickup"); Destroy(gameObject); } }
Jzyk JavaScript: function OnTriggerEnter(col : Collider){ if(col.gameObject.tag == "Player"){ col.gameObject.SendMessage("CellPickup"); Destroy(gameObject); } }
198
Rozdzia 6. • Kolekcja, inwentarz i HUD
Mamy tutaj do czynienia z podobn funkcj OnTriggerEnter(), której uywalimy ju w przypadku strefy wyzwalania placówki. Wewntrz funkcji umiecilimy instrukcj if, sprawdzajc, czy obiekt biorcy udzia w kolizji zawiera znacznik o nazwie Player. Jeli ten warunek jest speniony, wywoujemy funkcj CellPickup(), któr dopiero napiszemy. Zostanie ona umieszczona w skrypcie Inventory, przypisanym do postaci gracza. Wreszcie obiekt powerCell jest usuwany ze sceny poleceniem Destroy(). Pamitaj, e ta instrukcja powinna zawsze znajdowa si na kocu funkcji, gdy musimy by pewni, e inne polecenia zostan poprawnie wykonane. Zapamitaj skrypt i wró do rodowiska Unity. Kliknij przycisk Play (granie), aby przetestowa gr, a nastpnie przemie posta gracza w kierunku obiektu powerCell. Po zetkniciu si z nim na pasku konsoli rodowiska Unity, znajdujcym si w lewym dolnym obszarze okna, powinna pojawi si informacja o bdzie, zaprezentowana na poniszym rysunku:
Ten bd by przez nas oczekiwany, poniewa nie napisalimy jeszcze skryptu, który powinien zawiera funkcj CellPickup(). rodowisko Unity ostrzega nas, e chocia sam kod jest poprawny, jednak wysyany komunikat nie zosta odebrany przez aden obiekt. Teraz zapamitamy obiekt powerCell w postaci prefabrykatu, a nastpnie zajmiemy si tworzeniem skryptu Inventory. Dziki temu gracz bdzie dysponowa miejscem do przechowywania informacji o kadym zebranym ogniwie energetycznym.
Zapisywanie obiektu w postaci prefabrykatu Gdy obiekt powerCell jest ju gotowy, musimy go jeszcze powieli w trzech egzemplarzach, aby w sumie dysponowa czterema ogniwami energetycznymi. Najlepiej bdzie wykorzysta w tym celu system prefabrykatów rodowiska Unity. Utworzony prefabrykat umiecimy w istniejcym folderze o nazwie Prefabs (prefabrykaty), który suy do ich przechowywania. Przecignij obiekt powerCell z panelu Hierarchy (hierarchia) do folderu Prefabs w panelu Project (projekt). Spowoduje to jego zapisanie w postaci prefabrykatu. Bdzie to take oznacza , e obiekt w panelu Hierarchy stanie si instancj nowo stworzonego prefabrykatu. Obiekty sceny, bdce instancjami prefabrykatów lub modeli projektu, s prezentowane w panelu Hierarchy w kolorze niebieskim. W przeciwiestwie do nich obiekty dostpne jedynie w scenie s opisywane czcionk w standardowym kolorze czarnym.
199
Projektowanie gier w rodowisku Unity 3.x
Rozrzucanie ogniw energetycznych Gdy ogniwo energetyczne zostao zapamitane w postaci prefabrykatu, moemy utworzy kilka jego instancji i umieci je w scenie. Upewnij si, e obiekt powerCell jest wci wybrany w panelu Hierarchy (hierarchia), a nastpnie powiel go trzykrotnie, by uzyska sumaryczn liczb czterech ogniw energetycznych. Mona to zrobi poprzez wybranie opcji menu gównego Edit/Duplicate (edycja/powielanie), uycie skrótu klawiszowego Command+D (Mac) lub Ctrl+D (PC) albo kliknicie prawym klawiszem myszy obiektu znajdujcego si w panelu Hierarchy i wybranie opcji Duplicate (powielanie) z menu podrcznego. Uwaga Powielane obiekty pojawiaj si w scenie zawsze w tym samym pooeniu. Nie powinno Ci to jednak wprowadza w zakopotanie. Takie dziaanie wynika z przyjtego standardu, dotyczcego lokalizacji nowo tworzonych obiektów. Pamitaj, e kady z nich zawiera takie same ustawienia jak obiekt ródowy, wcznie z pooeniem. Ponadto atwiej zapamita, e lokalizacja powstaego obiektu jest taka sama jak jego oryginau. Naley go pó niej po prostu przemieci we waciwe miejsce.
Teraz w panelu Hierarchy wybierz po kolei kady z obiektów powerCell, a nastpnie uyj narzdzia Translate (skrót klawiszowy W), aby umieci ogniwa energetyczne wokó obiektu outPost. Pamitaj, e moesz uy gadetu widoku, znajdujcego si w prawym górnym naroniku okna Scene (scena), by zmieni sposób spogldania na wiat gry z perspektywicznego na widok z góry, z dou lub z boku. Upewnij si, e ogniwa energetyczne s umieszczane na waciwej wysokoci. Nie powinny si znajdowa zbyt wysoko ani zbyt nisko, co powodowaoby, e gracz zbieraby je za pomoc nóg! Gdy rozmiecie ju cztery ogniwa energetyczne wokó obiektu outPost, wygld jego otoczenia powinien przypomina poniszy rysunek. Zwró uwag, e zaznaczono na nim wszystkie cztery obiekty powerCell znajdujce si w panelu Hierarchy, aby zaprezentowa ich pooenie i zdefiniowane zderzacze.
Inwentarz gracza W tym podrozdziale stworzymy skrypt, który bdzie przechowywa informacje o elementach zebranych przez gracza w grze. S nimi ogniwa energetyczne, suce do zasilania drzwi, oraz pudeko zapaek, pozwalajce na rozpalenie ognia. Informacje o inwentarzu zapiszemy w obiekcie gracza. Dziki temu inne obiekty bd mogy wysya zapytania do zwizanego z nim skryptu Inventory. Na przykad w dalszej czci ksiki stworzymy trójwymiarowy model generatora, który bdzie wywietla biecy stan zasilania drzwi, wykorzystujc w tym celu dane z tego skryptu.
200
Rozdzia 6. • Kolekcja, inwentarz i HUD
Wybierz folder Scripts (skrypty), znajdujcy si w panelu Project (projekt), a nastpnie kliknij przycisk Create (stwórz) i wybierz odpowiedni jzyk skryptowy. Zmie nazw nowo utworzonego skryptu na Inventory oraz uruchom edytor MonoDevelop.
Zapamitywanie poziomu zasilania Tworzymy inwentarz zebranych elementów, dlatego powinnimy sprawi , e poszczególne jego czci bd dostpne dla wszystkich skryptów. Liczba zebranych ogniw energetycznych zostanie zapamitana w zmiennej zwanej charge. Aby si upewni , e bdzie ona dostpna dla innych skryptów, stworzymy j jako zmienn statyczn. Naley j umieci we waciwym miejscu w skrypcie. Dla uytkowników C# oznacza to wiersz znajdujcy si poniej deklaracji klasy, a dla uytkowników JavaScript — po prostu pocztek pliku: Jzyk C#: public static int charge = 0;
Jzyk JavaScript: static var charge : int = 0;
Ta zmienna typu cakowitego zostanie zainicjalizowana w skrypcie, w którym si znajduje. Zazwyczaj w skrypcie nie tworzymy zmiennych publicznych, poniewa byyby one widoczne w panelu Inspector (inspektor). Jednake zmienne statyczne nie s w nim dostpne, dlatego nie mamy z tym problemu. Zalet uycia zmiennej statycznej jest to, e przechowywana w niej
201
Projektowanie gier w rodowisku Unity 3.x
informacja jest dostpna globalnie. W zwizku z tym inne skrypty mog jej uywa poprzez zwyke odwoanie si do niej, na przykad: if(Inventory.charge == 4){
Dziki temu bdziemy mogli sprawdzi warto zmiennej charge w stworzonym wczeniej skrypcie TriggerZone, aby nie zezwoli na wejcie do obiektu outPost, jeli uytkownik zgromadzi mniej ni cztery ogniwa energetyczne. Skrypt TriggerZone zostanie odpowiednio zmodyfikowany po utworzeniu skryptu Inventory.
Definiowanie pocztkowej wartoci zmiennej Aby upewni si, e po wywietleniu sceny zmienna charge zawiera warto 0, jej inicjalizacja powinna zosta umieszczona w funkcji Start(). Podczas testowania i ponownego uruchamiania tej samej sceny wartoci zmiennych mog zosta zachowane. Umieszczenie polecenia inicjalizujcego w funkcji Start() pozwala unikn tego problemu. Jzyk C#: void Start () { charge = 0; }
Jzyk JavaScript: function Start () { charge = 0; }
Efekt d wikowy Oprócz zmiennej charge w skrypcie umiecimy take inn zmienn publiczn, która bdzie odpowiada za efekt dwikowy odtwarzany podczas zbierania ogniw energetycznych: Jzyk C#: public AudioClip collectSound;
Jzyk JavaScript: var collectSound : AudioClip;
Dodawanie funkcji CellPickup() Poniewa nasz skrypt zawiera ju zmienn, która przechowuje liczb zebranych ogniw energetycznych, moemy teraz stworzy funkcj CellPickup(). Bdzie ona wywoywana poleceniem SendMessage(), wysyanym ze skryptu PowerCell podczas kadej czynnoci podnoszenia ogniwa energetycznego.
202
Rozdzia 6. • Kolekcja, inwentarz i HUD
Dodaj nastpujc funkcj do skryptu: Jzyk C#: void CellPickup(){ AudioSource.PlayClipAtPoint(collectSound, transform.position); charge++; }
Jzyk JavaScript: function CellPickup(){ AudioSource.PlayClipAtPoint(collectSound, transform.position); charge++; }
Powysza funkcja, wywoywana poleceniem SendMessage() wykonywanym w skrypcie PowerCell, bdzie odtwarza klip dwikowy collectSound oraz zwiksza o 1 warto zmiennej charge. Uywamy polecenia AudioSource.PlayClipAtPoint(), gdy obiekt gracza nie zawiera róda audio. Po wywoaniu tej instrukcji jest tworzony tymczasowy obiekt gry z aktywnym ródem dwiku, który odtwarza klip, a nastpnie jest automatycznie usuwany. Drugi argument funkcji PlayClipAtPoint, czyli transform.position, jest lokalizacj, w której chcemy utworzy tymczasowy obiekt dwiku. Uywamy w tym celu biecego pooenia gracza, dlatego e dwik powinien po prostu zosta odtworzony w jego pobliu. Oznacza to take, i dwik bdzie zanika , gdy gracz oddali si od miejsca, w którym znajdowa si zebrany obiekt. Zapamitaj swój skrypt i wró do rodowiska Unity.
Dodawanie inwentarza do obiektu gracza Przypisz nowo utworzony skrypt do obiektu First Person Controller. W tym celu przecignij go z folderu Scripts, znajdujcego si w panelu Project, na odpowiedni obiekt w panelu Hierarchy. Twój obiekt First Person Controller powinien teraz zawiera komponent Inventory (Script), a zmienna publiczna collectSound, reprezentujca klip audio, powinna by widoczna w panelu Inspector. Rozwi folder Book Assets/Sounds (zasoby ksiki/dwiki) w panelu Project, a nastpnie przecignij klip cell_collected na t zmienn. A teraz przetestujmy nasz skrypt! Poniewa nie zdefiniowalimy jeszcze strefy wyzwalania, zalenej od wartoci poziomu zasilania, zobaczymy jedynie, e w czasie zbierania ogniw energetycznych nie bdzie si ju pojawia bd SendMessage has no receiver (nie zdefiniowano odbiorcy dla funkcji SendMessage). Powiniene take sysze dwik towarzyszcy tej czynnoci. Kliknij przycisk Play (granie), aby si upewni , e skrypt dziaa prawidowo. Jak zwykle po zakoczeniu testowania ponownie nacinij przycisk Play, by wróci do fazy projektowania.
203
Projektowanie gier w rodowisku Unity 3.x
Ograniczenie dostpu do placówki Poniewa potrafimy ju gromadzi w naszym inwentarzu ogniwa energetyczne, zdefiniujmy odpowiedni mechanik gry, która bdzie zmusza gracza do zebrania wszystkich czterech ogniw, zanim uzyska on dostp do obiektu outPost. W tym celu stwórzmy najpierw odpowiedni kod, a nastpnie umie my na ekranie dwa wskaniki wizualne. Tekstura tworzca dwuwymiarowy wywietlacz HUD bdzie pochodn klasy GUITexture. Jej wygld powinien by zaleny od wartoci zmiennej charge, znajdujcej si w skrypcie Inventory.
Kolejna tekstura, tworzca model generatora, który zostanie umieszczony obok drzwi placówki, równie bdzie si zmienia w zalenoci od wartoci zmiennej charge.
Ograniczenie dostpu do drzwi za pomoc licznika ogniw W tym punkcie stworzymy kod zwizany z inwentarzem, który bdzie sprawdza , czy gracz ma wystarczajc liczb ogniw energetycznych, by otworzy drzwi placówki. Uywamy ju strefy wyzwalania, zwizanej z otwieraniem drzwi, dlatego zmodyfikujemy j, by za kadym
204
Rozdzia 6. • Kolekcja, inwentarz i HUD
razem, gdy gracz zbliy si do drzwi, odczytywaa warto zmiennej charge, znajdujcej si w skrypcie Inventory. Sprawmy, by drzwi otwieray si jedynie wówczas, gdy gracz zgromadzi cztery ogniwa energetyczne. Odszukaj skrypt TriggerZone w panelu Project (projekt), a nastpnie wczytaj go do edytora MonoDevelop lub innego, uywanego przez Ciebie. W funkcji OnTriggerEnter() zlokalizuj istniejc instrukcj if i umie wewntrz niej ponisze polecenie if/else, które bdzie sprawdza biec liczb ogniw energetycznych w skrypcie Inventory: Jzyk C# i JavaScript: if(col.gameObject.tag == "Player"){ if(Inventory.charge == 4){ transform.FindChild("door").SendMessage("DoorCheck"); }else{ } }
W powyszym kodzie sprawdzamy, czy statyczna zmienna charge, zdefiniowana w klasie Inventory, jest równa 4. Jeli tak, moemy wywoa t sam funkcj DoorCheck()co poprzednio. W przeciwnym razie bdziemy wykonywa instrukcje zawarte w poleceniu else. Zostan one tam umieszczone w póniejszym czasie i pozwol na poinformowanie gracza, e nie zebra jeszcze odpowiedniej liczby ogniw energetycznych potrzebnej do otwarcia drzwi. Wczeniej jednak stworzymy wywietlacz HUD oraz obiekty typu GUIText, które pozwol na prezentowanie na ekranie odpowiednich komunikatów. Zapamitaj swój skrypt i wró do rodowiska Unity, abymy mogli przetestowa utworzony kod. Kliknij przycisk Play i upewnij si, e drzwi si nie otwieraj, zanim nie zgromadzisz wszystkich czterech ogniw energetycznych.
Wywietlacz HUD dla ogniwa energetycznego Poniewa stworzylimy ju inwentarz zebranych ogniw energetycznych, powinnimy teraz przedstawi graczowi wizualn reprezentacj tego, co zostao zgromadzone. Tekstury, zaimportowane z folderu Book Assets (zasoby ksiki), zostay zaprojektowane w taki sposób, aby wyranie informowa , e gracz musi zgromadzi cztery ogniwa energetyczne w celu uzyskania penego zasilania drzwi. Poprzez zamian tekstury, symbolizujcej nienaadowane ogniwo, na grafik, która prezentuje kolejno jedn czwart maksymalnego poziomu naadowania, nastpnie dwie czwarte itd., moemy stworzy iluzj elementu o dynamicznym interfejsie. Zostao to przedstawione na poniszym rysunku:
205
Projektowanie gier w rodowisku Unity 3.x
Folder Book Assets/Textures (zasoby ksiki/tekstury) zawiera pi plików graficznych, które s niezbdne do stworzenia wywietlacza HUD, opartego na teksturach. W jednym z nich znajduje si grafika nienaadowanego ogniwa energetycznego, a w pozostaych — grafika kolejnych etapów jego adowania. Zostay one stworzone za pomoc programu Adobe Photoshop z zastosowaniem przezroczystego ta, a nastpnie zapamitane w formacie PNG (Portable Network Graphics). Wybrano go, poniewa pozwala na kompresj danych, a jednoczenie wspiera wysokiej jakoci kanay alfa. Oprócz zwykych kanaów, zwizanych z kolorem czerwonym, zielonym i niebieskim, w obrazach wykorzystuje si kanay alfa, które reprezentuj okrelony poziom ich przezroczystoci. Aby stworzy graficzny interfejs uytkownika, który bdzie wywietla poziom naadowania ogniwa energetycznego, powinnimy rozpocz od umieszczenia w scenie grafiki prezentujcej nienaadowan bateri. W tym celu wykorzystamy komponent rodowiska Unity o nazwie GUITexture. W panelu Project (projekt) rozwi folder Textures (tekstury), znajdujcy si wewntrz folderu Book Assets, a nastpnie wybierz plik o nazwie hud_nocharge. Zamiast uy standardowej metody przecigania i upuszczania zasobów w widoku Scene (scena), utworzymy nowy obiekt z komponentem GUITexture i przypiszemy mu tekstur hud_nocharge.
Importowanie ustawie tekstur GUI Zanim w scenie przypiszemy plik tekstury do komponentu GUITexture, bdziemy musieli „poinformowa ” rodowisko Unity, w jaki sposób plik ten powinien by interpretowany. Gdy tekstura hud_nocharge jest wci wybrana w panelu Project, przyjrzyj si ustawieniom importu, wywietlonym w panelu Inspector (inspektor) poniej nagówka Texture Importer (importer tekstur). Kliknij menu Texture Type (rodzaj tekstury) i wybierz opcj GUI (graficzny interfejs uytkownika) zamiast domylnej Texture (tekstura). Spowoduje to, e rodowisko Unity, uywajc tekstury jako elementu GUI, wywietli j przy wykorzystaniu pierwotnej perspektywy widoku.
Tworzenie obiektu GUITexture Technicznie rzecz biorc, procedura tworzenia obiektu GUITexture skada si z trzech etapów. Moe zosta jednak zrealizowana w pojedynczym kroku poprzez zaznaczenie odpowiedniej tekstury w panelu Project, a nastpnie wybranie opcji menu gównego GameObject/Create other/GUITexture (obiekt gry/stwórz inny/GUITexture). Wykonaj t czynno . Zostanie utworzony nowy obiekt, który bdzie zawiera komponent GUITexture. Pola Width (szeroko ) i Height (wysoko ) parametru Pixel Inset (wstawka pikselowa) zawieraj ju odpowiednie wartoci, wynikajce z wymiarów wybranej tekstury.
206
Rozdzia 6. • Kolekcja, inwentarz i HUD
Pola Pixel Inset definiuj rozmiary obiektu i jego obszar wywietlania. Zazwyczaj parametry Width i Height odpowiadaj oryginalnym rozmiarom pliku tekstury, natomiast X i Y s równe poowie ich wartoci. Inicjalizacja tych pól zostaje automatycznie przeprowadzona przez rodowisko Unity podczas wybierania tekstury w panelu Project, przy czym wartoci X i Y okrelaj punkt rejestracji, znajdujcy si na jej rodku. Definiowanie punktu rejestracji Uywanie standardowego punktu rejestracji, umieszczonego porodku tekstury, jest poprawnym dziaaniem w przypadku wywietlacza HUD, który wanie tworzymy, poniewa nie musi on by dokadnie dopasowany do innych elementów ekranu. Jeli jednak wykorzystujesz dwuwymiarowe elementy, które s wywietlane przy uyciu wspórzdnych ich lewego dolnego naronika, powiniene przypisa parametrom X i Y warto 0. Wane jest, aby zdawa sobie spraw z tego, e wpywa to na umieszczenie obiektu GUITexture na ekranie. Na poniszym rysunku obiekty GUITexture s umieszczone w tym samym miejscu, lecz róni si od siebie wartociami punktów rejestracji (czyli pól Pixel Inset X i Pixel Inset Y).
Teraz powiniene widzie na ekranie tekstur etapu 0, reprezentujc nienaadowane ogniwo energetyczne. Komponent Transform pokazuje, e domylne pooenie tekstury wynosi (0,5, 0,5, 0), czyli to rodek ekranu. Wybierz obiekt hud_nocharge w panelu Hierarchy, a nastpnie zmie jego nazw na PowerGUI, naciskajc klawisz Return (Mac) lub F2 (PC). Uwaga Poprzez okrelenie elementu graficznego, którego chcesz uy w pierwszej kolejnoci, rodowisko Unity zostaje poinformowane, e podczas tworzenia nowego obiektu z komponentem GUITexture naley równie wykorzysta ten plik jako tekstur i wypeni pola odpowiedzialne za jej rozmiary. Po wybraniu elementu graficznego, a nastpnie utworzeniu obiektu GUITexture za pomoc gównego menu ze wzgldu na wygod jego nazwa jest uzyskiwana na podstawie uywanego zasobu tekstury. Pamitaj o tym, gdy pomoe Ci to w wyszukiwaniu obiektów w panelu Hierarchy ju po ich utworzeniu.
207
Projektowanie gier w rodowisku Unity 3.x
Umieszczanie tekstury PowerGUI Podczas pracy z elementami dwuwymiarowymi musisz wykorzystywa wspórzdne ekranu. Takie obiekty maj jedynie dwa wymiary, dlatego uywaj osi X i Y. O Z suy do definiowania priorytetu warstw wielu elementów GUITexture. Wspórzdne ekranowe zawieraj si w zakresie od 0 do 1. Aby umieci obiekt PowerGUI w okrelonym pooeniu (lewy dolny naronik ekranu), musimy poda odpowiednie wartoci jego komponentu Transform w polach X i Y. Wprowad w polu X warto 0,15, a w polu Y warto 0,1. Teraz Twoja tekstura, wywietlana w widoku Game (gra), powinna si znajdowa w lewym dolnym naroniku okna. Moesz take wywietli szczegóy obiektu dwuwymiarowego w widoku Scene, klikajc przycisk Game Overlay (warstwy gry).
Skrypt do podmiany tekstury Poniewa w inwentarzu powinnimy zgromadzi kilka ogniw energetycznych, moemy uy skryptu Inventory do zarzdzania teksturami dla nowo stworzonego wywietlacza GUITexture. Aby obsugiwa tekstury ogniw i wczeniej zaprezentowanego modelu generatora, powinnimy wykorzysta w skryptach struktur danych zwan tablic.
208
Rozdzia 6. • Kolekcja, inwentarz i HUD
Tablice Tablice s kontenerami danych, które zawieraj wiele wartoci. Moesz je uwaa za zmienne przechowujce wiele wartoci. S one uporzdkowane za pomoc indeksu, czyli liczby wskazujcej pooenie elementu w tablicy. Jest on podobny do identyfikatora rekordu w tablicy bazy danych. Liczba przechowywanych elementów jest zwana dugoci tablicy. Tablice podstawowe mog by poszerzane w panelu Inspector — modyfikuje si w tym celu parametr Size (rozmiar) (uyjemy go za chwil), lecz z punktu widzenia programisty ich rozmiar jest tylko do odczytu i nie moe zosta zmodyfikowany w skrypcie. Deklarowanie tablicy jest podobne do deklarowania zmiennej: naley poda jej nazw i typ. Rónica polega na uyciu nawiasów kwadratowych, które definiuj zmienn jako tablic. Na przykad jeli chcielibymy utworzy tablic obiektów gry reprezentujcych wrogów, moglibymy uy poniszego fragmentu kodu: Jzyk C#: public GameObject[] enemies;
Jzyk JavaScript: var enemies : GameObject[];
Nastpnie trzeba ustali rozmiar tablicy w panelu Inspector oraz przypisa do niej obiekty. Na poniszym rysunku przedstawiono widok panelu Inspector, w którym podano rozmiar tablicy równy 3:
Przeciganie z panelu Hierarchy lub Project jest operacj suc do przypisywania obiektów do okrelonych pozycji tablicy. W tym celu moemy take wykorzysta skrypt. Obiekty mog by przypisywane do tablicy poprzez zdefiniowanie okrelonej pozycji wewntrz niej. Na przykad, jeli chcielibymy umieci obiekt gry na trzeciej pozycji w tablicy, uylibymy poniszego kodu: enemies[2] = gameObject;
Powysza warto gameObject moe by odwoaniem do dowolnego obiektu gry, dostpnego w scenie. Zapewne zauwaye, e indeksy tablicy rozpoczynaj si od wartoci zero, dlatego trzecia pozycja w powyszym przykadzie jest w rzeczywistoci indeksem numer 2. Jeli chciaby uy indeksu, który nie istnieje, rodowisko Unity wywietlioby bd Index is Out of Range (indeks poza zakresem) — oznacza to, e zastosowano liczb, która przekracza biec dugo tablicy.
209
Projektowanie gier w rodowisku Unity 3.x
Tworzenie tablicy dla wywietlacza HUD Dziki utworzeniu i uyciu tablicy piciu tekstur (czterech dla stanów naadowania oraz tekstury hud_nocharge, reprezentujcej nienaadowane ogniwo energetyczne) moemy umieci odpowiedni element graficzny na wywietlaczu HUD w zalenoci od biecej wartoci zmiennej charge. Oznacza to, e podniesienie kolejnego ogniwa energetycznego spowoduje zwikszenie wartoci zmiennej charge oraz automatyczn aktualizacj wygldu wywietlacza! Otwórz skrypt Inventory i umie kursor w nowym wierszu, zaraz pod zmienn collectSound. Uyjemy jednej tablicy na zdefiniowane wyej zadanie, a drugiej w celu przechowywania tekstur dla naszego generatora. Aby odróni zadeklarowane zmienne, uyjemy odpowiednich komentarzy. Umie poniszy kod w skrypcie Inventory: Jzyk C#: // HUD public Texture2D[] hudCharge; public GUITexture chargeHudGUI;
Jzyk JavaScript: // HUD var hudCharge : Texture2D[]; var chargeHudGUI : GUITexture;
Po komentarzu, który informuje nas, e poniszy kod obsuguje wywietlacz HUD, nastpuje deklaracja tablicy hudCharge o typie Texture2D i dostpie publicznym. Dalej zostaa zadeklarowana zmienna publiczna chargeHudGUI o typie GUITexture. Uyjemy jej w celu odwoania si do obiektu PowerGUI, dziki czemu skrypt bdzie móg bezporednio przypisa waciwo texture komponentu GUITexture do innej tekstury. Zapamitaj skrypt i wró do rodowiska Unity.
Przypisywanie tekstur do tablicy Aby wywietli komponent Inventory (Script) w panelu Inspector, wybierz obiekt First Person Controller w oknie Hierarchy. Widzisz teraz zmienne Hud Charge i Charge Hud GUI, wywietlone poniej parametru Collect Sound. Rozwi tablic Hud Charge: kliknij szar strzak po lewej stronie jej nazwy.
210
Rozdzia 6. • Kolekcja, inwentarz i HUD
Warto Size (rozmiar) równa 0 oznacza, e tablica nie zawiera adnych elementów. Przypisz jej warto 5, co spowoduje, e niej pojawi si pola oznaczone jako Element 0 do Element 4, obok których bdzie widoczny ich typ Texture2D. W folderze Book Assets/Textures znajdziesz tekstury, których nazwy rozpoczynaj si od cigu znaków hud_charge. Uywajc metody „przecignij i upu ”, przypisz te tekstury do odpowiednich pozycji tablicy, pamitaj jednoczenie, e skadnik Element 0 powinien uywa elementu hud_nocharge. Nastpnie przypisz obiekt PowerGUI z panelu Hierarchy do zmiennej Charge Hud GUI, co spowoduje, e komponent bdzie wyglda tak jak na poniszym rysunku:
Wró my do kodu i uyjmy wartoci zmiennej charge, by wybra odpowiedni tekstur z tablicy dla obiektu PowerGUI. W skrypcie Inventory umie poniszy wiersz kodu wewntrz istniejcej funkcji CellPickup(): Jzyk C# i JavaScript: chargeHudGUI.texture = hudCharge[charge];
W powyszym kodzie uywamy obiektu typu GUITexture (czyli PowerGUI), przypisanego do zmiennej chargeHudGUI. W tym obiekcie interesuje nas waciwo texture, której przypisujemy okrelon tekstur z tablicy hudCharge. Indeks tablicy, czyli odpowiednia tekstura, wynika z uycia zmiennej charge, która przechowuje liczb — sprytne, nieprawda? Zapamitaj skrypt i wró do rodowiska Unity. Przetestujmy gr! Kliknij przycisk Play (granie) i rozpocznij zbieranie ogniw energetycznych. Obserwuj jednoczenie, czy wywietlacz PowerGUI wywietla za kadym razem inn tekstur. Nacinij przycisk Play ponownie, by przerwa testowanie.
Wyczanie wywietlacza HUD przy starcie gry Poniewa stworzye wywietlacz HUD, którego zawarto jest sterowana skryptem Inventory, powiniene sprawi , by by on wyczany w trakcie dziaania gry. Nie naley udostpnia graczowi od razu zbyt wielu wskazówek. Wywietlacz powinien si pojawi dopiero wtedy, gdy gracz spróbuje wej do wntrza placówki.
211
Projektowanie gier w rodowisku Unity 3.x
Wybierz obiekt PowerGUI w panelu Hierarchy, a nastpnie wycz komponent GUITexture w panelu Inspector poprzez odznaczenie opcji wyboru, znajdujcej si po lewej stronie nazwy. Spowoduje to wyczenie komponentu, lecz moemy uy odpowiedniego kodu, by go ponownie wczy w trakcie gry. Powinnimy to wykona w dwóch przypadkach: 1. Gdy gracz pojawia si w strefie wyzwalania bez adnych ogniw energetycznych. 2. Gdy gracz podnosi ogniwo energetyczne, lecz nie pojawia si w strefie wyzwalania. Teraz zajmiemy si pierwszym przypadkiem: gracz pojawia si w strefie wyzwalania, ale nie ma przy sobie adnych ogniw energetycznych. Przypadek powinien zosta obsuony przez instrukcj else w skrypcie TriggerZone. Otwórz ten skrypt w edytorze. Gdy gracz wkracza w obszar wyzwalania, lecz nie moe otworzy drzwi, powinien si dowiedzie , e wymagane jest ródo zasilania. W tym celu odtworzymy odpowiedni klip dwikowy, który poinformuje, e drzwi nie mog zosta otwarte bez dziaajcego generatora. Nastpnie wywietlimy obiekt PowerGUI, prezentujcy nienaadowane ogniwo energetyczne. Powyej funkcji OnTriggerEnter() umie zmienn publiczn, która bdzie zawiera klip dwikowy reprezentujcy zamknite drzwi: Jzyk C#: public AudioClip lockedSound;
Jzyk JavaScript: var lockedSound : AudioClip;
Nastpnie umie kursor wewntrz instrukcji else w funkcji OnTriggerEnter() i wprowad poniszy kod: Jzyk C# i JavaScript: transform.FindChild("door").audio.PlayOneShot(lockedSound); col.gameObject.SendMessage("HUDon");
Wykorzystujemy tu dwa inne elementy — door, który naley do obiektu nadrzdnego outPost, oraz obiekt Player (First Person Controller), poniewa jest on przechowywany w polu col. ´gameObject. Do obiektu door odwoujemy si, tak jak poprzednio, za pomoc funkcji Find ´Child(). Nastpnie wykorzystujemy jego komponent AudioSource, aby odtworzy dwik lockedSound. Wreszcie wykonujemy procedur SendMessage(), by wywoa now funkcj HUDon(), któr wkrótce umiecimy w skrypcie Inventory. Bdzie ona po prostu sprawdza , czy wywietlacz PowerGUI jest wczony. Jeli nie, nastpi jego aktywacja poprzez ponowne przyczenie komponentu. Funkcj t umiecimy w skrypcie Inventory, poniewa zawiera on ju odwoanie do obiektu PowerGUI.
212
Rozdzia 6. • Kolekcja, inwentarz i HUD
Zapamitaj skrypt TriggerZone, a nastpnie jeszcze raz otwórz skrypt Inventory lub przejd do odpowiedniej zakadki w swoim edytorze.
Wczanie wywietlacza HUD w trakcie dziaania gry Podczas dziaania gry powinnimy wczy wywietlacz HUD w skrypcie Inventory zarówno gdy gracz podnosi pierwsze ogniwo energetyczne (a nie próbowa otwiera drzwi), jak i wówczas, gdy chce dosta si do wntrza placówki, lecz nie posiada adnych baterii. Teraz obsuymy przypadek drugi, gdy w skrypcie TriggerZone wanie umiecilimy wywoanie nowej funkcji. Umie poniszy kod po zamykajcym nawiasie klamrowym funkcji CellPickup(): Jzyk C#: void HUDon(){ if(!chargeHudGUI.enabled){ chargeHudGUI.enabled = true; } }
Jzyk JavaScript: function HUDon(){ if(!chargeHudGUI.enabled){ chargeHudGUI.enabled = true; } }
W powyszym kodzie, poprzez uycie zmiennej chargeHudGUI, wykorzystano komponent GUITexture z obiektu PowerGUI, który zosta ju przez nas skonfigurowany. Instrukcja if po prostu sprawdza, czy wywietlacz jest wyczony (if(!chargeHudGUI.enabled)) — znak wykrzyknika oznacza zaprzeczenie. Upewniamy si wic, czy opcja enabled jest równa false, a nastpnie przypisujemy jej warto true. A teraz zajmijmy si przypadkiem wczania wywietlacza HUD, gdy gracz najpierw podnosi ogniwo energetyczne. Wiemy ju, e ta czynno jest obsugiwana przez procedur CellPickup(), dlatego wewntrz niej wywoamy po prostu funkcj HUDon(), zamiast umieszcza w kodzie kolejn instrukcj if. Wprowad poniszy kod na pocztku funkcji CellPickup(): Jzyk C# i JavaScript: HUDon();
Kod ten sprawdza stan wywietlacza w przypadku, gdy gracz najpierw podnosi ogniwo energetyczne. Zapamitaj skrypt i wró do rodowiska Unity, aby przetestowa dziaanie wywietlacza HUD w rónych okolicznociach.
213
Projektowanie gier w rodowisku Unity 3.x
Przed rozpoczciem testów wybierz obiekt nadrzdny outPost, a nastpnie przypisz klip audio door_locked, znajdujcy si w folderze Book Assets/Sounds w panelu Project, do zmiennej publicznej Locked Sound, dostpnej w komponencie Trigger Zone (Script). Kliknij przycisk Play, aby rozpocz testowanie gry, a w dalszej kolejnoci upewnij si, e w przypadku pojawienia si w strefie wyzwalania bez ogniw energetycznych wywietlacz HUD zostaje wczony i sycha dwik wiadczcy o zamknitych drzwiach. Po wykonaniu tego testu ponownie uruchom gr (kliknij przycisk Play, aby wyj z trybu testowania, a póniej nacinij go jeszcze raz), by sprawdzi , czy podniesienie ogniwa energetycznego bez wchodzenia do obszaru wyzwalania równie powoduje wczenie wywietlacza HUD. Gdy sprawdzisz poprawne dziaanie mechaniki gry, zapamitaj scen poprzez wybranie opcji menu gównego File/Save Scene (plik/zapisz scen). Teraz umiecimy w scenie generator, prezentujcy taki sam poziom zasilania jak wywietlacz HUD, przez co poczymy go wizualnie z obiektem outPost.
Umieszczanie generatora energii Aby wizualnie poczy wywietlacz HUD obiektu PowerGUI z obiektem outPost, bdziemy musieli umieci w grze model generatora, prezentujcy poziom zasilania. Bdzie on przydatny, gdy gracz nie próbowa wej do placówki i nie wie, do czego su gromadzone ogniwa energetyczne. W podfolderze Models (modele) folderu Book Assets, znajdujcym si w panelu Project, odszukaj model o nazwie generator, a nastpnie przecignij go na widok Scene i umie przy placówce. Obró go o 180 stopni wokó osi Y: wprowad warto 180 w polu Rotation Y (obrót w osi Y) komponentu Transform, znajdujcego si w panelu Inspector. Nastpnie uyj narzdzia Translate, aby umieci generator przy cianie placówki, po prawej stronie schodów.
214
Rozdzia 6. • Kolekcja, inwentarz i HUD
Rozwi obiekt nadrzdny generator w panelu Hierarchy, aby wywietli jego obiekty podrzdne chargeMeter i generator. Wybierz obiekt potomny generator (patrz poniszy rysunek), a nastpnie uyj opcji menu gównego Component/Physics/Box Collider (komponent/parametry fizyczne/zderzacz skrzynkowy), by upewni si, e gracz nie moe przej przez generator.
Teraz wykorzystamy skrypt Inventory, aby zmodyfikowa tekstur w obiekcie podrzdnym chargeMeter. Poniewa obiekt ten jest niezalenym potomkiem obiektu generator, operacja zmiany tekstur bdzie znacznie atwiejsza.
Rozpoczniemy od stworzenia w skrypcie Inventory odwoania do obiektu chargeMeter, a take zdefiniowania innej tablicy, w której bdziemy przechowywa podmieniane tekstury, ponownie opierajc si na wartoci zmiennej charge. Jeszcze raz wczytaj skrypt Inventory do edytora lub wybierz odpowiedni zakadk, jeli jest ju uruchomiony. Nastpnie umie poniszy kod pod deklaracj tablicy dla wywietlacza HUD oraz zmiennej typu GUITexture:
215
Projektowanie gier w rodowisku Unity 3.x
Jzyk C#: // Generator public Texture2D[] meterCharge; public Renderer meter;
Jzyk JavaScript: // Generator var meterCharge : Texture2D[]; var meter : Renderer;
W powyszym kodzie po prostu zdefiniowalimy now tablic, pozwalajc na przechowywanie dwuwymiarowych tekstur, a take odwoanie do komponentu Renderer, któremu przypiszemy obiekt podrzdny chargeMeter, poniewa zawiera on komponent MeshRenderer z podmienianym materiaem. Dwuwymiarowe tekstury bd modyfikowa cay panel chargeMeter, podobnie jak ma to miejsce w przypadku obiektu PowerGUI, który zmienia ca tekstur, aby wywietli nowy stan zasilania.
Tak jak poprzednio w panelu Inspector przypiszemy parametrowi dugoci tablicy warto 5, a nastpnie kademu jej elementowi przyporzdkujemy tekstury z folderu Book Assets/Textures. Zanim to jednak zrobimy, dodamy kod, który podmienia tekstury w trakcie dziaania gry. W funkcji CellPickup() po istniejcym wierszu chargeHudGUI.texture = hudCharge[charge]; umie poniszy fragment kodu: Jzyk C# i JavaScript: meter.material.mainTexture = meterCharge[charge];
W powyszym wierszu wykorzystujemy odwoanie do komponentu renderera obiektu charge ´Meter, w którym uywamy przypisanego do niego materiau (material), a nastpnie jego tekstury (mainTexture). Parametrowi mainTexture przypisujemy okrelon tekstur, znajdujc si w odpowiednim elemencie tablicy meterCharge, którego wybór ponownie zaley od wartoci zmiennej charge. Zapamitaj skrypt i wró do rodowiska Unity. Wybierz obiekt First Person Controller, aby wywietli komponent Inventory (Script) w panelu Inspector. Rozwi nowo utworzon tablic Meter Charge poprzez kliknicie szarej strzaki, znajdujcej si po lewej stronie nazwy, a nastpnie przypisz parametrowi Size (rozmiar) warto 5. Podobnie jak miao to miejsce w przypadku poprzedniej tablicy, zostan wywietlone nazwy jej piciu elementów.
216
Rozdzia 6. • Kolekcja, inwentarz i HUD
W folderze Book Assets/Textures, znajdujcym si w panelu Project, zlokalizuj tekstury, których nazwy zaczynaj si od sowa meter_charge. Przypisz je do odpowiednich elementów tablicy Meter Charge. Nastpnie przecignij obiekt podrzdny chargeMeter, nalecy do obiektu generator, z panelu Hierarchy do zmiennej Meter, tak jak zaprezentowano na poniszym rysunku:
Poniewa kod jest ju gotowy, a tablica oraz zmienne zostay odpowiednio przypisane, wybierz opcj menu gównego File/Save Scene (plik/zapisz scen), aby zapamita biecy stan projektu. Kliknij przycisk Play, aby przetestowa dziaanie gry. Sprawd, czy podczas podnoszenia ogniw energetycznych miernik poziomu zasilania generatora wywietla odpowiedni tekstur, informujc uytkownika, ile elementów zostao ju zgromadzonych. Ponownie nacinij przycisk Play, eby zakoczy test.
Poinformowanie o otwarciu drzwi Aby ukoczy tworzenie mechaniki gry, zwizanej z zasilaniem generatora drzwi, postaramy si poinformowa gracza, e zostay one otwarte. Oczywicie bdzie on o tym wiedzia, poniewa zostanie wywietlona animacja otwierania drzwi. By jednak dopracowa dziaanie samej mechaniki, powinnimy wykona nastpujce czynnoci, gdy gracz pojawia si po raz pierwszy w obszarze wyzwalania i ma przy sobie wszystkie cztery ogniwa energetyczne: Q Usun wywietlacz HUD dla obiektu PowerGUI, gdy gracz nie musi ju wiedzie ,
e zebra wszystkie ogniwa energetyczne. Ukrycie wywietlacza bdzie informacj dla gracza, i ogniwa zostay poprawnie wykorzystane. Q Zmieni kolor wiata. Nad drzwiami umiecimy owietlenie, które zmieni kolor z czerwonego na zielony, aby poinformowa o otwarciu drzwi.
217
Projektowanie gier w rodowisku Unity 3.x
Umieszczanie owietlenia informujcego o otwarciu drzwi Aby przekaza informacj o stanie otwarcia drzwi, zastosujemy w scenie ródo wiata punktowego. Zostanie ono umieszczone nad drzwiami placówki w obiekcie outPost, poniej znajdujcego si tam panelu wietlnego.
Przed dodaniem róda wiata przygotujmy widok w oknie Scene w taki sposób, aby przypomina ten, który wida na powyszym rysunku. Pomoe nam to w odpowiednim umiejscowieniu dodawanego róda wiata, poniewa kady nowy obiekt tworzony w rodowisku Unity jest umieszczany w centrum widoku. Kliknij przycisk Create w panelu Hierarchy, a nastpnie wybierz opcj Point Light (wiato punktowe) z menu rozwijanego. Zmie nazw nowo utworzonego obiektu na Door Light. Zanim umiecisz wiato w odpowiednim miejscu, zmodyfikuj jego intensywno i zakres. W komponencie Light, nalecym do obiektu Door Light, przypisz pozycji Range (zasig) warto 1,2. Dla parametru Color (kolor) wybierz barw czerwon poprzez kliknicie prostoktnego obszaru koloru i wskazanie jakiego odcienia czerwieni z okna wyboru koloru. Wreszcie w polu Intensity (intensywno ) wprowad warto 3, dziki czemu ródo wiata bdzie miao krótki zasig, lecz wysok jaskrawo . Teraz uyj narzdzia Translate (skrót klawiszowy W), aby umieci ródo wiata zgodnie z poprzednim rysunkiem.
218
Rozdzia 6. • Kolekcja, inwentarz i HUD
Zmiana koloru wiata i usuwanie wywietlacza HUD Otwórz skrypt TriggerZone, a nastpnie na jego pocztku umie deklaracj zmiennej o typie Light: Jzyk C#: public Light doorLight;
Jzyk JavaScript: var doorLight : Light;
Mamy ju zmienn, dziki której moemy sterowa wiatem. Odpowiedni obiekt Door Light zostanie przypisany do niej w póniejszym czasie. Teraz zlokalizuj zagniedon instrukcj if, znajdujc si wewntrz gównego polecenia if w funkcji OnTriggerEnter(): if(Inventory.charge == 4){ transform.FindChild("door").SendMessage("DoorCheck"); }
Jest to fragment skryptu wykonywany w momencie, gdy drzwi s otwierane, po zebraniu przez gracza wszystkich ogniw energetycznych. W tym wanie miejscu powinnimy sprawdzi , czy gracz próbuje otwiera drzwi po raz pierwszy, a póniej wykona dwie akcje, o których pisalimy wczeniej. Zlokalizuj wiersz kodu: transform.FindChild("door").SendMessage("DoorCheck");
Umie bezporednio pod nim nastpujc instrukcj if: Jzyk C# i JavaScript: if(GameObject.Find("PowerGUI")){ Destroy(GameObject.Find("PowerGUI")); doorLight.color = Color.green; }
Powyszy kod jest zawarty w gównej instrukcji if, która zapewnia to, e gracz zebra wszystkie cztery ogniwa energetyczne. Moemy wic zaoy , e jest to waciwy moment na usunicie obiektu PowerGUI, dlatego te w warunku if nastpuje sprawdzenie, czy on istnieje. Jest to realizowane poleceniem GameObject.Find(), które wyszukuje nazw PowerGUI w hierarchii obiektów. Jeli obiekt PowerGUI nie istnieje, nie ma potrzeby zajmowania si nim. W przeciwnym razie instrukcja Destroy() usuwa go, ponownie wykonujc polecenie GameObject.Find() w celu odwoania si do niego. Nastpnie zmieniamy kolor wiata z czerwonego na zielony, uywajc w tym celu zmiennej doorLight. Przypisujemy jej wczeniej zdefiniowan warto green z klasy Color.
219
Projektowanie gier w rodowisku Unity 3.x
Tego typu uproszczone wartoci s zdefiniowane dla wszystkich gównych kolorów. Moesz take uywa zapisu RGB, reprezentujcego wszystkie trzy podstawowe kanay kolorów (czerwony, zielony, niebieski). Aby dowiedzie si wicej o tym zagadnieniu, zapoznaj si z dokumentacj tworzenia skryptów w rodowisku Unity: http://unity3d.com/support/documentation/ ScriptReference/Color.html. Zapisz swój skrypt i wró do rodowiska Unity. Poniewa utworzylimy zmienn publiczn, która reprezentuje obiekt Door Light, powinnimy j odpowiednio zainicjalizowa przed kontynuowaniem dziaa. W tym celu wybierz obiekt outPost w panelu Hierarchy, a nastpnie sprawd, czy zmienna publiczna Door Light pojawia si w komponencie Trigger Zone (Script) w panelu Inspector. Jeli wszystko jest w porzdku, przecignij obiekt Door Light z panelu Hierarchy na t zmienn. Wreszcie kliknij przycisk Play i postaraj si zgromadzi cztery ogniwa energetyczne, pozwalajce na zasilanie generatora sucego do otwierania drzwi. Gdy zbierzesz ju wszystkie, podejd do drzwi obiektu outPost. Powinno to spowodowa ich otwarcie, wyczenie wywietlacza PowerGUI oraz zmian koloru owietlenia z czerwonego na zielony.
Ponownie nacinij przycisk Play, aby zakoczy testy, a nastpnie zapisz biecy stan projektu Unity, wybierajc opcj menu gównego File/Save Scene. Postaramy si teraz wywietli dodatkow wskazówk dla gracza w postaci tekstu na ekranie. Zrobimy to w stylu klasycznych gier przygodowych: uyjemy wewntrznego monologu, za pomoc którego posta w grze rozmawia z graczem.
220
Rozdzia 6. • Kolekcja, inwentarz i HUD
Wskazówki dla gracza Co si stanie, gdy gracz, bardziej zainteresowany drzwiami placówki ni rozrzuconymi ogniwami energetycznymi, podejdzie do nich i bdzie chcia je otworzy ? Zwyke wywietlenie nienaadowanej baterii wydaje si niezbyt interesujcym rozwizaniem. Gdyby posta moga przemówi do gracza, byoby to duo bardziej przyjazne podejcie i spowodowaoby uzyskanie ciekawszych wrae zwizanych z rozgrywk. Na tym etapie wane jest take zastanowienie si, w jakiej formie bdziemy przemawia do gracza. Oczywicie moglibymy po prostu napisa : „Zgromad ogniwa energetyczne!”, lecz duo lepszym rozwizaniem z punktu widzenia rozgrywki bdzie udostpnienie wskazówek przy uyciu monologu wewntrznego. Polega on na tym, e myli postaci s przekazywane do gracza, na przykad: „Wyglda na to, e generator otwierajcy drzwi nie ma zasilania…”. Aby zaprezentowa tekst na ekranie, uyjemy komponentu GUIText. Istnieje wiele sposobów wykonania tego zadania, lecz ten jest najprostszy. Inne metody, takie jak uycie klasy GUIscripting, zostan zaprezentowane w dalszej czci ksiki.
Pisanie na ekranie za pomoc komponentu GUIText Gdy chcesz wywietli dwuwymiarowy tekst na ekranie, najprostsza metoda wykonujca to zadanie polega na uyciu komponentu GUIText. Ten sam rezultat mona take uzyska przy uyciu klasy GUIscripting. Obiekt GUI Text jest tworzony za pomoc opcji menu gównego. Zawiera on ju komponenty Transform i GUIText. Wybierz pozycj GUI Text, klikajc przycisk Create (stwórz) w panelu Hierarchy. Moesz take wybra opcj menu gównego GameObject/Create Other/GUIText (obiekt gry/stwórz inny/GUIText). Powiniene ju dysponowa nowym obiektem w panelu Hierarchy (hierarchia), zwanym GUI Text, oraz widzie na ekranie dwuwymiarowy napis „Gui Text”. Zmie nazw nowo utworzonego obiektu na TextHintGUI: wybierz go, a nastpnie nacinij klawisz Return (Mac) lub F2 (PC). Jeli obiekt jest wci wybrany w panelu Hierarchy, przyjrzyj si komponentowi GUIText w panelu Inspector (inspektor). Chcemy wywietla informacj dla gracza, dlatego powinnimy pozostawi biece parametry, definiujce pooenie napisu w komponencie Transform. Wartoci X i Y równe 0,5 oznaczaj rodek ekranu. Tekst wywietlony w tym miejscu na pewno zostanie zauwaony przez gracza. Oprócz moliwoci definiowania pooenia napisu na ekranie klasa GUIText zawiera równie parametr Alignment (wyrównanie), który dziaa podobnie jak ustawienia justyfikacji w oprogramowaniu przetwarzajcym teksty. Kliknij ikon z dwoma maymi strzakami, znajdujc si
221
Projektowanie gier w rodowisku Unity 3.x
po prawej stronie parametru Anchor (zakotwiczenie), a nastpnie wybierz opcj middle center (pooenie rodkowe, centrowane) i przypisz parametrowi Alignment warto center (centrowanie). Spowoduje to, e tekst bdzie si symetrycznie rozprzestrzenia z centralnego punktu ekranu, zamiast rozpoczyna si od rodka i wypenia praw cz okna. Waciwo Text (tekst) komponentu GUIText pozwala na proste wprowadzenie tekstu, który powinien si pojawi na ekranie. My jednak zastosujemy inne rozwizanie i wykorzystamy skrypt w celu dynamicznego wywietlania napisów.
Uycie skryptu w celu sterowania komponentem GUIText Pierwsza wskazówka, informujca gracza o tym, e drzwi wymagaj waciwego róda zasilania, powinna zosta wywietlona, gdy gracz próbuje wej do budynku placówki i nie ma odpowiedniej liczby ogniw energetycznych. Z tego powodu sensowne staje si umieszczenie kodu w skrypcie TriggerZone, a nastpnie wywoanie funkcji dla obiektu TextHintGUI, który wanie utworzylimy. Otwórz skrypt TriggerZone i umie ponisz deklaracj na jego pocztku, zaraz pod zmienn lockedSound: Jzyk C#: public GUIText textHints;
Jzyk JavaScript: var textHints : GUIText;
Uyty typ danych GUIText pozwoli na przecignicie obiektu TextHintGUI na zmienn publiczn i bezporednie odwoanie si do komponentu GUIText. Wybralimy go dlatego, e moemy zapamita w zmiennej cay obiekt gry. Uyjmy teraz utworzonego odwoania do obiektu GUIText i wylijmy do niego komunikat. Umie poniszy wiersz kodu w instrukcji else, znajdujcej si wewntrz funkcji OnTrigger ´Enter(): Jzyk C# i JavaScript: textHints.SendMessage("ShowHint", "This door seems locked... maybe that generator needs power...");
Ponownie wykorzystujemy tu polecenie SendMessage(), które wywouje funkcj obiektu TextHintGUI. Tym razem jednak podczas tej operacji uywamy argumentu. Nie przesyamy jedynie nazwy funkcji ShowHint, lecz dostarczamy dodatkowej informacji, oddzielonej przecinkiem od pierwszego elementu. Informacja ta jest argumentem funkcji, któr chcemy wywoa . Jego typem danych jest acuch znakowy i zawiera on tekst, który powinien zosta wywietlony na ekranie. Zapamitaj wprowadzone zmiany i wró do rodowiska Unity, aby utworzy nowy skrypt, zawierajcy funkcj ShowHint.
222
Rozdzia 6. • Kolekcja, inwentarz i HUD
Zanim napiszemy kod odbierajcy komunikat, przypiszmy now zmienn publiczn do obiektu GUIText. W tym celu wybierz obiekt outPost w panelu Hierarchy (hierarchia), aby wywietli komponent Trigger Zone (script). Nastpnie przecignij obiekt TextHintGUI z panelu Hierarchy na zmienn Text Hints. A teraz stwórzmy odbiornik komunikatu, którym bdzie skrypt doczony do obiektu TextHintGUI. Wybierz folder Scripts (skrypty) w panelu Project, kliknij przycisk Create oraz wybierz odpowiadajcy Ci jzyk programowania. Zmie nazw skryptu na TextHints i dwukrotnie j kliknij, by uruchomi edytor. Rozpoczniemy od stworzenia funkcji ShowHint(), która bdzie wywoywana ze skryptu TriggerZone. Umie poniszy fragment kodu w nowo utworzonym skrypcie: Jzyk C#: void ShowHint(string message){ guiText.text = message; if(!guiText.enabled){ guiText.enabled = true; } }
Jzyk JavaScript: function ShowHint(message : String){ guiText.text = message; if(!guiText.enabled){ guiText.enabled = true; } }
Stworzylimy funkcj z jednym argumentem (message), która bdzie odbiera tekst przesany za pomoc procedury SendMessage(). Na samym pocztku przypisujemy waciwoci text komponentu guiText acuch tekstowy, odebrany przez argument. Nastpnie przeprowadzamy podobne dziaanie, jakie wykonywalimy ju dla obiektu PowerGUI: sprawdzamy, czy komponent jest wczony. Jeli nie, wczamy go. Wypróbujmy nasz funkcj. Zapamitaj nowo utworzony skrypt i wró do rodowiska Unity. Przypisz go do obiektu TextHintGUI w panelu Hierarchy poprzez przecignicie go z panelu Project. Nastpnie usu domylny tekst „Gui Text”, przypisany do parametru text w komponencie GUIText. Dziki temu na ekranie nie pojawi si aden napis. Kliknij przycisk Play, znajdujcy si w górnej czci interfejsu. Powiniene zauway , e w czasie pojawiania si postaci gracza w obszarze wyzwalania obiektu placówki na ekranie wywietla si tekst zawierajcy napis, który zdefiniowalimy w funkcji SendMessage(), wywoujcej skrypt TextHints. Wszystko dziaa bardzo adnie, ale czy napis musi si równie wywietla , gdy oddalimy si od placówki? Kliknij przycisk Play, aby zakoczy testowanie, a nastpnie wró do skryptu TextHints.
223
Projektowanie gier w rodowisku Unity 3.x
Umie nastpujc zmienn na pocztku skryptu: Jzyk C#: float timer = 0.0f;
Jzyk JavaScript: private var timer : float = 0.0;
Zmienna ta jest po prostu licznikiem czasu. Do zwikszania wartoci zmiennej uyjemy funkcji Update(), gdy tylko nastpi wczenie komponentu GUIText. Po osigniciu okrelonej wartoci wyczymy go ponownie, aby usun tekst wywietlany na ekranie. Umie poniszy kod w funkcji Update(): Jzyk C# i JavaScript: if(guiText.enabled){ timer += Time.deltaTime; if(timer >=4){ guiText.enabled = false; timer = 0.0f; } }
W powyszym kodzie wykorzystujemy waciwo guiText.enabled, by sprawdzi , czy komponent zosta wczony przez funkcj ShowHint(). Uwaga Innym sposobem realizacji powyszego zadania byoby stworzenie zmiennej logicznej (o wartociach true lub false) oraz przypisanie jej wartoci true, gdy funkcja ShowHint() wczy komponent GUIText. Zmienna ta byaby nastpnie sprawdzana w pierwszej instrukcji if. Jednake moemy po prostu sprawdzi stan samego komponentu, a przez to uproci uywany kod.
Jeli waciwo guiText.enable jest równa true, zwikszamy zmienn timer poprzez dodanie do niej pola Time.deltaTime, które zlicza upyw czasu niezalenie od prdkoci klatek samej gry. Po wierszu zwikszajcym licznik czasu umiecilimy zagniedon instrukcj if, która sprawdza, czy jego warto odpowiada czterem sekundom. Jeli tak, wyczamy komponent, przypisujc false do waciwoci enabled, a nastpnie zerujemy licznik czasu, dziki czemu moe on ponownie rozpocz swoje dziaanie, gdy bdziemy potrzebowali wskazówki.
224
Rozdzia 6. • Kolekcja, inwentarz i HUD
Unikanie pominitych wartoci W sytuacjach, takich jak sprawdzanie upywu czasu, zawsze uywamy warunku „wikszy lub równy” (>=), poniewa nasza instrukcja if moe czasami pomin pewn klatk, w której warto zmiennej jest dokadnie równa 4,0, co mogoby spowodowa, e nigdy by si nie wykonaa. Dlatego te nie powiniene uywa warunku == w celu sprawdzenia zmiennej, która jest zwikszana w funkcji Update().
Zapamitaj skrypt i wró do rodowiska Unity, a nastpnie kliknij przycisk Play (granie). Testujc gr, powiniene zauway , e podczas pojawiania si w strefie wyzwalania obiektu outPost na ekranie wywietla si nastpujcy komunikat: This door seems locked… maybe that generator needs power… (te drzwi wygldaj na zamknite, by moe generator wymaga odpowiedniego zasilania…). Dziki zmiennej timer napis zniknie po czterech sekundach. Ponownie kliknij przycisk Play, aby zakoczy testowanie. Jeli w dolnej czci interfejsu Unity pojawi si jakie informacje o bdach, kliknij je dwukrotnie i wró do skryptu, by go poprawi , porównujc swój kod z treci umieszczon w tej ksice. A teraz zapamitaj scen w rodowisku Unity poprzez wybranie opcji menu gównego File/Save Scene (plik/zapisz scen).
Modyfikacja wskazówek w celu poinformowania o postpach Poniewa moemy ju wywietla wskazówki na ekranie, powinnimy zapewni to, e gracz bdzie wiedzia, i rozpoczcie gromadzenia ogniw energetycznych jest tym, czego si od niego oczekuje. Aby wykona to zadanie, bdziemy wywietla inny komunikat, gdy gracz ju rozpocz zbieranie ogniw, ale jeszcze ich wszystkich nie zgromadzi. Wró do skryptu TriggerZone, w którym wprowadzimy odpowiednie modyfikacje. Umie ponisz instrukcj else if w istniejcym poleceniu if/else, zawartym w funkcji OnTriggerEnter(). Pamitaj, e powinna si ona znajdowa przed kocow instrukcj else: Jzyk C# i JavaScript: else if(Inventory.charge > 0 && Inventory.charge < 4){ textHints.SendMessage("ShowHint", "This door won't budge... guess it needs fully charging - maybe more power cells will help..."); transform.FindChild("door").audio.PlayOneShot(lockedSound); }
W powyszym kodzie sprawdzamy, czy gracz zebra wicej ni zero ogniw energetycznych, lecz mniej ni cztery. Jeli ten warunek jest speniony, uywamy polecenia SendMessage(), aby wywoa funkcj ShowHint() dla obiektu TextHintGUI, a nastpnie odtwarzamy dwik zamknitych drzwi.
225
Projektowanie gier w rodowisku Unity 3.x
Caa struktura if/else if/else powinna wyglda nastpujco: Jzyk C# i JavaScript: if(Inventory.charge == 4){ transform.FindChild("door").SendMessage("DoorCheck"); }else if(Inventory.charge > 0 && Inventory.charge < 4){ textHints.SendMessage("ShowHint", "This door won't budge... guess it needs ´fully charging - maybe more power cells will help..."); transform.FindChild("door").audio.PlayOneShot(lockedSound); }else{ transform.FindChild("door").audio.PlayOneShot(lockedSound); col.gameObject.SendMessage("HUDon"); textHints.SendMessage("ShowHint", "This door seems locked... maybe that ´generator needs power..."); }
Powyszy kod pozwala na dynamiczne modyfikowanie komunikatów wysyanych do gracza. Dziki temu, poprzez odpowiedni reakcj gry, uzyskuje on potwierdzenie poprawnoci wykonywanych dziaa. Zapamitaj skrypt i wró do rodowiska Unity, a nastpnie rozpocznij testowanie gry. Po zebraniu pierwszego ogniwa energetycznego spróbuj otworzy drzwi. Na ekranie powinien pojawi si komunikat, który wanie dodae! Aby wskazówki byy wywietlane w bardziej profesjonalny sposób, uzupenimy mechanik poprzez dodanie czcionki do komponentu GUIText w obiekcie TextHintGUI. Wybierz opcj File/Save (plik/zapisz), aby zapamita biecy stan projektu.
Uycie czcionek Czcionki uywane w projekcie Unity musz zosta zaimportowane w postaci zasobu tak jak kady inny element dodawany przez Ciebie. Mona to zrobi , zwyczajnie dodajc plik typu TTF (TrueType font) (czcionka typu TrueType) lub OTF (OpenType font) (czcionka typu OpenType) do folderu projektu Assets (zasoby) przy uyciu aplikacji Finder (Mac) lub Windows Explorer (PC), a take w samym rodowisku Unity dziki wybraniu opcji menu gównego Assets/Import New Asset (zasoby/importowanie nowego zasobu). Dla naszego przypadku pobierzemy darmow do wykorzystania (w przypadku zastosowa niekomercyjnych) czcionk ze strony www.dafont.com. Strona ta zawiera wiele bezpatnych czcionek, które s bardzo przydatne podczas realizacji kadego projektu zwizanego z typografi. Uwaga Powiniene by wiadomy tego, e pewne strony internetowe udostpniaj czcionki, których wolno uywa za darmo, lecz które zawieraj ograniczenie mówice, i nie mona ich wykorzystywa w projektach pozwalajcych na ich wyodrbnienie. Ten problem nie wystpuje w przypadku Unity, poniewa wszystkie czcionki s zamieniane na tekstury podczas tworzenia wynikowego obrazu gry.
226
Rozdzia 6. • Kolekcja, inwentarz i HUD
Odwied t stron i pobierz czcionk, która Ci si podoba, a jednoczenie jest atwa do czytania. Pamitaj, e zostanie ona uyta do wywietlania instrukcji, wic nie moe by nadmiernie wyrafinowana, poniewa obniyaby wraenia odbioru gry. Jeli chciaby uy takiej samej czcionki, któr wida w przykadach dostpnych w tej ksice, powiniene odszuka nazw Sugo. Pobierz j, rozpakuj, a nastpnie uyj jednej z wczeniej wspomnianych metod, aby zaimportowa plik Sugo.otf (lub ten, który wybrae) w postaci zasobu projektu. Gdy czcionka znajduje si ju w projekcie, odszukaj j w panelu Project i wybierz. Czcionki w rodowisku Unity s reprezentowane przez ikon w ksztacie wielkiej litery A. Nastpnie uyj tej czcionki w obiekcie TextHintGUI. W tym celu wybierz go w panelu Hierarchy, a póniej przecignij czcionk z panelu Project na parametr Font (czcionka) komponentu GUIText w panelu Inspector. Wreszcie zwikszmy rozmiar czcionki w komponencie GUIText, przypisujc parametrowi Font Size (rozmiar czcionki) warto 25. Jeli jest on równy zeru, rodowisko Unity uywa domylnej wielkoci czcionki. Jej warto moesz sprawdzi poprzez wybranie czcionki w panelu Project, a nastpnie odczytanie odpowiedniego parametru w obszarze True Type Font Importer (importer czcionki TrueType) — zazwyczaj widnieje tam liczba 16. Kliknij przycisk Play, by przetestowa gr. Wskazówki dla gracza s teraz wywietlane przy uyciu nowo dodanej czcionki. Pamitaj, e pewne rodzaje czcionek mog wyglda odmiennie nawet po wybraniu tej samej wielkoci liter, dlatego gdy stwierdzisz, i rozmiar 25 nie jest odpowiedni, moesz go oczywicie zmodyfikowa zgodnie z wasnymi preferencjami.
Podsumowanie W tym rozdziale z powodzeniem stworzylimy i zaimplementowalimy scenariusz gry. Dziki ustaleniu, jakie elementy powinien widzie gracz podczas gry (niezalenie od wiedzy o jego dziaaniach), moesz wybra najlepsz metod, której powiniene uy jako projektant. Spójrz na kady nowy element w swojej grze z punktu widzenia gracza — zagraj w jakie istniejce gry, zastanów si nad scenariuszami ze wiata realnego, ale przede wszystkim zaó, e gracz nie dysponuje adn wczeniejsz wiedz (nawet w przypadku tradycyjnych gier, poniewa mog one by nowoci w technologii komputerowej). Najbardziej intuicyjna rozgrywka ma miejsce w grach, w których jest zachowana równowaga midzy zoonoci amigówek a waciwym wyposaeniem gracza z punktu widzenia uzyskiwanych informacji oraz przyjaznoci zastosowanej prezentacji. Bardzo wane jest zapewnienie odpowiedniej reakcji na dziaania gracza dziki wykorzystaniu w tym celu elementów wizualnych lub dwikowych. Podczas projektowania zawsze zwracaj uwag na to, jakie informacje s przekazywane do gracza w kadym etapie gry.
227
Projektowanie gier w rodowisku Unity 3.x
Gdy zrealizowalimy ju prosty scenariusz gry oraz przyjrzelimy si, w jaki sposób mona tworzy i kontrolowa elementy graficznego interfejsu uytkownika, powinnimy zaj si implementacj innego scenariusza. Bdzie on polega na stworzeniu specjalnego pomieszczenia, w którym gracz po trafieniu wszystkich celów wygra dodatkowe ogniwo energetyczne.
228
7 Konkretyzowanie obiektów i bryy sztywne W tym rozdziale zajmiemy si dokadniej dwoma zasadniczymi zagadnieniami, zwizanymi z projektowaniem gier 3D, z którymi zapoznalimy si ju w rozdziale 2. Zdefiniujemy abstrakcyjn mechanik gry, dotyczc celowania i rzucania obiektami, a nastpnie zaimplementujemy j w kontekcie wyspy, tworzc gr polegajc na rzucaniu do celu, w której bdzie uczestniczy gracz. Gdy rozpoczynasz tworzenie sceny, zdajesz sobie spraw z tego, e nie wszystkie obiekty, które s w niej wymagane, bd obecne na samym pocztku gry. Jest to prawda w przypadku takich gatunków gier, jak na przykad ukadanki — we pod uwag spadajce bloki w grze Tetris. W tym przypadku co pewien czas w górnej czci ekranu nastpuje tworzenie (lub konkretyzowanie) obiektów o losowych ksztatach, poniewa nie mog one by tam przechowywane w nieskoczono . Wemy teraz pod uwag nasz gr zwizan z eksploracj wyspy. W tym rozdziale zapoznamy si z konkretyzowaniem obiektów oraz fizyk bryy sztywnej poprzez stworzenie prostej gry opartej na rzucaniu do celu. Jednake w przeciwiestwie do prototypu, który wykonalimy wczeniej, pociski z orzechów kokosowych nie bd obecne w grze po jej rozpoczciu. Wynika std, e naley w tym przypadku zastosowa metod konkretyzowania obiektów. Uywajc prefabrykatów (z zapamitanym pooeniem i obrotem), mona konkretyzowa obiekty ju podczas trwania gry. Pozwoli nam to na utworzenie nowego orzecha kokosowego w momencie nacinicia przez gracza przycisku strzau.
Projektowanie gier w rodowisku Unity 3.x
Aby poczy t now cz gry z jej gównym wtkiem, usuniemy jedno ogniwo energetyczne. Poprzez wzicie udziau w grze rzucania do celu umoliwimy graczowi wygranie ostatniego ogniwa energetycznego, które jest wymagane do otwarcia drzwi placówki. W zasobach zwizanych z t ksik moesz znale odpowiedni model pomieszczenia oraz tarcz strzelniczych, które w nim umiecimy. Bdziesz musia stworzy prefabrykat orzecha kokosowego, a take zarzdza animacj tarcz strzelniczych. W tym celu wykorzystasz odpowiednie skrypty, które bd wykrywa zderzenia midzy orzechami i tarczami. Poniewa udostpnione tarcze zawieraj animacje typu „trafiony” i „gotowy do strzau”, bdziemy musieli równie napisa skrypt, który po trafieniu orzecha w cel umoliwi tarczom powrót w okrelonym czasie do stanu pocztkowego. Oznacza to, e gracz bdzie móg wygra t minigr jedynie wówczas, gdy wszystkie trzy cele zostan trafione w okrelonym przedziale czasu. Dziki temu uzyskujemy dodatkowy poziom trudnoci — moe on by modyfikowany poprzez zmian liczby sekund, po których upywie tarcze wracaj do pozycji pocztkowej. W tym rozdziale zostan zaprezentowane nastpujce zagadnienia: Q wspólne uycie bry sztywnych i prefabrykatów w funkcji Instantiate, Q dostarczanie informacji zwrotnej do gracza, Q uruchamianie animacji w wyniku wykrycia kolizji, Q zliczanie punktów przy uyciu zmiennych cakowitych, Q poczenie dwóch rónych typów mechaniki gier — placówki oraz rzucania do celu.
Wykorzystywanie konkretyzacji W tym rozdziale ponownie wykorzystamy polecenie Instantiate(), którego ju uywalimy w naszym wczeniejszym prototypie. Jest ono czsto stosowane w wielu grach do tworzenia pocisków, gromadzonych obiektów, a nawet postaci takich jak wrogowie. Konkretyzacja jest po prostu metod tworzenia (inaczej mówic, duplikowania) w trakcie dziaania gry obiektów na podstawie prototypu (w rodowisku Unity zwanym prefabrykatem). Jej przeciwiestwem jest sposób polegajcy na umieszczeniu obiektów w scenie ju podczas jej uruchamiania. Procedura konkretyzowania obiektów zawiera nastpujce czynnoci: Q Indywidualne utworzenie obiektu gry (tego, który powinien zosta skonkretyzowany
w naszej scenie) i w razie potrzeby uzupenienie go o niezbdne komponenty. Q Zapamitanie nowo utworzonego obiektu gry w postaci prefabrykatu. Q Usunicie pierwotnego obiektu ze sceny, dziki czemu od tej pory bdzie on istnie jedynie jako zasób w postaci prefabrykatu.
230
Rozdzia 7. • Konkretyzowanie obiektów i bryy sztywne
Q Napisanie skryptu, który zawiera funkcj Instantiate(), oraz przyczenie go do
aktywnego obiektu gry w scenie. Nastpnie uycie nowego prefabrykatu w funkcji Instantiate() poprzez stworzenie zmiennej publicznej, pozwalajcej na przypisanie go do skryptu. Instancja obiektu (w naszym przypadku orzecha kokosowego) musi zosta skonkretyzowana w okrelonym pooeniu wiata 3D. Powiniene si jednak zastanowi , czy nie mona by w tym celu wykorzysta pooenia ju istniejcego obiektu. Na przykad gdy bdziemy tworzy nasz prefabrykat orzecha kokosowego, umiecimy go w pooeniu zdefiniowanym przez pusty obiekt gry, który bdzie potomkiem obiektu podrzdnego Main Camera, nalecego do postaci gracza. Dziki temu moemy powiedzie , e zostanie on stworzony w przestrzeni lokalnej, czyli pooeniu zalenym od miejsca przebywania postaci gracza, a nie w konkretnej lokalizacji bezwzgldnej. Wynika to std, e wykorzystujemy w tym celu pooenie kamery, bdcej „oczami” postaci. Takie rozwizanie pomoe nam podj decyzj o lokalizacji kodu, czyli powizaniu midzy skryptem a odpowiednim obiektem. Doczenie skryptu do pustego obiektu, którego lokalizacj wykorzystamy dla nowo tworzonego orzecha kokosowego, pozwoli nam uy skadni z kropk i zastosowa wyraenie transform.position jako parametr pooenia w poleceniu Instantiate(). Dziki temu tworzony obiekt dziedziczy pooenie komponentu Transform, nalecego do pustego obiektu, do którego zosta doczony skrypt. Podobnie dziaa dziedziczenie obrotu, którego waciwoci zostaj pobrane z pustego obiektu nadrzdnego. Wywoanie polecenia Instantiate() powinno wyglda nastpujco: Instantiate(myPrefab, transform.position, transform.rotation);
Parametr myPrefab w powyszym kodzie jest odwoaniem do obiektu gry zapamitanego w postaci prefabrykatu. Wykorzystamy go praktycznie w dalszej czci tego rozdziau, lecz najpierw zapoznajmy si z fizyk bryy sztywnej oraz zastanówmy si nad jej znaczeniem w grach.
Bryy sztywne Silniki fizyczne pozwalaj na uzyskanie w grach odpowiedniego poziomu symulowanego realizmu w sensie fizycznym. Obecnie s one wbudowane w prawie wszystkie silniki gier lub uywane jako dodatkowa wtyczka. rodowisko Unity wykorzystuje nowoczesny i dokadny silnik fizyczny nVidia PhysX, który jest stosowany w wielu grach komercyjnych. Uycie silnika fizycznego oznacza nie tylko branie pod uwag takich parametrów, jak ciar i grawitacja, lecz równie realistyczne reagowanie na zjawiska fizyczne, np. tarcie, moment obrotowy oraz zderzenie mas.
231
Projektowanie gier w rodowisku Unity 3.x
Siy Silnik fizyczny oddziauje na obiekty gry odpowiednimi siami. Mog by one stosowane przy uyciu rónych metod, np. komponentów lub skryptów. Aby reagowa na dziaanie si fizycznych, obiekt gry musi by tak zwan bry sztywn.
Komponent Rigidbody Aby uy silnika fizycznego w obiekcie rodowiska Unity (czyli uczyni go bry sztywn), naley uzupeni go o komponent Rigidbody. Dziki temu nie ma potrzeby wykorzystania waciwoci silnika fizycznego w caej scenie — dziaa on w tle jedynie dla okrelonych obiektów. Po dodaniu komponentu Rigidbody w panelu Inspector (inspektor) zostan wywietlone okrelone parametry:
Komponent Rigidbody zawiera nastpujce parametry, które mog by modyfikowane i zarzdzane za pomoc skryptów: Q Mass (masa). Ciar obiektu wyraony w kilogramach. Pamitaj, e to ustawienie
spowoduje, i obiekty zaczn si zachowywa realistycznie. Na przykad uderzenie obiektu lejszego przez ciszy sprawi, e ten pierwszy zostanie odrzucony. Q Drag (opór powietrza). Ten parametr oznacza poziom oporu powietrza, jaki stawia
obiekt podczas poruszania si. Im wysza jest ta warto , tym szybciej nastpi zmniejszenie prdkoci obiektu podczas poruszania si w orodku wypenionym powietrzem. Q Angular Drag (opór powietrza dla prdkoci obrotowej). Parametr ten jest podobny
do poprzedniego, lecz wpywa na prdko obrotow, powodujc odpowiednie jej zmniejszenie w czasie obracania si obiektu w powietrzu. Q Use Gravity (uycie grawitacji). Nazwa parametru odpowiada dokadnie jego funkcji.
To ustawienie okrela, czy na obiekt bryy sztywnej bdzie oddziaywa sia cienia. Jeli jest ono wyczone, obiekt bdzie wci reagowa na odpowiednie siy generowane przez silnik fizyczny, lecz w rodowisku symulujcym zerow grawitacj.
232
Rozdzia 7. • Konkretyzowanie obiektów i bryy sztywne
Uwaga W rodowisku Unity istnieje take globalne ustawienie zwizane z grawitacj. Wybierz opcj menu gównego Edit/Project Settings/Physics (edycja/ustawienia projektu/parametry fizyczne), a nastpnie poprzez kliknicie szarej strzaki rozwi parametry Gravity (grawitacja). Pozwalaj one na zdefiniowanie wielkoci i kierunku dziaania siy cienia. Zwró uwag na to, e parametr Y jest równy 9,81, co oznacza standardowe przyspieszenie ziemskie 9,81 m/s . 2
Q Is Kinematic (uycie kinematyki). Ta opcja sprawia, e na obiekt bryy sztywnej nie
ma wpywu silnik fizyczny. Mógby uy tego parametru, jeli przykadowo chciaby, by pewien obiekt odbi bry sztywn przy dziaajcej grawitacji (tak jak ma to miejsce w przypadku odbijania piki przez „apk” we flipperze), lecz w taki sposób, aby samo uderzenie nie miao na niego wpywu. Ta opcja powinna by uywana podczas poruszania obiektu, którego ruch naley kontrolowa za pomoc skryptu lub animacji. Wynika std, e: (a) silnik fizyczny wpywa na ruch obiektu, a dziki temu poprawia ogóln wydajno gry, poniewa nie musimy wykonywa odpowiednich oblicze zwizanych ze zmian pooenia; (b) obiekt moe wci oddziaywa na inne poruszajce si obiekty, a jednoczenie nie jest bezporednio sterowany przez siy fizyczne. Q Interpolate/Extrapolate (interpolacja/ekstrapolacja). To ustawienie moe zosta uyte,
jeli bryy sztywne maj tendencj do drga. Interpolacja i ekstrapolacja mog si przyczyni do wyrównania ruchu poprzez, odpowiednio, wykorzystanie poprzedniej klatki lub przewidywanie nastpnej. Interpolacja jest przydatna do tworzenia postaci, które uywaj komponentu Rigidbody, natomiast stosowanie ekstrapolacji jest korzystne dla szybko poruszajcych si obiektów w celu poprawnego wykrywania ich zderze z innymi obiektami. Q Constraints (ograniczenia). Opcja ta moe zosta wykorzystana, by zablokowa
obiekty i sprawi , e nie bd si mogy porusza ani obraca w wyniku dziaania si generowanych przez silnik fizyczny. Jest ona szczególnie przydatna w obiektach, które musz wykorzystywa parametry fizyczne, lecz powinny znajdowa si w okrelonej pozycji. Na przykad w grach dwuwymiarowych obiekty nie mog zmienia swojego pooenia w osi Z (gboko ).
Tworzenie minigry Aby wykorzysta w praktyce powysze informacje, stworzymy gr polegajc na rzucaniu orzechami kokosowymi do celu. Zostanie ona powizana z uzyskaniem dostpu do placówki. Dziki wziciu udziau w grze gracz bdzie móg zdoby brakujce ogniwo energetyczne, wymagane do zasilania generatora otwierajcego drzwi budynku. Poniewa zdefiniowalimy ju ogniwa energetyczne, musimy z istniejcej sceny usun jedno z nich, co spowoduje, e gracz bdzie musia je zdoby .
233
Projektowanie gier w rodowisku Unity 3.x
W panelu Hierarchy (hierarchia) wybierz jeden z obiektów zwanych powerCell, a nastpnie usu go za pomoc skrótu klawiszowego Command+Backspace (Mac) lub Delete (PC).
Tworzenie prefabrykatu orzecha kokosowego Nasze prace rozpocznijmy od utworzenia obiektu, którym bdziemy rzuca , czyli orzecha kokosowego. W tym celu wybierz opcj menu gównego GameObject/Create Other/Sphere (obiekt gry/stwórz inny/kula). Spowoduje to umieszczenie w scenie prostego obiektu w ksztacie kuli. Jeli bdzie si on znajdowa w znacznej odlegoci od okna edytora, moesz go w prosty sposób przybliy : przemie kursor myszy nad widok Scene (scena), a nastpnie nacinij klawisz F. Wybierz obiekt w panelu Hierarchy, a nastpnie nacinij klawisz Return (Mac) lub F2 (PC) i podaj odpowiedni tekst, by zmieni jego nazw na Coconut. Teraz zmienimy parametry obiektu, aby lepiej dopasowa go do ksztatu orzecha kokosowego. W tym celu zmniejszymy jego rozmiar oraz delikatnie poszerzymy go w osi Z. W panelu Inspector (inspektor) przejd do komponentu Transform obiektu Coconut, a nastpnie odpowiednio wypenij pola w grupie Scale (skala). Parametrom X i Z przypisz warto 0,5, a Y — warto 0,6. Tekstura, która bdzie uyta w obiekcie orzecha kokosowego, zostaa pobrana razem z pozostaymi zasobami wykorzystywanymi w tej ksice. Nazywa si ona coconutTexture i znajduje si w katalogu Book Assets/Textures (zasoby ksiki/tekstury). Oprócz powyszej tekstury powiniene znale takie zasoby: Q Tekstur crosshair, znajdujc si w katalogu Book Assets/Textures. Q Dwa klipy dwikowe, których nazwy rozpoczynaj si od sowa target, a take plik
o nazwie coconut_throw. Powinny si one znajdowa w katalogu Book Assets/Sounds (zasoby ksiki/dwiki). Q Dwa modele trójwymiarowe: coconutShy i target — oba w katalogu Book
Assets/Models (zasoby ksiki/modele).
Przypisywanie tekstury do orzecha kokosowego Aby uy tekstury orzecha kokosowego, musimy dysponowa materiaem, któremu zostanie ona przypisana. W panelu Project (projekt) wybierz utworzony przez nas wczeniej folder Materials (materiay), a nastpnie kliknij przycisk Create (stwórz). Z rozwijanego menu wybierz opcj Material (materia). Zmie nazw nowo utworzonego materiau na Coconut Skin poprzez nacinicie klawisza Return (Mac) lub F2 (PC) i wprowadzenie odpowiedniego tekstu. Aby zastosowa tekstur w materiale, po prostu chwy i przecignij element coconutTexture z folderu Book Assets/Textures w panelu Project. Nastpnie umie go w pustym kwadracie widocznym po prawej stronie nazwy Base (RGB) (ustawienia podstawowe RGB) dla nowego materiau w panelu Inspector. Po tej operacji powiniene widzie okno podgldu materiau w dolnym obszarze panelu Inspector.
234
Rozdzia 7. • Konkretyzowanie obiektów i bryy sztywne
Pamitaj, e prezentuje ono jedynie wygld materiau naoonego na kul. Jest to domylny podgld w rodowisku Unity i jedynie zbiegiem okolicznoci jest to, e nasz obiekt ma równie ksztat kuli. Moesz zmodyfikowa prosty ksztat wywietlany w oknie podgldu. W tym celu naley klikn lewy przycisk, znajdujcy si po prawej stronie napisu Preview (podgld). Drugi przycisk suy do wyczania i wczania owietlenia oraz cienia. Nastpnie powinnimy przypisa materia Coconut Skin do obiektu gry Coconut, który umiecilimy w naszej scenie. Aby to zrobi , po prostu przecignij materia z panelu Project na odpowiedni obiekt w widoku Scene (scena) lub jego nazw w panelu Hierarchy.
Dodawanie obsugi parametrów fizycznych Poniewa obiekt gry Coconut ma si zachowywa realistycznie, powinnimy uzupeni go o komponent Rigidbody, co spowoduje rozpoczcie jego przetwarzania przez silnik fizyczny. Wybierz obiekt w panelu Hierarchy, a nastpnie przejd do opcji menu gównego Component/Physics/Rigidbody (komponent/parametry fizyczne/brya sztywna). Spowoduje to dodanie komponentu Rigidbody, który bdzie podlega prawu grawitacji. W wyniku tego obiekt rzucony przez gracza upadnie po chwili, tak jak staoby si w wiecie rzeczywistym. Domylne ustawienia komponentu Rigidbody mog pozosta niezmienione — w tym przypadku nie musisz ich modyfikowa . Moesz przetestowa , jak orzech kokosowy upada i si toczy (jeli umiecie go nad powierzchni wyspy — jeli nie, moesz go przemieci przy uyciu narzdzia Translate). Wystarczy klikn przycisk Play (granie) i obserwowa obiekt w widoku Scene (scena) lub Game (gra). Po zakoczeniu testów ponownie nacinij przycisk Play.
Zapisywanie obiektu w postaci prefabrykatu Poniewa nasz orzech kokosowy jest gotowy, moemy go zapisa w projekcie w postaci prefabrykatu. Dziki temu nie bdziemy dysponowa tylko pojedynczym egzemplarzem, lecz umoliwimy konkretyzowanie dowolnej liczby obiektów. Aby zapisa obiekt w postaci prefabrykatu, po prostu przecignij go z panelu Hierarchy i upu w dowolnym miejscu obszaru Project (projekt). W naszym przypadku wykonaj t czynno dla obiektu Coconut i umie go w folderze Prefabs (prefabrykaty), który wczeniej utworzylimy. Uwaga Twojemu prefabrykatowi zostanie nadana nazwa pochodzca od pierwotnego obiektu. Tekst wywietlony w panelu Hierarchy powinien zmieni kolor na niebieski, co oznacza, e ródem obiektu jest prefabrykat. Zalet takiego rozwizania jest to, i dowolna instancja obiektu moe zosta zmodyfikowana poprzez zmian ustawie prefabrykatu znajdujcego si w panelu Project. Przykadowo zaómy, e Twoja scena gry zawiera kilka budynków opartych na tym samym prefabrykacie. Modyfikacja wartoci przypisanego skryptu lub zamiana materiau moe zosta wówczas zrealizowana wycznie w prefabrykacie, co bdzie miao wpyw na wszystkie instancje obiektu dostpne w danej scenie.
235
Projektowanie gier w rodowisku Unity 3.x
Poniewa Twój obiekt Coconut jest ju zapamitany jako prefabrykat, usu pierwotn instancj ze sceny poprzez wybranie jej w panelu Hierarchy i nacinicie skrótu klawiszowego Command+Backspace (Mac) lub Delete (PC).
Tworzenie obiektu Launcher Poniewa chcemy umoliwi graczowi rzucanie stworzonym przed chwil prefabrykatem orzecha kokosowego, bdziemy potrzebowa dwóch rzeczy: skryptu do obsugi konkretyzacji oraz pustego obiektu gry, bdcego punktem wyjcia do okrelonego pooenia, w którym obiekt orzecha kokosowego zostanie umieszczony. Gdy w wiecie rzeczywistym rzucamy kul (znad gowy), wówczas staje si ona widoczna i pojawia si po której stronie gowy, kiedy nasze rami prostuje si, uwalniajc j z uchwytu. Wynika std, e powinnimy umieci nasz obiekt poza polem widzenia gracza i upewni si, e bdzie wyrzucany w kierunku jego spogldania. Widok gracza jest zarzdzany przez obiekt podrzdny Main Camera, nalecy do obiektu First Person Controller. Utworzenie pustego obiektu podrzdnego umoliwi poruszanie kamer, jego pooenie i obrót bd bowiem zawsze zalene od rodzica. Gdy kamera bdzie si obraca , tak samo bdzie si zachowywa jej obiekt podrzdny. Rozpocznij od utworzenia w scenie nowego pustego obiektu gry. Mona to zrobi , wybierajc opcj menu gównego GameObject/Create Empty (obiekt gry/stwórz pusty) lub uywajc skrótu klawiszowego Ctrl+Shift+N (PC) albo Command+Shift+N (Mac). Wybierz ten obiekt w panelu Hierarchy (domyln jego nazw jest GameObject) i zmie jego nazw na Launcher. Nastpnie rozwi obiekt First Person Controller poprzez kliknicie szarej strzaki po lewej stronie jego nazwy w panelu Hierarchy. Przecignij nowo utworzony obiekt Launcher nad obiekt Main Camera, co spowoduje, e stanie si on jego potomkiem. Zauwaysz, e wykonae t operacj prawidowo, gdy obok nazwy Main Camera pojawi si szara strzaka, która oznacza istnienie obiektów podrzdnych. Jak zaprezentowano na poniszym rysunku, obiekt Launcher znajduje si wewntrz obiektu Main Camera:
Poniewa jest on potomkiem obiektu Main Camera, porusza si i obraca razem ze swoim rodzicem. Wymaga on jednak zdefiniowania swojego pooenia. Przejd do komponentu Transform, zawartego w obiekcie Launcher i znajdujcego si w panelu Inspector. Pooenie mona zresetowa , wprowadzajc zera w odpowiednich polach, lecz wystarczy take uy ikony kóka zbatego, znajdujcego si w prawym górnym naroniku obszaru komponentu, a nastpnie wybra opcj Reset Position (resetuj pooenie) z rozwijanego menu.
236
Rozdzia 7. • Konkretyzowanie obiektów i bryy sztywne
Wskazówka Ikona kóka zbatego suy do szybkiego przeprowadzania okrelonych operacji. Znajduje si w panelu Inspector przy kadym komponencie. Zwizane z ni menu jest take przydatne, pozwala bowiem na usuwanie komponentów, które nie s ju potrzebne lub zostay dodane przez pomyk.
Umieszczenie obiektu potomnego Launcher w pooeniu 0 oznacza, e znajduje si on dokadnie w rodku swojego rodzica (lub inaczej mówic, w tym samym miejscu co on). Oczywicie nie jest to docelowe rozwizanie, lecz zupenie wystarczajce na sam pocztek. Jednake nie moemy pozostawi obiektu Launcher w tym pooeniu z dwóch powodów: Q Rzucane orzechy kokosowe bd jakby „wyskakiwa ” z gowy gracza, co bdzie
wygldao do dziwnie. Q Podczas konkretyzowania obiektów musisz upewni si, e nie bd one tworzone
w pooeniu, które doprowadzi do ich kolizji z innymi zderzaczami. Spowodowaoby to odrzucenie od siebie obu zderzaczy biorcych udzia w kolizji i mogoby zakóci wektor siy przyoony do orzecha kokosowego. Konkretyzowanie obiektu w pooeniu kamery oznaczaoby, e zderzacz kulisty orzecha pokryje si ze zderzaczem Character Controller obiektu First Person Controller. Aby tego unikn , musimy po prostu przesun obiekt Launcher do przodu i w prawo w stosunku do jego biecej lokalizacji. W tym celu w komponencie Transform przypisz parametrom pooenia X i Z warto 1. Launcher znajduje si teraz w miejscu, w którym powinno nastpowa uwalnianie obiektu rzucanego praw rk gracza, tak jak zaprezentowano na poniszym rysunku. By zobaczy obiekt, powiniene wybra narzdzie Translate (skrót klawiszowy W), co umoliwi wywietlanie osi wspórzdnych. Na poniszym rysunku wybrano równie obiekt Main Camera, by przedstawi odpowiedni perspektyw.
237
Projektowanie gier w rodowisku Unity 3.x
Aby sprawi , by orzech kokosowy by rzucany w kierunku, w którym spogldamy, musimy obróci obiekt Launcher wokó osi Y. W komponencie Transform wprowad warto 352 w polu Y dla pozycji Rotation (obrót), co oznacza obrót o 8 stopni. Teraz zajmiemy si tworzeniem skryptu, w którym obsuymy konkretyzacj orzecha kokosowego oraz jego sterowanie po naciniciu przez gracza przycisku strzau.
Skrypt obsugujcy rzucanie orzechami kokosowymi Poniewa orzech kokosowy powinien zosta wyrzucony po naciniciu przez gracza przycisku strzau, naley w kadej klatce gry sprawdza stan odpowiedniego klawisza. Klawisze i przyciski myszy s zwizane z domylnie nazwanymi portami wejciowymi w menederze wej rodowiska Unity. Mog one zosta zmodyfikowane poprzez wybór opcji menu gównego Edit/Project Settings/Input (edycja/ustawienia projektu/wejcie). Wywoaj t opcj, a nastpnie rozwi pozycj Axes (porty), klikajc ikon szarej strzaki po lewej stronie nazwy. Wreszcie rozwi zawart w niej pozycj zwan Fire1. Wród wywietlonych pozycji znajduj si trzy najwaniejsze parametry: Name (nazwa), Positive Button (przycisk zwikszania) i Alt Positive (alternatywny przycisk zwikszania). Parametr Name oznacza nazw portu, natomiast Positive Button i Alt Positive Button s faktycznymi klawiszami przyporzdkowanymi do niego. Nowe porty wejciowe mog zosta zdefiniowane przez zwyke zwikszenie wartoci pola Size (rozmiar), znajdujcego si w górnej czci interfejsu menedera wej . Spowoduje to utworzenie nowego portu, który moe zosta odpowiednio skonfigurowany.
Aby gracz móg rzuca orzechami kokosowymi w kierunku celów (umiecimy je w naszej scenie w dalszej kolejnoci), musimy stworzy skrypt, w którym zaimplementujemy dwie funkcjonalnoci:
238
Rozdzia 7. • Konkretyzowanie obiektów i bryy sztywne
Q konkretyzacj obiektu Coconut, który bdzie rzucany po naciniciu przycisku Fire1, Q przypisanie prdkoci do komponentu Rigidbody, by zaraz po utworzeniu orzecha
kokosowego uzyska jego ruch do przodu. W tym celu wybierz folder Scripts (skrypty) w panelu Project (projekt) i stwórz nowy plik w jzyku C# lub JavaScript, uywajc dostpnego przycisku Create (stwórz). Nacinij klawisz Return (Mac) lub F2 (PC) i zmie nazw skryptu na CoconutThrower. Nastpnie kliknij dwukrotnie jego ikon i wywoaj edytor.
Sprawdzanie wej Sprawdzanie, czy gracz nie nacisn odpowiedniego klawisza, powinno nastpowa w kadej klatce gry. Wynika std, e kod obsugujcy to zadanie musi si zawiera w funkcji Update(). Przesu zamykajcy nawias klamrowy tej funkcji o kilka wierszy w dó, a póniej umie w niej ponisz instrukcj if, która — podobnie jak w poprzednim prototypie — sprawdza, czy zosta nacinity klawisz Fire1: Jzyk C# i JavaScript: if(Input.GetButtonDown("Fire1")){ }
Wykorzystujemy tu klas Input, by oczekiwa na nacinicie przycisku zwizanego z portem Fire1 (lewy klawisz Ctrl i lewy klawisz myszy). Wewntrz instrukcji if znajdzie si obsuga dziaa, które zostan wykonane po naciniciu tego klawisza przez gracza. Najpierw powinnimy odtworzy dwik, który bdzie sygnaem zwrotnym dla gracza, informujcym o rzuceniu orzechem kokosowym. Gdybymy tworzyli strzelank, w tym miejscu najprawdopodobniej wykorzystalibymy dwik strzau. Jednake w naszym przypadku uyjemy delikatnego odgosu wistu, który bdzie reprezentowa rzut orzechem kokosowym.
Odtwarzanie d wiku zwrotnego By zaprezentowa odtwarzany klip audio, bdziemy musieli uy zmiennej. Umie wic ponisz deklaracj zmiennej publicznej nad funkcj Update(): Jzyk C#: public AudioClip throwSound;
Jzyk JavaScript: var throwSound : AudioClip;
Powyszy kod tworzy zmienn publiczn, do której po zakoczeniu tworzenia skryptu przypiszemy faktyczny klip audio w panelu Inspector (inspektor).
239
Projektowanie gier w rodowisku Unity 3.x
A teraz wewntrz instrukcji if umie my polecenie odtwarzajce dwik. Po otwierajcym j nawiasie klamrowym umie nastpujcy wiersz kodu: Jzyk C# i JavaScript: audio.PlayOneShot(throwSound);
Dziki powyszemu kodowi zostanie odtworzony odpowiedni dwik, gdy gracz nacinie przycisk Fire1. Sprawdmy, czy tak jest w rzeczywistoci — zapamitaj skrypt i wró do rodowiska Unity. Przecigajc skrypt z panelu Project (projekt), przypisz go do obiektu podrzdnego Launcher w panelu Hierarchy (hierarchia). Zanim rozpoczniemy test, musimy przypisa klip audio do dostpnej zmiennej publicznej Throw Sound. W tym celu przecignij klip coconut_throw z folderu Book Assets/Sounds (zasoby ksiki/dwiki) na t zmienn w komponencie Coconut Thrower (Script) obiektu Launcher. Wreszcie dodaj komponent Audio Source do obiektu Launcher poprzez wybranie go w panelu Hierarchy, a nastpnie przejcie do opcji menu gównego Component/Audio/Audio Source (komponent/audio/ródo audio). Kliknij przycisk Play (granie) i nacinij lewy klawisz Ctrl lub lewy klawisz myszy — powiniene usysze dwik rzucanego przedmiotu.
Konkretyzacja orzecha kokosowego Teraz musimy skonkretyzowa (inaczej mówic, utworzy lub sklonowa ) faktyczny orzech kokosowy. Wykonamy to równie w biecej instrukcji if. Wró do edytora lub ponownie wczytaj skrypt CoconutThrower, jeli go zamkne. Poniewa utworzylimy obiekt orzecha kokosowego, a nastpnie zapamitalimy go w postaci prefabrykatu, powinnimy doda kolejn zmienn publiczn. Bdziemy mogli póniej przypisa do niej nasz prefabrykat w panelu Inspector. Poniej zmiennej, któr ostatnio stworzylimy, umie nastpujcy kod: Jzyk C#: public Rigidbody coconutPrefab;
Jzyk JavaScript: var coconutPrefab: Rigidbody;
Powyszy kod dodaje zmienn publiczn typu Rigidbody. Mimo e nasz orzech kokosowy jest przechowywany w zasobie prefabrykatu, podczas konkretyzacji utworzymy obiekt gry zawierajcy komponent Rigidbody — std wynika uyty typ danych. Dziki temu bdziemy pewni, e do zmiennej w panelu Inspector nie przypiszemy adnego obiektu nieposiadajcego komponentu Rigidbody. cise zdefiniowanie typu danych oznacza równie, i w przypadku, gdy chcemy odwoa si do komponentu Rigidbody, nie musimy wykorzystywa polecenia GetComponent().
240
Rozdzia 7. • Konkretyzowanie obiektów i bryy sztywne
Po prostu piszemy kod, który bezporednio wykorzystuje klas Rigidbody podczas odwoywania si do nazwy zmiennej. Wewntrz instrukcji if, znajdujcej si w funkcji Update(), umie poniszy fragment kodu zaraz pod istniejcym wierszem, który dotyczy odtwarzania klipu audio: Jzyk C#: Rigidbody newCoconut = Instantiate(coconutPrefab, transform.position, ´transform.rotation) as Rigidbody;
Jzyk JavaScript: var newCoconut : Rigidbody = Instantiate(coconutPrefab, transform.position, ´transform.rotation);
W powyszym kodzie tworzymy lokaln zmienn newCoconut. Jest ona zwana lokaln, poniewa zostaa zadeklarowana wewntrz funkcji Update(), co oznacza, e nie jest poza ni dostpna. Do tej zmiennej przypisujemy konkretyzacj nowego obiektu Rigidbody, dlatego te charakteryzuje si ona wanie tym typem. Pamitaj, e trzema parametrami funkcji Instantiate() s: obiekt, pooenie i obrót. Bdziesz móg zauway , i wykorzystalimy zmienn publiczn coconutPrefab, aby stworzy instancj naszego prefabrykatu, a nastpnie odziedziczy wartoci pooenia i obrotu po komponencie Transform obiektu, do którego zosta przypisany skrypt — jest nim obiekt Launcher. Sprawdmy, jak wyglda postp naszych prac w rodowisku Unity. W tym celu zapamitaj skrypt i wró do interfejsu Unity. Wybierz obiekt podrzdny Launcher, przypisany rodzicowi Main Camera w panelu Hierarchy, co spowoduje, e zauwaysz pojawienie si nowej zmiennej publicznej, zwanej Coconut Prefab, która musi zosta zainicjalizowana. Aby to zrobi , przecignij i upu na ni prefabrykat Coconut znajdujcy si w folderze Prefabs. A teraz kliknij przycisk Play w górnej czci interfejsu, aby przetestowa gr. Kadorazowe nacinicie klawisza Fire1 powinno skutkowa utworzeniem nowej instancji prefabrykatu Coconut, co bdzie si objawia pojawianiem si obiektów Coconut (Clone) w panelu Hierarchy. Jednake kokosy nie poruszaj si! Dzieje si tak, gdy powiniene przypisa im jak prdko pocztkow. Jeszcze raz kliknij przycisk Play, aby przerwa testowanie, a nastpnie powró do edycji skryptu CoconutThrower.
Instancje nazwane Gdy w trakcie dziaania programu tworzysz obiekty przy uyciu funkcji Instantiate(), rodowisko Unity pobiera nazw prefabrykatu i docza do niej acuch tekstowy (Clone). Poniewa uzyskana nazwa nie jest odpowiednia do wykorzystania w kodzie (bdziemy musieli to póniej zrobi z naszymi obiektami celów), moemy po prostu j zdefiniowa , umieszczajc nastpujcy wiersz kodu poniej tego, który wanie dodalimy:
241
Projektowanie gier w rodowisku Unity 3.x
Jzyk C# i JavaScript: newCoconut.name = "coconut";
W powyszym kodzie uylimy nazwy stworzonej zmiennej, która odwouje si do nowej instancji prefabrykatu. Nastpnie zastosowalimy skadni z kropk, by uzyska dostp do parametru name. Wreszcie wykorzystalimy pojedynczy znak równoci, aby przypisa temu parametrowi odpowiedni acuch znakowy.
Przypisywanie wartoci prdkoci Mimo e stworzylimy zmienn, która reprezentuje instancj orzecha kokosowego, nasz skrypt wci nie jest gotowy. Musimy jeszcze przypisa okrelon prdko poruszania si nowo utworzonemu obiektowi. W przeciwnym razie (co moglimy zauway ) kady orzech bdzie po prostu upada na powierzchni wyspy. Ogólnie mówic, prdko jest poczeniem szybkoci oraz kierunku ruchu. Nasze dziaanie rozpoczniemy od zajcia si tym pierwszym parametrem. Aby ustali szybko rzucanego orzecha kokosowego, musimy powyej funkcji Update() utworzy kolejn zmienn publiczn. Uzyskanie odpowiedniej precyzji bdzie moliwe dziki zastosowaniu typu danych float. Pozwoli to na uycie wartoci dziesitnych. Umie nastpujcy kod poniej ostatnio zdefiniowanej zmiennej publicznej, zwanej coconutPrefab: Jzyk C#: public float throwSpeed = 30.0f;
Jzyk JavaScript: var throwSpeed: float = 30.0;
Poniej wywoania funkcji Instantiate() oraz wiersza name = "coconut";, znajdujcych si wewntrz instrukcji if, umie poniszy kod: Jzyk C# i JavaScript: newCoconut.velocity = transform.forward * throwSpeed;
Poprzez nazw zmiennej odwoujemy si do nowo utworzonego obiektu typu Rigidbody, czyli newCoconut. Nastpnie, uywajc skadni z kropk, wyuskujemy waciwo velocity klasy Rigidbody. Odpowiedni kierunek rzutu uzyskalimy dziki uyciu wyraenia transform.forward, poniewa wykorzystuje ono kierunek spogldania komponentu Transform, nalecego do obiektu Launcher. Dziki temu nie musielimy skorzysta z polecenia transformDirection, które zastosowalimy w prototypie utworzonym na pocztku tej ksiki. Wyraenie transform.forward jest równowane zapisowi (0, 0, 1). Dziki temu uzyskujemy przemieszczenie jednostkowe orzecha kokosowego w osi Z. Jest ono nastpnie mnoone przez nasz zmienn throwSpeed, aby nada obiektowi typu Rigidbody odpowiedni prdko .
242
Rozdzia 7. • Konkretyzowanie obiektów i bryy sztywne
Rzu my kilkoma orzechami kokosowymi! Zapamitaj skrypt i wró do rodowiska Unity. Kliknij przycisk Play i spróbuj nacisn przycisk Fire1. Tym razem orzech powinien zosta wyrzucony w kierunku, w którym spogldasz, poniewa odpowiedni parametr obiektu podrzdnego Launcher jest dziedziczony po rodzicu Main Camera. Kontynuujmy ulepszanie naszego skryptu poprzez umieszczenie w nim kilku elementów zabezpieczajcych. Kliknij przycisk Play, aby zakoczy testowanie mechaniki rzucania orzechami kokosowymi, a nastpnie wró do edytora skryptu.
Umieszczanie elementów zabezpieczajcych W tym punkcie przyjrzymy si kilku przykadom sposobów, dziki którym nasz kod nie spowoduje problemów podczas: Q projektowania gry, Q grania w gr.
Wanie stworzylimy mechanik, w której posta gracza moe rzuca orzechami kokosowymi. Jednake przed kontynuacj procesu projektowania powinnimy wykona kilka dziaa zapewniajcych to, e nasza mechanika nie spowoduje jakichkolwiek problemów: Q Musimy si upewni , e prefabrykat orzecha kokosowego, którym rzucamy, jest typu Rigidbody, poniewa parametr prdkoci wykorzystuje waciwoci uytej klasy.
Dlatego te musimy uzupeni kod o odpowiednie zabezpieczenie. Q Powinnimy si upewni , e midzy postaci gracza i orzechami kokosowymi nigdy
nie wystpi adne kolizje. Przyjrzymy si dwóm metodom, które wykonuj powysze zadanie. Jedna z nich zostanie zaimplementowana w kodzie, a druga bdzie wykorzystywa warstwy i macierz kolizji w rodowisku Unity. Q Dysponujemy klipem audio, odtwarzanym podczas rzutu. Musimy si upewni , e obiekt, któremu zosta przypisany skrypt, zawiera komponent róda audio.
Upewnienie si, e obiekt zawiera odpowiedni komponent Przed wykorzystaniem odpowiednich waciwoci lub polece zwizanych z okrelonym komponentem powiniene si upewni , e zosta on doczony do danego obiektu. W naszym przypadku tworzymy orzech kokosowy jako obiekt typu Rigidbody. Wiemy wic, e prefabrykat uyty w poleceniu Instantiate() musi by tego typu. W przeciwnym razie w testowanym skrypcie pojawiby si wyjtek (bd). By zaprezentowa , w jaki sposób moemy sprawdzi istnienie okrelonego komponentu, przyjrzymy si dokadnie poniszemu zabezpieczeniu. Pozwoli nam to pozna metod dodawania komponentu, gdy nie jest on jeszcze obecny w scenie. Na przykad w przypadku naszego tworzonego orzecha kokosowego moglibymy sprawdzi , czy zmienna newCoconut zawiera komponent Rigidbody:
243
Projektowanie gier w rodowisku Unity 3.x
if(newCoconut.rigidbody == null) { newCoconut.AddComponent(Rigidbody); }
Powysze polecenie sprawdza, czy komponent Rigidbody nie jest doczony do instancji zmiennej (czyli jest równy null), i jeli tak jest, dodaje go. Wskazówka Sprawdzenie, e komponent Rigidbody nie istnieje, nastpuje tu przez porównanie pola rigidbody z wartoci null. Zwyke umieszczenie znaku wykrzyknika na pocztku wyraenia wewntrz warunku if nie bdzie dziaa, poniewa w ten sposób mona sprawdzi jedynie stan obiektu. Praktyka ta moe jednak zosta wykorzystana do sprawdzenia, czy zmiennej typu acuchowego zostaa przypisana jaka warto, co nie dziaaoby, gdybymy uyli znaku wykrzyknika. Poniewa nasz prefabrykat zawiera ju komponent Rigidbody, nie musimy wykonywa dodatkowego sprawdzenia. Jest to jednak przydatna technika, o której powiniene wiedzie.
Zabezpieczenie si przed kolizjami Mimo i obiekt Launcher jest oddalony od zderzacza postaci (Controller Collider), powinnimy si upewni , e sam orzech nigdy nie zderzy si z graczem. Moemy to zrobi w rodowisku Unity za pomoc dwóch metod: poprzez uycie kodu ignorujcego zderzenia lub umieszczenie obiektów na warstwach, które na siebie nie oddziauj. Zapoznamy Ci z obiema technikami, aby upewni si, e zostaniesz najlepiej przeszkolony do przyszych zada projektowych. Uycie kodu IgnoreCollision() Aby sprawi , by obiekty gry nie oddziayway na siebie, umiecimy w skrypcie okrelony fragment kodu w celu zdefiniowania zabezpieczenia przed pojawianiem si nowych orzechów kokosowych, które przypadkowo mog kolidowa ze zderzaczem gracza. Moe to zosta zrealizowane poleceniem IgnoreCollision()z klasy Physics. Zawiera ono trzy argumenty: IgnoreCollision(Zderzacz A, Zderzacz B, czy naley ignorowa);
Do funkcji naley tylko przekaza dwa zderzacze, które nie powinny oddziaywa na siebie, a nastpnie przypisa trzeciemu parametrowi warto true. Umie wic poniszy kod w skrypcie CoconutThrower poniej wiersza, który ostatnio dodae (newCoconut.velocity...): Jzyk C# i JavaScript: Physics.IgnoreCollision(transform.root.collider, newCoconut.collider, true);
Poprzez uycie w powyszym kodzie wyraenia transform.root wyszukujemy zderzacz postaci gracza. Powoduje to znalezienie gównego obiektu nadrzdnego dla potomka Launcher. Jest on
244
Rozdzia 7. • Konkretyzowanie obiektów i bryy sztywne
dzieckiem obiektu Main Camera, a sama kamera nie zawiera zderzacza. W rzeczywistoci chcemy wic znale obiekt, do którego ona naley, czyli First Person Controller. Robimy to, uywajc wanie wyraenia transform.root. Nastpnie po prostu przekazujemy nazw zmiennej newCoconut, która reprezentuje nowo utworzony orzech kokosowy. Dla obu parametrów wykorzystujemy skadni z kropk, aby odwoa si do komponentu collider. Wskazówka W naszym przypadku musielimy znale gówny obiekt nadrzdny, ale jeli odwoujesz si tylko do rodzica, moesz wykorzysta zapis transform.parent.
Ignorowanie kolizji przy uyciu warstw Oprócz polecenia IgnoreCollision() z klasy Physics moemy take wykorzysta mechanizm warstw w rodowisku Unity, aby poinformowa silnik fizyczny, które obiekty nie powinny si ze sob zderza . Polega to na umieszczeniu obiektów w rónych warstwach, a nastpnie usuniciu ich z odpowiednich pozycji w macierzy kolizji warstw. T operacj informujemy rodowisko Unity, by nie rejestrowao zderze z obiektami dodanymi do danej warstwy. Rozpocznijmy od utworzenia dwóch nowych warstw. Otwórz Tag Manager (meneder znaczników), wybierajc opcj menu gównego Edit/Project Settings/Tags (edycja/ustawienia projektu/znaczniki). Poniej istniejcych znaczników swojego projektu bdziesz móg zauway list gotowych warstw, a pod ni — warstwy uytkownika (User Layers):
Dodaj dwie warstwy o nazwach Projectiles (pociski) i Player (gracz), tak jak przedstawiono na powyszym rysunku. Aby potwierdzi wprowadzenie zmian, nacinij klawisz Return (Mac) lub Enter (PC). Nastpnie, aby zmodyfikowa konfiguracj zwizan z oddziaywaniem tych warstw na siebie, przejd do opcji menu gównego Edit/Project Settings/Physics (edycja/ustawienia projektu/ parametry fizyczne). Rozwi ustawienia parametru Layer Collision Matrix (macierz kolizji warstw) i odznacz pola, w których przecinaj si obie warstwy.
245
Projektowanie gier w rodowisku Unity 3.x
Dziki temu warstwy bd ignorowa kolizje zachodzce midzy nimi. Teraz moemy po prostu przypisa nasze obiekty do nowo utworzonych warstw. Wybierz obiekt First Person Controller w panelu Hierarchy, a nastpnie, na samej górze panelu Inspector, wybierz warstw Player z rozwijanego menu. Wybierz prefabrykat Coconut z folderu Prefabs w panelu Project i uyj tej samej metody co poprzednio, aby przypisa go do warstwy Projectiles. Mamy ju dwa zabezpieczenia, które nie pozwalaj orzechowi kokosowemu oddziaywa na posta gracza. Implementacja takich rozwiza jest wanym elementem, minimalizujcym ryzyko pojawienia si bdów pod koniec procesu projektowania gry.
Doczanie komponentu Audio Source Poniewa czynno zwizana z rzucaniem powoduje odtworzenie dwiku, moemy uy polecenia RequireComponent, które sprawi, e rodowisko Unity doczy komponent Audio Source po przyczeniu skryptu do obiektu. Jzyk C#: Na samym pocztku skryptu zlokalizuj ponisze wiersze: using UnityEngine; using System.Collections;
Poniej nich umie taki kod: [RequireComponent (typeof (AudioSource))]
246
Rozdzia 7. • Konkretyzowanie obiektów i bryy sztywne
Jzyk JavaScript: Na samym kocu skryptu umie nastpujcy wiersz kodu: @script RequireComponent(AudioSource)
Zapisz skrypt przy uyciu opcji menu gównego File/Save (plik/zapisz), a nastpnie wró do rodowiska Unity.
Kocowe procedury sprawdzajce Mimo e kod, który wanie dodalimy, nie ma charakteru funkcjonalnego, lecz raczej zabezpiecza przed pojawieniem si bdów, powinnimy zawsze przeprowadza testy po wprowadzeniu modyfikacji w naszym skrypcie. Kliknij przycisk Play, a nastpnie sprawd, czy na pasku konsoli w dolnej czci interfejsu Unity nie pojawia si aden komunikat o bdzie. Póniej nacinij lewy przycisk myszy lub klawisz Ctrl, aby rozpocz rzucanie orzechami kokosowymi! Gdy upewnisz si, e wszystko dziaa prawidowo, ponownie kliknij przycisk Play, by zakoczy testy. Jeli pojawi si jakie problemy, wró do skryptu i sprawd dokadnie, czy jego tre odpowiada poniszemu kodowi: Jzyk C#: Pamitaj, e funkcja Start() oraz komentarze // zostay usunite. using UnityEngine; using System.Collections; [RequireComponent (typeof (AudioSource))] public class CoconutThrower : MonoBehaviour { public AudioClip throwSound; public Rigidbody coconutPrefab; public float throwSpeed; void Update () { if(Input.GetButtonDown("Fire1")){ audio.PlayOneShot(throwSound); RigidbodynewCoconut = Instantiate(coconutPrefab, transform.position, ´transform.rotation) as Rigidbody; newCoconut.name = "coconut"; newCoconut.rigidbody.velocity = transform.forward * throwSpeed; Physics.IgnoreCollision(transform.root.collider, newCoconut.collider, ´true); } } }
247
Projektowanie gier w rodowisku Unity 3.x
Jzyk JavaScript: var throwSound : AudioClip; var coconutPrefab: Rigidbody; var throwSpeed : float; function Update () { if(Input.GetButtonDown("Fire1")){ audio.PlayOneShot(throwSound); var newCoconut : Rigidbody = Instantiate(coconutPrefab, ´transform.position, transform.rotation); newCoconut.name = "coconut"; newCoconut.rigidbody.velocity = transform.forward * throwSpeed; Physics.IgnoreCollision(transform.root.collider, newCoconut.collider, ´true); } } @scriptRequireComponent(AudioSource)
Ograniczenia konkretyzacji oraz usuwanie obiektów Konkretyzowanie obiektów przy uyciu zastosowanej przez nas metody pozwala na idealne wykorzystanie systemu prefabrykatów rodowiska Unity. Dziki temu w prosty sposób mona umieszcza w scenie dowolne obiekty i tworzy wiele ich kopii w trakcie dziaania gry. Jednake tworzenie wielu kopii obiektu Rigidbody moe by kosztowne, poniewa kady z nich wymaga uycia silnika fizycznego oraz procesora karty grafiki. Dodatkowo do poruszania si po trójwymiarowym wiecie i oddziaywania na inne obiekty jest zuywany czas (moc) procesora. A teraz wyobra sobie, e pozwoliby graczowi na utworzenie nieskoczonej liczby obiektów o parametrach fizycznych. Skoczyoby si to zatrzymaniem caej gry po krótkim czasie. Poniewa wykorzystywaaby ona zbyt wiele czasu procesora oraz pamici, prdko klatek staaby si zbyt niska. Spowodowaoby to pojawienie si przestojów w grze w przeciwiestwie do poprzedniego pynnego trybu dziaania. Zrobioby to na pewno ze wraenie na graczu, a w sensie komercyjnym po prostu unicestwioby sam gr. Uwaga Gry przeznaczone na komputery typu PC i Mac maj niewielkie wymagania systemowe. Wynika to std, e projektanci przyjrzeli si istniejcemu sprztowi i stworzyli odpowiednie specyfikacje, pozwalajce na przeprowadzanie testów w celu zagwarantowania poprawnych wrae odbioru w sytuacjach nawet najbardziej intensywnego wykorzystania gier.
Zamiast mie nadziej, e gracz nie wyrzuci zbyt wielu orzechów kokosowych, wykonamy dwa dziaania, które zabezpiecz nas przed wygenerowaniem duej liczby obiektów mogcych spowolni dziaanie gry:
248
Rozdzia 7. • Konkretyzowanie obiektów i bryy sztywne
Q pozwolimy graczowi na rzucanie kokosami wycznie w okrelonym obszarze
wiata gry, Q napiszemy skrypt, który bdzie usuwa orzechy kokosowe ze wiata po upywie okrelonego czasu od ich utworzenia. Uwaga Gdybymy zajmowali si konkretyzacj na wiksz skal, na przykad wykorzystujc modele broni maszynowej, równie zastosowalibymy pewne opó nienie czasowe, zapewniajce istnienie okresu „przeadowania”. W naszym przypadku nie jest to jednak konieczne, poniewa nie dopuszczamy do jednoczesnego wyrzucenia zbyt wielu orzechów kokosowych, wykorzystujc do tego procedur GetButtonDown(). Mimo e jest ona uywana w funkcji Update(), gracz po oddaniu pierwszego strzau musi ponownie nacisn przycisk, aby wykona kolejny rzut — samo przytrzymanie klawisza nie bdzie dziaa.
Aktywowanie rzutu orzechem kokosowym Aby wykona pierwsze z zaprezentowanych wyej dziaa, trzeba zastosowa zmienn logiczn, która pozwoli graczowi na rzucanie kokosami, gdy jej warto bdzie równa true. Stanie si to jedynie wówczas, gdy posta gracza bdzie si znajdowa w pomieszczeniu, w którym rzuca si orzechami kokosowymi. Zezwolenie graczowi na rzucanie orzechami kokosowymi w pooeniu, które nie jest zwizane z minigr, nie miaoby sensu. Ograniczenie tego dziaania do okrelonego obszaru jest dobrym rozwizaniem, bez wzgldu na nasze rozwaania nad wydajnoci gry. Jeli skrypt CoconutThrower zosta zamknity, otwórz go, klikajc dwukrotnie jego ikon w panelu Project (projekt). W przeciwnym razie po prostu wró do edytora i kontynuuj prac. Wczeniej zajmowalimy si skryptami aktywujcymi i dezaktywujcymi, które wykorzystyway parametr enabled nalecy do danego komponentu. Teraz jednak moglibymy równie uy polecenia GetComponent(), wybra skrypt, a nastpnie wyczy go, by zabroni graczowi rzucania orzechami kokosowymi. Jednake, podobnie jak w przypadku kadego problemu zwizanego ze skryptami, istnieje wiele rozwiza. My uyjemy zmiennych statycznych, pozwalajcych na komunikacj midzyskryptow. Kiedy powinno si uywa zmiennych statycznych? Wane jest, aby zrozumia, kiedy moesz uywa zmiennych statycznych w swoich skryptach. W naszym przypadku tworzymy gr dla pojedynczego gracza, wic zastosowanie zmiennej statycznej jest prawidowym rozwizaniem, poniewa nie bdziemy nigdy uywa wicej ni jednej instancji danego skryptu. Jednake, jeli zajmujemy si gr wieloosobow, moemy zaoy, e pojawi si w niej wiele egzemplarzy skryptu. Moe to spowodowa powstanie konfliktu, gra musi bowiem wykorzystywa wiele skryptów sucych do rzucania orzechami kokosowymi, a nie tylko jedn jego instancj. Niewaciwym dziaaniem byoby na przykad uycie w grze zmiennej statycznej, która przechowuje poziom zdrowia wroga, poniewa najprawdopodobniej wystpuje w niej wicej obiektów wrogów. Wynika std, e taka informacja nie powinna by globalna.
249
Projektowanie gier w rodowisku Unity 3.x
Umie poniszy wiersz w skrypcie CoconutThrower przed nagówkiem funkcji Update(): Jzyk C#: public static bool canThrow = false;
Jzyk JavaScript: static var canThrow : boolean = false;
Prefiks static przed zmienn powoduje, e ma ona zasig globalny — moe by dostpna z innych skryptów. Korzystajc z tego, umiecimy dodatkowy warunek w istniejcej instrukcji if, który pozwoli nam na rzucanie orzechami. Zlokalizuj wic nastpujcy wiersz w funkcji Update(): if(Input.GetButtonUp("Fire1")){
Aby doda drugi warunek, po prostu uyj dwóch znaków && razem z nazw zmiennej statycznej i umie je przed prawym nawiasem klamrowym w instrukcji if: Jzyk C# i JavaScript: if(Input.GetButtonUp("Fire1") && canThrow){
Pamitaj, e powyszy zapis jest skrócon form wyraenia: if(Input.GetButtonUp("Fire1") && canThrow==true){
Zmiennej canThrow przypisalimy warto false podczas jej deklaracji. Jest ona statyczna (czyli nie jest zmienn publiczn, przez co nie pojawi si w panelu Inspector i nie bdzie moga zosta tam zmodyfikowana), dlatego bdziemy musieli stworzy kolejny fragment kodu, w którym przypiszemy jej warto true. Zakadajc, e gracz musi znajdowa si w okrelonym miejscu, najlepsz metod modyfikacji wartoci zmiennej canThrow jest uycie funkcji wykrywajcej kolizj. Bdzie ona moga sprawdzi , czy gracz zderza si z okrelonym obiektem, a jeli tak, ustawi zmienn statyczn na warto true i pozwoli na rzucanie orzechami kokosowymi. Poniewa pomieszczenie do rzucania kokosami bdzie wyposaone w podest, na którym musi stan gracz, stworzymy kolejny obszar wyzwalania, który bdzie peni funkcj przecznika, zmieniajcego warto zmiennej statycznej w skrypcie CoconutThrower. Gracz musi stan na podecie, aby mie moliwo rzucania do celu. Aby przypisa wartoci true lub false do zmiennej CoconutThrower.canThrow, uyjemy funkcji OnTriggerEnter() oraz OnTriggerExit().
Tworzenie skryptu wyzwalacza dla podestu Wybierz folder Scripts (skrypty) w panelu Project, a nastpnie kliknij przycisk Create (stwórz), aby utworzy nowy skrypt w wybranym przez Ciebie jzyku. Nazwij go ThrowTrigger oraz wczytaj do edytora, po czym umie w nim nastpujce instrukcje:
250
Rozdzia 7. • Konkretyzowanie obiektów i bryy sztywne
Jzyk C#: void OnTriggerEnter(Collider col){ if(col.gameObject.tag == "Player"){ CoconutThrower.canThrow=true; } } void OnTriggerExit(Collider col){ if(col.gameObject.tag == "Player"){ CoconutThrower.canThrow=false; } }
Jzyk JavaScript: function OnTriggerEnter(col : Collider){ if(col.gameObject.tag == "Player"){ CoconutThrower.canThrow=true; } } function OnTriggerExit(col : Collider){ if(col.gameObject.tag == "Player"){ CoconutThrower.canThrow=false; } }
Powysze funkcje po prostu sprawdzaj, czy obiekt zderzajcy si z wyzwalaczem jest graczem. Jest to realizowane przez sprawdzenie znacznika tag, a nastpnie przypisanie zmiennej statycznej canThrow w skrypcie CoconutThrower wartoci true, gdy gracz pojawia si w obszarze wyzwalania, oraz false, gdy go opuszcza. Zapamitaj swój skrypt i wró do rodowiska Unity. Teraz w wiecie gry umiecimy pomieszczenie do rzucania kokosami, a w dalszej kolejnoci przypiszemy skrypt do obiektu podrzdnego mat.
Dodawanie pomieszczenia przeznaczonego do rzucania kokosami Dziki umieszczeniu w scenie pomieszczenia do rzucania kokosami oraz trzech celów bdziemy mogli sprawdza kolizje zachodzce midzy orzechami i celami. Stworzymy take skrypt, który sprawdzi, czy wszystkie trzy cele zostay trafione za jednym razem — jest to warunek zwycistwa w minigrze. Rozpocznijmy od umieszczenia w wiecie gry pomieszczenia do rzucania kokosami, a take dodania zderzacza skrzynkowego z aktywnym trybem wyzwalania i powizania go ze skryptem ThrowTrigger, który wanie napisalimy.
251
Projektowanie gier w rodowisku Unity 3.x
W panelu Project (projekt) odszukaj folder Book Assets/Models (zasoby ksiki/modele). Wybierz trójwymiarowy model o nazwie coconutShy, aby wywietli jego waciwoci w panelu Inspector (inspektor).
Importowanie ustawie Zanim umiecimy pomieszczenie w scenie, stworzymy zderzacze dla kadej czci modelu, aby si upewni , e ma on waciw skal, pozwalajc na zmieszczenie si w nim postaci gracza. W komponencie FBXImporter, wystpujcym w panelu Inspector, przypisz warto 1 do pola Scale Factor (wspóczynnik skalowania), a nastpnie zaznacz opcj wyboru Generate Colliders (stwórz zderzacze), by upewni si, e rodowisko Unity przypisze zderzacz siatkowy do kadego skadnika modelu. Bdzie to oznacza , i gracz moe wej do pomieszczenia i si w nim porusza , a podest wykryje kolizj z nim. Aby potwierdzi wprowadzenie zmian, kliknij przycisk Apply (zastosuj) w dolnej czci panelu Inspector. Teraz przecignij model z panelu Project na okno Scene (scena), a nastpnie zastosuj narzdzie Translate (skrót klawiszowy W), by umieci go w pobliu placówki. Dziki temu gracz bdzie móg zrozumie , e te dwa obiekty s ze sob zwizane. Obró model coconutShy o 150–180 stopni w osi Y przy uyciu komponentu Transform, aby wejcie do niego byo umieszczone po tej samej stronie co drzwi do placówki. Moesz przeprowadzi pewne indywidualne korekty, tak by caa konstrukcja wygldaa bardziej naturalnie, a nie jak budynki w miecie, które stoj równo w rzdzie obok siebie — w kocu jeste na wyspie! Upewnij si, e pomieszczenie jest waciwie umieszczone: przecignij zielony uchwyt osi Y w ten sposób, by podstawy supków, które podtrzymuj biao-czerwony brezent, znajdoway si na powierzchni gruntu. Ta operacja moe by czasochonna — w razie potrzeby uyj klawisza Alt podczas przecigania myszy, aby odpowiednio zmodyfikowa widok. Pamitaj, e jeli powierzchnia gruntu, na którym umiecie pomieszczenie, nie jest dokadnie paska, spowoduje to, e bdzie si ona czy z podog. Moe to wyglda tak, jakby z desek podogowych wyrastay roliny. Jeli tak jest, po prostu ponownie wybierz obiekt Terrain w panelu Hierarchy (hierarchia), a nastpnie uyj drugiego w kolejnoci narzdzia z komponentu Terrain (script), sucego do modyfikacji wysokoci terenu, czyli Paint Height (modyfikacja wysokoci). Ustal wysoko równ 30, poniewa taki jest poziom gruntu, który zdefiniowalimy podczas tworzenia wyspy w pocztkowym rozdziale tej ksiki. Obni powierzchni gruntu do tego poziomu, a nastpnie znowu spróbuj umieci na nim pomieszczenie — warto pooenia dla osi Y powinna wynosi 30. Na kolejnym rysunku prezentujemy przykadow lokalizacj pomieszczenia przy uwzgldnieniu obrotu wokó osi Y równego 160 stopni. Jeli chcesz, moesz oczywicie poeksperymentowa z inn wartoci pooenia.
252
Rozdzia 7. • Konkretyzowanie obiektów i bryy sztywne
Tworzenie wyzwalacza dla podestu Kliknij szar strzak po lewej stronie nazwy coconutShy w panelu Hierarchy, aby rozwin struktur drzewa obiektów. Wybierz obiekt podrzdny mat, a nastpnie uruchom opcj menu gównego Component/Physics/Box Collider (komponent/parametry fizyczne/zderzacz skrzynkowy). Pojawi si okno dialogowe, informujce, e dodanie tego obiektu podrzdnego spowoduje utrat poczenia z prefabrykatem. Kliknij przycisk Add (dodaj). Komunikat informuje, e zmiany wprowadzone w komponentach doczonych do pierwotnego modelu w panelu Project (na przykad modyfikacja parametrów skryptów) nie bd ju stosowane do kopii obiektu znajdujcego si w scenie, poniewa poczenie midzy instancj a zasobem lub prefabrykatem zostanie zerwane. Nastpnie rodowisko Unity wywietli kolejny komunikat z pytaniem, czy chcesz zamieni istniejcy zderzacz lub doda nowy. Dzieje si tak, poniewa wczeniej zaznaczylimy opcj wyboru Generate Colliders (stwórz zderzacze), która spowodowaa, e zderzacze siatkowe zostay doczone do kadego elementu w hierarchii modelu. Zachowajmy zderzacz siatkowy, gdy chcemy, by gracz móg wchodzi na podest. Wybierz wic opcj Add (dodaj). Teraz powiniene widzie oba zderzacze (Box Collider i Mesh Collider), dostpne dla obiektu mat w panelu Inspector. Podczas dodawania zderzacza skrzynkowego do elementu o ksztacie prostopadocianu, takiego jak podest, nastpuje odpowiednie dopasowanie jego rozmiaru do obiektu docelowego. Zazwyczaj jest to oczekiwane rozwizanie, lecz w naszym przypadku postaramy si zwikszy wysoko zderzacza skrzynkowego. Wybierz narzdzie Hand (rka), aby ukry uchwyty osi w widoku Scene (scena), i przytrzymaj klawisz Shift w celu wywietlenia krawdziowych punktów zderzacza. Przecignij punkt znajdujcy si na górze podestu, a osigniesz wysoko równ w przyblieniu wielkoci postaci gracza.
253
Projektowanie gier w rodowisku Unity 3.x
Gdy zderzacz ma ju waciw skal, aktywuj jego opcj wyzwalania poprzez zaznaczenie opcji wyboru Is Trigger (jest wyzwalaczem), znajdujcej si w komponencie Box Collider w panelu Inspector. Wreszcie pocz skrypt ThrowTrigger z podestem: przecignij go z folderu Scripts w panelu Project i upu na obiekcie podrzdnym mat w panelu Inspector. Przetestujmy gr! Zapamitaj projekt w rodowisku Unity poprzez wybranie opcji menu gównego File/Save Scene (plik/zapisz scen), a nastpnie kliknij przycisk Play (granie). Moesz teraz rzuca orzechami kokosowymi jedynie wówczas, gdy stoisz na podecie.
Usuwanie orzechów kokosowych Jak wspomniano wczeniej, obecno w scenie zbyt wielu obiektów sterowanych silnikiem fizycznym moe powanie wpyn na wydajno gry. Dlatego te w przypadkach, gdy mamy do czynienia ze zwykym wyrzucaniem obiektów (nie musimy ich przechowywa ), powinnimy napisa skrypt, który bdzie je automatycznie usuwa po upywie okrelonego czasu. Wybierz folder Scripts (skrypty) w panelu Project (projekt), a nastpnie kliknij przycisk Create (stwórz), aby stworzy nowy skrypt w wybranym przez Ciebie jzyku programowania. Uywajc klawisza Return (Mac) lub F2 (PC), zmie jego nazw na TidyObject. Nastpnie dwukrotnie kliknij ikon znajdujc si przy skrypcie, aby wczyta go do edytora. Usu ze skryptu domyln funkcj Update(), poniewa nie bdzie nam potrzebna. W celu wyeliminowania obiektu z sceny moemy po prostu uy funkcji Destroy() i wykorzysta jej drugi argument do zdefiniowania czasu opónienia. Funkcja ta dziaa nastpujco: Destroy(który obiekt lub komponent naley usun, opcjonalny czas opónienia);
254
Rozdzia 7. • Konkretyzowanie obiektów i bryy sztywne
Aby uczyni skrypt uniwersalnym, stworzymy zmienn publiczn, która pozwoli na zdefiniowanie czasu opónienia. Moemy mie bowiem w przyszoci potrzeb usuwania innych obiektów po upywie pewnego czasu, lecz nie takiego, jak w przypadku prefabrykatu Coconut. Nad funkcj Start() umie deklaracj nastpujcej zmiennej: Jzyk C#: public float removeTime = 3.0f;
Jzyk JavaScript: var removeTime: float = 3.0;
Funkcj Destroy() wywoamy w poleceniu Start(). Uytkownicy jzyka C# ju je zdefiniowali w swoim skrypcie, dlatego musz jedynie doda do niego odpowiedni wiersz. Uytkownicy jzyka JavaScript powinni równie utworzy sam funkcj. Upewnij si, e Twój skrypt odpowiada poniszemu fragmentowi kodu: Jzyk C#: void Start () { Destroy(gameObject, removeTime); }
Jzyk JavaScript: function Start(){ Destroy(gameObject, removeTime); }
Uywajc polecenia Start(), wywoamy funkcj Destroy(), gdy tylko obiekt pojawi si w wiecie gry, to znaczy gdy zostanie skonkretyzowany przez gracza po naciniciu przycisku strzau. Odwoanie do zmiennej gameObject oznacza po prostu: „Uyj obiektu, do którego zosta doczony ten skrypt”. Po przecinku umieszczamy zmienn removeTime typu float, zawierajc czas (mierzony w sekundach), po którego upywie obiekt zostanie usunity. W wyniku dziaania skryptu wyrzucony orzech kokosowy bdzie pozostawa w wiecie gry przez trzy sekundy, a nastpnie zostanie usunity. Wybierz opcj File/Save (plik/zapisz) w edytorze i wró do rodowiska Unity. Wczeniejsze skrypty doczalimy do istniejcych obiektów w scenie. Jednake w tym przypadku utworzylimy ju prefabrykat orzecha kokosowego, którego adna konkretyzacja nie wystpuje w scenie. Istniej dwa sposoby pozwalajce zastosowa skrypt do prefabrykatu. Prostsza metoda jest nastpujca:
255
Projektowanie gier w rodowisku Unity 3.x
Q Przecignij skrypt TidyObject z panelu Project i upu go na odpowiedni prefabrykat. Alternatywnie moesz wybra prefabrykat Coconut w panelu Project, a nastpnie
przej do opcji menu gównego Component/Scripts/TidyObject (komponent/ skrypty/TidyObject). Bardziej skomplikowana metoda polega na odpowiedniej modyfikacji prefabrykatu w oknie Scene: Q Przecignij prefabrykat Coconut do okna Scene lub panelu Hierarchy. Q Przejd do opcji menu gównego Component/Scripts/TidyObject (komponent/
skrypty/TidyObject), a nastpnie kliknij przycisk Add (dodaj), by potwierdzi pytanie Adding a component will lose the prefab parent (dodanie komponentu spowoduje utrat poczenia z rodzicem prefabrykatu). Q Zapamitaj zmian w pierwotnym prefabrykacie poprzez wybranie opcji menu gównego GameObject/Apply Changes to prefab (obiekt gry/zapisz zmiany w prefabrykacie) lub kliknicie przycisku Apply (zastosuj) na górze obszaru Inspector. Q Usu instancj ze sceny skrótem klawiszowym Command+Backspace (Mac)
lub Delete (PC). W naszym przypadku zalecamy wybranie pierwszej, prostszej metody. Jednake w niektórych sytuacjach przydatne moe by ponowne umieszczenie obiektu w scenie i zmodyfikowanie go przed zastosowaniem zmian w prefabrykacie. Na przykad jeli projektujesz efekty wizualne (np. system czstek), chciaby zobaczy , jaki wynik uzyskasz po wprowadzeniu zmian lub dodaniu jakich komponentów. Dlatego te konkretyzacja prefabrykatu w scenie byaby wówczas konieczna. Przejd do opcji File/Save Project (plik/zapisz projekt) w rodowisku Unity, aby zapamita stan projektu. Nastpnie kliknij przycisk Play, by przetestowa gr. Gdy stoisz na podecie, moesz ju rzuca orzechami kokosowymi, które znikaj po upywie domylnych 3 sekund, zdefiniowanych w funkcji Destroy(). Oznacza to, e maksymalna liczba kokosów obecnych jednoczenie w wiecie gry zostaa ograniczona.
Cele i zderzenia orzechów kokosowych Zlokalizuj model target w folderze Book Assets/Models (zasoby gry/modele) w panelu Project, a nastpnie wybierz go, by wywietli parametry importu w panelu Inspector. W komponencie FBXImporter, widocznym w panelu Inspector, zaznacz opcj wyboru Generate Colliders (stwórz zderzacze), aby upewni si, e kady element siatki modelu bdzie móg zareagowa na uderzenie orzechem kokosowym. Pamitaj, e obiekty 3D niezawierajce zderzaczy po prostu przenikaj przez siebie. Zmie równie parametr Scale Factor (wspóczynnik skalowania), przypisujc mu warto 1. W komponencie Animations powinnimy okreli wartoci klatek oraz poda nazwy animacji, które chcielibymy utworzy dla modelu, podobnie jak uczynilimy w przypadku drzwi placówki.
256
Rozdzia 7. • Konkretyzowanie obiektów i bryy sztywne
Dodane animacje mog zosta wywoane w skrypcie, gdy tylko stwierdzimy, e nastpia kolizja midzy kokosem a odpowiednim elementem obiektu celu. Dodaj trzy animacje (jak zaprezentowano na poniszym rysunku) poprzez kliknicie ikony plusa (+), która znajduje si po prawej stronie tabeli animacji. Nastpnie wprowad odpowiednie wartoci w polach Name (nazwa), Start (pocztek) i End (koniec):
Po zakoczeniu wprowadzania zmian pamitaj o klikniciu przycisku Apply (zastosuj), znajdujcego si w dolnej czci panelu, aby zatwierdzi modyfikacje, jak równie inne zmiany zwizane z importowaniem zasobu.
Lokalizacja Aby w prosty sposób umieci cele wewntrz pomieszczenia, powinnimy je zdefiniowa jako potomków obiektu platform, znajdujcego si ju w scenie. Aby to zrobi , przecignij model target z folderu Book Assets/Models w panelu Project, a nastpnie upu na obiekt rodzica coconutShy w panelu Hierarchy. Zdefiniowanie obiektu target jako potomka obiektu coconutShy spowoduje, e struktura rodzica zostanie poszerzona i zaprezentuje nowo dodany element. Zresetujmy teraz pooenie obiektu target, aby umieci go w samym centrum pomieszczenia. Dziki temu bdziemy mogli go w prosty sposób przemieszcza . Gdy obiekt target jest wci wybrany, kliknij ikon kóka zbatego po prawej stronie komponentu Transform, a póniej wybierz opcj Reset position (resetuj pooenie) z rozwijanego menu. Obiekt target znajduje si ju w rodku pomieszczenia, dlatego umie my go w pooeniu bardziej odpowiednim dla gracza.
257
Projektowanie gier w rodowisku Unity 3.x
Najpierw obró cel o 180 stopni w osi Y, aby upewni si, e jest zwrócony w stron gracza. Pamitaj, e wybrana warto nie musi by równa wielkoci obrotu samego pomieszczenia, gdy cel jest teraz jego obiektem podrzdnym, co powoduje, i wspórzdne s ustalane wzgldem rodzica. W odpowiednich polach Position (pooenie) wprowad wartoci (0, 0, -2,4).
Wyczenie automatycznej animacji Aby upewni si, e nasz cel nie bdzie automatycznie odtwarza animacji, a take by sprawdzi , e zawiera on animacje zdefiniowane wczeniej w importerze, wycz opcj wyboru Play Automatically (odtwarzaj automatycznie), znajdujc si w komponencie Animation (animacja) w panelu Inspector. Nastpnie upewnij si, e stworzone przez nas animacje s widoczne, tak jak zaprezentowano na poniszym rysunku:
Dodawanie komponentu Rigidbody do ruchomych elementów Poniewa pewne elementy modelu target bd si porusza podczas trwania animacji, powinnimy si upewni , e maj one doczony kinematyczny komponent Rigidbody, który umoliwi ich obsug przez silnik fizyczny w celu przetwarzania ruchu i poprawy wydajnoci. Rozwi obiekt target w panelu Hierarchy poprzez kliknicie szarej strzaki po lewej stronie nazwy, a nastpnie wykonaj t sam czynno w odniesieniu do potomka target_pivot, co spowoduje wywietlenie trzech kolejnych obiektów podrzdnych target, target_support_1 i target_support_2. Bd one animowane w trakcie dziaania gry, dlatego powinny zosta wyposaone w kinematyczny komponent Rigidbody, niewykorzystujcy prawa grawitacji, aby poprawnie oddziaywa na inne bryy sztywne (np. orzechy kokosowe), lecz nie ulega istniejcym siom. Zaznacz pierwszy z trzech obiektów przedstawionych na poniszym rysunku, a nastpnie wybierz opcj menu gównego Component/Physics/Rigidbody (komponent/parametry fizyczne/ brya sztywna). Wreszcie odznacz opcj wyboru Use Gravity (uyj grawitacji), a zaznacz Is Kinematic (uyj kinematyki). Powtórz te dziaania w odniesieniu do pozostaych dwóch obiektów, upewniajc si, e kady z nich zostanie uzupeniony o kinematyczny komponent Rigidbody, który nie podlega prawu grawitacji.
258
Rozdzia 7. • Konkretyzowanie obiektów i bryy sztywne
Tworzenie skryptu wykrywajcego kolizj orzecha kokosowego Powinnimy napisa skrypt, który bdzie wykrywa kolizje jedynie z obiektem podrzdnym target (a nie na przykad target_support lub target_base), nalecym do gównego obiektu target. Wybierz folder Scripts w panelu Project i kliknij przycisk Create, aby utworzy skrypt w jzyku C# lub JavaScript. Zmie jego nazw na TargetCollision, a nastpnie dwukrotnie kliknij jego ikon, by otworzy go w edytorze.
Deklaracja zmiennych Najpierw musimy zadeklarowa pi zmiennych: Q beenHit — zmienna logiczna, która oznacza, e cel zosta trafiony; Q targetRoot — zmienna prywatna; Q hitSound — zmienna publiczna przechowujca klip dwikowy; Q resetSound — zmienna publiczna przechowujca klip dwikowy; Q resetTime — zmienna publiczna typu float.
Aby to zrobi , umie poniszy kod w skrypcie przed rozpoczciem funkcji Update(): Jzyk C#: bool beenHit = false; Animation targetRoot; public AudioClip hitSound; public AudioClip resetSound; public float resetTime = 3.0f;
Jzyk JavaScript: private var beenHit : boolean = false; private var targetRoot : Animation; var hitSound : AudioClip; var resetSound : AudioClip; var resetTime : float = 3.0;
259
Projektowanie gier w rodowisku Unity 3.x
Zwró uwag na to, e zmienne beenHit i targetRoot s prywatne, poniewa nie musz by dostpne w panelu Inspector — ich wartoci s modyfikowane i uywane jedynie wewntrz skryptu. Zmienna beenHit zostanie uyta w kadym obiekcie celu jako wskanik informujcy o jego stanie. Jeli bdzie równa true (warto ta zostanie przypisana po wykryciu kolizji z orzechem kokosowym), cel bdzie uwaany za trafiony i nie bdzie móg przyj kolejnego uderzenia, dopóki jego stan nie zostanie przywrócony do wartoci pocztkowej. Mamy take zmienn prywatn targetRoot o typie Animation. Bdzie ona uywana do reprezentowania komponentu animacji obiektu, który zosta do niej przypisany w skrypcie. Poniewa nasz skrypt zostanie przypisany do obiektu podrzdnego w modelu target, zmienn targetRoot wykorzystamy, aby przechowywa w niej odwoanie do gównego rodzica, do którego doczono komponent animacji. Oprócz tego mamy dwie zmienne przechowujce klipy dwikowe, które s odtwarzane po uderzeniu w cel i podczas przywracania jego stanu do wartoci pocztkowej. Wreszcie zmienna typu float okrela odstp czasowy midzy uderzeniem celu a jego powrotem do stanu pocztkowego. Zainicjalizujmy zmienn targetRoot w funkcji Start(). Umie poniszy kod w swoim skrypcie: Jzyk C#: void Start(){ targetRoot = transform.parent.transform.parent.animation; }
Jzyk JavaScript: function Start(){ targetRoot = transform.parent.transform.parent.animation; }
W powyszym kodzie przypisalimy zmiennej targetRoot typu Animation komponent animacyjny, doczony nie do rodzica obiektu target, lecz do jego „dziadka” (obiektu nadrzdnego wobec rodzica). Nie moemy po prostu napisa transform.parent, poniewa rodzicem obiektu target jest target_pivot — spójrz na panel Hierarchy, a zobaczysz t zaleno (patrz poniszy rysunek). Jest to wane, poniewa obiekt podrzdny target nie zawiera komponentu animacyjnego. Dlatego te uywamy skadni z kropk, aby odwoa si do jego rodzica (target_pivot), a nastpnie do rodzica rodzica (target), do którego doczono ju komponent Animation. Naley równie pamita , by przechowywa to odwoanie w zmiennej, gdy bdziemy je wykorzystywa w skrypcie wicej ni jeden raz. Uycie zmiennej jest w tym przypadku bardziej wydajne ni wielokrotny zapis wykorzystujcy skadni z kropk.
260
Rozdzia 7. • Konkretyzowanie obiektów i bryy sztywne
Wykrywanie kolizji Teraz powinnimy sprawdzi , czy obiekt target zosta trafiony przez orzech kokosowy. Stwórz nastpujc funkcj, która wykrywa kolizj: Jzyk C#: void OnCollisionEnter(Collision theObject) { if(beenHit==false && theObject.gameObject.name=="coconut"){ } }
Jzyk JavaScript: function OnCollisionEnter(theObject : Collision) { if(beenHit==false && theObject.gameObject.name=="coconut"){ } }
Funkcja OnCollisionEnter() róni si od funkcji OnTriggerEnter(), któr wykorzystywalimy wczeniej, poniewa obsuguje zwyke kolizje midzy obiektami zawierajcymi zderzacze o ksztatach podstawowych, niebdce zderzaczami kontrolera postaci ani zderzaczami z aktywnym trybem wyzwalania. Argument theObject, wykorzystywany w tej funkcji, jest instancj klasy Collision, która dla danej kolizji przechowuje informacje o prdkociach, bryach sztywnych, zderzaczach, transformacjach, obiektach gry oraz punktach zderzenia. Dlatego te wewntrz instrukcji if po prostu uyjemy tego argumentu, aby sprawdzi , czy zawiera on informacj o obiekcie gameObject, nazywajcym si coconut. By upewni si, e cel nie moe zosta wielokrotnie trafiony, uywamy dodatkowego warunku w poleceniu if, sprawdzajcego, czy zmienna beenHit jest równa false. Ten przypadek bdzie rozpatrywany na pocztku gry. W funkcji, która zostanie wywoana w momencie pojawienia si kolizji, zmiennej beenHit zostanie przypisana warto true, dziki czemu nie bdzie moliwe przypadkowe ponowne jej zresetowanie i ustawienie. Jednake powinnimy jeszcze wykona odpowiednie polecenia, gdy pojawia si sama kolizja, zamierzamy bowiem zastosowa inn metod rozwizania problemu, którym si ju kiedy zajmowalimy.
261
Projektowanie gier w rodowisku Unity 3.x
Uycie wspóprogramów w elementach gry zwizanych z upywem czasu W naszej mechanice drzwi placówki, któr utworzylimy w rozdziale 6., uylimy zderzacza z aktywnym trybem wyzwalania, wykrywajcego obecno gracza i otwierajcego drzwi. Nastpnie w skrypcie DoorManager wykorzystywalimy zmienn typu float, bdc licznikiem czasu i zwikszan w funkcji Update() a do okrelonej wartoci, której osignicie powodowao zamknicie drzwi. Nasz kod wyglda nastpujco: if(doorIsOpen){ doorTimer += Time.deltaTime; if(doorTimer>doorOpenTime){ Door(doorShutSound, false, "doorshut"); doorTimer = 0.0f; } }
Problem zwizany z resetowaniem naszych celów jest w rzeczywistoci taki sam jak z otwieraniem i zamykaniem drzwi — co si dzieje, mamy opónienie czasowe, a nastpnie dzieje si co innego. Jednake w tym przypadku uzupenimy nasz wiedz programistyczn i zamiast zastosowa licznik czasu, wykorzystamy rozwizanie zwane wspóprogramem. Przeprowadzanie dziaa w funkcji Update() jest kosztowne z punktu widzenia wydajnoci gry i jeli to moliwe, powinno si tego unika . Jednake w celu zapoznania si z mechanizmami Unity chcielimy zaprezentowa obie metody: poprzedni, wykorzystujc nieefektywn metod zliczania czasu i resetowania go, oraz teraz omawian, duo bardziej sprawn. Umiejtno tworzenia i obsugi liczników czasu jest równie przydatna w innych kontekstach, dlatego te zdobyta wiedza nie powinna zosta zapomniana — przyda si w sytuacji, gdy zaczniesz tworzy gr wykorzystujc mechanizmy czasu! Wspóprogramy s uzupenieniem funkcji Poniewa wspóprogramy s mechanizmem pozwalajcym na wykonywanie polece równoczenie z bieco realizowanym kodem, s one czsto najlepszym rozwizaniem, by zapewni strukturaln organizacj wewntrz Twoich skryptów. Wspóprogramy pozwalaj na wykonywanie instrukcji lub oczekiwanie, dopóki nie zostan spenione okrelone warunki. Dziki temu s one tak potnym narzdziem, e tworzenie za ich pomoc opó nienia czasowego jest jedynie minimalnym wykorzystaniem ich moliwoci.
Wspóprogram, mimo e wydaje si skomplikowanym zagadnieniem, wyglda i zachowuje si jak zwyka funkcja. Moe jednak wstrzyma swoje dziaanie do momentu, a upynie okrelony czas lub zostan spenione pewne warunki. Gówn rónic, widoczn w jzyku C#, jest rodzaj zwracanej wartoci: zamiast void uywamy sowa IEnumerator. Wykorzystajmy wic nasz wiedz w praktyce, umieszczajc poniszy kod w skrypcie TargetCollision:
262
Rozdzia 7. • Konkretyzowanie obiektów i bryy sztywne
Jzyk C#: IEnumerator targetHit(){ audio.PlayOneShot(hitSound); targetRoot.Play("down"); beenHit=true; yield return new WaitForSeconds(resetTime); audio.PlayOneShot(resetSound); targetRoot.Play("up"); beenHit=false; }
Jzyk JavaScript: function targetHit(){ audio.PlayOneShot(hitSound); targetRoot.Play("down"); beenHit=true; yield new WaitForSeconds(resetTime); audio.PlayOneShot(resetSound); targetRoot.Play("up"); beenHit=false; }
Powysza funkcja obsuguje zarówno trafienie, jak i resetowanie naszych celów. W pierwszych trzech wierszach wspóprogramu wykonuj si nastpujce dziaania: 1. Nastpuje odtworzenie klipu audio przypisanego do zmiennej hitSound. 2. Zostaje wywietlona animacja down, przypisana do komponentu animacji zapamitanego w zmiennej targetRoot. 3. Do zmiennej beenHit zostaje przypisana warto true, dziki czemu funkcja nie moe by ponownie wywoywana podczas wykrywania kolizji. Nastpnie wspóprogram wykorzystuje instrukcj yield, zwan WaitForSeconds, przekazujc jej warto zmiennej resetTime jako wielko opónienia czasowego. Po odczekaniu okrelonego czasu nastpuje wykonanie trzech ostatnich wierszy procedury, w których zostaje odtworzony klip audio resetSound oraz wywietlona animacja up, a wreszcie zmiennej beenHit jest ponownie przypisywana warto false, dziki czemu obiekt target jest znów gotowy do kolizji. Jak wida , powysza procedura jest prosta, a dodatkowo nie wykorzystujemy ju funkcji Update() do sprawdzania, czy zmienna beenHit zostaa zmieniona. Nie ma równie potrzeby uycia zmiennej typu float, bdcej licznikiem czasu, któr równie naleaoby resetowa .
263
Projektowanie gier w rodowisku Unity 3.x
Gratulacje, wanie napisae swój pierwszy wspóprogram! Jednake musimy go jeszcze wywoa w momencie, gdy pojawia si kolizja. Wró do funkcji OnCollisionEnter() i umie w niej poniszy wiersz kodu, który wywoa wspóprogram, gdy warunki instrukcji if zostan spenione: Jzyk C# i JavaScript: StartCoroutine("targetHit");
Caa funkcja powinna wyglda tak: Jzyk C#: void OnCollisionEnter(Collision theObject) { if(beenHit==false && theObject.gameObject.name=="coconut"){ StartCoroutine("targetHit"); } }
Jzyk JavaScript: function OnCollisionEnter(theObject : Collision) { if(beenHit==false && theObject.gameObject.name=="coconut"){ StartCoroutine("targetHit"); } }
Powyszy kod wywouje wspóprogram, korzystajc z jego nazwy — proste, nieprawda? I to jest wszystko, czego potrzebujemy. Nasz skrypt zarzdza wszystkim, poniewa zmienna beenHit jest odpowiednio modyfikowana przez wspóprogram, bez wzgldu na to, czym bdziemy rzuca . Procedura na pewno bdzie dziaa .
Doczanie komponentu Audio Source Poniewa bdziemy odtwarza dwiki, powinnimy doda polecenie RequireComponent, dziki czemu ródo audio zostanie umieszczone w obiekcie, do którego jest przypisany skrypt. Jzyk C#: Zlokalizuj ponisze wiersze w skrypcie: using UnityEngine; using System.Collections;
Pod nimi, a jednoczenie nad deklaracj klasy, umie taki wiersz kodu: [RequireComponent (typeof (AudioSource))]
Jzyk JavaScript: Umie nastpujcy wiersz kodu na kocu skryptu: @script RequireComponent(AudioSource)
264
Rozdzia 7. • Konkretyzowanie obiektów i bryy sztywne
Wybierz opcj File/Save (plik/zapisz) w edytorze, a nastpnie wró do rodowiska Unity.
Przypisywanie skryptu W panelu Hierarchy rozwi model target, który zosta dodany do projektu, co spowoduje wywietlenie jego obiektów podrzdnych. Nastpnie rozwi grup target_pivot, aby uzyska dostp do obiektu target i jego potomków. Struktura powinna wyglda tak jak na rysunku:
Na powyszym rysunku widzimy, e zosta wybrany model siatkowy okrgej tarczy celu (target). Ty równie go wybierz, a nastpnie przemie kursor myszy nad okno Scene i nacinij klawisz F, by przybliy widok. Powinnimy sprawdza wystpowanie kolizji z elementem podrzdnym, nie chcemy bowiem, aby byy one wykrywane, gdy gracz uderzy kokosem na przykad w supki utrzymujce tarcz. Gdy obiekt target jest wybrany, przejd do opcji menu gównego Component/Scripts/Target Collision (komponent/skrypty/Target Collision). Z obiektem zostanie poczony wanie napisany przez nas skrypt, wcznie z komponentem Audio Source. Teraz przecignij pliki dwikowe target_hit oraz target_reset z folderu Book Assets/Sounds (zasoby ksiki/dwiki) w panelu Project, a nastpnie upu je na odpowiednie zmienne publiczne w panelu Inspector. Wybierz opcj menu gównego File/Save Scene (plik/zapamitaj scen), aby zapamita biecy stan sceny. Kliknij przycisk Play, eby rozpocz testowanie gry, i sta na podecie (czyli obiekcie mat), by aktywowa zderzacz wyzwalajcy. Teraz powiniene mie moliwo rzucania orzechami kokosowymi i trafiania w cel. Ponownie kliknij przycisk Play, by przerwa testy. Aby ukoczy tworzenie minigry, musimy umieci w niej jeszcze dwie tarcze, uywajc do tego systemu prefabrykatów.
Tworzenie kolejnych celów Aby stworzy wicej celów, zapamitamy tarcz w postaci prefabrykatu, a nastpnie skopiujemy go. Zwi gówny obiekt rodzica target w panelu Hierarchy, by ukry wszystkich jego potomków. Nastpnie stwórz prefabrykat poprzez przecignicie go do folderu Prefabs (prefabrykaty) w panelu Project. rodowisko Unity automatycznie przeksztaci obiekt w prefabrykat. Zmie jego nazw z target na TargetPrefab, co pozwoli odróni go od pierwotnego modelu.
265
Projektowanie gier w rodowisku Unity 3.x
Nazwa target w panelu Hierarchy zmieni kolor na niebieski, co oznacza, e obiekt zosta podczony do prefabrykatu w projekcie. Teraz wybierz obiekt rodzica target w panelu Hierarchy, a nastpnie nacinij skrót klawiszowy Command+D (Mac) lub Ctrl+D (PC), by utworzy jego kopi. Po wybraniu kopii wprowad warto -1,6 w parametrze X Position (pooenie X) komponentu Transform, znajdujcym si w panelu Inspector. Powtórz operacj kopiowania, aby utworzy trzeci cel, a nastpnie zmie jego pooenie X na warto 1,6. Trzy tarcze celów powinny si ju znajdowa w pomieszczeniu i prezentowa taki widok, jak na poniszym rysunku:
Wygrywanie gry Aby zapewni pen funkcjonalno minigry i udostpni graczowi ostatnie ogniwo energetyczne potrzebne do zasilania generatora otwierajcego drzwi, musimy stworzy skrypt, który bdzie sprawdza , czy wszystkie trzy cele zostay trafione za jednym razem. Wybierz folder Scripts (skrypty) w panelu Project (projekt), a nastpnie uyj przycisku Create (stwórz), by utworzy plik w jzyku C# lub JavaScript. Zmie nazw skryptu na CoconutWin oraz dwukrotnie kliknij jego ikon, eby wczyta go do edytora.
Deklaracja zmiennych Umie ponisze cztery zmienne na pocztku skryptu:
266
Rozdzia 7. • Konkretyzowanie obiektów i bryy sztywne
Jzyk C#: public public public public
static int targets = 0; static bool haveWon = false; AudioClip winSound; GameObject cellPrefab;
Jzyk JavaScript: static var targets : int = 0; static var haveWon : boolean = false; var winSound : AudioClip; var cellPrefab : GameObject;
Pierwsza zmienna statyczna targets przechowuje informacj o tym, ile celów jest w danym momencie trafionych — jej inicjalizacja zostanie póniej umieszczona w skrypcie TargetCollisions. Kolejna zmienna statyczna haveWon zakoczy minigr, gdy po pierwszym zwycistwie zostanie jej przypisana warto true. Bdziemy si do niej odwoywa podczas sprawdzania, czy graczowi powinny zosta wywietlone wskazówki. Jeli wygra ju gr, wskazówki nie bd potrzebne. Nastpnie deklarujemy dwie zmienne publiczne: jedn, która przechowuje klip audio, oraz drug, zawierajc odwoanie do ogniwa energetycznego. Gdy gracz wygra minigr, w skrypcie utworzymy instancj nowej baterii na podstawie prefabrykatu, który zosta przez nas stworzony. Usuniemy równie widoczne ogniwo energetyczne, które znajduje si w pomieszczeniu. Sprawi to wraenie, e gracz po wygraniu gry otrzyma brakujc bateri. Prefabrykat zostanie przypisany do zmiennej zaraz po ukoczeniu tworzenia skryptu.
Sprawdzanie warunku zwycistwa Umie poniszy fragment kodu w funkcji Update(): Jzyk C#: if(targets==3 && haveWon == false){ targets=0; audio.PlayOneShot(winSound); GameObject winCell = transform.Find("powerCell").gameObject; winCell.transform.Translate(-1,0,0); Instantiate(cellPrefab, winCell.transform.position, transform.rotation); Destroy(winCell); haveWon = true; }
Jzyk JavaScript: if(targets==3 && haveWon == false){ targets=0; audio.PlayOneShot(winSound); var winCell : GameObject = transform.Find("powerCell").gameObject;
267
Projektowanie gier w rodowisku Unity 3.x
winCell.transform.Translate(-1,0,0); Instantiate(cellPrefab, winCell.transform.position, transform.rotation); Destroy(winCell); haveWon = true; }
Instrukcja if skada si z dwóch warunków. Pierwszy z nich zapewnia, e warto zmiennej target jest równa 3, co oznacza, i wszystkie cele zostay trafione. Drugi — e zmienna haveWon jest równa false, czyli gracz nie ukoczy jeszcze minigry. Gdy powysze warunki s spenione, wykonuj si nastpujce polecenia: Q Skrypt przypisuje zmiennej targets warto 0 (jest to kolejne zabezpieczenie przed powtórzeniem wykonania instrukcji if). Q Klip audio win zostaje odtworzony. Q Zostaje utworzona zmienna winCell, która reprezentuje istniejcy model powerCell,
bdcy czci pomieszczenia do rzucania orzechami. Znajduje si on po prawej stronie wewntrz obiektu powerHolder, a gracz nie moe go jeszcze wzi . Q Model powerCell zostaje wyjty z obiektu powerHolder poprzez przypisanie w funkcji Translate wartoci -1 do parametru reprezentujcego o X. Nastpnie zostanie on uyty w poleceniu Instantiate do utworzenia instancji prefabrykatu powerCell, któr w dalszej kolejnoci przypiszemy do zmiennej cellPrefab. Q Wymieniona instancja zostaje utworzona przy wykorzystaniu instrukcji Instantiate, która co prawda uywa pooenia przechowywanego w zmiennej winCell, lecz sam
obrót jest pobierany z obiektu pomieszczenia. Std proste uycie wyraenia transform.rotation, a nie winCell.transform.rotation. Q Pierwotny obiekt powerCell, przypisany do zmiennej winCell, zostaje usunity ze sceny poleceniem Destroy(), dziki czemu w pojemniku nie bdzie si ju znajdowa adne
ogniwo energetyczne. Q Zmiennej haveWon zostaje przypisana warto true, która oznacza, e gra nie moe zosta ponownie wygrana, i uniemoliwia graczowi zdobywanie kolejnych ogniw energetycznych. Poniewa powinnimy odtworzy dwik, wró do wczeniejszego podpunktu „Doczanie komponentu Audio Source”, aby doda do skryptu polecenie RequireComponent, pozwalajce na stworzenie róda audio. A moe spróbuj wykona t czynno bez korzystania z pomocy? Twój ukoczony skrypt CoconutWin powinien wyglda nastpujco: Jzyk C#: using UnityEngine; using System.Collections; [RequireComponent (typeof (AudioSource))]
268
Rozdzia 7. • Konkretyzowanie obiektów i bryy sztywne
public class CoconutWin : MonoBehaviour { public static int targets = 0; public static bool haveWon = false; public AudioClip winSound; public GameObject cellPrefab; void Update () { if(targets==3 && haveWon == false){ targets=0; audio.PlayOneShot(winSound); GameObject winCell = transform.Find("powerCell").gameObject; winCell.transform.Translate(-1,0,0); Instantiate(cellPrefab, winCell.transform.position, ´transform.rotation); Destroy(winCell); haveWon = true; } } }
Jzyk JavaScript: static var targets : int = 0; static var haveWon : boolean = false; var winSound : AudioClip; var cellPrefab : GameObject; function Update () { if(targets==3 &&haveWon == false){ targets=0; audio.PlayOneShot(winSound); var winCell : GameObject = transform.Find("powerCell").gameObject; winCell.transform.Translate(-1,0,0); Instantiate(cellPrefab, winCell.transform.position, transform.rotation); Destroy(winCell); haveWon = true; } } @scriptRequireComponent(AudioSource)
Wybierz opcj File/Save (plik/zapisz) w edytorze, a nastpnie wró do rodowiska Unity.
Przypisywanie skryptu Wybierz obiekt nadrzdny coconutShy w panelu Hierarchy (hierarchia) i przejd do opcji menu gównego Component/Scripts/Coconut Win (komponent/skrypty/Coconut Win). Nastpnie przypisz prefabrykat powerCell z folderu Prefabs (prefabrykaty) w panelu Project (projekt) do zmiennej publicznej Cell Prefab z komponentu Coconut Win (Script), a plik
269
Projektowanie gier w rodowisku Unity 3.x
dwikowy win_cell z folderu Book Assets/Sounds (zasoby ksiki/dwiki) do zmiennej publicznej Win Sound. Po wykonaniu tej operacji komponent skryptu powinien wyglda tak jak na poniszym rysunku:
Zwikszanie i zmniejszanie licznika trafie Aby gra moga dziaa , musimy wróci do skryptu TargetCollision. Wprowadzimy modyfikacj zwikszajc o jeden zmienn statyczn targets ze skryptu CoconutWin, gdy gracz trafi do celu, oraz zmniejszajc j o jeden, gdy cel wróci do stanu pocztkowego. Jest to proste zadanie, poniewa nasz skrypt jest ju gotowy do obsugi powyszych dwóch funkcji wewntrz jednego wspóprogramu. Przejd wic do skryptu TargetCollision lub gdy nie jest on otwarty, dwukrotnie kliknij jego ikon w folderze Scripts (skrypty), aby uruchomi edytor.
Zwikszanie licznika trafie Wspóprogram zawiera dwa stany: trafianie w cel i jego powrót do stanu pocztkowego. Mona je atwo odróni , poniewa oddziela je instrukcja yield, która oznacza opónienie czasowe wystpujce po trafieniu do celu. Zlokalizuj wiersz kodu: beenHit=true;
Poniej niego umie nastpujc instrukcj: CoconutWin.targets++;
Zmniejszanie licznika trafie Po instrukcji yield nastpuje procedura powrotu celu do stanu pocztkowego, a póniej umoliwienie ponownego rzucania do niego dziki przypisaniu zmiennej beenHit wartoci false. W tym miejscu powinnimy zmniejszy licznik trafie. Odszukaj wiersz kodu: beenHit=false;
Poniej niego umie nastpujce polecenie: CoconutWin.targets--;
W obu przypadkach zwikszania i zmniejszania licznika uywamy skadni z kropk, aby uzyska dostp do skryptu (lub nazwy klasy). Nastpnie wystpuje nazwa zmiennej statycznej targets oraz zapis ++ lub --, sucy odpowiednio do jej zwikszania lub zmniejszania. Wymienione cigi znaków s skrótowymi instrukcjami, które zwikszaj i zmniejszaj zmienn o warto 1. Mog one zosta równie zapisane w postaci +=1 i -=1.
270
Rozdzia 7. • Konkretyzowanie obiektów i bryy sztywne
W edytorze przejd do opcji menu gównego File/Save (plik/zapisz), a nastpnie wró do rodowiska Unity. Kliknij przycisk Play (granie), aby przetestowa gr. Rzucanie orzechami kokosowymi i strcenie wszystkich trzech celów powinno spowodowa pojawienie si dodatkowego ogniwa energetycznego, które moesz zabra . Gdy to nastpi, podejd i je we, podobnie jak uczyniby z jego innymi instancjami. Kliknij przycisk Play, aby zakoczy testy, a póniej wybierz w rodowisku Unity opcj menu gównego File/Save Scene (plik/zapisz scen), by zapisa biecy stan sceny.
Kocowe usprawnienia Aby uczyni minigr bardziej interesujc, na wywietlaczu póprzezroczystym umiecimy celownik, który bdzie aktywowany, gdy gracz stanie na podecie. Wykorzystamy take istniejcy obiekt TextHintGUI do przekazania graczowi wskazówki, co naley zrobi , by wygra t gr.
Dodawanie celownika Aby umieci celownik w scenie, wykonaj nastpujce czynnoci: Q Otwórz folder Book Assets/Textures (zasoby ksiki/tekstury) w panelu Project (projekt). Q Wybierz plik tekstury Crosshair. Q W obszarze Texture Importer (importer tekstur) panelu Inspector (inspektor) przypisz
warto GUI (graficzny interfejs uytkownika) do parametru Texture Type (rodzaj tekstury), aby poinformowa rodowisko Unity, e dana tekstura bdzie wykorzystywana w wywietlaczu dwuwymiarowym. Q Gdy tekstura jest wci zaznaczona, przejd do opcji menu gównego GameObject/
Create Other/GUI Texture (obiekt gry/stwórz inny/tekstura GUI) lub kliknij przycisk Create (stwórz) w panelu Hierarchy (hierarchia), a nastpnie wybierz opcj GUI Texture (tekstura GUI). Spowoduje to pobranie wymiarów pliku tekstury i przypisanie ich do tworzonego obiektu Crosshair typu GUI Texture. Obiekt zostanie automatycznie wybrany w panelu Hierarchy, dziki czemu w panelu Inspector pojawi si komponent GUITexture. Jeli opcja Game Overlay (warstwy gry) jest wczona, obraz celownika powinien by równie widoczny w widokach Game (gra) i Scene (scena). Poniewa domylnie pojawia si on w rodku okna, dokadnie pasuje do naszego niewielkiego pliku tekstury o rozmiarze 64×64 piksele. Podczas tworzenia pliku tekstury dla tego obiektu byo wane, e uylimy jasnych i ciemnych krawdzi, dziki czemu celownik jest dobrze widoczny bez wzgldu na to, na co spoglda gracz.
271
Projektowanie gier w rodowisku Unity 3.x
Wskazówka Pamitaj, e jeli podczas tworzenia obiektu GUITexture nie wybierzesz pliku tekstury, zostanie wywietlone domylne logo Unity. Musisz nastpnie wybra waciw tekstur w panelu Inspector oraz poda odpowiednie wymiary. Z tego powodu lepiej jest najpierw wybra tekstur, która posuy do utworzenia obiektu GUITexture.
Wczanie i wyczanie obiektu GUITexture dla celownika Otwórz skrypt ThrowTrigger z folderu Scripts (skrypty) w panelu Project. W funkcji OnTrigger ´Enter() bdziesz móg zauway polecenia sprawdzajce, czy gracz znajduje si na podecie. Poniewa chcemy, by celownik pojawia si jedynie w tym przypadku, umiecimy wicej kodu w instrukcjach if. Powyej wspomnianej funkcji stwórzmy najpierw odwoanie do celownika: Jzyk C#: public GUITexture crosshair;
Jzyk JavaScript: var crosshair : GUITexture;
Zadeklarowany obiekt moemy teraz z atwoci wcza i wycza wewntrz funkcji OnTrigger ´Enter() oraz OnTriggerExit(). W instrukcji if dla funkcji OnTriggerEnter() wprowad nastpujcy wiersz kodu: Jzyk C# i JavaScript: crosshair.enabled=true;
W instrukcji if dla funkcji OnTriggerExit() dodaj nastpujce polecenie: crosshair.enabled=false;
Zapamitaj skrypt i wró do rodowiska Unity. Wybierz obiekt podrzdny mat, nalecy do rodzica coconutShy, co spowoduje, e w komponencie Throw Trigger (script) bdziesz móg zobaczy nowo dodan zmienn publiczn Crosshair. Przecignij na ni obiekt Crosshair z panelu Hierarchy. Wreszcie upewnij si, e celownik bdzie domylnie wyczony. W tym celu wybierz obiekt Crosshair w panelu Hierarchy, a nastpnie wycz opcj wyboru, znajdujc si obok komponentu GUITexture w panelu Inspector. Zapamitaj stan projektu, wybierajc opcj menu gównego File/Save Scene, a nastpnie kliknij przycisk Play, by przetestowa gr. Celownik powinien pojawia si w scenie jedynie wówczas, gdy znajdujesz si na podecie w pomieszczeniu do rzucania orzechami. Gdy wyjdziesz z niego, powinien od razu znikn .
272
Rozdzia 7. • Konkretyzowanie obiektów i bryy sztywne
Przekazywanie graczowi wskazówek Aby pomóc graczowi zrozumie , czego od niego oczekujemy, uyjemy obiektu TextHintGUI, który ju wykorzystywalimy w rozdziale 6., zatytuowanym „Kolekcja, inwentarz i HUD”. Za jego pomoc wywietlimy komunikat na ekranie, gdy gracz pojawi si na podecie. Otwórz skrypt ThrowTrigger, a nastpnie powyej funkcji OnTriggerEnter() zadeklaruj zmienn publiczn, do której moemy przypisa obiekt TextHintGUI: Jzyk C#: public GUIText textHints;
Jzyk JavaScript: var textHints : GUIText;
W instrukcji if dla funkcji OnTriggerEnter() umie taki fragment kodu: Jzyk C# i JavaScript: if(!CoconutWin.haveWon){ textHints.SendMessage("ShowHint", "\n\n\n\n\n There's a power cell attached ´to this game, \n maybe I'll win it if I can knock down all the ´targets..."); }
Dziki powyszemu kodowi aktywujemy obiekt TextHintGUI jedynie wówczas, gdy zmienna statyczna haveWon w skrypcie CoconutWin jest równa false. Wskazuje na to uycie wykrzyknika na pocztku warunku. W rzeczywistoci sprawdzamy, czy zmienna nie jest równa true. Jeli jest ona równa false, wczamy obiekt TextHintGUI poprzez uycie polecenia SendMessage(), podobnie jak czynilimy to w skrypcie TriggerZone dla drzwi placówki. Tak jak poprzednio wywoujemy funkcj ShowHint(), przekazujc jej nastpujcy acuch tekstowy: "\n\n\n\n\n There's a power cell attached to this game, \n maybe I'll win it if ´I can knock down all the targets...");
Moesz zauway , e w tekcie znajduje si kilka znaków \n. S to instrukcje przejcia do nowego wiersza. Dlaczego wic uywamy a piciu tego typu wyrae na samym pocztku naszego tekstu? Czy potrafisz odgadn ? Dzieje si tak, poniewa w tym samym czasie na ekranie wywietlamy równie celownik. Aby unikn nakadania si tych dwóch elementów, a take koniecznoci zmiany pooenia obiektu TextHintGUI, troch oszukujemy i umieszczamy na pocztku pi pustych wierszy, by odpowiednio obniy pooenie wywietlanego tekstu. Wykorzystujemy take znak nowego wiersza, aby podzieli wywietlany acuch tekstowy na dwie czci, dziki czemu jest on atwiejszy do odczytania.
273
Projektowanie gier w rodowisku Unity 3.x
Zapamitaj skrypt i wró do rodowiska Unity. W komponencie Throw Trigger (Script) musimy przypisa nasz zmienn publiczn do obiektu TextHintGUI. W tym celu w panelu Hierarchy wybierz obiekt mat, bdcy potomkiem obiektu coconutShy. Nastpnie przecignij obiekt TextHintGUI z panelu Hierarchy na zmienn Text Hints. Kliknij przycisk Play, eby przetestowa gr. Stojc na podecie, powiniene widzie celownik oraz tekst wskazówki, który dodalimy.
Po zejciu gracza z podestu celownik powinien znikn , a po nim, za kilka sekund, zniknie równie wywietlana wiadomo . Ponownie kliknij przycisk Play, aby zakoczy testowanie gry, i wybierz opcj menu gównego File/Save Project (plik/zapisz projekt) w celu zapisania stanu projektu.
Podsumowanie W tym rozdziale omówilimy róne zagadnienia, które maj due znaczenie podczas tworzenia kadego rodzaju scenariusza gry. Przyjrzelimy si implementacji obiektów bry sztywnych w kontekcie tworzenia animowanych elementów dynamicznych oraz pocisków. Tego typu wiedza bdzie czsto wykorzystywana przez Ciebie w wielu scenariuszach gier tworzonych w rodowisku Unity. Zajlimy si równie dokadniej procesem konkretyzacji, o którym wspominalimy ju na pocztku ksiki podczas tworzenia przykadowego prototypu. Stworzylimy
274
Rozdzia 7. • Konkretyzowanie obiektów i bryy sztywne
mechanik gry, która jest zwizana z naszym projektem, poniewa zmusza gracza do nawizania interakcji z okrelonym skadnikiem w celu uzyskania dostpu do placówki. Oprócz tego zaplanowalimy i zaimplementowalimy prost amigówk, polegajc na wygraniu minigry wykorzystujcej rzucanie orzechami kokosowymi do celu. Zwycistwo w niej pozwoli graczowi na uzyskanie dostpu do ostatniego ogniwa energetycznego, które jest niezbdne do zasilania generatora otwierajcego drzwi placówki. Poprzez ponowne wykorzystanie obiektu TextHintGUI, którego uylimy w rozdziale 6. pt. „Kolekcja, inwentarz i HUD”, udostpnilimy graczowi kolejne wskazówki. W celu przesania informacji do tego obiektu zastosowalimy komunikacj midzyskryptow. Przyjrzelimy si równie sposobowi dziaania wspóprogramów, które pozwalaj zwikszy funkcjonalno skryptów. Ten mechanizm na pewno bdziesz stosowa w swojej pracy. Zagadnienia omówione w tym rozdziale bd wykorzystywane zarówno w dalszej czci tej ksiki, jak i w Twoich przyszych projektach w rodowisku Unity. W nastpnym rozdziale zrobimy sobie przerw w kodowaniu i zajmiemy si dokadniej efektami wizualnymi. Przeanalizujemy systemy czstek, pozwalajce na utworzenie ogniska na zewntrz budynku placówki. Stanie si on naszym kocowym celem gry — gracz bdzie musia znale w budynku pudeko zapaek, które zostanie uyte do rozpalenia ognia oraz wysania dziki temu widocznego sygnau pomocy.
275
Projektowanie gier w rodowisku Unity 3.x
276
8 Systemy czstek W tym rozdziale zajmiemy si bardziej uniwersalnymi efektami renderingu, które mog zosta osignite w wiecie 3D dziki uyciu systemów czstek. Gry wykorzystuj systemy czstek, by stworzy wiele rónych efektów, poczynajc od mgy i dymu, a koczc na iskrach, promieniach laserów i prostych ksztatach. W niniejszym rozdziale przyjrzymy si metodzie uzyskiwania symulacji ognia przez zastosowanie dwóch systemów czstek. Za chwil bdziesz móg si zapozna z takimi zagadnieniami: Q budowa systemu czstek — jego komponenty i ustawienia, Q tworzenie systemów czstek, symulujcych ogie i dym, Q instrukcje i informacje zwrotne dla gracza, wywietlane na ekranie, Q uycie skryptów w celu aktywowania systemów czstek w trakcie dziaania gry.
Co to jest system czstek? System czstek jako zoona struktura jest zaliczany w rodowisku Unity do grupy systemów. Skada si on z poniszych komponentów, które powinny ze sob wspópracowa , by móg on dziaa poprawnie: Q Particle Emitter (emiter czstek) — obsuguje tworzenie czstek, ich czas ycia,
prdkoci i zasig dziaania, Q Particle Animator (animator czstek) — okrela zachowanie czstki podczas jej ycia, Q Particle Renderer (renderer czstek) — definiuje wygld renderowanych czstek.
Zanim rozpoczniemy prac z samymi systemami, powinnimy zapozna si dokadniej z wymienionymi powyej komponentami.
Projektowanie gier w rodowisku Unity 3.x
Particle Emitter Emiter jest odpowiedzialny za tworzenie poszczególnych czstek. W rodowisku Unity s dostpne elipsoidalne oraz siatkowe emitery czstek. Emiter elipsoidalny jest najczciej uywany do tworzenia efektów, takich jak dym i kurz, oraz innych skadników otoczenia, które mog si pojawia w ograniczonej przestrzeni. Jego nazwa wynika std, i tworzy czstki wewntrz trójwymiarowej przestrzeni o ksztacie elipsoidalnym. W trakcie swojego ycia mog si one jednak rozprzestrzenia poza ten obszar. Emiter siatkowy tworzy czstki, które s bezporednio zwizane z ksztatem siatki trójwymiarowej i mog by animowane na jej powierzchni lub po prostu emitowane z jej wierzchoków. Tego typu emitery s czciej uywane w przypadkach, gdy naley bezporednio zarzdza pooeniem czstek. Udostpnienie projektantowi moliwoci obsugi wierzchoków siatki oznacza, e moe on tworzy precyzyjnie dziaajce systemy czstek, zawierajce si w dowolnym ksztacie trójwymiarowym. Z punktu widzenia komponentów oba wyej wymienione emitery zawieraj nastpujce wspólne parametry: Q rozmiar: widoczny rozmiar poszczególnych czstek, Q energia: czas (w sekundach), w którym czstki istniej w grze, zanim nastpi
ich samounicestwienie, Q emisja: liczba czstek emitowanych w jednostce czasu, Q prdko: szybko i kierunek przemieszczania si czstek.
W dalszej czci tego rozdziau przyjrzymy si bardziej szczegóowym ustawieniom, zwizanym z okrelonym typem emiterów. W przypadku naszego zadania, dotyczcego tworzenia ognia, uyjemy emitera elipsoidalnego, który pozwoli na uzyskanie bardziej przypadkowych efektów, poniewa nie jest zwizany z okrelonym ksztatem siatki.
Particle Animator Animator definiuje sposób zachowania si poszczególnych czstek w miar upywu czasu. Aby uzyska odpowiedni dynamik dziaania, czstki maj okrelony czas ycia, po którym nastpuje ich samounicestwienie. W przypadku tworzenia ognia czstki powinny by animowane, dziki czemu ich wygld bdzie si zmienia w trakcie ich ycia w wiecie gry. Pomienie rzeczywistego ognia zmieniaj si przez cay czas, wzrastajc i przygasajc. Moemy uy animatora w celu uzyskania odpowiedniej zmiennoci koloru i widocznoci symulowanego ognia, a take zastosowa odpowiednie siy do samych czstek, by uzyska wraenie dynamiki ruchu.
278
Rozdzia 8. • Systemy czstek
Particle Renderer Renderer definiuje wygld poszczególnych czstek. Czstki s w rzeczywistoci kwadratowymi sprajtami (elementami dwuwymiarowymi), renderowanymi w wikszoci przypadków tak jak trawa, któr umiecilimy na naszym terenie w rozdziale 3. Sposób ten polega na wykorzystaniu techniki billboardingu, sprawiajcej, e obiekt jest zawsze skierowany w kierunku kamery. Renderery w rodowisku Unity mog wywietla czstki przy uyciu rónych metod, lecz wród nich najczciej jest wykorzystywany billboarding. Komponent Particle Renderer obsuguje take materiay uyte w systemie czstek. Poniewa s one traktowane jako sprajty, moliwe staje si uycie w komponencie renderera odpowiednich procedur cieniowania materiaów. Oznacza to, e korzystajc z kanau alfa (przezroczystoci) w celu zaokrglenia krawdzi tekstur, moesz stworzy iluzj istnienia elementów o ksztacie rónym od kwadratowego. Na poniszym rysunku zaprezentowano to, co wkrótce zastosujemy w naszym materiale, czyli przykad z ogniem — ciemne obszary oznaczaj wczon przezroczysto .
W wyniku zastosowania opcji przezroczystoci czstki nie bd ju miay kwadratowych ksztatów, jak w przypadku zwykych sprajtów 2D. Dziki poczeniu renderingu jedynie widocznych czci tekstury z wysokimi wartociami emisji emitera bdziemy mogli uzyska wraenie spoistoci materiau. Renderery mog równie animowa czstki przy uyciu animacji UV. Wykorzystuje si do tego zestawy obrazów, by skutecznie zamienia tekstury w trakcie ycia czstek. Jest to jednak bardziej zaawansowane rozwizanie ni te, które omawiamy w niniejszej ksice, dlatego proponujemy, aby zapozna si z odpowiednim fragmentem dokumentacji w celu uzyskania bardziej szczegóowych informacji: http://unity3d.com/support/documentation/Components/class-Particle Renderer.html. System czstek dziaa, poniewa wykorzystuje kilka komponentów wspópracujcych ze sob. S nimi: emiter tworzcy czstki, animator definiujcy ich sposób dziaania w miar upywu czasu i wreszcie renderer, okrelajcy wygld czstek za pomoc materiaów i parametrów wywietlania.
279
Projektowanie gier w rodowisku Unity 3.x
Zastanowimy si teraz nad kolejnym etapem projektowania naszej gry, którego kulminacj bdzie rozpalenie ogniska, zdefiniowanego za pomoc dwóch systemów czstek. Jeden z nich bdzie odpowiedzialny za tworzenie ognia, a drugi — dymu.
Definiowanie zadania Nasza istniejca gra zawiera zadanie dla gracza, które powinno zosta wykonane, by uzyska dostp do placówki. Gracz musi mianowicie zgromadzi cztery ogniwa energetyczne, z których jedno powinno zosta wygrane w grze, stworzonej przez nas w poprzednim rozdziale i polegajcej na rzucaniu kokosami do celu. Po wejciu do budynku placówki gracz doznaje pewnego rozczarowania, poniewa nie znajduje w nim nic oprócz pustego biurka. W tym rozdziale wprowadzimy pewn zmian, polegajc na umieszczeniu w placówce pudeka zapaek, które moe zosta znalezione przez gracza. Nastpnie na zewntrz stworzymy ognisko, które bdzie mogo zosta rozpalone jedynie wówczas, gdy gracz zdobdzie zapaki. Moemy poinformowa gracza, e musi rozpali ognisko, co spowoduje, e bdzie on szuka pudeka zapaek, czyli przystpi do wykonania okrelonego zadania (otwarcia drzwi placówki). Aby zrealizowa powyszy scenariusz, w rodowisku Unity musz zosta wykonane nastpujce czynnoci: Q Umieszczenie w naszej scenie modelu ogniska poprzez zdefiniowanie jego pooenia
obok budynku placówki. Q Stworzenie systemów czstek do symulacji ognia i dymu. Nastpnie wyczenie
komponentów emitera, co spowoduje, e systemy nie bd generowa czstek a do momentu ich wczenia w skrypcie. Q Stworzenie funkcji wykrywania kolizji, zachodzcej midzy graczem a obiektem
ogniska i pozwalajcej na rozpalenie ognia dziki wczeniu komponentów emitera dla dwóch systemów czstek. Q Umieszczenie w placówce modelu pudeka zapaek oraz zdefiniowanie procedury
wyzwalajcego wykrywania kolizji, która pozwala na wzicie obiektu. Czynno ta powinna by warunkiem rozpalenia ogniska. Q Uycie obiektu TextHintGUI w celu wywietlenia wskazówki dla gracza, informujcej, e znalezienie pudeka zapaek pozwala na rozpalenie ogniska.
Uyte zasoby Nasze wiczenie bdzie wykorzystywa kilka plików, które zostay ju zaimportowane w ramach zasobów zwizanych z t ksik:
280
Rozdzia 8. • Systemy czstek
Q trójwymiarowy model ogniska, znajdujcy si w folderze Book Assets/Models
(zasoby ksiki/modele); Q tekstura dla materiau systemu czstek, symulujcego ogie, znajdujca si w folderze Book Assets/Textures (zasoby ksiki/tekstury); Q tekstura dla materiau systemu czstek, symulujcego dym, znajdujca si w folderze
Book Assets/Textures; Q klip audio, odtwarzajcy dwik poncego ognia, znajdujcy si w folderze Book
Assets/Sounds (zasoby ksiki/dwiki); Q tekstura dla trójwymiarowego modelu ogniska, znajdujca si w folderze Book
Assets/Textures.
Tworzenie sterty gazi W folderze Book Assets/Models, znajdujcym si w panelu Project (projekt), bdziesz móg znale model zwany campfire. Wybierz go, a nastpnie w komponencie FBXImporter w panelu Inspector (inspektor) zmie parametr Scale factor (wspóczynnik skalowania) na warto 0,5.
Sprawi to, e model zostanie zaimportowany do naszej sceny i bdzie mia odpowiedni rozmiar w stosunku do innych obiektów, które ju w niej istniej. Aby zatwierdzi wprowadzenie zmian, kliknij przycisk Apply (zastosuj) w dolnej czci panelu Inspector. A teraz przecignij model ogniska na obszar Scene (scena) i uyj narzdzia Transform, aby umieci go obok obiektów placówki i pomieszczenia do rzucania orzechami kokosowymi, które ju si tam znajduj.
281
Projektowanie gier w rodowisku Unity 3.x
Uwaga Modele znajdujce si w rodowisku Unity mog wymaga przeprowadzenia operacji zmiany skali. Jeli tworzysz je sam, powi troch czasu na zdefiniowanie waciwej skali, w której bd one wystpowa po zaimportowaniu. Upewnij si, e wczytany model szecianu o rozmiarze (1, 1, 1) odpowiada skal temu samemu typowi obiektu, utworzonemu w rodowisku Unity. Bdziesz móg zauway, e wymiary tworzonych obiektów róni si w zalenoci od uytego narzdzia modelowania.
Poniewa nie chcemy, bo gracz móg przechodzi przez ten model, musimy zdefiniowa dla niego odpowiedni zderzacz. W tak zoonych modelach jak nasz uywa si zazwyczaj komponentu FBXImporter do wygenerowania zderzaczy siatkowych dla kadej oddzielnej siatki, która si w nim znajduje. Skoro jednak wiemy o tym, e chcemy tylko sprawi , by gracz móg uderzy w obiekt, moemy wykorzysta prosty zderzacz kapsuowy. W naszym przypadku bdzie on cakiem dobrze wykonywa swoje zadanie, a dodatkowo pozwoli na zaoszczdzenie mocy procesora, poniewa nie bdzie konieczne tworzenie zderzaczy dla kadej siatki zwizanej z modelem. Wybierz obiekt campfire w panelu Hierarchy (hierarchia) i przejd do opcji menu gównego Component/Physics/Capsule Collider (komponent/parametry fizyczne/zderzacz kapsuowy). W wywietlonym oknie dialogowym Losing Prefab (utrata poczenia z prefabrykatem) zostaniesz poproszony o zgod na odczenie instancji od pierwotnego modelu. Jak zwykle kliknij przycisk Add (dodaj). Przy podstawie obiektu ogniska pojawi si niewielki, kulisty zderzacz. Musimy zwikszy jego rozmiar, aby zawrze w nim cay obiekt. W tym celu uyj narzdzia Hand (rka) (skrót klawiszowy Q), a nastpnie, trzymajc wcinity klawisz Shift, odpowiednio przecignij punkty lece na krawdziach zderzacza. Moesz take zmodyfikowa odpowiednie parametry komponentu
282
Rozdzia 8. • Systemy czstek
Capsule Collider, znajdujcego si w panelu Inspector (inspektor): w polu Radius (promie) wprowad warto 2, w polu Height (wysoko ) — 3, natomiast w polu Y dla opcji Center (rodek) wpisz 1. Twój zderzacz powinien wyglda podobnie do tego na poniszym rysunku. Przeprowadzenie testu gry potwierdzi, e gracz moe si ju zderza z obiektem.
Tworzenie systemów czstek dla ogniska W tym punkcie stworzymy dwa róne systemy czstek: jeden do symulacji ognia, a drugi do symulacji zwizanego z nim dymu. Dziki takiemu rozwizaniu uzyskamy wiksze moliwoci sterowania animacj czstek, poniewa nie bdziemy musieli zarzdza obiema symulacjami w pojedynczym systemie.
Tworzenie ognia Na samym pocztku musimy zdefiniowa obiekt gry, który zawiera trzy podstawowe komponenty zwizane z systemem czstek. W panelu Hierarchy (hierarchia) kliknij przycisk Create (stwórz), a nastpnie wybierz opcj Particle System (system czstek). Alternatywnie moesz przej do opcji menu gównego GameObject/Create Other/Particle System (obiekt gry/stwórz inny/system czstek). Zmie nazw stworzonego systemu na FireSystem (PC: F2, Mac: Return) i upewnij si, e nie wystpuje w niej aden znak spacji. Jest to wane, poniewa pozwoli nam zachowa konsekwentne nazewnictwo w tworzonych skryptach. Pamitaj, e dopóki nie ukoczymy definicji systemu czstek dla ognia, nie musimy jeszcze okrela jego pooenia. Dlatego te moe on zosta umieszczony w dowolnym miejscu trójwymiarowego wiata, z wyjtkiem sytuacji, w której znajdzie si pod ziemi. W tym przypadku
283
Projektowanie gier w rodowisku Unity 3.x
uyj narzdzia Translate (skrót klawiszowy W), aby go umieci na powierzchni gruntu, dziki czemu bdzie widoczny w oknie Scene (scena). Moesz go nastpnie przemieci do obiektu ogniska, by mu si przyjrze w tym kontekcie. eby to zrobi , po prostu wybierz obiekt campfire w panelu Hierarchy. Póniej przemie kursor myszy nad widok Scene i nacinij klawisz F, aby przybliy widok ogniska. Wybierz obiekt FireSystem w panelu Hierarchy, po czym przejd do opcji menu gównego GameObject/Move to View (obiekt gry/umie w widoku). Domylnie system czstek prezentuje zestaw biaych punktów o zaokrglonych krawdziach, które s podobne do gromady robaczków witojaskich. Wynika to z zastosowania najbardziej ogólnych ustawie dla kadego z komponentów: emiter generuje niewielk liczb czstek, animator sprawia, e pynnie pojawiaj si one i znikaj, natomiast renderer nie wykorzystuje adnego materiau. Przeanalizujmy po kolei wszystkie komponenty i zdefiniujmy dla nich odpowiednie ustawienia. Podgld systemu czstek jest dostpny w oknie Scene, wic uywaj go po wprowadzeniu kadej zmiany w panelu Inspector (inspektor).
Ustawienia elipsoidalnego emitera czstek Swoje dziaania rozpocznij od przypisania parametrowi Min Size (rozmiar minimalny) wartoci 0,5, za parametrowi Max Size (rozmiar maksymalny) wartoci 2. Wynika to std, e pomienie musz by znaczco wiksze od rozmiaru domylnych robaczków witojaskich. Emiter rozpocznie generowanie czstek o wielkociach zawartych w podanym zakresie. W polu Min Energy (energia minimalna) wprowad warto 1, a w polu Max Energy (energia maksymalna) — 1,5. Te parametry definiuj czas ycia i oznaczaj, e czstki bd istnie w wiecie gry przez 1 sekund do 1,5 sekundy, po czym nastpi ich automatyczne samounicestwienie. W polu Min Emission (emisja minimalna) wprowad warto 15, a w Max Emission (emisja maksymalna) — 20. Parametry te okrelaj, ile czstek w danym momencie istnieje w scenie. Im s one wysze, tym wicej czstek bdzie wystpowa , co przyczyni si do zwikszenia gstoci pomieni. Jednake generowanie wikszej liczby czstek moe by kosztowne dla procesora karty graficznej. Ogólnie mówic, wybrane przez nas ustawienia s minimalnymi wartociami, które mog by ju akceptowane z punktu widzenia estetyki. W polu Y opcji Word Velocity (prdko wiata) wprowad warto 0,1. Spowoduje to, e czstki bd si unosi w gór podobnie jak prawdziwe pomienie. Wykorzystalimy opcj Word Velocity, poniewa dotyczy ona obiektów, które w wiecie gry musz si zawsze porusza w gór. Gdyby dla obiektu, który w trakcie gry si porusza i obraca, zosta uyty parametr Local Velocity (prdko lokalna), wówczas jego lokalna o Y nie odpowiadaaby osi Y dla wiata. Na przykad ponca beczka, obsugiwana przez silnik fizyczny, mogaby si rozpa , co spowodowaoby, e osie doczonego do niej systemu czstek obróciyby si. Pomienie powinny si jednake wci unosi we wspórzdnych wiata. Poniewa ognisko nie porusza si, warto zrozumie rónice midzy jego wspórzdnymi lokalnymi i globalnymi.
284
Rozdzia 8. • Systemy czstek
W polu Y opcji Rnd Velocity (prdko losowa) wprowad warto 0,2. Spowoduje to, e niektóre pomienie bd wysze ni pozostae. Parametr Tangent Velocity (prdko stycznej) powinien przyj warto 0,1 dla obu pól X i Z; warto 0 naley pozostawi dla osi Y. Definiuje on pocztkow prdko oraz kierunek ruchu poszczególnych czstek w odniesieniu do przestrzeni elipsoidalnej, w której s one generowane. Przypisanie osiom X i Z powyszych wartoci oznacza, e pomienie bd miay tendencj do rozprzestrzeniania si w poziomie. Pole Emitter Velocity Scale (skala prdkoci emitera) moe mie warto 0. Jest ono wane jedynie w przypadku poruszajcych si systemów czstek i okrela, jak szybko czstki przemieszczaj si, gdy ich obiekt nadrzdny jest w ruchu. Poniewa ognisko jest statyczne, parametr Emitter Velocity Scale moe by równy 0. Parametr Simulate in Worldspace (symulacja w przestrzeni wiata) okrela, czy czstki podaj za obiektem gry, w którym zostay utworzone, czy te pozostaj w swoim pooeniu, zdefiniowanym w przestrzeni wiata, podczas gdy sam system si porusza. Nasze ognisko nie bdzie si przemieszcza , dlatego te parametr ten nie jest dla nas wany. Jednake gdybymy utworzyli poruszajc si pochodni, chcielibymy wczy t opcj, aby spowodowa , e pomie bdzie porusza si w przestrzeni wiata, lecz jednoczenie bdzie wci emitowany z okrelonego miejsca obiektu, do którego naley. Opcja One Shot (pojedynczy incydent) powinna zosta niewczona, poniewa chcemy, by ogie pon przez cay czas. Byaby ona bardziej przydatna na przykad w czasie tworzenia pojedynczego oboku dymu, wystpujcego po wystrzale armatnim. Wartoci pola Ellipsoid (elipsoida) mog by równe 0,5 dla kadej z osi. S one niewielkie, poniewa system czstek powinien generowa pomienie w niewielkim obszarze. W przypadku pióropusza dymu nad wulkanem parametry pola Ellipsoid powinny by odpowiednio wiksze, co pozwoli czstkom unosi si znacznie wyej ni w zwykym ognisku.
Ustawienia animatora czstek W dalszej kolejnoci musimy zdefiniowa parametry komponentu Particle Animator, który okrela zachowanie czstek w trakcie ich ycia. Musimy sprawi , by pynnie pojawiay si i znikay, a take wprowadzi animacj ich barw (odcieni koloru czerwonego i pomaraczowego). Powinnimy take przyoy do nich odpowiednie siy, co spowoduje, e pomienie bd si bardziej realistycznie kbi i odskakiwa na boki. Swoje dziaania rozpocznij od upewnienia si, e opcja Does Animate Color (czy animowa kolory) jest wczona. Spowoduje to pojawienie si piciu obszarów Color Animation (animacja koloru). Kliknij kady z nich, a pojawi si okno wyboru koloru. Wybierz odcienie od biaego (Color Animation[0]) do ciemnopomaraczowego (Color Animation[4]). Nastpnie zdefiniuj odpowiednie wartoci kanau alfa (suwak A w dolnej czci okna wyboru koloru) w taki sposób, by pola Color Animation[0] i Color Animation[4] miay ten sam poziom
285
Projektowanie gier w rodowisku Unity 3.x
przezroczystoci, mieszczcy si w zakresie od 0 do 5 procent caej dugoci obszaru koloru, co spowoduje pynne wygaszanie i pojawianie si czstek. Jest on reprezentowany w panelu Inspector przez biao-czarn lini, znajdujc si poniej kadego obszaru koloru. Na poniszym rysunku zaprezentowano wizualn reprezentacj zmian, które powiniene wprowadzi .
Jeli czytasz ksik w wersji papierowej, nie wiesz dokadnie, jakie kolory powinny zosta wybrane, poniewa ilustracje zostay wydrukowane w odcieniach szaroci. Zmodyfikuj wic wartoci znajdujce si przy suwakach RGBA w taki sposób, aby odpowiaday poniszym ustawieniom.
Twój system czstek, widoczny w oknie Scene, bdzie si teraz zachowywa bardziej naturalnie, a jego skadniki powinny zmienia kolor i wartoci kanau alfa. Uwaga Wynik dziaania elementu Color Animation moe by mniej lub bardziej widoczny. Zaley to od tego, jakie materiay, uyte w systemie czstek, wykorzystuj okrelone procedury cieniowania — niektóre z nich prezentuj kolory w wikszym stopniu ni inne. Na przykad procedury cieniowania z przezroczystoci mog prezentowa kolory w sposób mniej widoczny.
Wartoci opcji Rotation Axis (o obrotu) powinny by równe 0 dla wszystkich osi. W polu Size Grow (zwikszanie rozmiaru) wprowad warto -0,3. Dziki temu czstki bd si zmniejsza w trakcie swojego ycia, co stworzy bardziej dynamiczny wygld ognia.
286
Rozdzia 8. • Systemy czstek
Teraz powinnimy zastosowa siy, by uzyska bardziej realistyczny ruch pomieni. Siy róni si od prdkoci zdefiniowanych w ustawieniach emitera, poniewa s uywane w momencie tworzenia czstek. Powoduj one przyspieszenie ich ruchu, a nastpnie jego spowolnienie i kontynuowanie z prdkoci okrelon w parametrach emitera. Rozwi pole Rnd Force (sia losowa) poprzez kliknicie szarej strzaki, znajdujcej si po lewej stronie jego nazwy, a nastpnie wprowad warto 1 w pozycjach X i Z. Nastpnie w taki sam sposób rozwi pole Force (sia) i wprowad w pozycji Y warto równ 1. Przypisz parametrowi Damping (tumienie) warto 0,8. Definiuje on stopie spowalniania ruchu czstek w trakcie ich ycia. Domylna warto 1 oznacza, e nie wystpuje tumienie; wartoci pomidzy 0 i 1 spowalniaj ruch, natomiast 0 powoduje, e on zanika. Porednie ustawienie równe 0,8 powoduje, e spowolnienie czstek nie bdzie wygldao zbyt nienaturalnie. Ostatnia opcja, Autodestruct (samounicestwienie), moe pozosta niewczona. Wszystkie czstki i tak podlegaj autodestrukcji pod koniec swojego ycia, lecz to ustawienie odnosi si do obiektu nadrzdnego. Jeli jest ono wczone, a wszystkie czstki systemu zostay unicestwione, wówczas sam obiekt gry jest likwidowany. Uycie tego parametru ma sens w przypadku, gdy w komponencie emitera jest wczona opcja One Shot (pojedynczy incydent). Przykadowo wybuch armaty mógby wykorzystywa instancj systemu czstek z wczonymi opcjami One Shot i Autodestruct. Usunicie obiektu nadrzdnego oznacza równie, e wzronie ogólna wydajno gry.
Ustawienia renderera czstek W systemie czstek symulujcym ogie powinnimy po prostu zastosowa materia zawierajcy odpowiedni grafik, która zostanie pobrana i zaimportowana. Zanim to jednak zrobimy, upewnijmy si, e komponent Particle Renderer zosta waciwie skonfigurowany na nasze potrzeby. Poniewa czstki lub pomienie ognia powinny faktycznie emitowa wiato, wyczymy obie opcje Cast Shadows (rzucaj cienie) i Receive Shadows (wywietlaj cienie), aby upewni si, e nie bd one rzuca adnych cieni. Pamitaj, e wykonana przez nas czynno ma sens jedynie dla uytkowników systemu Unity Pro, gdy wersja darmowa nie obsuguje dynamicznego cieniowania. Teraz adne materiay nie s przypisane do systemu czstek, dlatego te obszar Materials (materiay) nie zawiera adnych pozycji. Za chwil zostanie to zmienione. Upewnij si, e pole Camera Velocity Scale (skala prdkoci kamery) zawiera warto 0. Mogoby by ono wykorzystywane jedynie wówczas, gdyby rendering naszych czstek nie stosowa opcji billboardingu. Jeli chcielibymy dynamicznie zmienia rozmiar czstek, uylibymy tego pola w celu okrelenia poziomu wpywu ruchu kamery na ich rozciganie. Jak powiedziano wczeniej, parametr Stretch Particles (rozciganie czstek) powinien wywietla opcj Billboard. Dziki temu czstki bd zawsze zwrócone w stron gracza, bez wzgldu na to, gdzie si on znajduje. Poniewa pola Length Scale (skalowanie dugoci) i Velocity Scale (skalowanie prdkoci) s wykorzystywane jedynie w czstkach rozciganych, moemy je bez
287
Projektowanie gier w rodowisku Unity 3.x
problemu pozostawi z ich domylnymi wartociami, równymi 0. Ich modyfikacja nie wpynie na czstki renderowane przy uyciu opcji billboardingu. Biorc pod uwag to, e nie skorzystamy z opcji UV Animation (animacja UV), moemy przyjrze si ostatniemu parametrowi, zwanemu Max Particle Size (maksymalny rozmiar czstki). Okrela on wielko czstki w odniesieniu do rozmiaru ekranu. Na przykad jeli przypiszemy mu warto 1, wówczas czstki bd miay maksymalny rozmiar równy wysokoci ekranu. Liczba 0,5 oznacza, e mog osiga wielko do poowy wysokoci ekranu itd. Poniewa czstki ognia nigdy nie bd musiay by tak due jak okno ekranu, moemy pozostawi domyln wielko tego parametru, równ 0,25.
Dodawanie materiau Gdy system czstek zosta ju zdefiniowany, pozostao nam tylko stworzy materia: wykorzystamy w tym celu tekstur ognia. Wybierz folder Materials (materiay) w panelu Project (projekt), a nastpnie kliknij przycisk Create (stwórz), znajdujcy si w górnej czci interfejsu, i z rozwijanego menu wybierz opcj Material (materia). Spowoduje to utworzenie nowego materiau o nazwie New Material. Zmie jego nazw na Flame i pozostaw zaznaczenie, by wywietli odpowiednie waciwoci w panelu Inspector (inspektor). Z rozwijanego menu Shader (cieniowanie) wybierz opcj Particles/Additive (soft) (czstki/cieniowanie addytywne, mikkie). Spowoduje to, e czstki bd wykorzystywa mikki rendering materiau z uyciem przezroczystoci. Przecignij tekstur flame z folderu Book Assets/Textures (zasoby ksiki/tekstury), znajdujcego si w panelu Project, a nastpnie upu j na niewypeniony kwadrat, pooony po prawej stronie nazwy Particle Texture (tekstura czstki), który obecnie zawiera napis None (Texture) (brak tekstury). Aby uy stworzonego materiau, po prostu przecignij go z folderu Materials i upu na obiekt FireSystem w panelu Hierarchy. Pojawi si on w komponencie Particle Renderer, znajdujcym si w panelu Inspector, i dziki temu bdzie móg by tam modyfikowany.
Lokalizacja obiektu FireSystem Aby w prostszy sposób zdefiniowa odpowiednie pooenie systemu czstek dla ognia, bdziemy musieli uczyni go potomkiem obiektu campfire, znajdujcego si ju w scenie. Przecignij obiekt FireSystem, widoczny si w panelu Hierarchy, a nastpnie upu go na obiekt gry zwany campfire, aby uczyni go jego potomkiem. Nastpnie zresetuj jego pooenie poprzez kliknicie ikony kóka zbatego, znajdujcej si po prawej stronie nazwy komponentu Transform obiektu Fire ´System, a w dalszej kolejnoci wybranie opcji Reset (resetuj) z rozwijanego menu. Po tej operacji Twój system czstek bdzie si znajdowa dokadnie w rodku jego obiektu nadrzdnego. Jak moesz zauway , jest on teraz pooony zbyt nisko. Jeli tego nie widzisz, wybierz obiekt w panelu Hierarchy, a nastpnie przemie kursor myszy nad okno Scene i nacinij klawisz F, by przybliy widok. W komponencie Transform przypisz osi Y warto 0,8, aby troch podnie system czstek.
288
Rozdzia 8. • Systemy czstek
Czas na test! Kliknij przycisk Play (granie), aby przetestowa gr, i zacznij podziwia swoje dzieo! Pamitaj, by ponownie nacisn przycisk Play w celu przerwania testowania i powrotu do projektu.
Tworzenie dymu Znane powiedzenie mówi: „Nie ma dymu bez ognia” (i na odwrót). Biorc to pod uwag, bdziemy potrzebowali pióropusza dymu unoszcego si nad ogniskiem, aby wygldao ono realistycznie. Rozpocznij od dodania nowego systemu czstek do sceny: kliknij przycisk Create, znajdujcy si w panelu Hierarchy, a nastpnie wybierz pozycj Particle System z rozwijanego menu lub przejd do opcji menu gównego GameObject/Create Other/Particle System. Zmie nazw nowo powstaego systemu czstek na SmokeSystem (ponownie zwró uwag, aby nie uywa w niej adnego znaku spacji, poniewa uatwi nam to tworzenie skryptów).
Ustawienia elipsoidalnego emitera czstek Poniewa przeanalizowalimy ju moliwe ustawienia tego komponentu, moemy po prostu zastosowa ponisze wartoci parametrów i obserwowa zmiany, jakie one spowoduj. Kady parametr, który nie jest obecny na licie, powinien zawiera domylne wartoci. Q Min Size: 0,8, Q Max Size: 2,5, Q Min Energy: 8, Q Max Energy: 10, Q Min Emission: 10, Q Max Emission: 15, Q World Velocity Y: 1,5, Q Rnd Velocity Y: 0,2, Q Emitter Velocity Scale: 0,1.
Ustawienia animatora czstek Zdefiniuj komponent Particle Animator w taki sposób, aby pozwala na animowanie odcieni szaroci, jak zaprezentowano na poniszym rysunku.
289
Projektowanie gier w rodowisku Unity 3.x
Jeszcze raz powiniene wzi pod uwag, e animacja koloru musi zawiera si pomidzy dwoma wartociami kanau alfa bliskimi zeru, by moga rozpoczyna si i koczy w sposób niewidoczny dla gracza. Dziki temu unikniemy wizualnego „szarpnicia”, gdy czstki bd usuwane. Jeli s one widoczne podczas przeprowadzania tego dziaania, staje si ono duo bardziej zauwaalne, a przez to mniej naturalne. A teraz wprowad nastpujce ustawienia: Q Size Grow: 0,2, Q Rnd Force: (1,2, 0,8, 1,2), Q Force: (0,1, 0, 0,1), Q Autodestruct: opcja niewybrana.
Ustawienia renderera czstek Za chwil stworzymy materia, który zostanie zastosowany w systemie czstek dymu, ale teraz upewnijmy si, e uylimy poniszych ustawie w komponencie renderera czstek: Q Cast Shadows: opcja niewybrana, Q Receive Shadows: opcja niewybrana, Q Stretch Particles: Billboard, Q Camera Velocity Scale, Length Scale, Velocity Scale: 0, Q Max Particle Size: 0,25.
Zastosuj si do polece zawartych we fragmencie „Dodawanie materiau”, nalecym do wczeniejszego punktu „Tworzenie ognia”. Tym razem jednak nazwij swój materia Smoke i przypisz mu plik tekstury, umieszczony w folderze Book Assets/Textures. Nastpnie przecignij nowo utworzony materia na obiekt SmokeSystem w panelu Hierarchy.
Lokalizacja Powtórz etap umieszczania ognia dla systemu dymu poprzez przecignicie i upuszczenie obiektu SmokeSystem na obiekcie nadrzdnym campfire w panelu Hierarchy. Nastpnie przy uyciu ikony kóka zbatego, znajdujcej si po prawej stronie komponentu Transform, wybierz opcj Reset oraz przypisz polu Y warto 1,5. Kliknij przycisk Play, aby upewni si, e nad ogniem pojawi si pióropusz dymu, zgodnie z poniszym rysunkiem. Jak zawsze pamitaj o ponownym naciniciu przycisku Play, by zakoczy testowanie.
Uzupenianie ognia o efekt d wikowy Ogie wyglda ju poprawnie pod wzgldem estetycznym. Powinnimy wic uzupeni go o dwik poncego drewna. W folderze Book Assets/Sounds, który zosta przez Ciebie zaimportowany, znajduje si plik dwikowy o nazwie fire_atmosphere. Wybierz go, a nastpnie przejd do komponentu Audio Importer, znajdujcego si w panelu Project. Upewnij si, e
290
Rozdzia 8. • Systemy czstek
zostaa wybrana opcja 3D Sound (dwik trójwymiarowy). Oznacza ona, e po przypisaniu pliku do róda audio oddalanie si gracza od ognia bdzie powodowao zanikanie dwiku, co jest sensownym rozwizaniem. Wybierz obiekt campfire w panelu Hierarchy, a nastpnie przejd do opcji menu gównego Component/Audio/Audio Source (komponent/audio/ródo audio). Spowoduje to dodanie komponentu Audio Source do obiektu. Póniej po prostu przecignij klip fire_atmosphere z folderu Book Assets/Sounds, znajdujcego si w panelu Project, i upu go na parametr Audio Clip, zawarty w komponencie Audio Source w panelu Inspector. Aby upewni si, e dwik bdzie odtwarzany przez cay czas, zaznacz opcj wyboru Loop (ptla). Kliknij przycisk Play oraz podejd do ogniska, aby usysze dwik poncego ognia. Nastpnie odejd od niego, by sprawdzi efekt zanikania dwiku. Ponownie nacinij przycisk Play, by zakoczy testy.
D wik trójwymiarowy Parametr Rolloff (zanikanie) definiuje, w jaki sposób nastpuje zanikanie dwiku podczas oddalania si od jego róda komponentu Audio Listener (zazwyczaj doczonego do kamery gracza). Moemy go zmieni poprzez odpowiedni modyfikacj krzywej zanikania w komponencie Audio Source. Dziki uyciu opcji 3D Sound Settings (ustawienia dwiku trójwymiarowego) w komponencie Audio Source bdziesz móg zobaczy i zmodyfikowa krzyw zanikania.
291
Projektowanie gier w rodowisku Unity 3.x
Poprzez przypisanie parametrowi Rolloff Mode (tryb zanikania) opcji Custom (konfiguracja uytkownika) i odpowiednie przecignicie punktów Béziera moesz zdefiniowa wasny ksztat krzywej, a nawet uczyni j lini prost w przypadku, gdy tworzysz gry wykorzystujce mniej realistyczne rodowiska. Standardowa krzywa logarytmiczna jest waciw opcj dla naszego ognia, lecz jeli chciaby troch poeksperymentowa , moesz to oczywicie zrobi .
Rozpalanie ognia Poniewa ogie zosta ju przygotowany, moemy teraz sprawi , by zacz dziaa w grze. W tym celu stworzymy mechanik, która zmusi gracza do wzicia pudeka zapaek, a nastpnie rozpalenia za jego pomoc ogniska. Najpierw musimy zablokowa dziaanie ogniska, poniewa nie powinno by ono aktywne na samym pocztku gry. Aby to zrobi , powinnimy wyczy wszystkie systemy czstek i ródo audio: Q Wybierz obiekt campfire w panelu Hierarchy (hierarchia), a nastpnie w komponencie Audio Source, znajdujcym si w panelu Inspector, odznacz opcj wyboru Play On
Awake (odtwarzanie przy uruchomieniu), dziki czemu dwik nie bdzie odtwarzany, dopóki nie zostanie wczony w skrypcie. Q Wybierz obiekt podrzdny FireSystem, nalecy do rodzica campfire, i w komponencie Particle Emitter wycz opcj Emit (emituj).
292
Rozdzia 8. • Systemy czstek
Q Wybierz obiekt podrzdny SmokeSystem, nalecy do rodzica campfire, a nastpnie w komponencie Particle Emitter wycz opcj Emit (emituj).
Teraz musimy utworzy kolekcj zapaek oraz wywietlacz HUD, który bdzie informowa o fakcie ich posiadania. W tym celu powinnimy wykona nastpujce czynnoci: Q Umieci w placówce model matchbox, który bdzie nagrod dla gracza za otwarcie
wejcia do niej. Q Przy uyciu komponentu GUITexture stworzy wywietlacz HUD prezentujcy pudeko zapaek, a nastpnie zapisa go w postaci prefabrykatu. Q Napisa skrypt Trigger, który pozwoli na zebranie pudeka zapaek i zarejestruje
odpowiedni kolekcj w skrypcie Inventory, podczonym do postaci gracza, a take wywietli element HUD.
Tworzenie pudeka zapaek Wybierz model matchbox w folderze Book Assets/Models (zasoby ksiki/modele), znajdujcym si w panelu Project (projekt), przecignij go do panelu Hierarchy (hierarchia), a nastpnie upu na obiekt outPost, czynic go jego potomkiem. Uatwi nam to póniej zdefiniowanie jego pooenia. Jeli obiekt matchbox jest wci wybrany, przejd do komponentu Transform, znajdujcego si w panelu Inspector (inspektor). Kliknij ikon kóka zbatego, widoczn po prawej stronie nazwy komponentu, a nastpnie wybierz opcj Reset Position (resetuj pozycj). W dalszej kolejnoci przypisz osi Y parametru Position (pooenie) warto 2,5. Poniewa pudeko zapaek znajduje si ju wewntrz placówki, uyj narzdzia Translate (skrót klawiszowy W), aby umieci je na stole, dziki czemu moe by atwo zauwaone przez gracza. Ma to sens, poniewa ten obiekt powinien by przez niego wzity po wejciu do budynku. Z tego powodu pudeko zapaek powinno by wyposaone w zderzacz, który bdzie wykrywa kolizje midzy nim i postaci gracza. Jeli obiekt matchbox jest wci wybrany, przejd do opcji menu gównego Component/Physics/Box Collider (komponent/parametry fizyczne/zderzacz skrzynkowy), a nastpnie kliknij przycisk Add (dodaj), gdy pojawi si okno dialogowe Losing Prefab (utrata poczenia z prefabrykatem). W celu uniknicia zderzania si postaci gracza z obiektem, a take umoliwienia wzicia pudeka zapaek przy uyciu funkcji OnTriggerEnter() w zderzaczu wczymy tryb wyzwalania. Aby to zrobi , po prostu zaznacz opcj wyboru Is Trigger (jest wyzwalaczem), znajdujc si w komponencie Box Collider, który naley do panelu Inspector. Poniewa obiekt nie ley na krawdzi stou, jest prawdopodobne, e najpierw nastpi kolizja zderzacza postaci gracza ze stoem ni z pudekiem zapaek. Aby tego unikn , moemy po prostu powikszy zderzacz pudeka zapaek, a nie przemieszcza samego obiektu. Odszukaj opcj Size (rozmiar) w komponencie Box Collider, a nastpnie wprowad w polach X, Y i Z warto 1. Twój zderzacz powinien teraz wyglda jak na poniszym rysunku, przedstawiajcym panel Scene (scena):
293
Projektowanie gier w rodowisku Unity 3.x
Operacje interakcji z pudekiem zapaek bd teraz prostsze do zrealizowania. Gdy gracz widzi pudeko, chce podej do niego i je wzi . Nie myli wówczas o pooeniu zderzacza postaci, lecz po prostu w swoim polu widzenia widzi obiekt, który chciaby wzi , dlatego zblia si do niego i go zabiera.
Tworzenie skryptu obsugujcego kolekcj zapaek Aby umoliwi graczowi wzicie pudeka zapaek, napiszemy skrypt sprawdzajcy wyzwalacz gracza, a nastpnie wywoujcy now funkcj, któr umiecimy w skrypcie Inventory. Zaznacz folder Scripts (skrypty) w panelu Project (projekt), kliknij przycisk Create (stwórz) i wybierz odpowiedni jzyk programowania. Zmie nazw nowo powstaego skryptu na Matches. Wczytaj go do edytora i umie w nim nastpujc funkcj: Jzyk C#: void OnTriggerEnter(Collider col){ if(col.gameObject.tag == "Player"){ col.gameObject.SendMessage("MatchPickup"); Destroy(gameObject); } }
Jzyk JavaScript: function OnTriggerEnter(col : Collider){ if(col.gameObject.tag == "Player"){
294
Rozdzia 8. • Systemy czstek
col.gameObject.SendMessage("MatchPickup"); Destroy(gameObject); } }
W powyszym kodzie — podobnie jak w skrypcie PowerCell — sprawdzamy, czy obiekt gry zawiera znacznik Player. Jeli tak, wysyamy do niego komunikat w celu wywoania funkcji MatchPickup, któr wkrótce umiecimy w skrypcie Inventory. Wreszcie sam obiekt gry, czyli pudeko zapaek, jest usuwany z gry za pomoc funkcji Destroy(). Zapisz swój skrypt i wró do rodowiska Unity. Nastpnie przecignij go z folderu Scripts na obiekt matchbox, znajdujcy si w panelu Hierarchy. Przetestuj gr, co powinno spowodowa pojawienie si bdu SendMessage has no receiver (funkcja SendMessage nie zawiera odbiornika). Wynika to std, i w adnym ze skryptów przypisanych graczowi nie istnieje funkcja, która odbieraaby wysyany komunikat. Powinnimy wic uzupeni kod o funkcj MatchPickup(), aby dokoczy tworzenie mechaniki zwizanej ze zbieraniem zapaek. Zanim jednak wprowadzimy odpowiednie zmiany w skrypcie Inventory, stwórzmy element graficznego interfejsu uytkownika, który bdzie reprezentowa zabrane pudeko zapaek.
Tworzenie elementu GUI odpowiadajcego pudeku zapaek Wybierz plik tekstury MatchGUI, znajdujcy si w folderze Book Assets/Textures (zasoby ksiki/tekstury) w panelu Project. Przejd do komponentu Texture Importer, wywietlanego w panelu Inspector, a nastpnie z menu podrcznego Texture Type (rodzaj tekstury) wybierz opcj GUI (graficzny interfejs uytkownika). Dziki temu dany zasób bdzie lepiej przystosowany do wywietlania go w dwóch wymiarach. Kliknij przycisk Apply (zastosuj), znajdujcy si w dolnej czci komponentu Texture Importer, aby zapamita wprowadzone zmiany. Jeli tekstura jest wci wybrana w panelu Project, przejd do opcji menu gównego GameObject/Create Other/GUI Texture (obiekt gry/stwórz inny/tekstura GUI). Nie musimy umieszcza tekstury na ekranie, poniewa zrobimy to, gdy utworzymy odpowiedni obiekt na podstawie prefabrykatu. Teraz okno gry powinno wyglda jak na poniszym rysunku. Aby zapisa tekstur jako prefabrykat, otwórz folder Prefabs (prefabrykaty), znajdujcy si w panelu Project, a nastpnie przecignij do niego obiekt MatchGUI z panelu Hierarchy. Wreszcie ponownie wybierz pierwotny obiekt MatchGUI, znajdujcy si w panelu Hierarchy, i usu go ze sceny poprzez uycie skrótu klawiszowego Delete (PC) lub Command+Backspace (Mac).
Zabieranie pudeka zapaek Przejd do folderu Scripts w panelu Project, a nastpnie otwórz skrypt Inventory. Do zapamitania, czy wzilimy ju pudeko zapaek, uyjemy zmiennej logicznej. Jej warto zostanie ustawiona na true, jeli bdziemy posiada zapaki. Stworzymy równie odwoanie do
295
Projektowanie gier w rodowisku Unity 3.x
prefabrykatu MatchGUI, co pozwoli nam na skonkretyzowanie obiektu po zabraniu pudeka przez gracza. Umie nastpujce wiersze poniej deklaracji zmiennych dla generatora: Jzyk C#: // Zapaki bool haveMatches = false; public GUITexture matchGUIprefab;
Jzyk JavaScript: // Zapaki private var haveMatches : boolean = false; var matchGUIprefab : GUITexture;
Zmienna matchGUIprefab jest typu publicznego, dlatego po ukoczeniu tworzenia skryptu powinnimy jej przypisa prefabrykat MatchGUI w panelu Inspector. Oprócz odwoania do prefabrykatu musimy równie zadeklarowa prywatn zmienn typu GUITexture, której uyjemy do przechowywania utworzonego obiektu gry MatchGUI. Moemy j wykorzysta do usunicia tego obiektu po uyciu zapaek przez gracza. Poniej dwóch nowo stworzonych zmiennych umie nastpujc deklaracj: Jzyk C#: GUITexture matchGUI;
296
Rozdzia 8. • Systemy czstek
Jzyk JavaScript: private var matchGUI : GUITexture;
Nastpna funkcja, któr stworzymy, bdzie si nazywa MatchPickup(). Jak zapewne pamitasz, jest ona wywoywana przez instrukcj SendMessage() w skrypcie Matches, gdy dochodzi do kolizji postaci gracza ze zderzaczem pudeka zapaek. Umie ponisz funkcj w skrypcie Inventory. Jzyk C#: void MatchPickup(){ haveMatches = true; AudioSource.PlayClipAtPoint(collectSound, transform.position); GUITexture matchHUD = Instantiate(matchGUIprefab, new Vector3(0.15f, 0.1f, 0), ´transform.rotation) as GUITexture; matchGUI = matchHUD; }
Jzyk JavaScript: function MatchPickup(){ haveMatches = true; AudioSource.PlayClipAtPoint(collectSound, transform.position); var matchHUD : GUITexture = Instantiate(matchGUIprefab, Vector3(0.15, 0.1, 0), ´transform.rotation); matchGUI = matchHUD; }
W powyszym kodzie przypisujemy zmiennej haveMatches warto true. Bdziemy j jeszcze sprawdza , gdy stworzymy funkcj pozwalajc na uycie zapaek. Nastpnie odtwarzamy dwik informujcy o zabraniu pudeka zapaek. W póniejszym czasie na pocztku skryptu umiecimy deklaracj nowej zmiennej, aby odróni dwik zbieranego pudeka zapaek od dwiku gromadzenia ogniw energetycznych. Dla uproszczenia uyjemy teraz tego samego klipu audio. W trzecim wierszu funkcji tworzymy instancj prefabrykatu matchGUIprefab oraz zapamitujemy j w zmiennej lokalnej, zwanej matchHUD. Pooenie obiektu zostao zdefiniowane za pomoc typu Vector3 i jest równe (0,15, 0,1, 0), co oznacza lewy dolny obszar ekranu. Wreszcie przypisujemy nowo utworzon instancj matchHUD do zmiennej prywatnej matchGUI. Wykorzystamy j w momencie, gdy bdziemy chcieli usun obiekt MatchGUI ju po uyciu zapaek do rozpalenia ogniska. Zapamitaj skrypt Inventory i wró do rodowiska Unity.
297
Projektowanie gier w rodowisku Unity 3.x
Wybierz obiekt First Person Controller, aby wywietli komponent Inventory (Script). Moesz zauway pojawienie si zmiennej publicznej Match GUIprefab, której naley przypisa obiekt GUITexture. W tym celu przecignij i upu na ni prefabrykat MatchGUI z folderu Prefabs, znajdujcego si w panelu Project. Zapamitaj biec scen poprzez wybranie opcji menu gównego File/Save Scene (plik/zapisz scen). Kliknij przycisk Play, by sprawdzi , czy po wejciu do placówki moesz wzi pudeko zapaek, jeli zbliysz si do niego. Jego tekstura powinna si pojawi w lewym dolnym obszarze okna. A teraz uyjemy zmiennej haveMatches, aby okreli , czy mona ju rozpali ognisko.
Rozpalanie ogniska Aby zapali ogie, musimy sprawdzi , czy nie zachodzi kolizja midzy graczem i obiektem ogniska. W tym celu wró do edytora, by zmodyfikowa skrypt Inventory. Jeli jest on zamknity, otwórz go ponownie, klikajc jego nazw w folderze Scripts, znajdujcym si w panelu Project. Bdziemy wykrywa kolizje gracza z ogniskiem. Jednake teraz uywamy zderzacza fizycznego, a nie zderzacza z wczonym trybem wyzwalania. Dlatego powinnimy wykorzysta funkcj wykrywania kolizji dla kontrolera postaci — OnControllerColliderHit(). Zajmowalimy si ni podczas pierwszej próby otwierania drzwi placówki, lecz zrezygnowalimy z niej, poniewa uycie wyzwalaczy w tym przypadku byo bardziej odpowiednie. Umie ponisz funkcj w skrypcie Inventory.
298
Rozdzia 8. • Systemy czstek
Jzyk C#: void OnControllerColliderHit(ControllerColliderHit col){ if(col.gameObject.name == "campfire"){ LightFire(col.gameObject); } }
Jzyk JavaScript: function OnControllerColliderHit(col : ControllerColliderHit){ if(col.gameObject.name == "campfire"){ LightFire(col.gameObject); } }
W powyszej funkcji jak zwykle wykorzystujemy zmienn, która przechowuje wykrywane interakcje. Podobnie jak w przypadku innych instancji wykrywania kolizji, aby uproci kod, uywamy zmiennej col, lecz tym razem funkcja OnControllerColliderHit() przechowuje typ ControllerColliderHit. Wci moemy jednak mie dostp do obiektu gameObject, z którym si zderzylimy, dlatego te wykorzystujemy t moliwo w poleceniu if. Jeli warunek if jest speniony, wówczas wywoujemy wasn funkcj LightFire(), do której przekazujemy obiekt gry biorcy udzia w kolizji. Stwórzmy teraz t funkcj.
Uycie tablic i ptli w celu wywoywania polece dla wielu obiektów W tworzonej funkcji uyjemy tablicy i ptli for, aby wykona okrelony zestaw instrukcji dla wielu obiektów. Ta metoda jest przydatna w wielu scenariuszach gier. Na przykad w amigówce gracz wybiera okrelone elementy w pewnej kolumnie, które nastpnie musz zosta usunite. Uycie ptli do odszukania tych skadników i zastosowania w odniesieniu do nich odpowiednich polece jest najbardziej wydajnym sposobem realizacji zadania. Po zamykajcym nawiasie klamrowym funkcji OnControllerColliderHit() umie nastpujc deklaracj: Jzyk C#: void LightFire(GameObject campfire){ }
Jzyk JavaScript: function LightFire(campfire : GameObject){ }
W nawiasach powyszej funkcji znajduje si argument campfire o typie GameObject, który zawiera obiekt biorcy udzia w kolizji, przesany przez funkcj OnControllerColliderHit().
299
Projektowanie gier w rodowisku Unity 3.x
Funkcja rozpala ognisko poprzez wczenie waciwoci emit w komponencie Particle Emitter dla systemów czstek FireSystem i SmokeSystem. W tym celu powinnimy utworzy tablic zawierajc komponenty emitera, a nastpnie przeglda j i kolejno wcza waciwoci emit. Jzyk C#: Rozpocznij od zadeklarowania lokalnej tablicy wewntrz funkcji LightFire(): ParticleEmitter[] fireEmitters;
Teraz musimy zainicjalizowa t tablic obydwoma komponentami emitera czstek. W tym celu wykorzystamy funkcj GetComponentsInChildren, która odszuka komponenty we wszystkich potomkach okrelonego obiektu gry. Z tego powodu uywamy argumentu campfire, poniewa przechowuje on odwoanie do nadrzdnego obiektu, zawierajcego obiekty FireSystem i Smoke ´System. Umie poniszy wiersz kodu w funkcji LightFire(): fireEmitters = campfire.GetComponentsInChildren();
W powyszym kodzie do tablicy fireEmitters przekazujemy komponenty Particle Emitter, które znalelimy w potomkach obiektu campfire. Powinnimy po prostu uy ptli for, aby przetworzy t tablic i wykona polecenie dla kadego znalezionego emitera. Umie nastpujcy kod zaraz pod wierszem, który wanie dodae: foreach(ParticleEmitter emitter in fireEmitters){ emitter.emit = true; }
Wewntrz warunku ptli tworzymy zmienn zwan emitter, do której przekazujemy kolejny element tablicy fireEmitters w trakcie trwania kadej iteracji. Jest ona nastpnie uywana, by uzyska parametr emit komponentu Particle Emitter, któremu przypisujemy warto true. Jzyk JavaScript: Umie poniszy kod w funkcji LightFire(): var fireEmitterComponents : Component[] = campfire.GetComponentsInChildren(ParticleEmitter); var fireEmitter : ParticleEmitter; for (var i=0; i< fireEmitterComponents.Length; i++) { fireEmitter = fireEmitterComponents[i] as ParticleEmitter; fireEmitter.emit=true; }
W powyszym kodzie deklarujemy tablic typu Component[]. Nastpnie inicjalizujemy j komponentami Particle Emitters, znalezionymi we wszystkich potomkach obiektu gry campfire. W kolejnym wierszu deklarujemy pojedyncz zmienn fireEmitter o typie ParticleEmitter. Jest ona uywana w ptli for, która rozpoczyna si od utworzenia zmiennej i oraz przypisania
300
Rozdzia 8. • Systemy czstek
jej wartoci 0. Zmienna ta reprezentuje okrelony skadnik tablicy. Ptla dziaa tyle razy, ile elementów skada si na tablic fireEmitterComponents, std uycie wyraenia .Length. W kadej iteracji do zmiennej tymczasowej fireEmitter przypisujemy element tablicy fireEmit ´terComponents i definiujemy jego typ jako ParticleEmitter, wykorzystujc w tym celu zapis as ParticleEmitter. Nastpnie w emiterze ustawiamy waciwo emit na warto true. Na samym kocu powinnimy wczy efekt dwikowy dla ogniska. Po zamykajcym nawiasie klamrowym ptli for umie taki wiersz kodu: Jzyk C# i JavaScript: campfire.audio.Play();
Informowanie o uyciu inwentarza W typowy sposób, charakterystyczny dla gier wideo, powinnimy poinformowa gracza, e wykorzysta ju pudeko zapaek. Bdzie on polega po prostu na usuniciu wywietlacza MatchGUI z ekranu. Powinnimy take przypisa zmiennej logicznej haveMatches warto false, aby zapamita , e nie moemy ju uywa zapaek. Po wierszu wczajcym efekt dwikowy w funkcji Light ´Fire() umie nastpujcy kod: Jzyk C# i JavaScript: Destroy(matchGUI); haveMatches=false;
Funkcja Destroy() usuwa obiekt gry MatchGUI, który zosta umieszczony w zmiennej matchGUI przez funkcj OnControllerColliderHit(). Wreszcie przypisujemy zmiennej haveMatches warto false. Uyjemy jej, by zagwarantowa , e wykrycie kolizji bdzie dziaa inaczej, gdy mamy zapaki, a inaczej, gdy ich nie posiadamy. Q Mamy zapaki: powinna zosta wywoana funkcja LightFire(). Q Nie mamy zapaek: gracz powinien otrzyma komunikat z wykorzystaniem istniejcego obiektu TextHintGUI.
Wró na sam pocztek skryptu i umie w nim kolejn zmienn publiczn, która pozwoli nam na odwoanie si do obiektu TextHintGUI. Jzyk C#: public GUIText textHints;
Jzyk JavaScript: var textHints : GUIText;
301
Projektowanie gier w rodowisku Unity 3.x
Gdy ukoczymy tworzenie skryptu, w panelu Inspector przypiszemy obiekt TextHintGUI do powyszej zmiennej. Wewntrz istniejcego polecenia if, zawartego w funkcji OnControllerCol ´liderHit(), powinnimy zdefiniowa zagniedon instrukcj if else. Kod wyglda teraz nastpujco: if(col.gameObject.name == "campfire"){ LightFire(col.gameObject); }
Zmodyfikuj go tak, by sprawdza, czy gracz podniós pudeko zapaek. if(col.gameObject.name == "campfire"){ if(haveMatches){ LightFire(col.gameObject); }else{ textHints.SendMessage("ShowHint", "I could use this campfire to signal ´for help... if only I could light it..."); } }
Teraz kolizja z obiektem ogniska spowoduje jego rozpalenie, gdy gracz posiada pudeko zapaek. W przeciwnym razie na ekranie zostanie wywietlona wskazówka. Zapamitaj swój skrypt i wró do rodowiska Unity. Powinnimy teraz przypisa obiekt Text ´HintGUI do zmiennej Text Hints, któr wanie dodalimy do skryptu Inventory. Wybierz obiekt First Person Controller w panelu Hierarchy, a nastpnie przecignij obiekt TextHintGUI na zmienn publiczn Text Hints, znajdujc si w komponencie Inventory (script) w panelu Inspector. Ponownie przetestuj gr, aby upewni si, e gdy podchodzisz do ogniska bez pudeka zapaek, pojawia si wskazówka, natomiast gdy ju je posiadasz, nastpuje rozpalenie ognia (patrz poniszy rysunek). Wszystko dziaa prawidowo, lecz jest jeszcze jeden problem — czy wiesz jaki? Moe ju go odkrye? Za chwil o nim powiemy i znajdziemy rozwizanie, lecz najpierw zapamitajmy stan naszego projektu. Kliknij przycisk Play, aby przerwa dziaanie gry, a nastpnie wybierz opcj menu gównego File/Save Project (plik/zapisz projekt).
Testowanie i weryfikacja dziaania Testowanie dziaania kadego nowego skadnika gry jest bardzo wane. W rozdziale 10. oraz 11. zapoznamy si z metodami optymalizacji gry oraz upewnimy si, e kompilacje testowe dziaaj zgodnie z oczekiwaniami. Poznamy take róne opcje zwizane z udostpnianiem gry odbiorcom docelowym.
302
Rozdzia 8. • Systemy czstek
Teraz powiniene si upewni , e gra na razie dziaa prawidowo. Nawet jeli w konsoli rodowiska Unity nie wywietlaj si adne bdy (PC: Ctrl+Shift+C, Mac: Command+Shift+C), musisz zawsze sprawdza , e podczas grania w gr nie pojawiaj si problemy. Uwaga Jeli podczas testowania napotkasz jakie bdy, przycisk Pause (zatrzymaj), znajdujcy si w górnej czci interfejsu Unity, pozwoli na zatrzymanie gry, a nastpnie jej kontynuowanie. Dziki temu bdziesz móg zapozna si z bdami pojawiajcymi si w oknie Console (konsola). Gdy zauwaysz jaki bd, po prostu kliknij go dwukrotnie w konsoli, a zostaniesz przeniesiony do okrelonego wiersza kodu, który odpowiada za jego powstanie, a przynajmniej do samego skryptu, w którym si on pojawi. Moesz take wcisn przycisk Error Pause (zatrzymanie podczas bdu) w oknie Console, co spowoduje, e gra zatrzyma si po napotkaniu dowolnego bdu. Moesz próbowa analizowa sam bd lub zapozna si z dokumentacj Unity, aby si upewni, e uye waciwego rozwizania. Jeli w dalszym cigu nie moesz sobie da rady z bdami, popro o pomoc na forum Unity lub kanale IRC. By uzyska wicej informacji, odwied nastpujc stron: http://unity3d.com/support/community.
A wic jaki mamy problem? Mimo e w kodzie nie ma adnych bdów, wci pojawia si niewielki problem, zwizany z metod rozpalania ogniska — czy ju wiesz jaki?
303
Projektowanie gier w rodowisku Unity 3.x
Podczas grania w gr powiniene zauway , e podczas kolizji gracza dysponujcego pudekiem zapaek z obiektem ogniska nastpuje, co prawda, rozpalenie ognia, ale podpowied jest wci widoczna na ekranie, gdy znajduje si wewntrz instrukcji else, czyli jest wywietlana, gdy warto zmiennej haveMatches jest równa false. Aby to naprawi , powinnimy stworzy kolejn zmienn logiczn, sprawdzajc, czy ogie zosta rozpalony. Jeli uwaasz, e potrafisz to zrobi sam, zamknij ksik, a nastpnie spróbuj napisa odpowiedni kod. Lecz jeli nie jeste jeszcze cakowicie pewien, jak naley to zrobi , nie martw si. Za chwil poznasz waciwe rozwizanie.
Zabezpieczenie z dodatkowymi warunkami Ponownie wczytaj skrypt Inventory do edytora, a nastpnie umie na jego pocztku nastpujc zmienn: Jzyk C#: bool fireIsLit = false;
Jzyk JavaScript: private var fireIsLit : boolean = false;
A teraz przejd na koniec funkcji LightFire() i po wierszu haveMatches=false; umie kod, który zmienia warto zmiennej fireIsLit: Jzyk C# i JavaScript: fireIsLit=true;
Wró do instrukcji if, znajdujcej si w funkcji OnControllerColliderHit(), i zmie j w poniszy sposób: Jzyk C# i JavaScript: if(haveMatches&& !fireIsLit){ LightFire(col.gameObject); }else if(!haveMatches&& !fireIsLit){ textHints.SendMessage("ShowHint", "I could use this campfire to signal for ´help... if only I could light it..."); }
W powyszym kodzie upewniamy si, e gdy gracz, majc przy sobie pudeko zapaek, zblia si do nieponcego jeszcze ogniska, nastpi jego rozpalenie poprzez wywoanie funkcji Light ´Fire(). Jeli jednak gracz nie ma zapaek i ognisko nie ponie, wówczas na ekranie zostanie wywietlona wskazówka. Oznacza to, e podczas zapalania ognia podpowied nie bdzie prezentowana, poniewa warunek else if wymaga, by zmienna fireIsLit bya równa false (umieszczony przed ni wykrzyknik oznacza negacj). Zapamitaj swój skrypt i wró do rodowiska Unity.
304
Rozdzia 8. • Systemy czstek
Ponownie zagraj w gr, by potwierdzi , e wszystko dziaa prawidowo. Po zakoczeniu testów zapamitaj swój projekt i scen przy uyciu odpowiedniej opcji menu gównego File (plik).
Podsumowanie W tym rozdziale uylimy systemów czstek, by poprawi dynamik naszej gry. S one wykorzystywane w rónych scenariuszach gier, poczynajc od samochodów i statków kosmicznych, a koczc na broni palnej i uwalnianiu pary wodnej. Najlepsz metod przyswojenia sobie wiedzy, któr wanie poznalimy, jest eksperymentowanie. Poniewa mona modyfikowa wiele parametrów, najlepsze wyniki osiga si po jakim czasie, w którym sprawdzamy, jakie efekty mona uzyska . Zapoznalimy si take ze sposobem doczania systemów czstek do naszej aplikacji. Bdziesz go czsto wykorzystywa w trakcie projektowania rónych rodzajów gier. W nastpnym rozdziale zajmiemy si budowaniem systemu menu naszej gry. Bdzie to wymagao tworzenia skryptów wykorzystujcych klas graficznego interfejsu uytkownika (GUI) dla rodowiska Unity, a take zasobów typu GUISkin, pozwalajcych na zdefiniowanie stylu i sposobu zachowania Twojego interfejsu. Klasa GUI jest specjalnym skadnikiem silnika Unity i moe by wykorzystywana do tworzenia menu oraz wywietlaczy póprzezroczystych HUD. Po poczeniu jej z zasobami GUISkin staje si cakowicie modyfikowalna wizualnie oraz jest gotowa do ponownego wykorzystania. Wynika to std, e zasoby typu GUISkin mog by stosowane w dowolnej liczbie skryptów wykorzystujcych klas GUI, co powoduje, e przyczyniaj si do zdefiniowania jednolitego stylu w projektach Unity.
305
Projektowanie gier w rodowisku Unity 3.x
306
9 Projektowanie menu Aby w tym rozdziale stworzy atrakcyjnie wygldajc gr, bdziemy musieli zaprojektowa oddzieln scen, która posuy jako menu aplikacji. Menu w rodowisku Unity moe zosta zaimplementowane w róny sposób: mona uy poczenia istniejcej funkcjonalnoci oraz renderingu dwuwymiarowych tekstur. Odpowiednie tytuy mog zosta dodane przy uyciu klasy GUITexture lub zastosowaniu skryptów z wykorzystaniem klasy GUI, a take poprzez umieszczenie tekstur na paszczynie. Dziki temu mona uzyska winiet powitaln, zawierajc logo projektanta, elementy interfejsu graficznego uytkownika lub ekrany wczytywania zasobów gry. W tym rozdziale poznasz nastpujce zagadnienia: Q dwie róne metody tworzenia interfejsu uytkownika, Q zarzdzanie komponentami GUITexture przy uyciu zdarze myszy obsugiwanych
w skryptach, Q tworzenie podstawowego skryptu GUI w rodowisku Unity, Q definiowanie przestrzeni dwuwymiarowych za pomoc wartoci typu Rect, Q stylizowanie kodu GUI oraz uycie zasobów GUI, pozwalajcych na definiowanie
kompozycji graficznych interfejsu uytkownika, Q wczytywanie scen do menu oraz adowanie poziomu gry.
Do utworzenia interaktywnych elementów menu moesz wykorzysta dwie róne metody. Jedna z nich polega na uyciu prostego komponentu Unity, opartego na klasie GUITexture — jest to zagadnienie, które poznalimy ju podczas implementowania elementu graficznego dla pudeka zapaek w poprzednim rozdziale oraz celownika w rozdziale 7. Inn metod jest uycie klasy GUI, zawartej w rodowisku Unity, i poczenie jej z zasobami pozwalajcymi na definiowanie kompozycji graficznych interfejsu.
Projektowanie gier w rodowisku Unity 3.x
Tak wic za chwil poznamy dwa sposoby na umieszczenie w grze interaktywnych elementów menu. 1. Klasa GUITexture i uycie skryptów wykorzystujcych zdarzenia myszy. Pierwsza metoda polega na tworzeniu obiektów GUITexture oraz skryptów obsugujcych zdarzenia myszy (na przykad przemieszczenie kursora myszy, nacinicie przycisku, zwolnienie przycisku). Dziki temu mona podmieni odpowiednie tekstury wykorzystywane przez te obiekty. Samo tworzenie przycisków jest do proste, lecz wszystkie dziaania zwizane z obsug grafiki musz by zarzdzane za pomoc skryptów. 2. Klasa GUI rodowiska Unity oraz kompozycje graficzne interfejsu uytkownika. Druga metoda wykorzystuje metodyk opart w wikszym stopniu na skryptach. W przeciwiestwie do pierwszego sposobu tworzenie caego menu realizuje si za pomoc skryptu. Cho w celu wygenerowania elementów menu wykorzystuje si skrypty, jednake moliwe staje si uycie zasobów definiujcych kompozycje graficzne interfejsu uytkownika. Dziki temu mona zmodyfikowa styl grafiki i okreli jej dziaanie przy uyciu panelu Inspector (inspektor), definiujcego zdarzenia myszy. Wykorzystujc to rozwizanie, w mniejszym stopniu obciamy procesor karty graficznej, poniewa zazwyczaj mamy do czynienia tylko z jednym obiektem obsugiwanym przez skrypt, a nie z wieloma elementami reprezentujcymi kady ze skadników menu. Drugi sposób jest, ogólnie rzecz biorc, bardziej akceptowan metod tworzenia penego menu do gry, poniewa pozostawia projektantowi wicej swobody. Same elementy menu s tworzone w skrypcie, lecz póniejsza ich stylizacja przy zastosowaniu kompozycji graficznych GUI jest opcj porównywaln z rozwizaniami typu HTML i CSS, stosowanymi podczas tworzenia stron internetowych. CSS (kaskadowe arkusze stylów, ang. Cascading Style Sheets) zarzdzaj wygldem formularza, a HTML dostarcza waciwych treci. W naszym przypadku graficzny interfejs uytkownika jest elementem HTML, natomiast kompozycja graficzna GUI odpowiada kaskadowym arkuszom stylów.
Interfejsy i menu Menu jest najczciej uywane do definiowania elementów sterujcych i modyfikowania ustawie gry zwizanych z grafik i dwikiem. Umoliwia take wczytywanie zapamitanych stanów rozgrywki. Wane jest, by stworzone menu nie przeszkadzao graczowi w uzyskaniu odpowiedniego poziomu immersji. Gdy mówimy o wspaniaej grze, mamy na myli waciwy program, a nie jego system menu (chyba e zosta on wyjtkowo dobrze lub le zaprojektowany).
308
Rozdzia 9. • Projektowanie menu
Czsto projektanci staraj si powiza menu z wygldem lub stylem samej gry. Na przykad w wymienitej grze World Of Goo („wiat glutów”), dostpnej na platformach 2D Boy oraz Wii, kursor przyjmuje ksztat gluta, który zostawia za sob lad w trakcie poruszania si po strukturze menu gry, dopasowujc si do wizualnego stylu caego interfejsu.
Jest to waciwy przykad, poniewa gra udostpnia graczowi co podobnego do jej zasadniczej mechaniki, dziki czemu bawi równie w trakcie przemieszczania si po strukturze menu pocztkowego. W grze LittleBigPlanet („MaaDuaPlaneta”) firmy Media Molecule jeszcze bardziej rozwinito ten pomys i stworzono menu, które wymaga od gracza nauczenia si sterowania postaci, zanim bdzie móg on si nim posugiwa . Gówn zasad projektowania menu powinno by zachowanie jednolitoci. W naszym przypadku musimy si upewni , e uywamy odpowiedniego zestawu kolorów oraz czcionek dopasowanych do caoci. By moe znasz jakie gry, które zostay bdnie zaprojektowane. Charakteryzuj si one uyciem zbyt duej liczby czcionek lub niewaciwych kolorów, co gracz zauwaa ju w samym menu gry. Te czynniki w bardzo duym stopniu obniaj poziom zabawy i mog unicestwi gr pod wzgldem komercyjnym. Zasoby, które zostan uyte podczas tworzenia menu, s dostpne w folderze Book Assets/ Textures (zasoby ksiki/tekstury). Znajdziesz tam nastpujce pliki: Q Tekstury suce do stworzenia gównego tytuu gry oraz trzech przycisków: Play
(granie), Instructions (instrukcje) oraz Quit (zakoczenie). Ich nazwy rozpoczynaj si od sowa menu_. Q Klip audio beep, odtwarzany podczas klikania przycisków.
309
Projektowanie gier w rodowisku Unity 3.x
Tworzenie sceny W tym punkcie wykorzystamy istniejcy widok wyspy i uyjemy go jako to naszego menu. Dziki stworzonemu kontekstowi wizualnemu gracze bd mieli ju jakie pojcie o otoczeniu, w którym si znajd. Widok naszej wyspy z dalekiej perspektywy posuy jako to dwuwymiarowych elementów interfejsu, których uyjemy, wykorzystujc w tym celu dwa wczeniej zaprezentowane rozwizania. W naszym menu chcemy wykorzysta ju utworzone rodowisko wyspy. Umieszczenie jej widoku w tle menu spowoduje, e gracz zapozna si z otoczeniem, które wkrótce bdzie móg bada . Tego typu wizualne zachty mog si wydawa nieznaczce, lecz dziaaj w sposób podwiadomy, zachcajc gracza do rozpoczcia gry i narzucajc mu odpowiedni nastrój.
Duplikowanie wyspy Na pocztku uyjemy naszej sceny Island (wyspa), któr ju utworzylimy. By uatwi zarzdzanie caoci, zgrupujemy gówne zasoby zwizane z otoczeniem: sam wysp, wod oraz ródo wiata kierunkowego. Oddzielimy je od obiektów, których nie potrzebujemy, czyli budynku placówki, pomieszczenia do rzucania orzechami kokosowymi oraz ogniw energetycznych. W ten sposób podczas duplikowania poziomu moemy po prostu usun wszystko oprócz grupy elementów, które chcemy zachowa .
310
Rozdzia 9. • Projektowanie menu
Grupowanie obiektów rodowiska Operacja grupowania w rodowisku Unity polega po prostu na zagniedeniu obiektów jako potomków pustego obiektu nadrzdnego. Wykonaj nastpujce czynnoci: 1. Przejd do opcji menu gównego GameObject/Create Empty (obiekt gry/stwórz pusty) (skrót klawiszowy dla PC: Ctrl+Shift+N, Mac: Shift+N). 2. Pojawi si nowy obiekt zwany po prostu GameObject. Zmie jego nazw na Environment. 3. W panelu Hierarchy (hierarchia) przecignij obiekty Directional Light, Daylight Simple Water oraz Terrain na pusty obiekt Environment. Jeste ju gotowy do operacji duplikowania poziomu w celu umieszczenia naszego menu w oddzielnej scenie.
Duplikowanie sceny Wykonaj ponisze czynnoci w celu zduplikowania sceny: 1. Wybierz opcj menu gównego File/Save Scene (plik/zapisz scen), aby zapamita scen Island. Nastpnie wybierz zasób Island w panelu Project (projekt). 2. Przejd do opcji menu gównego Edit/Duplicate (edycja/duplikacja) lub uyj odpowiedniego skrótu klawiszowego (PC: Ctrl+D, Mac: Command+D). Podczas operacji duplikowania rodowisko Unity po prostu dodaje kolejny numer do nazwy nowo tworzonego obiektu lub zasobu, dlatego Twój duplikat bdzie si nazywa Island 1. Wybierz go w panelu Project, a nastpnie zmie jego nazw na Menu. 3. Wczytaj scen Menu poprzez dwukrotne kliknicie jej ikony w panelu Project. 4. Jeeli scena Menu jest otwarta, moemy usun wszystkie obiekty, których nie potrzebujemy. Jeli uywasz komputera PC, przytrzymaj wcinity klawisz Ctrl, natomiast w przypadku komputera Mac uyj klawisza Command. Nastpnie wybierz wszystkie obiekty w panelu Hierarchy z wyjtkiem grupy Environment, klikajc je po kolei. 5. Usu zaznaczone obiekty ze sceny skrótem klawiszowym Delete (PC) lub Command+ Backspace (Mac).
Tworzenie ta ekranu menu Jak zaprezentowano na poprzednim rysunku, ekran, który chcemy stworzy , zawiera odlegy obraz wyspy, znajdujcy si w prawym dolnym naroniku ekranu, a take tytu gry i menu, umieszczone w wolnej przestrzeni, takiej jak niebo i morze. Aby uzyska ten rezultat, musimy umieci w scenie dodatkow kamer, poprzednio uywalimy bowiem tylko jednej, doczonej do obiektu First Person Controller. Poniewa scena nie zawiera jeszcze adnej kamery, widok Game (gra) powinien by zupenie pusty. Wynika to std, i w trójwymiarowym wiecie gry nie zostao jeszcze utworzone adne okno widoku.
311
Projektowanie gier w rodowisku Unity 3.x
Aby stworzy kamer, kliknij przycisk Create (stwórz) w panelu Hierarchy, a nastpnie z rozwijanego menu wybierz opcj Camera (kamera). Alternatywnie moesz take przej do opcji menu gównego GameObject/Create Other/Camera (obiekt gry/stwórz inny/kamera). W dalszej kolejnoci zdefiniuj widok w oknie Scene (scena) w taki sposób, by uzyska odlegy obraz wyspy, tak jak zaprezentowano na poniszym rysunku:
A teraz dopasuj kamer do utworzonego widoku: wybierz obiekt Camera w panelu Hierarchy, a nastpnie przejd do opcji menu gównego GameObject/Align with view (obiekt gry/dopasuj do widoku). Jeli widok gry nie zawiera adnych szczegóów, po prostu zmodyfikuj warto parametru Far (paszczyzna daleka), nalecego do grupy Clipping Planes (paszczyzny obcinajce), znajdujcej si w komponencie Camera w panelu Inspector. Zwikszaj j a do momentu, gdy w widoku zobaczysz ca wysp i horyzont wody. Jeli jednak nie podoba Ci si uzyskany wynik, moesz zawsze zmodyfikowa widok sceny i powtórzy powysz operacj. Jest ona prostym i do uniwersalnym sposobem definiowania pooenia kamer bez potrzeby wykorzystywania uchwytów osi oraz widoku gry.
Przygotowywanie tekstur do uycia w graficznym interfejsie uytkownika Istnieje wiele rónych ustawie zwizanych z importem danych, które musisz uwzgldnia podczas umieszczania zasobów w rodowisku Unity. Dotycz one take tekstur. W tym podpunkcie postaramy si przygotowa nasze tekstury, tworzce przysze menu, do uycia w postaci dwuwymiarowych elementów graficznego interfejsu uytkownika, a nie grafiki wypeniajcej trójwymiarowe siatki obiektów. Rozpocznij od wybrania pliku tekstury menu_mainTitle, znajdujcego si w folderze Book Assets/ Textures (zasoby ksiki/tekstury) w panelu Project. W panelu Inspector pojawi si odpowiednie
312
Rozdzia 9. • Projektowanie menu
ustawienia komponentu Texture Importer. Aby sprawi , e plik bdzie traktowany jako element GUI, a nie tekstura, po prostu wybierz opcj GUI (graficzny interfejs uytkownika) z menu podrcznego Texture Type (rodzaj tekstury). Kliknij przycisk Apply (zastosuj), by potwierdzi wprowadzon zmian. To ustawienie powinno zosta wybrane w komponencie Texture Importer dla wszystkich tekstur, których uyjemy w naszym menu. Powtórz wic powysz czynno dla nastpujcych tekstur, znajdujcych si w folderze Book Assets/Textures: Q menu_instructionsBtn, Q menu_instructionsBtnOver, Q menu_playBtn, Q menu_playBtnOver, Q menu_quitBtn, Q menu_quitBtnOver.
Poniewa zajmujemy si grafik dwuwymiarow, nie musimy modyfikowa ustawie Aniso Level (poziom filtrowania anizotropowego), Filter Mode (tryb filtrowania) oraz Wrap Mode (tryb zawijania) — s one zwizane z renderowaniem tekstur trójwymiarowych obiektów. Oto inne parametry dostpne w komponencie Texture Importer, o których powiniene wiedzie : Q Max Size (rozmiar maksymalny): ten parametr moe mie mniejsz warto ni rozmiar
pierwotnego pliku. Graficy czsto wykorzystuj grafik o wysokiej rozdzielczoci, a nastpnie uywaj tego ustawienia, by skompresowa swój plik do mniejszych rozmiarów, dziki czemu nie musz wykonywa odpowiedniej czynnoci w aplikacji graficznej. Q Format (format): ogólnie mówic, dla tego parametru powinna zosta wybrana opcja
Compressed (skompresowany), gdy pozwala ona rodowisku Unity na zarzdzanie poziomem kompresji tekstur. Jeli jednak jest to konieczne, mona równie wybra ustawienie Truecolor (peen kolor), umoliwiajce uzyskanie penej gamy kolorów.
Tworzenie tytuu gry Teraz do sceny menu powinnimy doda logo naszej gry. Najprostszy sposób polega na zastosowaniu zaprojektowanej tekstury, która zostanie zdefiniowana w rodowisku Unity w postaci obiektu GUITexture, podobnie jak ma to miejsce w przypadku elementów wywietlacza HUD uywanych w innych fragmentach gry.
313
Projektowanie gier w rodowisku Unity 3.x
Formaty typu GUITexture W folderze Book Assets/Textures, znajdujcym si w panelu Project, wybierz tekstur o nazwie menu_mainTitle. Zostaa ona zaprojektowana w programie Photoshop, a nastpnie zapisana w formacie PNG (Portable Network Graphics). Jest on odpowiedni dla tekstur, które powinny zosta uyte jako obiekt GUITexture. Zapewnia zachowanie grafiki o wysokiej jakoci i nieskompresowanego kanau przezroczystoci oraz umoliwia uniknicie problemów z pojawianiem si biaych konturów, które mog by widoczne w przypadku uycia innych formatów, takich jak GIF (Graphics Interchange Format).
Tworzenie obiektu GUITexture Jeli wspomniany wyej plik tekstury jest zaznaczony, stwórz nowy obiekt GUITexture: przejd do opcji menu gównego GameObject/Create Other/GUITexture (obiekt gry/stwórz inny/GUITexture) lub kliknij przycisk Create (stwórz), znajdujcy si w panelu Hierarchy, a nastpnie wybierz opcj GUITexture z rozwijanego menu. Tak jak wspominano, rozmiary tekstury zostan automatycznie odczytane i przypisane do nowego obiektu. W panelu Hierarchy pojawi si nowy obiekt menu_mainTitle, poniewa jego nazwa zostaa pobrana z odpowiedniego pliku tekstury.
Definiowanie pooenia Poniewa w dzisiejszych czasach wikszo komputerów potrafi obsuy rozdzielczoci równe 1024×768 pikseli lub wiksze, wybierzemy t warto jako domyln do przeprowadzenia testów menu. Uywajc klasy Screen, upewnimy si równie, e gra dziaa take dla innych wielkoci ekranu, oraz sprawdzimy funkcjonowanie dynamicznej zmiany rozdzielczoci. W górnym lewym naroniku widoku Game (gra) widnieje rozwijane menu. Pozwala ono na okrelanie rónych wspóczynników ksztatu ekranu oraz jego rozdzielczoci. Wybierz z tego menu opcj Standalone (1024x768) (aplikacja samodzielna, 1024×768), aby odpowiednio zmieni wielko okna podgldu. Wskazówka Pamitaj, e w przypadku, gdy rozdzielczo Twojego komputera jest zbliona do wybranej przez Ciebie wartoci, okno Game nie bdzie dokadnie odwzorowywa wygldu gry, poniewa moe wykorzystywa niedostateczny obszar interfejsu rodowiska Unity. Aby dla widoku Game (i innych paneli interfejsu) przej w tryb penoekranowy, moesz umieci nad nim kursor myszy, a nastpnie nacisn klawisz spacji. W tym rozdziale podczas umieszczania elementów GUI uywaj tej metody do sprawdzenia, jak bdzie wyglda interfejs gry po jej ukoczeniu. Pamitaj, e zarzdzanie wielkociami interfejsu jest duo atwiejsze, gdy tryb gry nie jest aktywny, poniewa rodowisko Unity zakada, i klawisz spacji moe by domylnie uywany w rozgrywce, i zmusza Ci do klikania mysz poza obszarem widoku gry, jeli chcesz powikszy lub pomniejszy inne panele. Z tego powodu na górnej krawdzi okna Game znajduje si przycisk Maximize on Play (maksymalizuj podczas gry).
Domylnie wszystkie obiekty GUITexture maj pooenie równe (0,5, 0,5, 0), co oznacza rodek ekranu przy zaoeniu, e wspórzdne ekranowe zawieraj si w przedziale od 0 do 1.
314
Rozdzia 9. • Projektowanie menu
W komponencie Transform obiektu menu_mainTitle, znajdujcego si w panelu Hierarchy, zdefiniuj pooenie równe (0,2, 0,8, 0). Spowoduje to umieszczenie naszego logo w prawym górnym obszarze ekranu. Pamitaj, e moe on czciowo znajdowa si poza obszarem okna, dopóki nie powikszysz go na cay obszar interfejsu (uyj w tym celu klawisza spacji) — patrz wczeniejsza wskazówka. Gdy w grze umiecilimy ju gówne logo, powinnimy doda trzy przyciski, wykorzystujc kolejne obiekty GUITexture.
Tworzenie menu za pomoc obiektów GUITexture i zdarze myszy W pierwszej metodzie stworzymy menu, które wykorzystuje tekstur z przezroczystym tem, reprezentowan jako obiekt GUITexture. Bdzie to ten sam sposób, jakiego uylimy podczas umieszczania na ekranie gównego logo gry. Nastpnie napiszemy skrypt, aby spowodowa , e tekstura bdzie otrzymywa zdarzenia myszy, takie jak przemieszczenie lub usunicie kursora z obszaru menu oraz nacinicie i zwolnienie przycisku.
Dodawanie przycisku uruchamiania gry W folderze Book Assets/Textures (zasoby ksiki/tekstury), znajdujcym si w panelu Project (projekt), wybierz tekstur menu_playBtn. Przejd do opcji menu gównego GameObject/ Create Other/GUITexture (obiekt gry/stwórz inny/GUITexture) lub wybierz opcj GUITexture z menu podrcznego, wywietlonego po naciniciu przycisku Create (stwórz). Wybierz obiekt menu_playBtn w panelu Hierarchy (hierarchia), a nastpnie przejd do panelu Inspector (inspektor) i przypisz parametrowi Position (pooenie) komponentu Transform warto (0,3, 0,55, 0).
Skrypt obsugujcy przycisk klasy GUITexture Tworzymy pierwszy z trzech przycisków. Poniewa maj one tak sam funkcjonalno , napiszemy skrypt, który moe zosta uyty dla kadego z nich. W tym celu wykorzystamy zmienne publiczne, które pozwol na modyfikowanie odpowiednich parametrów. Przykadowo kady przycisk bdzie móg: Q odtwarza dwik po stwierdzeniu jego kliknicia, Q przeprowadza dziaania, takie jak wczytywanie kolejnej sceny lub wychodzenie z gry, Q podmienia tekstury w momencie, gdy kursor myszy znajduje si nad nim, aby uzyska
efekt podwietlenia.
315
Projektowanie gier w rodowisku Unity 3.x
Wybierz folder Scripts (skrypty), znajdujcy si w panelu Project (projekt), kliknij przycisk Create (stwórz) i wybierz odpowiedni jzyk programowania. Zmie nazw nowo utworzonego skryptu NewBehaviorScript na MainMenuBtns oraz kliknij jego ikon, by wczyta go do edytora. Uytkownicy jzyka C# powinni dodatkowo usun ca funkcj Start(). Rozpocznij od zadeklarowania powyej funkcji Update() czterech zmiennych publicznych, tak jak w poniszym fragmencie kodu: Jzyk C#: public public public public
string levelToLoad; Texture2D normalTexture; Texture2D rollOverTexture; AudioClip beep;
Jzyk JavaScript: var var var var
levelToLoad : String; normalTexture : Texture2D; rollOverTexture : Texture2D; beep : AudioClip;
Pierwsza zmienna bdzie uywana do przechowywania nazwy wczytywanego poziomu, gdy przycisk, do którego przypiszemy ten skrypt, zostanie nacinity. Poprzez umieszczenie tej informacji w zmiennej bdziemy mogli udostpni skrypt wszystkim trzem przyciskom, a nastpnie uy nazwy zmiennej do wczytania poziomu. Dwie kolejne zmienne s typu Texture2D, jednake nie zostay im jeszcze przypisane adne zasoby. Nastpi to podczas przecignicia i upuszczenia odpowiedniej tekstury w panelu Inspector (inspektor). Wreszcie jest tworzona zmienna typu AudioClip, która zostanie uyta podczas odtwarzania dwiku odpowiadajcego klikniciu myszy. Poniewa nasze zmienne s ju zadeklarowane, moemy stworzy funkcj, która zdefiniuje tekstur uywan przez komponent GUITexture w momencie, gdy kursor myszy pojawi si w jej obszarze. Taka sytuacja jest zazwyczaj zwana stanem aktywowania lub przeczania. Jzyk C#: void OnMouseEnter(){ guiTexture.texture = rollOverTexture; }
Jzyk JavaScript: function OnMouseEnter(){ guiTexture.texture = rollOverTexture; }
316
Rozdzia 9. • Projektowanie menu
W zaimportowanym folderze Book Assets/Textures (zasoby ksiki/tekstury) znajduj si tekstury odpowiadajce stanom normalnym i aktywowanym dla kadego z przycisków. Pierwsza funkcja OnMouseEnter() po prostu przypisuje do waciwoci texture dowolny obiekt, który zosta zdefiniowany w zmiennej publicznej rollOverTexture, znajdujcej si w panelu Inspector. Aby wykry sytuacj, gdy kursor myszy znika z obszaru tekstury, dodaj nastpujc funkcj: Jzyk C#: void OnMouseExit(){ guiTexture.texture = normalTexture; }
Jzyk JavaScript: function OnMouseExit(){ guiTexture.texture = normalTexture; }
Gdyby powyszej funkcji nie byo, tekstura rollOverTexture pozostaaby na przycisku, informujc, e opcja menu jest wci podwietlona. W celu obsugi dwiku i umoliwienia wczytania odpowiedniej sceny dodaj nastpujc funkcj: Jzyk C#: IEnumerator OnMouseUp(){ audio.PlayOneShot(beep); yield return new WaitForSeconds(0.35f); Application.LoadLevel(levelToLoad); }
Jzyk JavaScript: function OnMouseUp(){ audio.PlayOneShot(beep); yield new WaitForSeconds(0.35); Application.LoadLevel(levelToLoad); }
Zauwa, e w jzyku C# funkcja zwraca inny typ danych, zwany IEnumerator. Oznacza to, e wspiera ona operacj udostpnienia czasu procesora, co nie moe zosta zrealizowane przy uyciu zwykego typu void, z którego zazwyczaj korzystamy. Zdefiniowanie typu zwracanego jako IEnumerator sprawia, e funkcja staje si wspóprogramem, poniewa ogólne pojcie programu oznacza zestaw instrukcji wykonywanych zgodnie z zasadami programowania. Wspóprogramy mog by uywane w celu wstrzymania wykonywania polece w przypadku wystpienia okrelonych warunków. W tym czasie pozostaa cz skryptu dziaa normalnie. Mona take zatrzyma dziaanie caego skryptu a do spenienia okrelonych wymaga. Jest to przydatne, gdy chcesz przerwa na jaki czas wykonywanie polece, tak jak uczynilimy
317
Projektowanie gier w rodowisku Unity 3.x
w naszym przykadzie. Odpowiednik powyszego kodu zapisany w jzyku JavaScript nie wymaga takiej modyfikacji, poniewa udostpnianie czasu procesora jest realizowane w standardowej funkcji OnMouseUp(). Pierwszym poleceniem wykonywanym w funkcji jest odtworzenie dwiku. Dziki temu sprawimy, e zostanie to cakowicie zrealizowane przed wczytaniem nowej sceny. Umieszczajc polecenie yield midzy odtworzeniem dwiku a zaadowaniem kolejnej sceny, zatrzymujemy dziaanie skryptu na okrelon liczb sekund. Wskazówka Uycie polecenia yield w skryptach jest prost metod tworzenia opó nienia bez koniecznoci pisania dodatkowego kodu obsugujcego licznik czasu.
Wczytywanie scen Po wykonaniu polecenia yield gra wczyta scen przy uyciu instrukcji Application.LoadLevel(). Wykorzystuje ona argument bdcy acuchem tekstowym, który zawiera napis przypisany do publicznej zmiennej levelToLoad w panelu Inspector. Pozwoli to na zaadowanie odpowiedniego pliku sceny. Aby wykona pewne operacje w tworzonym przez Ciebie projekcie, moesz uy klasy Appli ´cation. Zawiera ona funkcj LoadLevel(), a take szereg innych procedur i waciwoci. Podczas kocowych usprawnie gry wykorzystamy t klas do dynamicznego wyboru renderowania przycisku zakoczenia gry, który nie powinien si pojawia w wersji przeznaczonej dla przegldarki. Aby dowiedzie si wicej o klasie Application, zapoznaj si z fragmentem dokumentacji rodowiska Unity powiconym tworzeniu skryptów: http://unity3d.com/support/documentation/ ScriptReference/Application.html. Obsuga klikni myszy w przyciskach Dobre wzorce postpowania podczas tworzenia interfejsów uytkownika mówi, e dziaania wykonywane po klikniciu myszy powinny si zazwyczaj rozpoczyna dopiero po zwolnieniu jej przycisku, a nie po jego naciniciu. Dziki temu gracz ma szans na przemieszczenie kursora myszy w przypadku, gdy wybra niewaciwy element.
Poniewa zamierzamy odtwarza dwik, upewnij si, e Twój obiekt bdzie zawiera komponent AudioSource. W tym celu umie polecenie RequireComponent we waciwym miejscu swojego skryptu. Jeli nie pamitasz, jak naley to zrobi , poniej przedstawiamy waciw procedur:
318
Rozdzia 9. • Projektowanie menu
Jzyk C#: Zlokalizuj wiersz zawierajcy polecenie using System.Collections. Poniej niego, ale jeszcze przed deklaracj klasy MainMenuBtns, umie nastpujcy kod: [RequireComponent (typeof (AudioSource))]
Jzyk JavaScript: Na samym kocu skryptu umie nastpujcy wiersz kodu: @script RequireComponent(AudioSource)
W swoim edytorze przejd do opcji menu gównego File/Save (plik/zapisz), a nastpnie wró do rodowiska Unity. Wybierz obiekt menu_playBtn w panelu Hierarchy (hierarchia), a nastpnie przejd do opcji menu gównego Component/Scripts/Main Menu Btns (komponent/skrypty/Main Menu Btns), aby przypisa mu nowo utworzony skrypt. Moesz take przecign skrypt z panelu Project (projekt) na obiekt menu_playBtn, znajdujcy si w panelu Hierarchy. W panelu Inspector (inspektor) powinien si pojawi nowy komponent Main Menu Btns (Script). W wyniku dziaania polecenia RequireComponent zosta take wywietlony komponent Audio Source.
Przypisywanie zmiennych publicznych Zmienne publiczne musz zosta zainicjalizowane przed uruchomieniem waciwego skryptu. W zmiennej Level To Load wprowad warto Island, co sprawi, e po klikniciu przycisku zostanie wczytany waciwy poziom. Nastpnie przecignij tekstury menu_playBtn i menu_ playBtnOver z folderu Book Assets/Textures (zasoby ksiki/tekstury) w panelu Project odpowiednio na zmienne Normal Texture i Roll Over Texture. Odszukaj plik dwikowy menu_beep, znajdujcy si w folderze Book Assets/Sounds (zasoby ksiki/dwiki), a nastpnie go wybierz. W dalszej kolejnoci odznacz opcj wyboru 3D Sound (dwik trójwymiarowy), widoczn w komponencie Audio Importer w panelu Inspector. Oznacza to, e dwik bdzie odtwarzany z normaln si, która nie bdzie zalena od odlegoci od komponentu odbiornika audio znajdujcego si w kamerze. Pamitaj o klikniciu przycisku Apply (zastosuj) w celu zapamitania wykonanej zmiany. Wreszcie przecignij klip audio menu_beep z folderu Book Assets/Sounds na zmienn Beep. Po zakoczeniu dziaa Twój komponent powinien wyglda nastpujco:
319
Projektowanie gier w rodowisku Unity 3.x
Testowanie przycisku Aby upewni si, e bdziemy mie do czynienia z poprawnym wygldem ekranu, odszukaj i nacinij przycisk Maximize on Play (maksymalizacja podczas gry), znajdujcy si w widoku Game (gra). Oznacza to, e podczas testów widok gry zostanie powikszony. W zalenoci od rozdzielczoci Twojego ekranu powinien on uywa domylnego rozmiaru, przyjtego dla samodzielnej aplikacji. Aby uzyska ten rezultat, upewnij si, e w pierwszym rozwijanym menu, widocznym po lewej stronie widoku gry, zostaa wybrana opcja Standalone (1024x768) (aplikacja samodzielna, 1024×768). Jeli jej nie widzisz, sprawd, czy w opcji menu gównego File/ Build Settings (plik/ustawienia docelowe) wybrano warto PC and Mac Standalone (aplikacja samodzielna dla PC i Mac). Jeeli nie, wybierz j, a nastpnie kliknij przycisk Switch Platform (zmie platform), znajdujcy si w dolnej czci okna dialogowego. A teraz kliknij przycisk Play (granie), aby przetestowa dziaanie sceny. W trakcie przemieszczania kursora myszy nad przycisk Play Game (rozpocznij gr) powinna si pojawia tekstura PlayBtnOver, która zostaa zaprojektowana w kolorze czerwonym, a po prawej stronie zawiera motyw ognia. Gdy kursor myszy zostanie usunity z tekstury, powinien zosta przywrócony jej wczeniejszy wygld. Spróbuj klikn przycisk. W dolnym pasku interfejsu rodowiska Unity pojawi si bd pochodzcy z konsoli. Jego tre jest nastpujca: Level 'Island' (-1) couldn’t be loaded because it has not been added to the build settings (poziom „Island” (–1) nie móg zosta wczytany, poniewa nie by uwzgldniony w ustawieniach kompilacji docelowej). W ten sposób rodowisko Unity upewnia si, czy nie zapomniae doda odpowiednich poziomów w oknie dialogowym Build Settings (ustawienia docelowe). Suy ono do zdefiniowania parametrów zwizanych z eksportem Twojej gry, czyli tworzeniem wersji finalnej lub testowej. Ustawienia docelowe musz zawiera wszystkie sceny dostpne w grze. Aby rozwiza nasz problem, kliknij przycisk Play, by przerwa testowanie, a nastpnie przejd do opcji menu gównego File/Build Settings. W oknie dialogowym Build Settings kliknij przycisk Add Current (dodaj biec scen), znajdujcy si poniej obszaru Scenes to build (sceny zawarte w kompilacji docelowej). Sceny na licie kompilacji docelowej s umieszczone w odpowiedniej kolejnoci, o której wiadczy numer porzdkowy, znajdujcy si po prawej stronie nazwy sceny. Upewnij si, e scena, która powinna zosta wczytana jako pierwsza, jest zawsze na pozycji równej 0. Przecignij scen Island z panelu Project i upu j na licie, zaraz poniej sceny Menu.unity. Pamitaj, e w oknie Build Settings nie ma adnego przycisku zatwierdzajcego wprowadzone zmiany, dlatego po prostu zamknij je i ponownie uruchom gr, klikajc przycisk Play w interfejsie Unity. Nastpnie spróbuj klikn przycisk Play Game. Powinno to spowodowa odtworzenie dwiku menu_beep, a nastpnie wczytanie poziomu Island. Jeszcze raz nacinij przycisk Play, aby przerwa testowanie, dziki czemu automatycznie powrócisz do sceny Menu.
320
Rozdzia 9. • Projektowanie menu
Dodawanie przycisku wywietlajcego instrukcje Aby umieci drugi przycisk w naszym menu, po prostu wybierz tekstur menu_instructionsBtn z folderu Book Assets/Textures, znajdujcego si w panelu Project, a nastpnie przejd do opcji menu gównego GameObject/Create Other/GUITexture (obiekt gry/stwórz inny/GUITexture) lub kliknij przycisk Create (stwórz), znajdujcy si w panelu Hierarchy, oraz wybierz opcj GUITexture z rozwijanego menu. Spowoduje to pojawienie si obiektu menu_instructionsBtn w panelu Hierarchy. Przejd do jego komponentu Transform i przypisz parametrowi Position (pooenie) warto (0,3, 0,45, 0). Poniewa odpowiedni skrypt zosta ju stworzony, po prostu przejd do opcji menu gównego Component/Scripts/Main Menu Btns (komponent/skrypty/Main Menu Btns) lub przecignij skrypt na obiekt w panelu Hierarchy, a nastpnie przypisz odpowiednie tekstury i plik dwikowy menu_beep w taki sam sposób, jak pokazano we wczeniejszym punkcie „Przypisywanie zmiennych publicznych”. Poniewa nie zaprojektowalimy jeszcze adnego obszaru prezentujcego instrukcje, pozostaw zmienn Level To Load niezainicjalizowan.
Dodawanie przycisku zakoczenia gry Przycisk ten dziaa tak jak dwa poprzednie, lecz nie wczytuje sceny. Zamiast tego wykorzystuje klas Application, aby wywoa polecenie Quit(), koczce dziaanie gry przez sam system operacyjny. Oznacza to, e bdziemy musieli zmodyfikowa skrypt MainMenuBtns, aby uwzgldni t opcj. Jeli nie jest on jeszcze otwarty, dwukrotnie kliknij jego nazw, znajdujc si w folderze Scripts (skrypty) w panelu Project, by wczyta go do edytora. Zlokalizuj w skrypcie deklaracj zmiennej beep, a poniej niej umie nastpujc logiczn zmienn publiczn: Jzyk C#: public bool quitButton = false;
Jzyk JavaScript: var quitButton : boolean = false;
Powysza zmienna bdzie uywana jako przecznik. Jeli zostanie jej przypisana warto true, wówczas spowoduje to, e kliknicie przycisku w funkcji OnMouseUp() wywoa polecenie Quit(). Gdy zmienna quitButton bdzie równa false (stan domylny), nastpi wczytanie poziomu zdefiniowanego w zmiennej levelToLoad. Aby zaimplementowa powysz funkcjonalno , zmodyfikuj odpowiednio funkcj OnMouseUp(), umieszczajc w niej instrukcj if else:
321
Projektowanie gier w rodowisku Unity 3.x
Jzyk C#: IEnumerator OnMouseUp(){ audio.PlayOneShot(beep); yield return new WaitForSeconds(0.35f); if(quitButton){ Application.Quit(); } else{ Application.LoadLevel(levelToLoad); } }
Jzyk JavaScript: function OnMouseUp(){ audio.PlayOneShot(beep); yield new WaitForSeconds(0.35); if(quitButton){ Application.Quit(); } else{ Application.LoadLevel(levelToLoad); } }
Funkcj zmodyfikowalimy w prosty sposób, pozwalajc odtwarza dwik i udostpnia czas procesora (polecenie yield) bez wzgldu na to, jaki rodzaj przycisku zosta uyty. Jednake musimy wybra midzy dwoma opcjami: jeli zmienna quitButton jest równa true, wówczas zostaje wywoane polecenie Application.Quit(); w przeciwnym razie (else) jest wczytywany odpowiedni poziom gry. Przejd do opcji File/Save (plik/zapisz) w swoim edytorze, a nastpnie wró do rodowiska Unity. Wybierz tekstur menu_quitBtn z folderu Book Assets/Textures, znajdujcego si w panelu Project, po czym wska opcj menu gównego GameObject/Create Other/GUITexture (obiekt gry/stwórz inny/GUITexture) lub odpowiednio uyj przycisku Create z panelu Hierarchy. Spowoduje to utworzenie obiektu menu_quitBtn i umieszczenie go w panelu Hierarchy. W komponencie Transform tego obiektu przypisz parametrowi Position (pooenie) warto (0,3, 0,35, 0). Gdy obiekt menu_quitBtn jest wci wybrany w panelu Hierarchy, przejd do opcji menu gównego Component/Scripts/Main Menu Btns (komponent/skrypty/Main Menu Btns) lub przecignij skrypt MainMenuBtns z panelu Project na nazw obiektu. Tak jak poprzednio w panelu Inspector zainicjalizuj zmienne publiczne, lecz tym razem pozostaw zmienn Level To Load nieprzypisan, a take zaznacz opcj wyboru, znajdujc si przy nowo utworzonej zmiennej Quit Button.
322
Rozdzia 9. • Projektowanie menu
Poniej prezentujemy poprawny kod caego skryptu, aby móg go dokadnie porówna z Twoj wersj. Jzyk C#: using UnityEngine; using System.Collections; [RequireComponent (typeof (AudioSource))] public class MainMenuBtns : MonoBehaviour { public public public public
string levelToLoad; Texture2D normalTexture; Texture2D rollOverTexture; AudioClip beep;
public bool quitButton = false; void OnMouseEnter(){ guiTexture.texture = rollOverTexture; } void OnMouseExit(){ guiTexture.texture = normalTexture; } IEnumerator OnMouseUp(){ audio.PlayOneShot(beep); yield return new WaitForSeconds(0.35f); if(quitButton){ Application.Quit(); } else{ Application.LoadLevel(levelToLoad); } } }
Jzyk JavaScript: var var var var var
levelToLoad : String; normalTexture : Texture2D; rollOverTexture : Texture2D; beep : AudioClip; quitButton : boolean = false;
function OnMouseEnter(){ guiTexture.texture = rollOverTexture; }
323
Projektowanie gier w rodowisku Unity 3.x
function OnMouseExit(){ guiTexture.texture = normalTexture; } function OnMouseUp(){ audio.PlayOneShot(beep); yield new WaitForSeconds(0.35); if(quitButton){ Application.Quit(); } else{ Application.LoadLevel(levelToLoad); } } @script RequireComponent(AudioSource)
Wybierz opcj menu gównego File/Save Scene (plik/zapisz scen), aby zapamita stan projektu, a nastpnie kliknij przycisk Play w celu przetestowania menu gry. Nacinicie przycisku Play (rozpoczcie gry) powinno spowodowa wczytanie poziomu Island. Przycisk Instructions (instrukcje) spowoduje powstanie tego samego bdu co poprzednio („poziom nie móg zosta wczytany…”), gdy w komponencie skryptu nie przypisalimy adnej sceny do zmiennej Level To Load. Kliknicie przycisku Quit (zakoczenie gry) nie spowoduje pojawienia si bdu ani te wykonania oczekiwanej od niego czynnoci (jest to normalne — przecie nie chcemy, aby nasz test by przyczyn zakoczenia dziaania samego edytora!). Musimy wic poczeka do momentu, gdy stworzymy wersj docelow gry. Pamitaj o ponownym klikniciu przycisku Play, by zakoczy faz testowania. Pierwsze rozwizanie tworzenia menu zostao ju w peni zaimplementowane, dlatego teraz przyjrzymy si innej metodzie, która wykorzystuje skrypty i klas GUI w celu generowania przycisków w rodowisku Unity.
Testowanie skryptów przy uyciu polece debugowania Poniewa nie moglimy przetestowa dziaania polecenia Application.Quit(), powinnimy upewni si, e przycisk Quit rzeczywicie dziaa, a nie zakada , e tak wanie jest. Do sprawdzenia dziaania dowolnego fragmentu skryptu mona uy instrukcji Debug. Debugowanie polega na usuwaniu bdów w skrypcie. Moe zosta jednak uyte do wysania informacji z okrelonego miejsca programu. Polecenie, którego za chwil uyjemy, bdzie przesya komunikat, wywietlany nastpnie w wierszu konsoli rodowiska Unity w dolnej czci interfejsu. Sprawdmy wic dziaanie instrukcji Debug. Wró do skryptu MainMenuBtns i w kodzie zlokalizuj miejsce uycia zmiennej quitButton: if(quitButton){ Application.Quit(); }
324
Rozdzia 9. • Projektowanie menu
Komunikaty otrzymywane dziki uyciu polecenia Debug pojawiaj si w konsoli obok innych informacji o bdach. Przykadowe wywoanie instrukcji Debug wyglda nastpujco: Debug.Log("Ten fragment kodu dziaa poprawnie!");
Dziki umieszczeniu powyszego wiersza kodu w miejscu, w którym powinno nastpi jego wykonanie, moesz sprawdzi , czy okrelone fragmenty skryptu s poprawne. W naszym przypadku umiecimy polecenie Debug za wywoaniem funkcji Application.Quit(), poniewa bdzie to dowodzi , e zostaa ona wykonana bezbdnie. Zmodyfikowany kod powinien wyglda nastpujco: Jzyk C# i JavaScript: if(quitButton){ Application.Quit(); Debug.Log("This part works!"); }
Zapamitaj skrypt poprzez wybranie w edytorze opcji menu gównego File/Save (plik/zapisz), a nastpnie wró do rodowiska Unity. Przetestuj dziaanie sceny menu: nacinij przycisk Play i kliknij przycisk Quit w menu gry. Spowoduje to pojawienie si odpowiedniej informacji w wierszu konsoli rodowiska Unity. Otwórz oddzielne okno konsoli poprzez wybranie opcji menu gównego Window/Console (okno/konsola) lub uycie skrótu klawiszowego (PC: Ctrl+Shift+C, Mac: Command+Shift+C). Bdziesz móg zobaczy w nim ten sam komunikat, który by widoczny w wierszu konsoli, co zaprezentowano na poniszym rysunku:
Uyta przez nas metoda jest bardzo przydatna podczas analizowania problemów wystpujcych w skrypcie, a nawet projektowania fragmentów programu, dla których nie zostay jeszcze zdefiniowane adne polecenia. Wskazówka Oprócz wywietlania za pomoc instrukcji Debug.Log() zwykych komunikatów tekstowych zawartych w cudzysowach moesz take umieszcza w niej zmienne i funkcje, by sprawdza ich wartoci w trakcie dziaania gry. Taka opcja staje si bezcenna podczas testowania aplikacji i zaleca si jej uycie po napotkaniu jakiegokolwiek niewaciwego dziaania skryptów.
325
Projektowanie gier w rodowisku Unity 3.x
Tworzenie menu za pomoc klasy GUI rodowiska Unity oraz kompozycji graficznych Poniewa nasze menu ju dziaa, nie usuniemy go ze sceny, lecz po prostu tymczasowo zablokujemy dziaanie obiektów, które go tworz.
Wyczanie obiektów gry Wybierz po kolei obiekty menu_playBtn, menu_instructionsBtn i menu_quitBtn, znajdujce si w panelu Hierarchy (hierarchia), a nastpnie wycz je poprzez wykonanie nastpujcych czynnoci dla kadego z nich: Q Wycz opcj znajdujc si w panelu Inspector (inspektor) po lewej stronie nazwy
danego obiektu. Q Upewnij si, e nazwa obiektu w panelu Hierarchy zmienia kolor na jasnoszary, a sam
element znikn z widoku Game (gra). Teraz powinna tam widnie jedynie tekstura z logo tytuowym gry.
Tworzenie menu W metodzie wykorzystamy klas GUI rodowiska Unity, a take zastosujemy wartoci typu float i Rect. Typ Rect zawiera cztery wartoci zmiennoprzecinkowe (float), z których dwie okrelaj pooenie w osi X i Y, a pozostae — szeroko i wysoko . Tego typu uyjemy do zdefiniowania obszaru, w którym zawiera si menu, oraz by okreli powierzchni zajmowan przez kady z przycisków. Nastpnie w skrypcie umiecimy funkcj OnGUI(), w której wykorzystamy zasoby GUISkin. Dziaaj one podobnie jak arkusze stylów uywane podczas projektowania stron internetowych, dostarczajc spójnego zestawu kompozycji graficznych, które mog by wielokrotnie stosowane. Gotowe menu powinno wyglda jak na poniszym rysunku. Na pocztku utwórz nowy obiekt gry poprzez wybranie opcji menu gównego GameObject/ Create Empty (obiekt gry/stwórz pusty). Spowoduje to pojawienie si nowego elementu w panelu Hierarchy, zwanego GameObject i zawierajcego jedynie komponent Transform. Bdzie on zawiera nasze menu, zarzdzane skryptem z wykorzystaniem klasy GUI. By skrypt móg by uruchamiany, musi mieci si w jakim obiekcie w postaci jego komponentu. Ze wzgldu na zachowanie porzdku sensowne jest wic utworzenie pustego obiektu, przeznaczonego wycznie do tego celu.
326
Rozdzia 9. • Projektowanie menu
Poniewa pooenie elementów GUI bdzie definiowane w skrypcie, odpowiednie wartoci zawarte w komponencie Transform nie s w tym momencie wane, wic nie musimy ich modyfikowa . Po prostu zmie nazw obiektu na Menu2, uywajc standardowej metody. Wybierz folder Scripts (skrypty), znajdujcy si w panelu Project (projekt), a nastpnie kliknij przycisk Create (stwórz) oraz wybierz opcj C# lub Javascript z menu podrcznego. Zmie nazw nowo utworzonego skryptu na MainMenuGUI i dwukrotnie kliknij jego ikon, aby wczyta go do edytora.
Tworzenie zmiennych publicznych Tworzenie skryptu rozpocznij od zadeklarowania szeciu zmiennych publicznych powyej funkcji Update(): Jzyk C#: public public public public public public
AudioClip beep; GUISkin menuSkin; Rect menuArea; Rect playButton; Rect instructionsButton; Rect quitButton;
Jzyk JavaScript: var beep : AudioClip; var menuSkin : GUISkin; var menuArea : Rect;
327
Projektowanie gier w rodowisku Unity 3.x
var playButton : Rect; var instructionsButton : Rect; var quitButton : Rect;
W powyszym kodzie tworzymy tak sam zmienn, przechowujc klip dwikowy, której uywalimy w poprzedniej metodzie. Nastpnie deklarujemy kontener dla kompozycji graficznej, któr zastosujemy dla menu, a oprócz tego cztery zmienne typu Rect, przechowujce informacje o pooeniu i rozmiarach obszaru menu i jego przycisków.
Funkcja OnGUI() Poniej zadeklarowanych zmiennych umie w skrypcie nastpujc funkcj: Jzyk C#: void OnGUI(){ GUI.skin = menuSkin; }
Jzyk JavaScript: function OnGUI(){ GUI.skin = menuSkin; }
W powyszym kodzie tworzymy funkcj OnGUI() oraz inicjalizujemy w niej pierwszy podstawowy skadnik, przypisujc mu zasób kompozycji graficznej, reprezentowany przez zmienn menuSkin. Oznacza to, e dowolne elementy GUI, takie jak przyciski, formatki itd., umieszczone w funkcji OnGUI(), bd podporzdkowane stylowi kompozycji graficznej zdefiniowanemu w tej zmiennej. Dziki temu w prosty sposób mona zmienia same kompozycje, co z kolei powoduje kompletne przeksztacenie stylu graficznego interfejsu uytkownika.
Pooenie elementów GUI Teraz powinnimy zdefiniowa obszar, w którym zostan utworzone przyciski. Dysponujemy ju zmienn menuArea typu Rect, która czeka na wykorzystanie. Dobrym wiczeniem, pozwalajcym na zdobycie wiedzy o definiowaniu pooenia elementów, bdzie umieszczenie obszaru zarówno w okrelonym miejscu ekranu, jak i w jego rodku, co pozwoli obsuy róne rozdzielczoci graficzne.
Wspórzdne pikselowe W pierwszej metodzie definiowania pooenia elementów GUI umiecimy menu w okrelonym miejscu ekranu. Przejd do funkcji OnGUI() i poniej wiersza GUI.skin stwórz obszar dla elementów interfejsu uytkownika poprzez zdefiniowanie nowej grupy GUI: Jzyk C# i JavaScript: GUI.BeginGroup(menuArea);
328
Rozdzia 9. • Projektowanie menu
Funkcja BeginGroup() wymaga podania parametru typu Rect. Do tego celu uylimy zmiennej publicznej menuArea, której wkrótce przypiszemy odpowiednie wartoci pooenia i rozmiarów. Instrukcja tworzenia nowej grupy GUI powinna koczy si odpowiednim poleceniem, zamykajcym t definicj. Nacinij wic kilkakrotnie klawisz przejcia do nowego wiersza (PC: Return, Mac: Enter), aby stworzy woln przestrze, w której umiecimy kod, a nastpnie wprowad ponisz instrukcj: Jzyk C# i JavaScript: GUI.EndGroup();
Ten wiersz powoduje zakoczenie definicji nowej grupy GUI i jednoczenie oznacza, e unikniemy pojawienia si bdów w konsoli rodowiska Unity. Poniewa grupy GUI s waciwie pustymi kontenerami, sucymi do przechowywania elementów graficznego interfejsu uytkownika, renderowanie ich bez przypisania im adnych skadników, takich jak przyciski, suwaki, pola tekstowe itd., bdzie oznacza , e na ekranie nie zobaczymy dosownie nic. Kontynuujmy wic tworzenie naszego skryptu i umie my w nim trzy przyciski, a póniej przetestujmy dziaanie rozwizania. Po wierszu GUI.BeginGroup(), lecz przed EndGroup(), umie poniszy kod, który definiuje trzy przyciski: Jzyk C#: if(GUI.Button(new Rect(playButton), "Play")){ } if(GUI.Button(new Rect(instructionsButton), "Instructions")){ } if(GUI.Button(new Rect(quitButton), "Quit")){ }
Jzyk JavaScript: if(GUI.Button(Rect(playButton), "Play")){ } if(GUI.Button(Rect(instructionsButton), "Instructions")){ } if(GUI.Button(Rect(quitButton), "Quit")){ }
W powyszym kodzie wykorzystujemy funkcj Button klasy GUI, która wymaga podania parametrów typu Rect oraz acucha tekstowego, tekstury lub obiektu typu GUIContent. W naszym przypadku zastosujemy acuchy tekstowe, aby po prostu wywietli odpowiedni tekst na przyciskach. Aby dowiedzie si wicej o funkcji Button, przeczytaj jej dokumentacj: http://unity3d.com/support/documentation/ScriptReference/GUI.Button.html.
329
Projektowanie gier w rodowisku Unity 3.x
Przyciski umieszczamy w instrukcjach if, gdy pozwala nam to odpowiednio reagowa na ich kliknicia. W przeciwnym razie przyciski byyby tylko renderowane. Uywajc zmiennych publicznych typu Rect, moemy w panelu Inspector (inspektor) zdefiniowa rozmiary i pooenie kadego z przycisków. Zanim jednak zapamitamy skrypt i zainicjalizujemy odpowiednie zmienne, sprawmy, aby uycie przycisków spowodowao wykonanie jakiej akcji. Dziki temu bdziemy wiedzie , e operacja ich klikania dziaa poprawnie. W pierwszym rozwizaniu wykorzystalimy funkcj Debug.Log(), która wywietlaa komunikat w konsoli rodowiska Unity. Tym razem jednak zastosujemy co innego, co faktycznie zostanie uyte w samym menu. Jak pamitasz, stworzylimy zmienn, która przechowuje klip audio — spowodujmy wic, by by on odtwarzany po klikniciu przycisku przez gracza. Umie nastpujcy wiersz kodu w kadej instrukcji if: Jzyk C# i JavaScript: audio.PlayOneShot(beep);
Poniewa odtwarzamy klip dwikowy, wykorzystujc do tego komponent Audio Source (std zastosowanie w skrypcie sowa audio), powinnimy si upewni , e bdzie on obecny w obiekcie, któremu przypiszemy nasz skrypt. Aby to zrobi , uyjemy starego znajomego, czyli polecenia RequireComponent(). Jeli nie pamitasz, jak naley to zrobi , skorzystaj z poniszej instrukcji: Jzyk C#: Umie nastpujcy wiersz przed deklaracj klasy: [RequireComponent(typeof(AudioSource))]
Jzyk JavaScript: Na samym kocu skryptu umie poniszy wiersz kodu: @script RequireComponent(AudioSource)
A teraz zapamitaj skrypt i wró do rodowiska Unity. eby umoliwi jego uruchomienie, musimy go doda do pustego obiektu Menu2. Przecignij skrypt MainMenuGUI z panelu Project (projekt) i upu go na obiekcie Menu2 w panelu Hierarchy (hierarchia). Po wybraniu obiektu powiniene zobaczy komponenty Main Menu GUI (Script) oraz Audio Source. Rozwi wszystkie cztery zmienne publiczne typu Rect (Menu Area oraz trzy przyciski), klikajc szar strzak po lewej stronie ich nazw. Skrypty GUI przeprowadzaj rendering tylko wówczas, gdy gra jest uruchomiona. Poniewa zmienna Menu Area, definiujca rozmiary grupy GUI, jest równa 0, musimy j odpowiednio zmodyfikowa , aby zobaczy jakiekolwiek wyniki renderingu. To samo powinnimy zrobi w przypadku pozostaych trzech przycisków. Wprowad odpowiednie wartoci w polach zwizanych z pooeniem i rozmiarami, pamitajc o tym, e moesz uywa klawisza Tab do sprawnego przemieszczania si midzy kolejnymi pozycjami.
330
Rozdzia 9. • Projektowanie menu
Na powyszym rysunku zdefiniowalimy zmienn Menu Area, odpowiadajc grupie GUI, która znajduje si w odlegoci 100 pikseli od lewej krawdzi ekranu oraz 300 pikseli od jego góry. Obszar ma szeroko 200 pikseli i wysoko 150 pikseli. Wynika std, e parametry elementów interfejsu uytkownika s wyznaczane wzgldem lewego górnego naronika ekranu. Taka zaleno jest równie prawdziwa w przypadku przycisków mieszczcych si w grupie GUI. Ich pooenie X i Y odnosi si do lewego górnego naronika samej grupy, a nie ekranu. Dlatego pooenie przycisku Play równe 0,0 oznacza, e znajduje si on w lewym górnym naroniku grupy. Poniewa przycisk Instructions jest umieszczony w odlegoci 50 pikseli od górnej krawdzi grupy, natomiast przycisk Quit w odlegoci 100 pikseli, odstpy midzy nimi wynosz 10 pikseli. Wynika to std, e wysoko przycisków jest równa 40 pikselom. Przed przeprowadzeniem testów zlokalizuj plik menu_beep, znajdujcy si w panelu Project w folderze Book Assets/Sounds (zasoby ksiki/dwiki), a nastpnie przypisz go do zmiennej publicznej Beep, zawartej w komponencie skryptu. Styl naszego menu zostanie zdefiniowany zaraz po przetestowaniu jego dziaania. Zapamitaj scen, wybierajc opcj menu gównego File/Save Scene (plik/zapisz scen), i kliknij przycisk Play, aby j przetestowa . Podczas testowania upewnij si, e w widoku Game (gra) zostaa wybrana opcja Maximize on Play (maksymalizuj podczas gry), a rozdzielczo ekranu jest równa Standalone (1024x768) (aplikacja samodzielna, 1024×768). Powiniene zobaczy menu wywietlone przy uyciu domylnej kompozycji graficznej rodowiska Unity. Upewnij si, e po klikniciu kadego przycisku syszysz dwik klipu audio przypisanego do menu. Jeli tak, wszystko dziaa zgodnie z oczekiwaniami! W razie wystpienia jakiegokolwiek problemu dokadnie sprawd zawarto skryptu i przyjrzyj si informacjom wywietlanym w oknie konsoli.
331
Projektowanie gier w rodowisku Unity 3.x
Zapewne zgadzasz si, e nasze menu nie wyglda zbyt interesujco: tekstury przycisków nie odpowiadaj stylowi naszej gry, a czcionka jest zbyt prosta i maa. Poprawmy je wic przy uyciu waciwej kompozycji graficznej!
Zmiana stylu przycisków przy uyciu kompozycji graficznej Kliknij przycisk Play, aby przerwa testowanie, a nastpnie nacinij przycisk Create (stwórz) w panelu Project i wybierz opcj GUI Skin (kompozycja graficzna) z rozwijanego menu. Zmie nazw nowo utworzonego zasobu na Main Menu, a póniej wybierz go w panelu Project, aby wywietli jego waciwoci w panelu Inspector. Moesz zauway szereg elementów GUI, które moesz utworzy za pomoc kodu klasy GUI, a nastpnie dopasowa ich styl do biecej kompozycji graficznej. Jeli masz jakie dowiadczenie w projektowaniu stron internetowych, potraktuj kompozycj graficzn jako co w rodzaju arkusza stylów. Dopasowanie stylu rozpocznij od przecignicia z panelu Project czcionki gry Sugo (lub tej, której uye) i upuszczenia jej na waciwo Font (czcionka), znajdujc si na samej górze panelu Inspector. Moesz take definiowa róne czcionki dla poszczególnych elementów GUI poprzez ich rozwinicie, a nastpnie zmodyfikowanie odpowiedniej waciwoci Font. W naszej sytuacji bdziemy jednak uywa podstawowej czcionki dla wszystkich skadników GUI, chyba e zostanie podane, by w okrelonym przypadku stosowa inn. A teraz rozwi obszar Button (przycisk), klikajc szar strzak po lewej stronie nazwy, co spowoduje wywietlenie wszystkich waciwoci w panelu Inspector.
332
Rozdzia 9. • Projektowanie menu
Nastpnie rozwi stany Normal (normalny), Hover (aktywowany) i Active (aktywny), poniewa gracz bdzie móg ich uywa w menu. Stan aktywny jest wywietlany, gdy przycisk jest wcinity. Moe on trwa krótko, lecz powinnimy si upewni , e uwzgldniamy go w naszym projekcie.
Uycie tekstur do utworzenia ta przycisków GUI Podczas renderowania przycisku GUI powinnimy uywa kompozycji graficznej, pozwalajcej na modyfikacj jego stylu. W tym celu w folderze Book Assets/Textures (zasoby ksiki/tekstury) udostpnilimy trzy tekstury: guiBtnNormal, guiBtnHover i guiBtnActive. Wybierz kad z nich w panelu Project, a nastpnie przejd do panelu Inspector i zmodyfikuj waciwo Texture Type (rodzaj tekstury) w komponencie Texture Importer, przypisujc jej warto GUI. Póniej kliknij przycisk Apply (zastosuj), znajdujcy si w dolnej czci okna, aby zapamita wprowadzone zmiany. Tekstura przycisku GUI zostaje odpowiednio rozcignita, aby dopasowa si do jego prostoktnych rozmiarów. Nasze ta zostay wic zaprojektowane z zaokrglonymi naronikami — bd one odpowiednio przeskalowane i uzyskaj inn szeroko .
Jeli chcesz zaprojektowa wasne ta przycisków, moesz korzysta z ich docelowych rozmiarów lub zastosowa styl uywanych zasobów, tworzc zaokrglone ksztaty graficzne odpowiadajce rónym szerokociom obiektów. Ponownie wybierz kompozycj graficzn Main Menu w panelu Project, a nastpnie przecignij tekstury guiBtnNormal, guiBtnHover i guiBtnActive odpowiednio na waciwoci Button/Normal/ Background (przycisk/stan normalny/to), Button/Hover/Background (przycisk/stan aktywowany/ to) i Button/Active/Background (przycisk/stan aktywny/to), tak jak zaprezentowano na pierwszym rysunku na nastpnej stronie Wreszcie zmie wartoci Text Color (kolor tekstu), by odpowiaday teksturom ta. Dla stanu normalnego wybierz kolor biay, dla stanu aktywowanego — ciemnoniebieski, a dla aktywnego — odcie czerwieni. A teraz musimy tylko przyporzdkowa kompozycj graficzn do komponentu skryptu GUI. Wybierz obiekt Menu2 w panelu Hierarchy, a nastpnie przecignij kompozycj Main Menu z panelu Project na zmienn publiczn Menu Skin. Zapisz scen i kliknij przycisk Play (patrz drugi rysunek na nastpnej stronie), aby sprawdzi dziaanie menu! (na drugim rysunk na nastpnej stronie).
333
Projektowanie gier w rodowisku Unity 3.x
Wybór rozmiaru czcionki dla przycisków GUI Menu wyglda adnie, lecz tekst wywietlany na przyciskach jest wci zbyt mao widoczny! Zamiast modyfikowa rozmiar samej czcionki, moemy wykorzysta do tego celu kompozycj graficzn, która umoliwia zdefiniowanie tego parametru kontrolek przycisków. Wybierz kompozycj Main Menu w panelu Project, a nastpnie odszukaj waciwo Font Size (rozmiar czcionki) kontrolki Button (przycisk) — powinna si ona znajdowa w dolnej czci listy wszystkich parametrów. Przypisz jej warto 26 i ponownie przetestuj gr. Teraz przyciski wygldaj jeszcze bardziej interesujco! Pamitaj, by sprawdzi dziaanie stanu aktywowania poprzez umieszczenie kursora myszy nad przyciskiem, a nastpnie kliknicie. W wyniku tego powiniene usysze dwik klipu audio menu_beep.
334
Rozdzia 9. • Projektowanie menu
Pooenie niezalene od rozdzielczoci Wszystko dziaa prawidowo, lecz pojawia si kolejny problem: jak zapewni poprawne wywietlanie elementów menu w przypadku innych rozdzielczoci ekranu? Pozostawienie takich samych wartoci X i Y dla obszaru menu oznaczaoby, e gdyby tekstura menu_mainTitle znajdowaa si w pooeniu (0,2, 0,8), zdefiniowanym we wspórzdnych ekranowych, samo menu zostaoby umieszczone w miejscu oddalonym od lewego górnego naronika dokadnie o 100 i 300 pikseli. Nasz gr testowalimy w rozdzielczoci Standalone (1024×768), w której uzyskalimy poprawne pooenie menu.
Jednake w przypadku, gdy gra jest samodzieln aplikacj, gracz bdzie mia moliwo wybrania innej rozdzielczoci, co oznacza, e menu znajdujce si w bezwzgldnym pooeniu (100, 300) pikseli moe nie by zsynchronizowane z elementem tytuu, którego wspórzdne s wzgldne. Na przykad w rozdzielczoci 1680×1050 otrzymamy rezultat jak na poniszym rysunku. Zwró uwag na to, e pooenie ekranowe tekstury tytuu równe 0,2 dla osi X powoduje, i znajduje si ona we waciwym miejscu, dopasowanym do biecego rozmiaru okna. Powinnimy wic zdefiniowa takie wspórzdne menu, by nie pasoway jedynie do rozdzielczoci 1024×768, lecz pozwalay na okrelenie pooenia wzgldnego. Z tego powodu stworzymy dodatkow zmienn prywatn typu Rect, która pozwoli na przypisywanie wartoci w zakresie od 0 do 1 parametrom X i Y, nalecym do publicznej zmiennej Menu Area, dostpnej w panelu Inspector. Dziki temu obszar menu bdzie wywietlany w pooeniu zalenym od biecego rozmiaru ekranu, podobnie jak ma to miejsce przy renderowaniu tytuu typu GUITexture.
335
Projektowanie gier w rodowisku Unity 3.x
Wró do skryptu MainMenuGUI i poniej istniejcych deklaracji, znajdujcych si na samym jego pocztku, umie tak zmienn: Jzyk C#: Rect menuAreaNormalized;
Jzyk JavaScript: private var menuAreaNormalized : Rect;
Powyszy kod powoduje utworzenie zmiennej typu Rect, której moemy uywa podczas definiowania grupy elementów GUI w podanej wczeniej funkcji BeginGroup(). Aby nasza praca nie posza na marne, wczeniej musimy przeksztaci wartoci zawarte w istniejcej zmiennej menuArea, a nastpnie przypisa je zmiennej menuAreaNormalized. T operacj wykonamy w funkcji Start(), dziki czemu zostanie ona przeprowadzona podczas wczytywania sceny. Wykrywanie rozdzielczoci ekranu i przypisywanie grupie GUI odpowiedniego pooenia powinno by realizowane wanie w tym miejscu, a nie w funkcji OnGUI(), poniewa jest to operacja jednorazowa. Umie funkcj Start() nad istniejc funkcj OnGUI(): Jzyk C#: void Start(){ }
Jzyk JavaScript: function Start(){ }
336
Rozdzia 9. • Projektowanie menu
Teraz dodamy wiersz kodu, który przeksztaci pooenie w osi X i Y dla zmiennej menuArea typu Rect na wartoci znormalizowane. Wektor znormalizowany charakteryzuje si kierunkiem oraz dugoci, odpowiednio przeskalowan do wartoci 1. Jest on przydatny na przykad do przypisywania prdkociom parametrów pocztkowych, gdy moe przechowywa kierunek, a jego warto moe by atwo mnoona. W naszym przypadku okrelamy pooenie GUI jako znormalizowane, poniewa przeksztacamy wartoci osi X i Y w taki sposób, by zawieray si one w panelu Inspector w zakresie od 0 do 1. Umie poniszy kod w funkcji Start(): Jzyk C#: menuAreaNormalized = new Rect(menuArea.x * Screen.width ´(menuArea.width * 0.5f), menuArea.y * Screen.height ´(menuArea.height * 0.5f), menuArea.width, menuArea.height);
Jzyk JavaScript: menuAreaNormalized = Rect(menuArea.x * Screen.width ´(menuArea.width * 0.5), menuArea.y * Screen.height ´(menuArea.height * 0.5), menuArea.width, menuArea.height);
Powyszy wiersz kodu na pierwszy rzut oka wyglda do skomplikowanie, dlatego postaramy si przeanalizowa jego skadniki. Poniewa przeprowadzamy te same obliczenia dla obu osi X i Y, przyjrzyjmy si po prostu, w jaki sposób przypisujemy pooenie X zmiennej typu Rect. Wyobramy sobie, e waciwoci X parametru Menu Area przypisujemy w panelu Inspector warto 0,2. Nastpnie mnoymy j przez Screen.width: menuArea.x * Screen.width
Parametr Screen.width jest równy szerokoci ekranu wyraonej w pikselach, dlatego gdy go pomnoymy przez 0,2, otrzymamy to samo pooenie co w przypadku wprowadzenia wartoci 0,2 dla osi X w komponencie Transform, nalecym do obiektu menu_mainTitle typu GUITexture. Mnoc biec rozdzielczo (1024 piksele) przez 0,2, uzyskujemy wynik 204,8 piksela. Caa operacja, zmierzajca do odtworzenia poprzedniej metody, nie jest jednak jeszcze kompletna, gdy wczeniej pooenie w osi X byo oddalone o 100 pikseli od lewej krawdzi ekranu. Dzieje si tak, poniewa musimy wzi pod uwag fakt, e obiekt GUITexture podczas umieszczania go na ekranie jest renderowany z jego rodka, przy uwzgldnieniu wartoci parametru Pixel Inset X (wstawka pikselowa X) minus poowa szerokoci tekstury. Na przykad jeli pomnoylibymy pooenie przez 0,5 i spróbowalibymy umieci grup GUI w rodku ekranu, uzyskalibymy taki wynik:
337
Projektowanie gier w rodowisku Unity 3.x
Na powyszym przykadzie grupa GUI zostaa co prawda umieszczona w poowie szerokoci ekranu, lecz znajduje si po jego prawej stronie, poniewa jest renderowana od jej lewej krawdzi. Ten problem zosta skorygowany poprzez odjcie w równaniu poowy szerokoci grupy.
Mimo e nie tworzymy menu, które ma si znajdowa w centrum ekranu, równie powinnimy odj poow szerokoci zdefiniowanej w zmiennej menuArea, czyli wykona operacj menuArea. ´width*0.5. Mnoymy przez 0,5, poniewa ta czynno jest mniej wymagajca dla procesora ni dzielenie przez 2. Dlatego te uzyskujemy nastpujce równanie: menuArea.x * Screen.width – (menuArea.width * 0.5)
Dziki temu otrzymujemy warto 103,8 dla osi X w zmiennej menuAreaNormalized typu Rect. Chocia nie uzyskalimy dokadnej wartoci 100 pikseli, której uywalimy wczeniej, rendering przebiega praktycznie tak samo, a nasze rozwizanie pozwala dodatkowo na odpowiednie przeskalowanie w przypadku innych rozdzielczoci ekranu, co byo naszym gównym celem. Podobn operacj wykonujemy dla pooenia w osi Y: menuArea.y * Screen.height - (menuArea.height * 0.5)
Zamieniamy Screen.width na Screen.height i odejmujemy poow wartoci menuArea.height. W celu uzupenienia ostatnich dwóch waciwoci typu Rect w zmiennej menuAreaNormalized po prostu kopiujemy do nich wartoci rozmiarów menuArea.width i menuArea.height. Aby uy nowo utworzonej zmiennej, odszukaj nastpujcy wiersz w funkcji OnGUI(): GUI.BeginGroup (menuArea);
338
Rozdzia 9. • Projektowanie menu
Zamie go na ponisze wyraenie: Jzyk C# i JavaScript: GUI.BeginGroup (menuAreaNormalized);
Oznacza to, e grupa GUI bdzie renderowana przy uyciu znormalizowanych równowaników wartoci zmiennej publicznej Menu Area typu Rect. Zapisz skrypt i wró do rodowiska Unity. Nastpnie wybierz obiekt Menu2, aby wywietli jego komponent Main Menu GUI (Script). Nie wida adnych zmian, poniewa zmienna, któr wanie dodalimy, jest prywatna i wykonuje swoje zadanie, dziaajc w tle. Jednake wiedzc, e znormalizowany typ Rect jest oparty na wartociach zmiennej Menu Area z panelu Inspector, musimy je poprawi , aby uzyska zakres od 0 do 1. Przypisz wic parametrowi X warto 0,2, a Y — warto 0,45, po czym kliknij przycisk Play, aby przetestowa dziaanie menu. Powinno ono zosta wywietlone tak jak na pierwotnym rysunku, prezentujcym rozdzielczo 1024×768 pikseli. Nasz kod pozwala ju na skalowanie pooenia menu dla rónych rozdzielczoci graficznych. Wró my zatem do samego menu i zaimplementujmy jego faktyczn funkcjonalno . Zapisz scen w rodowisku Unity, a nastpnie wró do edycji skryptu MainMenuGUI.
Skryptowa obsuga akcji zwizanych z przyciskami W naszej pierwszej metodzie uylimy skryptu, który móg by stosowany z kadym przyciskiem. Z tego powodu korzystalimy ze zmiennej publicznej typu acuchowego, zawierajcej nazw sceny, która powinna zosta wczytana. Poniewa uywalimy do tego rónych polece if dla kadego z przycisków, teraz stworzymy wasn funkcj, która bdzie odtwarza dwik kliknicia, zatrzymywa si na chwil, a nastpnie wykonywa dziaanie, czyli wczytywa scen lub koczy gr. Po zamykajcym nawiasie klamrowym funkcji OnGUI() umie nastpujc funkcj: Jzyk C#: IEnumerator ButtonAction(string levelName){ audio.PlayOneShot(beep); yield return new WaitForSeconds(0.35f); if(levelName != "quit"){ Application.LoadLevel(levelName); }else{ Application.Quit(); Debug.Log("Have Quit"); } }
339
Projektowanie gier w rodowisku Unity 3.x
Jzyk JavaScript: function ButtonAction(levelName : String){ audio.PlayOneShot(beep); yield new WaitForSeconds(0.35); if(levelName != "quit"){ Application.LoadLevel(levelName); }else{ Application.Quit(); Debug.Log("Have Quit"); } }
Zwró uwag na to, e w jzyku C# uylimy typu zwrotnego IEnumerator, aby wskaza , e definiujemy wspóprogram, a nie zwyk funkcj, poniewa wykorzystujemy w nim polecenie yield, które pozwala na uzyskanie przerwy w dziaaniu procedury, tak jak widzielimy to ju w naszym pierwszym rozwizaniu. Funkcja uywa pojedynczego argumentu levelName o typie acucha znakowego. Dziki niemu moemy przekaza informacj odczytan z panelu Project, która scena powinna zosta wczytana. W celu uycia przycisku Quit (wyjcie) sprawdzamy wystpienie sowa „quit”, by wykona polecenie Quit(). Na pocztku funkcji odtwarzamy klip dwikowy zwizany z klikniciem elementu menu, a nastpnie wstrzymujemy dziaanie procedury na 0,35 sekundy. W tym czasie bdzie odtwarzany plik audio. Kontynuujemy dziaanie funkcji, sprawdzajc, czy naley wczyta scen przy uyciu polecenia Application.LoadLevel(). Wykonujemy je tylko wówczas, gdy argument levelName przekazany do funkcji nie jest równy acuchowi tekstowemu quit. W przeciwnym razie (czyli gdy levelName jest równy quit) nastpuje wywoanie polecenia Application.Quit() i zakoczenie dziaania gry. Poniewa polecenie Application.Quit() nie wpywa na funkcjonowanie rodowiska Unity, uylimy instrukcji Debug.Log("Have Quit");, umieszczonej zaraz po nim. Dziki temu moemy si upewni , e dany fragment skryptu dziaa prawidowo. Oszczdza nam to wysiku zwizanego z kompilacj gry do postaci samodzielnej aplikacji, by przetestowa dziaanie instrukcji else zawierajcej obsug przycisku Quit. A teraz wywoajmy nasz funkcj wewntrz polece if w funkcji OnGUI(). Umie kursor w instrukcji if dla przycisku Play, a nastpnie usu istniejcy wiersz audio.PlayOneShot(beep);, poniewa nowo utworzona funkcja obsuguje ju t opcj. W miejscu usunitego wiersza wprowad odpowiedni instrukcj. Jzyk C#: Poniewa w jzyku C# uylimy wspóprogramu, musimy zastosowa polecenie StartCoroutine(): StartCoroutine("ButtonAction", "Island");
340
Rozdzia 9. • Projektowanie menu
W powyszym wierszu kodu nazw funkcji, któr naley wywoa , podajemy w postaci acucha tekstowego. Nastpnie znajduje si przecinek, a po nim argument tej funkcji przekazany równie jako acuch tekstowy. W podobny sposób w poleceniu SendMessage() wywoywalimy funkcj z argumentem, gdy wywietlalimy wskazówk na ekranie przy uyciu skryptu TriggerZone. Jzyk JavaScript: ButtonAction("Island");
Po prostu wywoujemy nasz funkcj ButtonAction(), a wewntrz niej przekazujemy acuch tekstowy Island do jej argumentu levelName. Zostanie on rozpoznany jako rónicy si od sowa quit i przez to spowoduje wczytanie sceny Island. Na razie pominiemy obsug przycisku Instructions (instrukcje), a odpowiedni kod stworzymy w nastpnym punkcie. Teraz umie kursor wewntrz instrukcji if obsugujcej klawisz Quit, usu wiersz audio.PlayOneShot(beep); i dodaj poniszy: Jzyk C#: StartCoroutine("ButtonAction", "quit");
Jzyk JavaScript: ButtonAction("quit");
Jak zapewne zgadujesz, powyszy kod jeszcze raz wywouje nasz funkcj ButtonAction(), lecz tym razem przekazujc sowo quit do jej argumentu levelName, który jest nastpnie wykrywany w instrukcji if i powoduje wykonanie polecenia Application.Quit() koczcego dziaanie gry. Zapamitaj skrypt i wró do rodowiska Unity. Kliknij przycisk Play, aby przetestowa dziaanie gry. Nacinij przycisk Quit w menu, by sprawdzi , czy polecenie Debug.Log() spowoduje wywietlenie komunikatu Have Quit (nacinito klawisz wyjcia z gry) w konsoli (patrz dolny wiersz interfejsu Unity). Nastpnie kliknij przycisk Play w menu. W wyniku tego powinno nastpi odtworzenie klipu dwikowego oraz wczytanie sceny Island. Peen sukces! Aby sprawdzi , czy zawarto Twojego skryptu jest poprawna, porównaj go z poniszym listingiem: Jzyk C#: using UnityEngine; using System.Collections; [RequireComponent(typeof(AudioSource))] public class MainMenuGUI : MonoBehaviour { public AudioClip beep; public GUISkin menuSkin;
341
Projektowanie gier w rodowisku Unity 3.x
public public public public
Rect Rect Rect Rect
menuArea; playButton; instructionsButton; quitButton;
Rect menuAreaNormalized; void Start(){ menuAreaNormalized = new Rect(menuArea.x * Screen.width ´(menuArea.width * 0.5f), menuArea.y * Screen.height ´(menuArea.height * 0.5f), menuArea.width, menuArea.height); } void OnGUI(){ GUI.skin = menuSkin; GUI.BeginGroup (menuAreaNormalized); if(GUI.Button(new Rect(playButton), "Play")){ StartCoroutine("ButtonAction", "Island"); } if(GUI.Button(new Rect(instructionsButton), "Instructions")){ audio.PlayOneShot(beep); } if(GUI.Button(new Rect(quitButton), "Quit")){ StartCoroutine("ButtonAction", "quit"); } GUI.EndGroup(); } IEnumerator ButtonAction(string levelName){ audio.PlayOneShot(beep); yield return new WaitForSeconds(0.35f); if(levelName != "quit"){ Application.LoadLevel(levelName); }else{ Application.Quit(); Debug.Log("Have Quit"); } } }
Jzyk JavaScript: var beep : AudioClip; var menuSkin : GUISkin; var menuArea : Rect; private var menuAreaNormalized : Rect; var playButton : Rect; var instructionsButton : Rect;
342
Rozdzia 9. • Projektowanie menu
var quitButton :
Rect;
function Start(){ menuAreaNormalized = Rect(menuArea.x * Screen.width ´(menuArea.width * 0.5f), menuArea.y * Screen.height ´(menuArea.height * 0.5f), menuArea.width, menuArea.height); } function OnGUI(){ GUI.skin = menuSkin; GUI.BeginGroup (menuAreaNormalized); if(GUI.Button(Rect(playButton), "Play")){ ButtonAction("Island"); } if(GUI.Button(Rect(instructionsButton), "Instructions")){ audio.PlayOneShot(beep); } if(GUI.Button(Rect(quitButton), "Quit")){ ButtonAction("quit"); } GUI.EndGroup(); } function ButtonAction(levelName : String){ audio.PlayOneShot(beep); yield new WaitForSeconds(0.35f); if(levelName != "quit"){ Application.LoadLevel(levelName); }else{ Application.Quit(); Debug.Log("Have Quit"); } }
Dokoczmy tworzenie naszego menu poprzez umieszczenie strony zawierajcej instrukcje dla gracza.
Tworzenie strony z instrukcjami Zamiast stosowa wiele skryptów, które s wczane i wyczane, do skoczenia naszego menu wykorzystamy pojedynczy skrypt GUI, pozwalajcy na dynamiczn zmian renderowanego elementu grafiki. Nasza strona Instructions (instrukcje) powinna odzwierciedla styl pozostaych skadników menu, dlatego odpowiednio zmodyfikujemy skrypt GUI w scenie Menu. Dziki temu to graficzne okna bdzie pozostawa niezmienione podczas nawigowania po menu.
343
Projektowanie gier w rodowisku Unity 3.x
Tworzenie stron menu Upewnij si, e skrypt MainMenuGUI jest wci otwarty. Jeli nie, wczytaj go do edytora poprzez dwukrotne kliknicie jego ikony w folderze Scripts panelu Project. Kod skryptu obsuguje przycisk Instructions, generujc dwik kliknicia, co upewnia nas, e dziaa prawidowo. Uyjemy tego przycisku, by przecza widok midzy tym, co nazywamy gówn stron menu (czyli istniejcym ekranem, prezentujcym przyciski Play, Instructions i Quit), a now stron, która informuje gracza o celu gry oraz zawiera przycisk Back (powrót), pozwalajcy na powrót do gównego menu. Aby to osign , stworzymy zmienn menuPage typu acuchowego, która bdzie przechowywa biec stron menu. Nastpnie w kodzie GUI umiecimy dodatkow struktur if else, która bdzie sprawdza stan tej zmiennej i na tej podstawie renderowa róne przyciski lub elementy interfejsu uytkownika. Uywamy typu acuchowego, by zapewni przejrzysto , lecz nasze zadanie mogoby take zosta rozwizane dziki wykorzystaniu zmiennej cakowitej, na przykad jeli przypiszemy warto 0 do gównego menu, a 1 do strony z instrukcjami. Rozpocznijmy od zadeklarowania nowej zmiennej prywatnej typu string, której uyjemy do okrelenia, na jakiej stronie si znajdujemy, a co za tym idzie — jakie elementy graficzne maj by renderowane w naszym menu. Zostanie to zrealizowane poprzez przypisywanie do tej zmiennej rónych acuchów tekstowych. Poniej deklaracji menuAreaNormalized umie nastpujc zmienn prywatn: Jzyk C#: string menuPage = "main";
Jzyk JavaScript: private var menuPage : String = "main";
Nastpnie odszukaj istniejc grup instrukcji if: Jzyk C#: if(GUI.Button(new Rect(playButton), "Play")){ StartCoroutine("ButtonAction", "Island"); } if(GUI.Button(new Rect(instructionsButton), "Instructions")){ audio.PlayOneShot(beep); } if(GUI.Button(new Rect(quitButton), "Quit")){ StartCoroutine("ButtonAction", "quit"); }
Jzyk JavaScript: if(GUI.Button(Rect(playButton), "Play")){ ButtonAction("Island");
344
Rozdzia 9. • Projektowanie menu
} if(GUI.Button(Rect(instructionsButton), "Instructions")){ audio.PlayOneShot(beep); } if(GUI.Button(Rect(quitButton), "Quit")){ ButtonAction("quit"); }
Powyej tych instrukcji stwórz pusty wiersz, a nastpnie umie w nim pocztek nowego polecenia if: Jzyk C# i JavaScript: if(menuPage == "main"){
W dalszej kolejnoci zamknij t instrukcj za pomoc nawiasu klamrowego }, który umie za trzema istniejcymi poleceniami if, upewniajc si, e znajd si wewntrz niej. Napisany kod sprawdzi, czy warto zmiennej menuPage jest równa domylnej wartoci main, co spowoduje, e po zaadowaniu sceny zostan wywietlone trzy przyciski tworzce nasze menu. Aby poprawi czytelno kodu, powiniene uy klawisza Tab do wykonania odpowiednich wci w tekcie. W edytorze MonoDevelop moe to zosta osignite za pomoc prostego zaznaczenia fragmentu kodu, który powinien zosta przesunity w prawo, a nastpnie nacinicia klawisza Tab na klawiaturze. Zgodnie z poniszym rysunkiem zaznacz wic trzy instrukcje if, które tworz nasze menu, i nacinij klawisz Tab, co spowoduje powstanie nowego wcicia poniej nowo dodanego nadrzdnego polecenia if (na rysunku zaprezentowano widok dla jzyka C#): Dziki temu moesz od razu zauway , e trzy instrukcje if znajduj si wewntrz polecenia if (menuPage == "main"){. Nastpnie przesu o jeden wiersz w dó wywoanie funkcji audio.PlayOneShot(beep);, znajdujce si w instrukcji if (drugiej z trzech) obsugujcej klawisz Instructions. W otrzymanym pustym wierszu umie polecenie, które pozwoli nam na przejcie do strony z instrukcjami: Jzyk C# i JavaScript: menuPage="instructions";
Powyszy kod powoduje zaniechanie renderowania naszej gównej strony menu, dlatego musimy go uzupeni o kolejn instrukcj else if, pozwalajc na obsug zmiennej menuPage równej sowu instructions. Umie kursor za zamykajcym nawiasem klamrowym nadrzdnego polecenia if, które sprawdza, czy zmienna menuPage jest równa main, a nastpnie wprowad poniszy kod: Jzyk C#: else if(menuPage == "instructions"){ GUI.Label(new Rect(instructions), "You awake on a mysterious island... ´Find a way to signal for help or face certain doom!");
345
Projektowanie gier w rodowisku Unity 3.x
if(GUI.Button(new Rect(quitButton), "Back")){ audio.PlayOneShot(beep); menuPage="main"; } }
Jzyk JavaScript: else if(menuPage == "instructions"){ GUI.Label(Rect(instructions), "You awake on a mysterious island... ´Find a way to signal for help or face certain doom!"); if(GUI.Button(Rect(quitButton), "Back")){ audio.PlayOneShot(beep); menuPage="main"; } }
W powyszym kodzie sprawdzamy, czy zmienna menuPage jest równa sowu instructions. Gdy uytkownik kliknie przycisk Instructions, zmiennej zostanie przypisana ta warto , co spowoduje, e GUI wywietli elementy, które znajduj si wewntrz nowo dodanej instrukcji if. Jak moesz zauway , utworzylimy nowy element GUI — Label, który wykorzystuje niezadeklarowan jeszcze zmienn typu Rect zwan instructions, okrelajc obszar zajmowany na ekranie. Dodajmy j teraz, dziki czemu bdziemy mogli j wkrótce zdefiniowa w panelu Inspector. Poniej istniejcych zmiennych publicznych typu Rect umie wiersz kodu:
346
Rozdzia 9. • Projektowanie menu
Jzyk C#: public Rect instructions;
Jzyk JavaScript: var instructions : Rect;
Element Label jest etykiet tekstow i zawiera tekst, w prosty sposób wyjaniajcy graczowi, co powinien zrobi , by wygra gr. W kolejnym wierszu wystpuje instrukcja if, w której tworzymy kolejny przycisk, wykorzystujc wielko obszaru zapamitan w zmiennej quitButton. Dziki temu uzyskamy kontrolk, której rozmiar i pooenie bd takie same jak w przypadku przycisku Quit. Oznacza to, e gdy uytkownik wybierze ten element menu, przycisk Quit zostanie natychmiast podmieniony przez przycisk Back. Instrukcja if, obsugujca przycisk Back, zawiera dwa polecenia: przypisuje zmiennej menuPage pocztkow warto main, co powoduje, e kod GUI bdzie wywietla gówn stron menu, a take odtwarza klip audio beep, podobnie jak ma to miejsce w przypadku innych przycisków. Wypróbujmy dziaanie naszego menu. Zapamitaj skrypt i wró do rodowiska Unity. Wybierz obiekt Menu2 w panelu Hierarchy, aby wywietli komponent Main Menu GUI (Script) w panelu Inspector. Moesz zauway , e pojawia si w nim nowa zmienna publiczna Instructions typu Rect. Poniewa powinna ona zosta zainicjalizowana, kliknij szar strzak przy jej nazwie, aby rozwin waciwoci, a nastpnie wprowad odpowiednie wartoci: pozostaw parametry X i Y równe 0, natomiast w polu Width (szeroko ) podaj 200, a w Height (wysoko ) — 150. Kliknij przycisk Play, a nastpnie Instructions w menu gry. Zostanie wywietlona nowa strona, lecz jednoczenie pojawi si problem — domylnie tekst etykiety jest wywietlany w kolorze jasnoszarym, przez co nie wyglda zbyt wyranie na tle chmur! Moemy to jednak szybko naprawi poprzez przypisanie naszego istniejcego stylu do kontrolki etykiety. Upewnij si, e zakoczye tryb testowania, a nastpnie wybierz zasób kompozycji graficznej Main Menu, znajdujcy si w panelu Project. Moesz go od razu znale , klikajc jego nazw przy zmiennej Menu Skin w komponencie Main Menu GUI (Script). rodowisko Unity podwietli pozycj zasobu w panelu Project, dziki czemu bdziesz go móg atwo wybra .
Formatowanie etykiety GUI za pomoc zasobu kompozycji graficznej Rozwi ustawienia parametru Label (etykieta), a od razu zobaczysz, czym jest spowodowany nasz problem: stan Normal (normalny) tego elementu graficznego zawiera waciwo Text Color (kolor tekstu), która zostaa zdefiniowana na kolor jasnoszary. Kliknij obszar koloru w celu wywoania okna wyboru koloru, a nastpnie wybierz w nim ciemnoszary odcie barwy.
347
Projektowanie gier w rodowisku Unity 3.x
Oprócz tego zdefiniuj inne waciwoci stylu Label: Q Font (czcionka) — przecignij wybran przez Ciebie czcionk i upu na to ustawienie. Q Alignment (wyrównanie) — wybierz opcj Upper Center (w rodku, na górze),
aby wywietli tekst wyrównany centralnie na górze obszaru zdefiniowanego przez typ Rect. Q Font Size (rozmiar czcionki) — wprowad warto 21.
Zapisz swoj scen menu w rodowisku Unity, by zapamita stan projektu. Poniewa nasza kompozycja graficzna GUI zostaa ju przypisana, nie musimy wykonywa innych czynnoci — po prostu kliknij przycisk Play i sprawd dziaanie nowego fragmentu menu. Twój ekran z instrukcjami powinien wyglda tak jak na poniszym rysunku. Jeli nie, wró do edycji parametrów kompozycji graficznej GUI i upewnij si, e prawidowo wprowadzie wszystkie parametry, które przed chwil omawialimy.
Gratulacje! Twoje menu jest gotowe. Powiniene mie teraz moliwo przeczania si midzy stron gówn i stron z instrukcjami. Poniewa zdefiniowalimy zmienn, która okrela biecy element menu, moesz równie dodawa inne jego elementy. Kod modyfikujcy dziaanie jakiego skadnika staraj si zawsze tworzy w sposób, który pozwoli na jego rozbudow w przyszoci.
348
Rozdzia 9. • Projektowanie menu
Uwaga zwizana z optymalizacj procesu wczytywania Poniewa zdefiniowalimy nasze menu w postaci oddzielnej sceny, moesz si dziwi , dlaczego wybralimy takie rozwizanie, a nie wykorzystalimy istniejcej sceny Island. Taki sposób pozwala na zoptymalizowanie czasu wczytywania naszej gry. Poprzez stworzenie mniej zoonej sceny, która jest adowana na samym pocztku, skutecznie powstrzymujemy gracza od wczytania gównej sceny Island. W przypadku, gdy gra zostaje umieszczona w rodowisku przegldarki sieciowej, taka operacja trwa do dugo, dlatego moe by ona wykonywana „w tle”, kiedy scena menu jest ju dostpna dziki zastosowaniu strumieniowania odtwarzacza sieciowego. Obsug tej technologii omówimy w rozdziale 12. Wczytywanie i strumieniowanie gównej czci gry podczas wywietlania mniej zoonej sceny jest czsto spotykanym rozwizaniem i umoliwia graczowi wykonywanie pewnych czynnoci (na przykad przeczytanie instrukcji). Wicej o strumieniowaniu za pomoc odtwarzacza sieciowego moesz si dowiedzie z dokumentacji uytkownika: http://unity3d.com/support/documentation/Manual/Publishing%20Builds.html.
Podsumowanie W tym rozdziale zapoznalimy si z dwoma gównymi metodami tworzenia elementów interfejsu uytkownika w rodowisku Unity: wykorzystalimy obiekty GUITexture i zastosowalimy skrypty GUI. Teraz posiadasz wystarczajc wiedz, by tworzy interfejsy przy uyciu obu opisanych sposobów. Mimo e skrypty GUI umoliwiaj rozwizywanie wielu rónych zagadnie, metody budowania skadników interfejsu s bardzo wane, poniewa bdziesz je zawsze wykorzystywa podczas tworzenia kodu GUI. Przyjrzelimy si take sposobowi pozwalajcemu za pomoc skryptu GUI decydowa , jakie skadniki interfejsu powinny by renderowane. Jest to bardzo znaczcy element tworzenia obsugi menu w grach napisanych w rodowisku Unity. W nastpnym rozdziale, dotyczcym podstaw animacji, ukoczymy nasz gr, zamieszczajc w niej kilka komunikatów gratulujcych graczowi jej wygrania po rozpaleniu przez niego ogniska, które pozwoli na wysanie sygnaów o pomoc.
349
Projektowanie gier w rodowisku Unity 3.x
350
10 Podstawy animacji W tym rozdziale ulepszymy gr poprzez dodanie do niej animowanej sekwencji, zwizanej z wygraniem gry. Gdy gracz ukoczy wszystkie zadania, które s niezbdne do wygrania gry, zaprezentujemy mu sekwencj gratulacyjnych komunikatów. W bardziej zoonej grze byby to na przykad krótki film, prezentujcy kolejn cz gry. Poniewa jednak jestemy na etapie uczenia si, poznamy podstawy animacji: wykorzystamy w tym celu skrypty z interpolacj liniow oraz narzdzie animacyjne, dostpne w rodowisku Unity. W tym rozdziale poznasz nastpujce zagadnienia: Q przyciemnianie ekranu przy uyciu obiektów GUITexture i skryptów, Q realizacja przej midzy wartociami przy uyciu interpolacji liniowej, Q animacja z zastosowaniem krzywych w narzdziu animacyjnym, Q tworzenie warstw obiektów dwuwymiarowych.
Sekwencja animacji po wygraniu gry Postaramy si stworzy sekwencj elementów GUI, która zostanie wywoana, gdy gracz wygra gr. Ta sekwencja bdzie si skada z trzech etapów. Po pierwsze na ekranie pojawi si animowany tekst, informujcy gracza, e rozpalenie ogniska spowodowao wygranie przez niego gry. Informacje bd animowane za pomoc techniki skryptowej zwanej interpolacj liniow, czyli metody zmiany w okrelonym czasie jednej wartoci na drug. Interpolacja liniowa jest przydatna w wielu zadaniach skryptowych, dlatego naley si jej nauczy .
Projektowanie gier w rodowisku Unity 3.x
Po zaprogramowaniu animacji za pomoc kodu zapoznamy si z oknem Animation (animacja) rodowiska Unity. Dowiemy si, w jaki sposób moemy go uy do wizualnego projektowania animacji obiektów. Korzystajc z okna Animation, stworzymy drug cz sekwencji animacji, w której ekran bdzie powoli przyciemniany, a nastpnie pojawi si na nim animowany tekst, przed wywietleniem gównego menu informujcy gracza, e gra jest wczytywana (patrz poniszy rysunek). Wygaszanie ekranu i tekst informujcy o wczytywaniu gry dodamy za pomoc obiektów GUI ´Texture. Stworzymy skrypt, który dopasuje obszar wygaszania do biecej rozdzielczoci ekranu. Nastpnie uyjemy okna Animation, aby zaprojektowa animacje dla metody wygaszania. Zmiana poziomu przezroczystoci (lub wartoci kanau alfa) spowoduje powstanie efektu przyciemniania ekranu. W przypadku tekstu informujcego o wczytywaniu gry postaramy si zmodyfikowa jego pooenie, dziki czemu bdzie si on przemieszcza z dou ekranu.
Metoda tworzenia sekwencji animacji W jaki jednak sposób utworzymy w scenie wspomniane wyej elementy? Zanim rozpoczniemy dziaania, przyjrzyjmy si wybranej metodzie: Q Posta gracza (First Person Controller), gdy ma pudeko zapaek, zderza si
z obiektem ogniska. Q Skrypt Inventory, przypisany do postaci gracza, wysya komunikat do obiektu obsugujcego sekwencj zwycistwa w celu wywoania funkcji GameOver().
352
Rozdzia 10. • Podstawy animacji
Q Funkcja GameOver() jest wspóprogramem, który rozpoczyna si od konkretyzacji prefabrykatu WinSequence zawierajcego trzy napisy, animowane przy uyciu interpolacji liniowej. Napisy te s obiektami GUITexture i informuj gracza
o wygraniu gry. Q Wspóprogram GameOver() wykorzystuje polecenie yield w celu uzyskania
omiosekundowej przerwy, pozwalajcej graczowi na odczytanie tekstu. Q Wspóprogram GameOver() konkretyzuje prefabrykat fade w postaci czarnego obiektu GUITexture. Q Obiekt fade jest przyczony do skryptu Fader, który przeskalowuje go na cay ekran. Komponent Animation realizuje animacj, która pynnie przyciemnia
elementy obrazu. Q Podczas przyciemniania ekranu zdarzenie animacyjne wywouje funkcj w skrypcie Fader, co powoduje utworzenie kocowego elementu, wczytujcego skadniki GUI. Jest to kolejny obiekt GUITexture, zawierajcy tre „Loading”, który pojawia si u dou ekranu, przemieszcza w gór, a wreszcie znów znika na dole. Q Animacja wczytywania elementów GUI koczy si zdarzeniem animacyjnym, które wywouje funkcj Reload(), znajdujc si w przyczonym skrypcie Reloader. Funkcja ta wykorzystuje polecenie Application.LoadLevel() do wczytania sceny Menu.
Poniewa znamy ju kolejno wykonywanych operacji, moemy rozpocz tworzenie kocowej sekwencji i poznawanie zasad dziaania animacji. Upewnij si, e nie uywasz ju sceny Menu — wczytaj scen Island poprzez dwukrotne kliknicie jej ikony w panelu Project (projekt).
353
Projektowanie gier w rodowisku Unity 3.x
Uruchamianie sekwencji wygrania gry W skrypcie Inventory zdefiniowalimy ju warunek zwycistwa — jest nim funkcja LightFire(). Zawiera ona warunek umoliwiajcy wygranie gry, dlatego sensowne jest, abymy uyli jej jako miejsca, w którym poinformujemy gracza o zwycistwie. Odszukaj i wczytaj do edytora skrypt Inventory, znajdujcy si w folderze Scripts (skrypty) panelu Project. Musimy umieci w nim referencj do obiektu, który bdzie obsugiwa tworzenie sekwencji wygrania gry. Umie nastpujc zmienn publiczn poniej deklaracji istniejcych zmiennych, znajdujcych si na pocztku skryptu: Jzyk C#: public GameObject winObj;
Jzyk JavaScript: var winObj : GameObject;
Teraz uyjmy referencji winObj, wywoujc z niej polecenie SendMessage(), które z kolei wykona funkcj zawart w zewntrznym obiekcie gry. Gdy gracz rozpali ognisko, powinna si rozpocz sekwencja wygrania gry, dlatego z poziomu obiektu winObj wywoamy odpowiedni funkcj. Umie poniszy kod w dolnej czci funkcji LightFire(), zaraz za wierszem fireIsLit=true;: Jzyk C# i JavaScript: winObj.SendMessage("GameOver");
To polecenie wysya do obiektu komunikat, który zostanie wkrótce przez nas utworzony. Z tego obiektu zostaje wywoana funkcja GameOver(), zawarta w doczonym do niego skrypcie. Zwró uwag na to, e podawanie nazwy skryptu nie jest konieczne. Wynika to std, i polecenie SendMessage() przeszukuje wywoujcy j obiekt bez wzgldu na skrypt, który zawiera interesujc nas funkcj. Po zdefiniowaniu animowanych elementów GUI utworzymy obiekt obsugujcy sekwencj zwycistwa, a nastpnie napiszemy skrypt z funkcj GameOver(), który do niego przypiszemy. Teraz zapamitaj skrypt Inventory i wró do rodowiska Unity.
Tworzenie komunikatów informujcych o wygraniu gry W folderze Book Assets/Textures (zasoby ksiki/tekstury) w panelu Project znajduj si trzy tekstury o nazwach zaczynajcych si od win:
354
Rozdzia 10. • Podstawy animacji
Q win_message, Q win_survival, Q win_youWin.
Zostay one zaprojektowane do uycia jako obiekty GUITexture, które bd animowane na ekranie. Po kolei wybierz kad z tych tekstur, a nastpnie w komponencie Texture Importer, znajdujcym si w panelu Inspector (inspektor), przypisz parametrowi Texture Type (rodzaj tekstury) warto GUI, pamitajc, by klikn przycisk Apply (zastosuj) w celu zapamitania wprowadzonych zmian.
Definiowanie pooenia elementów sekwencji wygrania gry Nastpnie wybierz tekstur win_message oraz kliknij przycisk Create (stwórz) w panelu Hierarchy. W wywietlonym menu podrcznym przejd do opcji GUITexture. Powtórz powysze kroki dla tekstur win_survival i win_youWin. Domylnie tekstury znajduj si w pooeniu (0,5, 0,5, 0), które oznacza rodek ekranu. Odpowiednio zmie parametry komponentu Transform, aby oddzieli je od siebie: Q win_message — (0,5, 0,4, 0), Q win_survival — (0,5, 0,8, 0), Q win_youWin — (0,5, 0,7, 0).
Pamitaj, e moesz je zobaczy we waciwym pooeniu jedynie wówczas, gdy zmaksymalizujesz widok gry (chyba e uywasz bardzo duej rozdzielczoci ekranu). Przemie kursor myszy nad widok Game (gra), a nastpnie nacinij klawisz spacji, by powikszy okno.
Grupowanie obiektów GUITexture w celu uzyskania zoptymalizowanej konkretyzacji Poniewa powysze tekstury zostan póniej skonkretyzowane przy uyciu obiektu winObj, powinnimy zdefiniowa je jako potomków elementu nadrzdnego. Dziki temu bdziemy mogli stworzy pojedynczy prefabrykat zamiast kilku. Ta metoda pozwala nam unikn wywoywania trzech polece konkretyzujcych i dlatego jest bardziej wydajna. Wybierz opcj GameObject/Create Empty (obiekt gry/stwórz pusty) z menu gównego, a nastpnie zmie nazw nowo utworzonego obiektu gry na WinSequence. Zresetuj jego wartoci Position (pooenie) poprzez kliknicie ikony kóka zbatego po prawej stronie komponentu Transform i wybranie opcji Reset Position (resetuj pooenie) z rozwijanego menu. A teraz wybierz wszystkie trzy obiekty, których nazwy zaczynaj si od win_, i przecignij je na obiekt WinSequence. Spowoduje to ich przypisanie w postaci elementów podrzdnych.
355
Projektowanie gier w rodowisku Unity 3.x
Animowanie przy uyciu interpolacji liniowej Aby utworzy animacj przy uyciu interpolacji liniowej, musimy napisa nowy skrypt. Wybierz wic folder Scripts (skrypty), znajdujcy si w panelu Project (projekt), a nastpnie kliknij przycisk Create (stwórz). Z wywietlonego rozwijanego menu wybierz preferowany przez Ciebie jzyk programowania. Zmie nazw nowo utworzonego skryptu na Animator. W skrypcie, który za chwil napiszemy, bdziemy uywa wielu znanych nam ju mechanizmów. Jedynym nowym elementem jest interpolacja liniowa. Pamitajc o tym, uzupenijmy skrypt, a nastpnie przyjrzyjmy si jego fragmentowi, który nas interesuje. Wprowad poniszy kod, a póniej go przeanalizuj. Jzyk C#: using UnityEngine; using System.Collections; public class Animator : MonoBehaviour { public float xStartPosition = -1.0f; public float xEndPosition = 0.5f; public float speed = 1.0f; float startTime; void Start () { startTime = Time.time; } void Update () { Vector3 pos = new Vector3(Mathf.Lerp(xStartPosition, xEndPosition, ´(Time.time-startTime)*speed), ´transform.position.y,transform.position.z); transform.position = pos; } }
Jzyk JavaScript: var xStartPosition : float = -1.0; var xEndPosition : float = 0.5; var speed : float = 1.0; private var startTime : float; function Start(){ startTime = Time.time; } function Update () {
356
Rozdzia 10. • Podstawy animacji
transform.position.x = Mathf.Lerp(xStartPosition, ´xEndPosition,(Time.time-startTime)*speed); }
Zauwa, e skrypt jzyka C# róni si troch od kodu JavaScript, poniewa musielimy zmodyfikowa cay parametr zwizany z pooeniem i przechowa go tymczasowo w zmiennej typu Vector3. W skrypcie JavaScript moemy bezporednio modyfikowa wspórzdn X i przystosowa j do interpolacji liniowej. Interpolacja liniowa jest najwaniejsz czci naszego skryptu, któr teraz przeanalizujemy: Mathf.Lerp(xStartPosition, xEndPosition,(Time.time-startTime)*speed)
Powysze polecenie zawiera trzy argumenty: warto pocztkow (w naszym przypadku jest to pooenie, cho moe by dowoln waciwoci), warto kocow oraz czas, w cigu którego powinno dokona si przejcie lub interpolacja midzy tymi wartociami. Uwaga W naszym przypadku identyfikujemy interpolacj ze zmian midzy dwoma wartociami. Aby dowiedzie si wicej o tym zagadnieniu, moesz skorzysta z Wikipedii: http://pl.wikipedia.org/wiki/Interpolacja_ %28matematyka%29.
Do operacji zwizanej z czasem uywamy parametru Time.time. Pamita on czas, który upyn od uruchomienia gry, lecz jest resetowany po odjciu od niego wartoci startTime. Podczas konkretyzacji obiektu do zmiennej startTime zostaje przypisana warto Time.time. W wyniku tego uzyskujemy licznik czasu, którego warto wzrasta od zera. Ostatecznie modyfikujemy uzyskany wynik, mnoc go przez zmienn speed. Teraz jest ona równa 1,0, co oznacza, e nie wpynie na rezultat. Jednake kada warto wiksza od 1 spowoduje zwikszenie prdkoci, a mniejsza od 1 — odpowiednio jej zmniejszenie. Przejd do opcji menu gównego File/Save (plik/zapisz) w edytorze skryptu, a nastpnie wró do rodowiska Unity. Poniewa skrypt Animator zawiera zmienne publiczne pozwalajce na modyfikowanie pocztkowego i kocowego pooenia obiektu, moemy stworzy róne animacje do dowolnych zastosowa bez potrzeby przeprowadzania edycji skryptu. Oznacza to, e bdziemy mogli uy go dla wszystkich trzech obiektów GUITexture, które zawieraj komunikaty informujce o wygraniu gry. Dla kadego z nich utworzymy oddzieln animacj. Przypisz skrypt Animator do wszystkich obiektów podrzdnych nalecych do rodzica WinSe ´quence: win_message, win_survival i win_youWin. W tym celu przecignij skrypt z folderu Scripts (skrypty) w panelu Project (projekt), a nastpnie upu w panelu Hierarchy na kady z trzech wspomnianych obiektów.
357
Projektowanie gier w rodowisku Unity 3.x
Dopasowywanie animacji Nasz skrypt zawiera prost implementacj metody interpolacji liniowej, dziki czemu moemy modyfikowa pooenie obiektów w osi X i uzyska animacj w poziomie. Istnieje jednak moliwo zdefiniowania kierunku, z którego bdzie si rozpoczyna nasza animacja. Do tego suy zmienna XStart Position, dostpna w panelu Inspector (inspektor). Wybierz kady z trzech obiektów GUITexture, a póniej zdefiniuj dla nich nastpujce wartoci w parametrze XStart Position (pooenie pocztkowe osi X), znajdujcym si w komponencie Animator (Script) panelu Inspector: Q win_message: 1, Q win_survival: 1, Q win_youWin: -1.
Warto -1 oznacza, e tekstura bdzie si pojawia z lewej strony ekranu, natomiast 1 spowoduje wykonanie animacji z prawej strony okna. Wynika std, e tytu „Survival” oraz akapit z informacj pojawi si z prawej strony, za tekstura z tekstem „You win” wyoni si z lewej strony okna. Moesz take spowolni dziaanie animacji: wybierz obiekt win_message i wprowad warto 2 dla parametru XStart Position oraz 0,5 dla parametru Speed (prdko ). Zapamitaj scen w rodowisku Unity poprzez wybranie opcji menu gównego File/Save (plik/ zapisz), a nastpnie kliknij przycisk Play (granie), aby przyjrze si uzyskanemu rezultatowi.
Zapamitywanie sekwencji wygrania gry Jeli jeste zadowolony z efektu animacji, jaki uzyskae, rozwi folder Prefabs (prefabrykaty) w panelu Inspector, a nastpnie wybierz nadrzdny obiekt WinSequence z panelu Hierarchy. Przecignij go i upu na panel Project w folderze Prefabs, aby zapamita go wraz z obiektami podrzdnymi jako pojedynczy prefabrykat. Nie chcemy, by sekwencja znajdowaa si domylnie w grze, dlatego uyjemy wspomnianego wczeniej obiektu obsugujcego sekwencj zwycistwa, dziki któremu skonkretyzujemy j we waciwym momencie. Poniewa zapamitalimy ju obiekt w postaci prefabrykatu, moemy go usun . Zaznacz wic obiekt nadrzdny WinSequence w panelu Hierarchy, a nastpnie uyj skrótu klawiszowego Delete (PC) lub Command+Backspace (Mac), by usun go ze sceny Island.
Tworzenie obiektu obsugujcego sekwencj zwycistwa Aby zarzdza konkretyzacj obiektów GUI, które wanie zdefiniowalimy, utworzymy obiekt obsugujcy sekwencj zwycistwa, do którego odwoujemy si ju w skrypcie Inventory. Nastpnie przypiszemy go do zmiennej publicznej w komponencie Inventory (Script), zawartym w obiekcie First Person Controller.
358
Rozdzia 10. • Podstawy animacji
Wybierz opcj menu gównego GameObject/Create Empty (obiekt gry/stwórz pusty) i zmie nazw nowo utworzonego obiektu na winObj. Wybierz folder Scripts (skrypty) w panelu Project (projekt) oraz kliknij przycisk Create (stwórz). Z menu podrcznego wybierz preferowany przez Ciebie jzyk programowania. Zmie nazw skryptu na WinGame, a nastpnie przecignij go na pusty obiekt winObj, znajdujcy si w panelu Hierarchy (hierarchia). Wczytaj skrypt do edytora poprzez dwukrotne kliknicie jego ikony w panelu Project. Rozpocznij od utworzenia trzech zmiennych publicznych: Jzyk C#: public GameObject winSequence; public GUITexture fader; public AudioClip winClip;
Jzyk JavaScript: var winSequence: GameObject; var fader : GUITexture; var winClip : AudioClip;
Zmienna winSequence tworzy odwoanie do prefabrykatu WinSequence, zawierajcego obiekty podrzdne GUITexture wykorzystywane w animacji. Zmienna fader jest odwoaniem do obiektu przyciemniania ekranu, który wkrótce utworzymy, a zmienna winClip zawiera klip audio, który jest odtwarzany po wygraniu gry przez gracza. Teraz w skrypcie WinGame utwórz now funkcj zwan GameOver(). Jej nazwa jest bardzo wana, wykorzystujemy j bowiem podczas wywoywania polecenia SendMessage() ze skryptu Inventory. Jzyk C#: IEnumerator GameOver () { }
Jzyk JavaScript: function GameOver () { }
Zwró uwag na to, e w jzyku C# naley uy prefiksu IEnumerator, a nie void. Dziki temu definiujemy funkcj jako wspóprogram, co pozwoli nam na chwilowe przerwanie jej dziaania poleceniem yield. Nastpnie umie w niej polecenie PlayClipAtPoint(), a take funkcj Instantiate() dla zmiennej winSequence:
359
Projektowanie gier w rodowisku Unity 3.x
Jzyk C# i JavaScript: AudioSource.PlayClipAtPoint(winClip, transform.position); Instantiate(winSequence);
Zauwa, e w powyszym kodzie uywamy funkcji Instantiate() tylko z jednym argumentem, czyli odwoaniem do zasobu, który musi zosta utworzony. Dziki temu konkretyzowany prefabrykat uzyska pooenie i obrót z pierwotnego obiektu gry — pamitaj, e wartoci komponentu Transform s równie przechowywane w prefabrykacie. Dlatego te obiekt winSequence zostanie utworzony dokadnie w takim pooeniu, jakie mia poprzednio, czyli (0, 0, 0). Naley o tym szczególnie pamita , gdy konkretyzujemy obiekty, które musz by umieszczane z zastosowaniem wspórzdnych ekranowych w zakresie od 0 do 1. Nastpnie zatrzymamy dziaanie skryptu poleceniem yield, którego uywalimy wczeniej. W dalszej kolejnoci rozpoczniemy operacj przyciemniania ekranu poprzez utworzenie obiektu fader typu GUITexture. Umie ponisze dwa wiersze kodu w funkcji GameOver(): Jzyk C#: yield return new WaitForSeconds(8.0f); Instantiate(fader);
Jzyk JavaScript: yield WaitForSeconds(8.0); Instantiate(fader);
Skrypt tworzy komunikaty informujce o wygraniu gry, odczekuje 8 sekund, a nastpnie konkretyzuje inny obiekt GUITexture, który bdzie realizowa operacj wygaszania ekranu i wywietlania informacji o adowaniu gry. Zapamitaj swój skrypt i wró do rodowiska Unity. Zmiennym publicznym okrelone wartoci przypiszemy w komponencie Win Game (Script) pod koniec tego rozdziau, gdy tylko je utworzymy.
Tworzenie skryptu wygaszania ekranu i uycie panelu Animation Przyciemnianie ekranu wprowadza si za pomoc obiektu GUITexture z przypisan do niego animacj, zdefiniowan przy uyciu panelu Animation (animacja) dostpnego w rodowisku Unity. Po jego konkretyzacji nastpi odtworzenie animacji, a nastpnie utworzenie kolejnego animowanego obiektu typu GUITexture, który przed powrotem programu do menu wywietli informacj o wczytywaniu gry. W folderze Book Assets/Textures (zasoby gry/tekstury) znajduje si plik o nazwie fade. Jest to po prostu kwadratowa tekstura o rozmiarze 2×2 piksele, która zostanie rozcignita do wymiarów
360
Rozdzia 10. • Podstawy animacji
ekranu i bdzie animowa jego przyciemnianie, rozpoczynajc od maksymalnego poziomu przezroczystoci. Gdy ju wybierzesz t tekstur w panelu Project, przypisz parametrowi Texture Type (rodzaj tekstury) komponentu Texture Importer w panelu Inspector (inspektor) warto GUI, a nastpnie kliknij przycisk Apply (zastosuj). Póniej kliknij przycisk Create (stwórz) w panelu Hierarchy (hierarchia) i z menu podrcznego wybierz opcj GUI Texture (tekstura GUI). Poniewa nasza tekstura powinna pokrywa cay obszar ekranu, zmie ustawienia komponentu GUITexture tak, aby odpowiaday poniszemu rysunkowi:
Dziki temu tekstura bdzie dziaa z domylnym rozmiarem ekranu 1024×768 pikseli, przeznaczonym dla samodzielnej aplikacji. Za chwil wprowadzimy take moliwo przeskalowania do biecej rozdzielczoci.
Dopasowywanie do rónych rozdzielczoci Aby upewni si, e wygaszanie ekranu bdzie dziaa poprawnie w kadej rozdzielczoci, napiszemy skrypt, który bdzie sprawdza , jakie powinny by wartoci parametru Pixel Inset (wstawka pikselowa) podczas konkretyzacji obiektu. Do tego celu wykorzystamy funkcj Start(). Aby kontynuowa nasz projektow metod tworzenia oddzielnych skryptów do obsugi rónych zada zwizanych z obiektem, zdefiniujemy skrypt, który bdzie sprawdza systemowe parametry Screen.width i Screen.hight w podobny sposób, w jaki obsugiwalimy menu w poprzednim rozdziale. Wybierz folder Scripts w panelu Project, a nastpnie kliknij przycisk Create. Z rozwijanego menu wybierz preferowany jzyk programowania. Zmie nazw nowo utworzonego skryptu na Fader i dwukrotnie kliknij jego ikon, by wczyta go do edytora. Parametr Pixel Inset ma znany nam ju typ danych — Rect. Moemy wic po prostu w funkcji Start() stworzy now warto typu Rect, a póniej przypisa j do waciwoci pixelInset obiektu GUITexture. Aby to zrobi , umie nastpujc funkcj w swoim skrypcie: Jzyk C#: void Start(){ Rect currentRes = new Rect(-Screen.width * 0.5f, -Screen.height * 0.5f, ´Screen.width, Screen.height); guiTexture.pixelInset = currentRes; }
361
Projektowanie gier w rodowisku Unity 3.x
Jzyk JavaScript: function Start(){ var currentRes : Rect = Rect(-Screen.width * 0.5, -Screen.height * 0.5, ´Screen.width, Screen.height); guiTexture.pixelInset = currentRes; }
W powyszym kodzie tworzymy zmienn typu Rect, zwan currentRes, a nastpnie przekazujemy ujemne wartoci szerokoci i wysokoci ekranu do jej waciwoci X i Y, dzielc je przez 2 (za pomoc mnoenia przez 0,5). We waciwociach szerokoci i wysokoci po prostu uywamy wartoci Screen.width i Screen.height. Dziki temu wygaszanie ekranu bdzie dziaa w kadej rozdzielczoci! Zapamitaj swój skrypt i wró do rodowiska Unity. Wybierz skrypt Fade w panelu Project, a nastpnie przecignij go na obiekt fade w panelu Hierarchy. Teraz kliknij przycisk Play, by przetestowa dziaanie skryptu. Powiksz widok gry (umie kursor myszy nad nim i nacinij klawisz spacji). Skrypt powinien przeskalowa obiekt wygaszania ekranu do dowolnego rozmiaru, jaki ma okno gry. Jeszcze raz kliknij przycisk Play, by zakoczy testowanie.
Zdefiniowanie pocztkowego stanu obiektu wygaszania ekranu Musimy si upewni , e obiekt wygaszania ekranu nie zaciemni nam widoku podczas jego konkretyzacji. Moe si zdarzy , e zostanie wywietlony domylny stan obiektu, zanim rozpocznie si animowana zmiana poziomu widocznoci od 0 do maksymalnej wartoci. Aby tego unikn , powinnimy zdefiniowa obiekt GUITexture jako domylnie niewidoczny. W tym celu przypiszemy kanaowi alfa warto 0. Kliknij pole koloru Color (kolor), a nastpnie w oknie definiowania koloru przecignij suwak A (kana alfa) do wartoci 0, by uczyni obiekt cakowicie niewidocznym. Powiniene teraz widzie jedynie czarn lini poniej pola koloru Color, wskazujc warto kanau alfa równ 0. Uruchom panel Animation (animacja) poprzez wybranie opcji menu gównego Window/Animation (okno/animacja).
Przegld panelu animacyjnego Zanim uyjemy panelu do przyciemniania obiektu GUITexture, zapoznajmy si pobienie ze sposobem jego dziaania. Poniej zaprezentowano wygld okna Animation dla wybranego obiektu fade. Na poniszym rysunku zosta ju utworzony nowy klip zwany fadeOut. Podczas rozpoczynania tworzenia animacji za pomoc okna Animation rodowisko Unity automatycznie dodaje do obiektu komponent Animation, poniewa jest on niezbdny do uycia utworzonego klipu.
362
Rozdzia 10. • Podstawy animacji
Na poniszym rysunku przedstawiono podstawowe elementy kontrolne okna Animation:
A teraz sprawdmy w praktyce dziaanie powyszych elementów okna Animation i zdefiniujmy animacj tekstury GUITexture.
Tworzenie klipu animacyjnego Kliknij obszar Current Clip (biecy klip), a nastpnie z rozwijanego menu wybierz opcj Create New Clip (stwórz nowy klip).
Pojawi si okno dialogowe z pytaniem o nazw nowego klipu. Nazwij go fadeOut i zapisz w gównym folderze Assets (zasoby), aby zapamita go na najwyszym poziomie panelu Project. Moesz take utworzy nowy folder Animations (animacje) i zapamita go w nim.
363
Projektowanie gier w rodowisku Unity 3.x
Tworzenie klatek kluczowych Nazwa nowo utworzonego klipu pojawia si w obszarze Current Clip. Jeli uywasz wielu animacji przypisanych do pojedynczego obiektu, moesz je w prosty sposób wybiera , uywajc rozwijanego menu. By animowa dostpne parametry komponentów, musisz po prostu utworzy krzyw animacji. Aby to zrobi , ustal najpierw parametr, który bdzie animowany. W naszym przypadku bdziemy modyfikowa skadnik Color.a (kana alfa koloru) tekstury GUITexture. Kliknij ikon po prawej stronie nazwy parametru, a nastpnie wybierz opcj Add Curve (dodaj krzyw animacji), jak zaprezentowano na poniszym rysunku:
Spowoduje to utworzenie pierwszej klatki kluczowej w pozycji 0 listwy czasu. Klatki kluczowe su do tworzenia punktów w czasie, w których dana waciwo ma okrelon warto . Poniewa gry dziaaj tak jak animacje, czyli w kolejnych klatkach realizuj rendering obrazu, spodziewamy si jakich zmian. Aby uytkownik nie musia definiowa kadej klatki z osobna, oprogramowanie wspomaga proces animacji poprzez umoliwienie ustalania miejsc na listwie czasu, w których dane parametry bd miay okrelon wielko . Nastpnie program wyznacza porednie wartoci dla pozostaych klatek. Taki proces, zwany tweeningiem (animacj automatyczn), jest realizowany przez rodowisko Unity. Z tego powodu zdefiniujemy klatk kluczow na pocztku naszej animacji, dla której warto kanau alfa obiektu GUITexture jest równa 0. Nastpnie stworzymy kolejn klatk kluczow na kocu animacji z odpowiedni wartoci kanau alfa równ 1. Oznacza to, e pod koniec animacji tekstura GUITexture bdzie cakowicie widoczna. Poniewa jest ona renderowana przed trójwymiarowym widokiem kamery, obraz zostanie zasonity czarnym tem, co da efekt przyciemniania ekranu.
364
Rozdzia 10. • Podstawy animacji
Klatki kluczowe s reprezentowane przez ikon w ksztacie rombu. Gdy wskanik odtwarzania, widoczny jako czerwona linia, znajduje si nad klatk kluczow, mona zmieni jej warto poprzez jej kliknicie, a nastpnie wprowadzenie odpowiedniej modyfikacji. Poniewa zdefiniowalimy ju pocztkow klatk kluczow, powiniene zauway , e jej warto parametru Color.a jest równa 0. Dlatego te nasza animacja bdzie powodowa przyciemnianie tekstury, poczynajc od wartoci kanau alfa równej 0. A teraz przesu wskanik odtwarzania (czerwon lini): przecignij go mysz i umie w pooeniu listwy czasu, które jest równe 2 sekundom. Jeli nie widzisz tej pozycji, po prostu uyj poziomego paska przewijania przy dolnej krawdzi okna. Po umieszczeniu wskanika w pozycji 2:00 kliknij przycisk Add Keyframe (dodaj klatk kluczow), a nastpnie wprowad w polu Color.a warto 1. Trudno bdzie zauway jakkolwiek zmian w linii animacji na wykresie, poniewa widok domylnie nie zosta przybliony w takim stopniu, by wywietli przejcie z wartoci 0 na 1. Niektóre animacje (na przykad zmiana pooenia) modyfikuj parametry w wikszym zakresie, std te wynika domylny obszar widoku. Aby rzeczywicie zobaczy zmian zachodzc midzy obiema klatkami kluczowymi, po prostu przecignij w dó zaokrglony koniec prawego paska przewijania i przesu cay pasek w miejsce, w którym bdziesz móg widzie ca krzyw.
Alternatywnie moesz wykorzysta opcj automatycznego przybliania widoku, dostpn w rodowisku Unity. Po prostu przemie kursor myszy nad widok Animation i nacinij klawisz F.
365
Projektowanie gier w rodowisku Unity 3.x
Uycie krzywych animacyjnych Aby utworzy bardziej agodny efekt przyciemniania, moemy zastosowa odpowiedni krzywizn w klatkach kluczowych. Pozwala to na uzyskanie pynnej animacji przy wykorzystaniu krzywych Béziera, umoliwiajcych sterowanie ruchem. Kliknij prawym klawiszem myszy pierwsz klatk kluczow (znajdujc si na wykresie, w przeciwiestwie do rombu, który jest widoczny ponad listw czasu, na górze wykresu), a nastpnie z rozwijanego menu wybierz opcj Flat (paski).
Powtórz ten krok dla drugiej klatki kluczowej. Twoja krzywa animacji powinna wyglda nastpujco:
Zwró uwag na to, e na powyszym rysunku zaznaczono obie klatki kluczowe, by wywietli ich uchwyty. Nasza pierwsza animacja jest gotowa! Zamknij panel Animation lub zadokuj go w interfejsie Unity, a póniej kliknij przycisk Play, by sprawdzi dziaanie efektu przyciemniania ekranu dla tekstury GUITexture. Nacinij przycisk Play ponownie, aby przerwa testowanie, albo spróbuj porusza si w ciemnoci! Jeli w panelu Inspector wida komponent Animation naszego obiektu przyciemniania
366
Rozdzia 10. • Podstawy animacji
ekranu, wywietla on fadeOut jako biec animacj, która bdzie automatycznie odtwarzana, poniewa odpowiednia opcja Play Automatically (odtwarzaj automatycznie) jest domylnie wczona.
Skoro nasz obiekt przyciemniania ekranu jest ju animowany, musimy wykona jeszcze jedno kocowe dziaanie, zanim zapamitamy go w postaci prefabrykatu — uyjemy animacji do uruchomienia procesu tworzenia nowego elementu GUI.
Dodawanie zdarze animacyjnych Zdarzenia s elementem animacji i mog by umieszczane na listwie czasu. Pozwalaj one atwo wywoywa funkcje w okrelonych momentach. Po napisaniu skryptu i przypisaniu go do animowanego obiektu moesz okreli nazw funkcji i wywoa j w okrelonym etapie animacji. Aby poinformowa gracza, co bdzie si dzia po zakoczeniu gry, stworzymy animacj kolejnego obiektu GUITexture, zawierajcego napis „Loading”. Obiekt ten zostanie skonkretyzowany podczas dziaania animacji fadeOut. Do utworzenia funkcji wykorzystamy skrypt Fader, który zosta ju doczony do obiektu fade. Odszukaj go w panelu Project, a nastpnie wczytaj do edytora lub wró do niego, jeli jest ju otwarty. Wprowad nastpujc deklaracj zmiennej publicznej oraz funkcji, która po prostu konkretyzuje obiekt typu GUITexture (utworzymy go wkrótce), sucy do wywietlenia napisu „Loading”. Jzyk C#: public GUITexture loadGUI; void LoadAnim(){ Instantiate(loadGUI); }
Jzyk JavaScript: var loadGUI : GUITexture; function LoadAnim(){ Instantiate(loadGUI); }
367
Projektowanie gier w rodowisku Unity 3.x
Zapamitaj skrypt i wró do rodowiska Unity. Poniewa skrypt jest ju gotowy i zosta wczeniej doczony do obiektu fade, moemy go uy w zdarzeniu animacyjnym. Jeli obiekt fade jest wci wybrany w panelu Hierarchy, otwórz okno Animation poprzez wskazanie opcji menu gównego Window/Animation (okno/animacja) lub uycie odpowiedniego skrótu klawiszowego (PC: Ctrl+6, Mac: Command+6). Wybierz waciwo Color.a komponentu GUITexture, znajdujcego si po lewej stronie panelu, a nastpnie przesu wskanik odtwarzania na pozycj 1:00 na listwie czasu. Kliknij przycisk Add Event (dodaj zdarzenie).
Powinno zosta utworzone zdarzenie oraz wywietlone okno dialogowe Edit Animation Event (edycja zdarzenia animacyjnego). Mona je równie otworzy , klikajc ikon zdarzenia na listwie czasu. W oknie moesz wywietli list funkcji dostpnych w skrypcie, który jest doczony do animowanego obiektu. Kliknij rozwijane menu na napisie No Function Selected (nie wybrano funkcji), a nastpnie wybierz funkcj, któr wanie napisalimy, czyli LoadAnim():
Funkcja ta zostanie wywoana w zdefiniowanym punkcie listwy czasu. Moe by on przesuwany poprzez wybranie ponownej edycji animacji, a nastpnie zmodyfikowanie jego pooenia na listwie czasu. Zapamitaj stan projektu, wybierajc opcj menu gównego File/Save Scene (plik/zapisz scen). Na kocu sekwencji wygrania gry, po przyciemnieniu ekranu, powinien pojawi si napis „Loading”. Przygotowalimy ju waciwy obiekt wraz z metod jego konkretyzacji, dlatego
368
Rozdzia 10. • Podstawy animacji
trzeba teraz po prostu go utworzy i przypisa do skryptu Fader. Element GUI z napisem „Loading” zakoczy proces wywietlania sekwencji wygrania gry poprzez ponowne wczytanie gównego menu po upywie okrelonego czasu.
Utworzenie i animowanie elementu GUI z napisem „Loading” W folderze Book Assets/Textures (zasoby ksiki/tekstury) wybierz plik loadingGUI. Nastpnie w komponencie Texture Importer, dostpnym w panelu Inspector (inspektor), wybierz opcj GUI z menu Texture Type (rodzaj tekstury) i kliknij przycisk Apply (zastosuj), by zatwierdzi wprowadzone zmiany. Gdy tekstura jest wci zaznaczona, kliknij przycisk Create (stwórz) w panelu Hierarchy (hierarchia) i wybierz opcj GUI Texture (tekstura GUI). Zostanie utworzony obiekt loadingGUI, nastpnie umieszczony w panelu Hierarchy. Aby si upewni , e znajduje si on poza ekranem, przypisz jego pooeniu Y warto -1. Ponownie otwórz panel Animation i kliknij przycisk Add Clip (dodaj klip). Zmie nazw nowo utworzonego klipu na showHide i zapisz go w domylnym folderze Assets (zasoby) lub Twoim folderze Animations (animacje). Kliknij prawym klawiszem myszy waciwo Position.y (pooenie na osi Y) komponentu Transform w obszarze znajdujcym si po lewej stronie okna, a nastpnie wybierz opcj Add
Curves (dodaj krzywe). W kolejnym kroku wybierz waciwo Position.y, aby zostaa podwietlona w kolorze niebieskim. Na wykresie bdziesz móg zobaczy zielon klatk kluczow. Upewnij si, e jej warto jest równa -1, dziki czemu element GUI bdzie si znajdowa na osi Y poza ekranem. A teraz poprzez odpowiednie przemieszczanie si po listwie czasu stwórz nastpujce klatki kluczowe i wartoci dla waciwoci Position.y: Q czas 1:00: 0,5, Q czas 4:00: 0,5, Q czas 5:00: -1.
Spowoduje to animowanie obiektu GUITexture do rodka ekranu (pooenie 0,5), wstrzymanie animacji przez 4 sekundy, a nastpnie usunicie tekstury z okna po 5 sekundach. Twoja krzywa powinna wyglda jak na poniszym rysunku. Oznacza to jednake, e tekstura loadingGUI bdzie animowana przy uyciu krzywej o agodnym nachyleniu a do pooenia powyej rodka ekranu, a nastpnie opadnie tak, jakby bya obiektem, który zosta podrzucony i spad pod wpywem dziaania siy grawitacji. Sprawd to: kliknij przycisk Play (odtwarzanie) w oknie Animation i obserwuj widok Scene (scena) lub Game (gra).
369
Projektowanie gier w rodowisku Unity 3.x
Aby to naprawi , po prostu kliknij prawym klawiszem myszy klatki kluczowe dla czasów 1:00 i 4:00, a póniej wybierz opcj Flat (krzywa paska) z menu podrcznego. Kliknij przycisk Play w panelu Animation. W widoku sceny lub gry powiniene widzie tekstur loadingGUI, która pojawia si u dou ekranu, pozostaje przez kilka sekund na jego rodku, a nastpnie ponownie znika na dole. Animacja ekranu jest ju gotowa, wic nadszed czas, aby wczyta gr! Poniewa potrafimy ju obsugiwa zdarzenia animacyjne, uyjmy jednego z nich do wczytania sceny Menu naszej gry, co pozwoli graczowi na ponowne zagranie lub wyjcie (w przypadku samodzielnej aplikacji).
Wczytywanie sceny przy uyciu zdarzenia animacyjnego Zanim dodamy zdarzenie do animacji, powinnimy napisa skrypt wraz z funkcj, która zostanie wywoana. Wybierz folder Scripts (skrypty) w panelu Project, a nastpnie kliknij przycisk Create (stwórz) i wybierz jzyk C# lub JavaScript. Zmie nazw nowo utworzonego skryptu na Reloader. Poprzez przecignicie skryptu z panelu Project przypisz go do obiektu loadingGUI w panelu Hierarchy i wczytaj do edytora. Skrypt bdzie uywany do adowania sceny zawierajcej menu gry, dlatego po prostu napisz ponisz funkcj: Jzyk C#: void Reload(){ Application.LoadLevel("Menu"); }
Jzyk JavaScript: function Reload(){ Application.LoadLevel("Menu"); }
370
Rozdzia 10. • Podstawy animacji
Zapamitaj skrypt i wró do rodowiska Unity. Wybierz obiekt loadingGUI w panelu Hierarchy, a nastpnie uruchom okno Animation, jeli zostao zamknite. Obiekt loadingGUI powinien zosta wybrany w panelu Hierarchy, poniewa bierze on udzia w animacji showHide, nad któr musimy jeszcze popracowa . Pamitaj, e informacje o aktualnie wybranym obiekcie i jego animacji s wywietlane w lewym górnym obszarze panelu Animation. Umie wskanik odtwarzania w pooeniu 6:00 na listwie czasu, czyli 1 sekund po znikniciu animowanego tekstu „Loading” w dolnej czci ekranu. Nacinij przycisk Add Event (dodaj zdarzenie), a nastpnie kliknij graficzny znacznik zdarzenia, aby wywietli okno dialogowe Edit Animation Event (edycja zdarzenia animacyjnego). Z menu wybierz funkcj Reload() i zamknij okno. Gratulacje, nasze animacje s gotowe! Pamitaj jednak, e nie chcemy, aby obiekt loadingGUI wystpowa domylnie w scenie Island, poniewa uywamy skryptu Fader, który go dla nas konkretyzuje w wyniku wystpienia pierwszego zdarzenia animacyjnego.
Zapamitywanie i konkretyzowanie obiektu loadingGUI Zapamitaj obiekt loadingGUI w postaci prefabrykatu: przecignij go z panelu Hierarchy do folderu Prefabs (prefabrykaty) w panelu Project. Usu instancj obiektu loadingGUI z panelu Hierarchy poprzez uycie odpowiedniego skrótu klawiszowego (PC: Delete, Mac: Command+ Backspace). Pamitaj, e skrypt Fader zawiera polecenie Instantiate(), które powinno zosta wykorzystane z prefabrykatem loadingGUI. Bdzie ono wywoywane przez zdarzenie animacyjne podczas uruchamiania funkcji LoadAnim(). Dlatego te powinnimy teraz przypisa prefabrykat do skryptu Fader, co pozwoli na konkretyzacj obiektu loadingGUI. Wybierz obiekt fade w panelu Hierarchy, aby wywietli komponent Fader (Script) w panelu Inspector. Moesz zauway zmienn publiczn Load GUI, której powinien zosta przypisany odpowiedni obiekt GUITexture. Przecignij wic na ni prefabrykat loadingGUI z folderu Prefabs. Twój komponent Fader (Script) powinien wyglda nastpujco:
Jak zwykle nie potrzebujemy obiektu w panelu Hierarchy podczas dziaania gry, dlatego zapamitamy go jako prefabrykat. W tym celu przecignij obiekt fade z panelu Hierarchy do folderu Prefabs w panelu Project, a nastpnie usu go z pierwotnego miejsca.
371
Projektowanie gier w rodowisku Unity 3.x
Wczytywanie sekwencji wygrania gry Poniewa prefabrykat fade jest ju przygotowany do konkretyzacji prefabrykatu loadingGUI, która nastpi po rozpoczciu operacji przyciemniania ekranu, a obiekt loadingGUI moe wczyta scen Menu, ostatni czynnoci, jak powinnimy wykona , jest upewnienie si, e po wygraniu gry przez gracza skrypt WinGame, przypisany do obiektu winObj, uruchomi dwa etapy sekwencji zwycistwa. Wybierz obiekt winObj w panelu Hierarchy, aby wywietli komponent Win Game (Script). Z folderu Prefabs w panelu Project przecignij prefabrykat fade na zmienn publiczn Fader. Podobnie przecignij prefabrykat WinSequence i upu go na zmienn Win Sequence. Wreszcie przypisz klip audio win_clip z folderu Book Assets/Sounds (zasoby ksiki/dwiki) do zmiennej Win Clip.
Wybierz obiekt First Person Controller z panelu Hierarchy, a nastpnie przecignij obiekt winObj z tego samego panelu na zmienn publiczn Win Obj, widoczn w komponencie Inventory (Script), który jest wywietlony w panelu Inspector. Spowoduje to uruchomienie funkcji Game ´Object() dla obiektu winObj po rozpaleniu ogniska przez gracza. Gdy ju przypiszesz elementy sekwencji wygrania gry, przetestuj je w dziaaniu! Kliknij przycisk Play i zagraj w gr. Po rozpaleniu ogniska na ekranie powinny pojawi si komunikaty z gratulacjami, a po upywie 8 sekund ekran powinien si przyciemni . W tym czasie w oknie pojawi si napis „Loading”, po czym nastpi wczytanie sceny Menu. Ale chwileczk! Przecie w grze jest bd! Komunikaty GUITexture s wci widoczne w trakcie wygaszania ekranu i podczas wywietlania tekstu „Loading”. Dlaczego? Dzieje si tak, poniewa podczas umieszczania tekstur GUITexture na scenie waciwo Z komponentu Transform jest uywana do okrelenia kolejnoci pojawiania si tych elementów graficznych (jest to co w rodzaju gbokoci obiektów trójwymiarowych). Wszystkie obiekty GUI maj t sam warto Z, dlatego nie s renderowane we waciwej kolejnoci, która powinna by nastpujca: komunikat, obiekt przyciemniania ekranu, a wreszcie napis „Loading” na samej górze. Spróbujmy wic poprawi nasz bd.
372
Rozdzia 10. • Podstawy animacji
Umieszczanie obiektów GUITexture w warstwach Aby upewni si, e obiekt fade znajduje si przed komunikatami o wygraniu gry, lecz za obiektem loadingGUI, moemy wykorzysta o Z do zdefiniowania warstw obiektów dwuwymiarowych. Poniewa komunikaty o zwycistwie powinny si znajdowa pod obiektami fade i loadingGUI, wybierz kady z potomków prefabrykatu WinSequence w folderze Prefabs, a nastpnie w komponencie Transform w panelu Inspector i przypisz parametrowi Z warto -2.
A teraz pozostaw pooenie Z równe 0 (co oznacza, e obiekt znajduje si na samej górze; inaczej mówic, ponad innymi elementami) w komponencie Transform obiektu loadingGUI, natomiast dla prefabrykatu fade przypisz mu warto -1. Wszystko gotowe! Zapisz scen i zagraj w gr, cieszc si w peni dziaajc sekwencj zwycistwa. Po zakoczeniu testowania pamitaj o ponownym klikniciu przycisku Play.
373
Projektowanie gier w rodowisku Unity 3.x
Wyzwanie — zmiana koloru ekranu w scenie Island Wykorzystajmy zdobyt wiedz i stwórzmy efekt zmiany koloru ekranu z barwy biaej, który powinien si pojawi przy rozpoczynaniu poziomu Island. Poniewa nie wpywa to na funkcjonalno naszej gry, nie bdziemy dokadnie opisywa , co naley zrobi . Jest to dla Ciebie zadanie do rozwizania! Poniej przedstawiamy jedynie ogólne wskazówki, co powinno zosta wykonane. Szczegóy rozwizania pozostawiamy Tobie. Uyj wiedzy, któr zdobye w tym rozdziale. Q Aby utworzy obiekt GUITexture, zastosuj tekstur fadeWhite z folderu Book
Assets/Textures (zasoby ksiki/tekstury). Q Docz skrypt z kodem, który pozwoli na jej wywietlenie w uywanej
rozdzielczoci ekranu. Q Przypisz parametrowi kanau alfa warto 1 (w peni widzialny). Q Stwórz now animacj dla obiektu GUITexture, zmieniajc warto kanau alfa
od 1 do 0. Q Stwórz zdarzenie animacyjne na kocu animacji, które usunie obiekt gry ze sceny.
Powodzenia!
Podsumowanie W tym rozdziale przyjrzelimy si dwóm rónym metodom tworzenia animacji w rodowisku Unity. Pamitaj, e interpolacja liniowa oraz panel Animation mog by uywane w celu animowania praktycznie kadej waciwoci gry przy wykorzystaniu okrelonego parametru komponentu. Dziki temu uzyskujesz praktycznie cakowit kontrol nad tym, co dzieje si w Twoich scenach gry. W nastpnym rozdziale zajmiemy si dopracowywaniem szczegóów i zapoznamy z nowymi technikami, takimi jak odwzorowywanie wiata, które spowoduj, e Twoja gra nabierze profesjonalnego wygldu, odróniajcego j od innych produktów.
374
11 Poprawa wydajnoci i kocowe modyfikacje W tym rozdziale zmodyfikujemy odpowiednio nasz gr, która z prostego przykadu zamieni si w co, co bdzie mona ju udostpni uytkownikom kocowym. Podczas czytania tej ksiki zapoznawalimy si z kolejnymi przykadami, które pozwalay nam na zdobywanie nowych umiejtnoci. W tym rozdziale pogbimy wiedz dotyczc poznanych ju zagadnie, a take przyjrzymy si dokadniej pewnym efektom, które nie maj duego wpywu na rozgrywk, lecz sprawiaj, e Twój produkt nabiera profesjonalnego wygldu. Dlatego te najlepiej jest wprowadzi te zmiany dopiero pod koniec procesu projektowego. Podczas tworzenia dowolnej gry najwaniejszym jej elementem jest mechanika. Fizycznie dziaajce elementy gry musz by ju gotowe, zanim zostan w niej umieszczone dodatkowe skadniki graficzne i rodowiskowe. Podobnie jak w wielu innych przypadkach, równie podczas tworzenia gier terminy docelowe bd definiowane w ramach wasnej dyscypliny projektowej przez Ciebie lub przez firm wydawnicz, z któr wspópracujesz. Planujc kocowe modyfikacje na zakoczenie cyklu projektowego, upewniasz si, e powicie wikszo czasu na stworzenie dziaajcej rozgrywki, co jest po prostu najwaniejszym zadaniem. Aby osign cele niniejszej ksiki, zaómy, e nasza mechanika gry zostaa ju stworzona i dziaa zgodnie z oczekiwaniami. A teraz zastanówmy si, co moglibymy jeszcze umieci w rodowisku wyspy oraz ogólnie w grze, by przyczyni si do jej upikszenia. W tym rozdziale przeanalizujemy nastpujce zagadnienia: Q ulepszenie terenu i zdefiniowanie pooenia pocztkowego gracza, Q dodanie mgy w celu zwikszenia poziomu realizmu, Q odwzorowanie wiata w rodowisku wyspy,
Projektowanie gier w rodowisku Unity 3.x
Q zdefiniowanie systemu czstek dla wulkanu, Q zdefiniowanie odgosów wulkanu w postaci dwiku trójwymiarowego, Q stworzenie smug wietlnych, prezentujcych trajektori lotu orzechów kokosowych
w minigrze.
Ulepszenie terenu i zdefiniowanie pooenia pocztkowego gracza Aby gra bya atrakcyjna dla gracza, powi my troch czasu na poprawienie jakoci terenu wyspy, a nastpnie zdefiniujmy pooenie obiektu First Person Controller, dziki czemu posta gracza pojawi si na wyspie w miejscu, które nie ujawni od razu obecnoci budynków i celu gry.
Ulepszanie terenu Teraz powrócimy do narzdzi terenu i poprawimy szczegóy wyspy. Poniewa bdziemy modyfikowa teren sceny Island, upewnij si, e zostaa ona wybrana w rodowisku Unity. Zastosujemy trzy sposoby pozwalajce na dodanie szczegóów do terenu: Q umieszczanie drzew, Q modyfikacja wzgórz i dolin oraz zastosowanie techniki przenikania tekstur, Q zaznaczanie cieki gracza.
Umieszczanie drzew Aby uzyska naturalny wygld drzew umieszczonych na wyspie, powiniene zastanowi si, w jakich miejscach mog one rosn . Mówic krótko, drzewa rozrzucaj nasiona, które padaj w przypadkowych miejscach. Po upywie lat wyrastaj z nich kolejne roliny. Oprócz tego drzewa posadzone przez czowieka s rozmieszczone w równych rzdach, midzy którymi zachowano okrelon przestrze. Nasza wyspa ma by dziewiczym rodowiskiem, dlatego te powi troch czasu, by rozmieci na niej drzewa w maych grupach. Wybierz obiekt nadrzdny Environment w panelu Hierarchy (hierarchia), a nastpnie kliknij jego szar strzak, by go rozwin . Wybierz obiekt Terrain i przejd do panelu Inspector (inspektor). Kliknij przycisk Place Trees (rozmieszczanie drzew) w komponencie Terrain (Script). Zdefiniuj nastpujce ustawienia: Q Brush Size (wielko pdzla): 1, Q Tree Width/Height (grubo /wysoko drzewa): 60, Q Variation (poziom zmiennoci): 5.
376
Rozdzia 11. • Poprawa wydajnoci i kocowe modyfikacje
Nastpnie rozmie drzewa w grupach, a take spróbuj utworzy rzd drzew zaraz przed krawdzi wybrzea, aby uzyska odpowiednie zagszczenie rolin. Podczas wykonywania tej czynnoci pamitaj, e za chwil dodamy wicej wzgórz i tekstur, które sprawi, e lokalizacja drzew bdzie wyglda bardziej naturalnie.
Modyfikacja wzgórz i dolin oraz zastosowanie techniki przenikania tekstur A teraz powi my troch czasu na eksperymenty z narzdziem Raise/Lower Terrain (zwikszanie/zmniejszanie wysokoci terenu), by stworzy bardziej interesujcy krajobraz ze wzgórzami i dolinami. Wybierz to narzdzie i przypisz parametrowi Brush Size (wielko pdzla) warto 35, a Opacity (nieprzezroczysto ) — 10. Rozpoczniemy od niskiego poziomu nieprzezroczystoci, co pozwoli nam na wielokrotne klikanie i uzyskanie bardziej rónorodnego rezultatu. Oto przykad wyspy przed utworzeniem dodatkowych wzgórz i dolin:
Rozpocznij proces ulepszania wyspy od zmienienia rozmiaru pdzla, by utworzy wzgórza z mniejszymi szczegóami. Moesz take wybra inne rodzaje pdzli. Zachowuj niski poziom nieprzezroczystoci i pracuj powoli, pamitajc o tym, e jeli chciaby obniy teren, po prostu przytrzymaj klawisz Shift. Gdy popenisz bd, uyj polecenia Undo (wycofanie zmian) (PC: Ctrl+Z, Mac: Command+Z). Podczas definiowania dodatkowych szczegóów terenu postaraj si uywa do tego celu narzdzia Paint Texture (nakadanie tekstur). Zachowujc niski poziom nieprzezroczystoci, umieszczaj szczegóy w miejscach, w których zmodyfikowae poziom terenu. Pamitaj, e tam, gdzie nastpuje zmiana krajobrazu, adnie wygldaj róne rodzaje rolin. Na przykad tereny wyynne
377
Projektowanie gier w rodowisku Unity 3.x
mog mie skay zamiast trawy oraz oddzielajcy pas z piasku. Dlaczego wic nie mona byoby uy tekstury skay, by stworzy ciek prowadzc przez wysp i umieszczon na wzgórzach pokrytych piaskiem?
Plaa Spróbuj zastosowa narzdzia Smooth Height (wygadzanie powierzchni) oraz Paint Height (ustalanie wysokoci), by na przykad stworzy pla poprzez zdefiniowanie paskowyu po jednej stronie wyspy. Aby to zrobi , w narzdziu Paint Height przypisz parametrowi Height (wysoko ) warto 9, a nastpnie uyj narzdzia Smooth Height, aby wyrówna przejcia midzy pla, morzem i ldem. Wreszcie dodaj troch drzew i zdefiniuj szczegóy tekstury, by poprawi wygld zmieniajcego si krajobrazu.
Pamitaj, e im wicej bdziesz wiczy , tym lepiej poznasz dziaanie pdzli i staniesz si bardziej kreatywny podczas tworzenia swojego rodowiska. Nie obawiaj si prób z nowymi rozwizaniami — zawsze masz moliwo wycofania zmian!
Zdefiniowanie waciwej cieki Aby umoliwi graczowi dojcie do obszaru wyspy, na którym znajduj si budynki, stwórz ciek prowadzc do niego z utworzonej wanie play. Zmusi to gracza do zbadania terenu wyspy, a ostatecznie doprowadzi go do celu. Uyj narzdzia Paint Height, rozpoczynajc od poziomu 12, a nastpnie powoli zwikszaj wysoko w miar zbliania si do lokalizacji z budynkami. By unikn tworzenia stromych stoków prowadzcych do cieki, zastosuj narzdzie Smooth Height, pozwalajce na definiowanie agodnych przej . Póniej zastosuj tekstury Rock (skaa) i Sandy (piasek), aby stworzy ciek, która wyglda podobnie jak na poniszym rysunku:
378
Rozdzia 11. • Poprawa wydajnoci i kocowe modyfikacje
Przejd si po wyspie i kontynuuj jej edycj, dodajc do niej interesujce skadniki. Pamitaj, aby stworzy tak ciek, która pozwoli graczowi na intuicyjne dostanie si do obszaru z budynkami. Pod koniec cieki stwórz wzgórze otaczajce budynki, dziki czemu gracz bdzie wiedzie , e dotar we waciwe miejsce.
Pocztkowa lokalizacja postaci gracza Skoro ju stworzylimy ciek, zdefiniujmy pooenie postaci gracza. Wybierz obiekt First Person Controller w panelu Hierarchy (hierarchia), a nastpnie uyj narzdzia Translate (skrót klawiszowy W), by przemieci go na pla, któr wczeniej utworzylimy. Do tego moe
379
Projektowanie gier w rodowisku Unity 3.x
si przyda widok boczny i z góry, który ustawisz za pomoc gadetu widoku w prawym górnym naroniku okna Scene (scena). Ostatecznie posta gracza powinna znajdowa si w pooeniu zaprezentowanym na poniszym rysunku:
Poniewa nasze rodowisko wyglda ju poprawnie, postarajmy si jeszcze bardziej je dopracowa !
Optymalizacja wydajnoci W tym podrozdziale przyjrzymy si sposobom poprawiania wydajnoci gry jako produktu kocowego. Proces ten, zwany take optymalizacj, staje si bardzo wany po upewnieniu si, e gra dziaa zgodnie z oczekiwaniami, a gracz podczas grania w ni ma moliwie najlepsze wraenia. Za chwil zostan omówione podstawy optymalizacji, które powiniene pozna . Musisz równie zrozumie , e zagadnienie poprawy wydajnoci jest rozlege i naley pozna je gbiej, gdy tylko zdobdziesz wicej dowiadczenia w uytkowaniu rodowiska Unity.
Paszczyzny odcinajce i mga Aby poprawi wygld wyspy, stworzymy na niej mg. Mga w rodowisku Unity moe zosta bardzo prosto udostpniona, a póniej uyta razem z ustawieniem kamery Far Clip Plane (daleka paszczyzna odcinajca) w taki sposób, aby obiekty znajdujce si dalej ni okrelona odlego od kamery nie byy wywietlane. Dziki temu nastpi zwikszenie wydajnoci. Poprzez uycie mgy bdziesz móg wstrzyma renderowanie odlegych obiektów i jednoczenie poprawi wraenia zwizane z eksploracj wyspy. Oznacza to, e moemy zwikszy wydajno przez zmniejszenie obszaru, w którym jest przeprowadzany rendering gry, a równoczenie wci zapewnia gracza, e uyty efekt zosta zaplanowany przez projektanta.
380
Rozdzia 11. • Poprawa wydajnoci i kocowe modyfikacje
Ustawienie Far Clip Plane zostao ju omówione w rozdziale 4. podczas analizy obiektu First Person Controller. Teraz zmodyfikujmy jego warto , aby poprawi wydajno dziki zmniejszeniu obszaru, w którym obiekty s renderowane przez kamer: Q Rozwi grup nadrzdn First Person Controller poprzez kliknicie szarej strzaki
po lewej stronie nazwy w panelu Hierarchy (hierarchia). Q Wybierz obiekt podrzdny Main Camera. Q W panelu Inspector (inspektor) odszukaj komponent Camera, a nastpnie przypisz parametrowi Far Clip Plane warto 400. Jest to niewielka odlego , wyraona
w metrach. Pomimo e takie ustawienie spowoduje ograniczenie obszaru widoku, zostanie to ukryte, gdy wprowadzimy mg. Nastpnie wybierz opcj menu gównego Edit/Render Settings (edycja/ustawienie renderingu). W panelu Inspector zostan wywietlone ustawienia renderingu. Po prostu zaznacz opcj wyboru Fog (mga), a póniej kliknij obszar koloru znajdujcy si po prawej stronie parametru Fog Color (kolor mgy), by otworzy okno wyboru koloru i poziomu przezroczystoci. Przesu suwak A (kana alfa) na pozycj równ 155, odpowiadajc 60% dugoci caego paska. Zamknij okno wyboru koloru, a nastpnie w panelu Inspector wprowad warto 0,005 w polu Fog Density (gsto mgy). Parametrom kanau alfa oraz gstoci mgy zostay przypisane niskie wartoci, poniewa domylne i wysze zasoniyby widok tak skutecznie, e czstki wyrzucane przez wulkan tworzyyby zbyt duy kontrast z mg, dopóki gracz nie stanby blisko niego.
Odwzorowywanie wiata Odwzorowywanie wiata (ang. lightmapping) jest metod wypalania czy te tworzenia mapy wiata na powierzchni tekstury. Oznacza to, e owietlenie ma wpyw na wywietlany obiekt trójwymiarowy. Takie dziaanie moe zosta wykonane w aplikacji modelujcej, lecz system Unity równie pozwala na integracj wiata ze rodowiskiem, na które ono pada, zmian parametrów owietlenia i ponowne odwzorowanie wiata. Jest to sposób pracy, który odpowiada eksperymentalnej naturze samego systemu Unity. Z tego powodu wielu projektantów uywa wbudowanego w rodowisko Unity narzdzia odwzorowania wiata, a nie korzysta z zewntrznych pakietów graficznych. Dlaczego potrzebujemy mapy wiata? Po pierwsze owietlenie, które jest wykorzystywane w scenach gry, powoduje, e procesor karty graficznej jest bardziej obciony. Dziki zapamitaniu rezultatu owietlenia w teksturze (a nie przetwarzaniu róde wiata dynamicznie) uzyskujemy wzrost wydajnoci oraz jednoczenie poprawiamy wygld elementów rodowiska gry.
381
Projektowanie gier w rodowisku Unity 3.x
Uwaga Naley równie przypomnie, e w darmowej wersji rodowiska Unity uycie cieni dynamicznych nie jest wspierane, dlatego tworzenie mapy wiata na elementach rodowiska jest bardzo istotn czynnoci.
Odwzorowywanie wiata jest w zasadzie wykonywane tylko na obiektach, które nie poruszaj si w grze. Dlatego te rodowisko Unity wykorzystuje opcj wyboru Static (statyczny), dostpn dla kadego obiektu gry w górnej czci panelu Inspector (inspektor). Przekonaj si sam, e tak wanie jest! Aby przygotowa obiekt trójwymiarowy do operacji odwzorowywania wiata, naley wykona dwa wstpne dziaania: 1. Upewni si, e zasób trójwymiarowy, z którego pochodzi obiekt gry, ma wczon opcj Generate Lightmap UVs (generowanie wspórzdnych UV dla mapy wiata), dostpn dla komponentu FBXImporter w panelu Inspector. 2. Zaznaczy opcj wyboru Static (statyczny) w panelu Inspector dla obiektu gry, który istnieje w scenie, aby poinformowa rodowisko Unity, by uwzgldnio go w swoim procesie odwzorowywania wiata.
Owietlanie i wypalanie wyspy Zanim wypalimy scen, powinnimy odpowiednio przygotowa do tego obiekty: placówk, pomieszczenie do rzucania kokosami oraz ognisko.
Przygotowanie do odwzorowywania wiata Pierwszym obiektem, który przygotujemy, bdzie placówka, czyli outPost. Poniewa oczekujemy, e owietlenie wewntrzne bdzie si róni od zewntrznego, musimy owietli wntrze budynku. Zamiast jednak przypisywa ródo wiata do lampy, by sprawi , e bdzie ona wieci , uyjemy procedury cieniowania Self Illuminated (samowieccy) do komponentu Material, zawartego w skadniku lamp naszego modelu. Dziki temu uzyskamy wraenie, e lampa owietla pomieszczenie. W rzeczywistoci owietlenie bdzie jednak wprowadzane przez wypalone punkty wiata. Uwaga Pamitaj, e w rodowisku Unity Pro procedury cieniowania Self Illuminated bd powodoway owietlenie otoczenia w ramach odwzorowania wiata. Taka funkcjonalno jest elementem opcji Global Illumination (globalne owietlenie), dostpnej w rodowisku Unity Pro.
382
Rozdzia 11. • Poprawa wydajnoci i kocowe modyfikacje
Placówka i generator Zanim zmodyfikujemy instancj obiektu gry outPost, który umiecilimy ju w scenie, trzeba wybra zasób modelu outPost w folderze Book Assets/Models (zasoby ksiki/modele), znajdujcym si w panelu Project (projekt). W komponencie FBXImporter zaznacz opcj wyboru Generate Lightmap UVs, a nastpnie kliknij przycisk Apply (zastosuj) w dolnej czci obszaru Inspector. Pozwoli to rodowisku Unity na przygotowanie drugiego kanau UV w pliku zasobu dla modelu.
A teraz wybierz obiekt outPost w panelu Hierarchy (hierarchia) oraz przyjrzyj si jego ustawieniom w panelu Inspector. Moesz zauway , e opcja Static, znajdujca si u góry panelu, jest nieaktywna — wcz j. Pojawi si okno z pytaniem, czy chcesz zastosowa to ustawienie do potomków obiektu, czy tylko do samego rodzica. Powiniene wybra odpowied Yes, change children (tak, zmie dla potomków), gdy model zawiera kilka obiektów podrzdnych, takich jak stó, lampa sufitowa itd., które musz podlega procedurze odwzorowania wiata tak samo jak ciany samej struktury.
Powtórz powysze kroki dla obiektu generator, aby upewni si, e równie on bdzie uwzgldniany w procedurze odwzorowywania wiata.
Owietlenie wewntrz placówki Poniewa przygotowujemy placówk do procesu odwzorowywania wiata, bdziemy musieli owietli jej wntrze. W przeciwnym razie bdzie ona zupenie nieowietlona, gdy si do niej wejdzie. Wewntrz modelu znajduje si lampa wiszca pod sufitem, dziki której moemy owietli cae wntrze, uywajc w tym celu procedury cieniowania Self Illuminated doczonej do materiau. Jednak to nie ten materia bdzie ródem wiata w pomieszczeniu, lecz siatka, do której zosta on przypisany.
Owietlenie siatki za pomoc procedury cieniowania Self Illuminated Rozwi obiekt nadrzdny outPost, aby wywietli jego potomków, a nastpnie wybierz obiekt podrzdny lamp. Odszukaj materia lamp w panelu Inspector i z rozwijanego menu Shader (procedura cieniowania) wybierz opcj Self-Illumin/Diffuse (samowieccy/wiato rozproszone).
383
Projektowanie gier w rodowisku Unity 3.x
Kliknij obszar koloru MainColor, a póniej w oknie wyboru koloru wybierz odcie barwy ótej. Wreszcie w dolnej czci obszaru zwizanego z ustawieniami materiau przypisz parametrowi Emission (Lightmapper) (warto emisji dla procedury odwzorowywania wiata) warto 80. Parametr ten okrela poziom jasnoci materiau. Twój komponent materiau lampy powinien wyglda tak jak na poniszym rysunku:
Owietlanie wntrza za pomoc wiate punktowych, uywanych tylko do wypalania Gdy owietlasz wntrza, w których naley przeprowadzi operacj odwzorowywania wiata, moesz czsto poprawi wydajno poprzez upewnienie si, e uywane przez Ciebie róda wiata s przeznaczone tylko do procesu wypalenia. Oznacza to, e nie mog one owietla obiektów dynamicznych, co zmniejsza wydajno dziaania gry. Zamiast tego generowane wiato bdzie uyte jedynie w narzdziu odwzorowywania wiata i owietli tekstur utworzon podczas procesu wypalania. Stwórzmy takie wanie ródo wiata, które bdzie reprezentowao lamp znajdujc si wewntrz placówki. Kliknij przycisk Create (stwórz) w panelu Hierarchy, a nastpnie wybierz opcj Point Light (wiato punktowe). Aby szybko umieci nowo utworzone ródo wiata Point Light we waciwym miejscu, przecignij je i upu na obiekcie podrzdnym lamp, nalecym do rodzica outPost, dziki czemu stanie si ono jego potomkiem. A teraz kliknij ikon kóka zbatego, znajdujc si po prawej stronie komponentu Transform w panelu Inspector, i wybierz opcj Reset (resetuj). Spowoduje to umieszczenie obiektu Point Light w centrum lampy, co samo w sobie jest bardzo dobrym punktem startowym, lecz nie umoliwi owietlenia sufitu, poniewa ródo wiata przecina si z siatk, która je definiuje. Lampa ma ksztat obrotowy, co wynika z jej definicji, dlatego bdziemy musieli umieci obiekt Point Light poniej jego rodzica, wykorzystujc w tym celu o Z zamiast zazwyczaj uywanej
osi Y. Jest to czsto spotykany problem w pracy z uyciem zewntrznych modeli, z którego istnienia powiniene zdawa sobie spraw. W parametrze obiektu Point Light, reprezentujcym o Z, wprowad warto -1, co spowoduje obnienie róda wiata.
384
Rozdzia 11. • Poprawa wydajnoci i kocowe modyfikacje
Teraz powiniene si upewni , e ródo Point Light jest jedynie elementem procedury odwzorowywania wiata, a nie próbuje samodzielnie owietla innych obiektów. W komponencie Light wybierz z menu Lightmapping (odwzorowywanie wiata) opcj BakedOnly (tylko do wypalania).
I to wszystko! Obiekty outPost i generator zostay przygotowane do operacji odwzorowywania wiata, dlatego zajmijmy si teraz innymi skadnikami, czyli pomieszczeniem do rzucania orzechami kokosowymi (coconutShy) oraz ogniskiem (campfire).
Pomieszczenie do rzucania kokosami Równie w tym przypadku musimy si upewni , e model bdzie uywa wspórzdnych UV, wygenerowanych na potrzeby procedury odwzorowywania wiata. W tym celu wybierz pierwotny model coconutShy, znajdujcy si w folderze Book Assets/Models (zasoby ksiki/modele), a nastpnie zaznacz opcj Generate Lightmap UVs w komponencie FBXImporter w panelu
385
Projektowanie gier w rodowisku Unity 3.x
Inspector. Kliknij przycisk Apply, aby zapamita wprowadzone zmiany. Poniewa obiekty celów, umieszczone wewntrz pomieszczenia, pochodz z innego modelu, powtórz powyszy krok dla elementu target, równie znajdujcego si w folderze Book Assets/Models. Zakadajc, e pomieszczenie nie zawiera owietlenia zdefiniowanego w modelu, umiecimy w nim ródo wiata punktowego, aby poprawi jego wygld i zachci gracza do wejcia. W przeciwnym razie po operacji odwzorowania wiata bdzie ono zbyt przyciemnione. Kliknij przycisk Create (stwórz) w panelu Hierarchy, a nastpnie wybierz opcj Point Light (wiato punktowe) z rozwijanego menu. Uczy nowo utworzony obiekt Point Light potomkiem obiektu coconutShy. W tym celu przecignij go i upu na obiekt nadrzdny coconutShy, znajdujcy si w panelu Hierarchy. Nastpnie umie ródo wiata w rodku pomieszczenia poprzez kliknicie ikony kóka zbatego, wywietlonej w prawym górnym obszarze komponentu Transform, i wybranie opcji Reset (resetuj). Dziki temu ródo wiata zostanie umieszczone w pierwotnym centrum obiektu, które znajduje si w jego podstawie. Aby skorygowa pooenie, przypisz parametrowi osi Y warto 1,5. Oprócz tego w polu Intensity (intensywno ) wprowad warto 2, a w polu Color (kolor) wybierz kolor rónicy si od barwy biaej, na przykad jasnoóty, co sprawi, e ciany pomieszczenia bd si charakteryzoway ciepym odcieniem.
Teraz musimy uwzgldni pomieszczenie do rzucania orzechami w procesie odwzorowywania wiata. W tym celu wybierz obiekt nadrzdny coconutShy i zaznacz opcj wyboru Static (statyczny), znajdujc si obok jego nazwy w panelu Inspector. Ponownie odpowiedz Yes, change children (tak, zmie dla potomków) na pytanie, które si pojawi.
386
Rozdzia 11. • Poprawa wydajnoci i kocowe modyfikacje
Ognisko Poniewa chcielibymy, aby obiekt campfire rzuca cienie na powierzchni gruntu, a take by owietlany ródem wiata bezporedniego w procedurze wypalania, wybierz go w panelu Hierarchy, a nastpnie zaznacz opcj wyboru Static (statyczny), znajdujc si obok jego nazwy w panelu Inspector. Potwierd tak jak wczeniej, e obiekty podrzdne równie maj by statyczne.
Wypalanie mapy wiata Poniewa obiekty outPost, coconutShy i campfire zostay ju przygotowane do procedury odwzorowywania wiata, nadszed czas na zajcie si waciwym narzdziem. Otwórz okno Lightmapping (odwzorowywanie wiata) poprzez wybranie opcji menu gównego Window/Lightmapping (okno/ odwzorowywanie wiata). Wskazówka By moe bdziesz chcia zadokowa okno Lightmapping w interfejsie Unity, na przykad w pozycji panelu Inspector. Aby to zrobi, po prostu przecignij zakadk z tytuem okna i upu j po prawej stronie tytuu panelu Inspector. Okno dopasuje si do rozmiarów interfejsu i bdziesz móg przechodzi pomidzy nim i panelem Inspector, klikajc odpowiedni zakadk.
Narzdzie Lightmapping Okno Lightmapping skada si z trzech gównych zakadek: Object (obiekt), Bake (wypalanie) i Maps (mapy): Q Object: pierwsza zakadka zawiera parametry obiektu, który chcesz wypali .
Ustawienia domylne s czsto stosowane. Q Bake: ta zakadka pozwala na zdefiniowanie ustawie samej procedury wypalania.
W darmowej wersji rodowiska Unity moesz po prostu zmodyfikowa parametry jakoci i rozdzielczoci. Wersja Unity Pro umoliwia uzyskanie wikszej kontroli nad sposobem tworzenia map wiata. Q Maps: ta zakadka umoliwia uzyskanie dostpu do plików map wiata po ich
utworzeniu i zapisaniu. Pozwala to na przeprowadzenie w razie koniecznoci edycji tekstur w programach zewntrznych, takich jak Photoshop.
wiato otoczenia W opcji menu gównego Edit/Render Settings (edycja/ustawienia renderingu) moesz take zdefiniowa dla sceny parametr Ambient Light (wiato otoczenia). W naszym przypadku ródem wiata bezporedniego jest soce, dlatego wiato otoczenia pozwoli na uzyskanie ogólnego poziomu jasnoci, dziki czemu bdzie mona odróni noc od dnia. Spróbuj zmodyfikowa ten parametr, klikajc jego obszar koloru, a nastpnie eksperymentujc z ustawieniami barwy i przezroczystoci.
387
Projektowanie gier w rodowisku Unity 3.x
Pamitaj, e gdy zmodyfikujesz wiato otoczenia po wykonaniu procesu wypalania, bdziesz musia jeszcze raz przeprowadzi ten proces, wybierajc okno Lightmapping, a nastpnie opcj Bake (wypalanie).
Doczanie róde wiata Zanim bdziemy kontynuowa dziaania zwizane z wypalaniem, zmodyfikujemy dwa istniejce w scenie róda wiata. Obiekty Directional Light (czyli soce) oraz Point Light w pomieszczeniu do rzucania orzechami kokosowymi równie powinny by statyczne. ródo wiata umieszczone nad drzwiami placówki nie moe by statyczne, mimo e pozostaje w tym samym miejscu nawet wówczas, gdy po otwarciu drzwi zmienia kolor na zielony. Wynika to std, i mapa wiata jest przechowywana w postaci tekstury, która po wypaleniu nie bdzie ju si zmieniaa. Chocia nie musimy docza wspomnianych wyej róde wiata do procesu wypalania, przypisanie im atrybutu statycznoci zwikszy ogóln wydajno gry. Pamitaj, e wiata mog by wykorzystywane jedynie w procesie odwzorowywania wiata, co uzyskuje si poprzez wczenie opcji BakedOnly, uytej przez nas wczeniej dla obiektu Point Light. Inna zaleta uczynienia róde wiata statycznymi polega na tym, e przypomina Ci ona, i nie moesz ich przemieszcza . Wybierz obiekt Directional Light w panelu Hierarchy. Powiniene pamita , e jest on potomkiem pustego obiektu Environment, który moesz rozwin w razie koniecznoci. Zaznacz opcj wyboru Static w panelu Inspector, a nastpnie otwórz okno Lightmapping, jeli nie jest jeszcze widoczne na ekranie. W zakadce Object okna Lightmapping wybierz z menu Baked Shadows (cienie wypalone) opcj On (Realtime: Soft Shadows) (wczone mikkie cienie podczas dziaania gry). Inne parametry powinny pozosta niezmienione.
Wykluczanie obiektów z procedury wypalania Mimo e odwzorowywanie wiata sprawi, i nasza scena bdzie wyglda duo lepiej, a take poprawi wydajno dziaania gry, musimy pamita o tym, aby wykluczy pewne obiekty
388
Rozdzia 11. • Poprawa wydajnoci i kocowe modyfikacje
z procesu wypalania. Na przykad nie moemy pozwoli , by ródo wiata punktowego w pomieszczeniu przeznaczonym do rzucania kokosami tworzyo cienie na wypalonej teksturze. W przeciwnym razie cie rzucany przez animowany cel pozostaby na tylnej cianie! Z tego powodu nie moemy równie uczyni pudeka zapaek obiektem statycznym, gdy jego cie na stole byby widoczny nawet po zabraniu zapaek przez gracza. Rozwi obiekt nadrzdny outPost, aby wywietli jego potomka matchbox, wybierz go, a nastpnie odznacz opcj Static, znajdujc si w górnej czci panelu Inspector. Wybierz obiekt podrzdny Point Light, którego rodzicem jest coconutShy, a nastpnie w panelu Inspector wycz opcj Static. Aby upewni si, e adne cienie nie s rzucane, przejd do panelu Lightmapping i w zakadce Object przypisz parametrowi Baked Shadows opcj Off (cienie wyczone).
Wypalanie sceny Skoro nasza scena jest ju przygotowana (zauwa, e obiekt Terrain jest domylnie statyczny), moemy rozpocz wypalanie! W dolnej czci panelu Lightmapping znajdziesz trzy przyciski: Q Clear (wyczy ): ta opcja usuwa wszystkie zapamitane mapy wiata, pozwalajc
na zaprezentowanie jedynie owietlenia dynamicznego oraz jasnoci, waciwej dla materiaów i tekstur przypisanych do obiektów. Q Bake Selected (wypal wybrane): ta opcja wypali obiekt, który zosta wybrany w panelu
Hierarchy, a oprócz tego usunie poprzednio wypalon scen. Taka funkcjonalno jest przydatna, pozwala bowiem skoncentrowa si na owietleniu pojedynczego obiektu bez czekania na zakoczenie procesu renderowania caej sceny. Q Bake (wypal): ta opcja wypala ca scen.
W tym momencie by moe chciaby wróci do edytora terenu, aby uzupeni wysp o dodatkowe szczegóy lub doda wicej drzew wokó obiektów outPost i coconutShy, dziki czemu obszar wygldaby bardziej atrakcyjnie. Po operacji odwzorowania wiata drzewa mogyby rzuca cienie, co uczyni ca sceneri bardziej naturaln. Przejd do okna Lightmapping i wybierz zakadk Bake (wypal). Przypisz parametrowi Resolution (rozdzielczo ) warto 50. Definiuje on ogóln jako wypalania. Jeli uwaasz, e docelowy materia ma zbyt nisk jako , zawsze moesz zmodyfikowa ten parametr, odpowiednio go zwikszajc, a nastpnie ponownie wykona operacj odwzorowywania wiata. Wypalanie mapy wiata jest czsto dugotrwaym procesem i zaley przede wszystkim od prdkoci komputera, w którym zainstalowano rodowisko Unity. Poniewa przeprowadzanych jest wiele operacji obliczeniowych, w zalenoci od zoonoci sceny wypalanie moe trwa od kilku sekund do kilku godzin. W naszym przypadku nie mamy zbyt wielu obiektów do wypalenia, wic procedura nie powinna trwa zbyt dugo, ale moe powiniene zaj si czym innym podczas oczekiwania na jej zakoczenie! Du zalet narzdzia Lightmapping w rodowisku Unity jest to, e moesz oglda swoj scen, podczas gdy wypalanie jest wykonywane w tle.
389
Projektowanie gier w rodowisku Unity 3.x
Oczywicie nie jest moliwe wprowadzanie zmian, poniewa spowodowaoby to uniewanienie procedury. Kliknij przycisk Bake (wypal) w dolnej czci okna Lightmapping, aby rozpocz wypalanie. Ukae si niebieski pasek postpu, pokazujcy obliczenia wykonywane dla rónych skadników procesu odwzorowywania wiata. Bd cierpliwy! Warto poczeka na zakoczenie wypalania! Oto kilka przykadowych wyników — jak moesz zauway , po uzupenieniu sceny dodatkowym owietleniem i cieniami rzeczywicie wida rónice. Przed operacj odwzorowywania wiata:
Po operacji odwzorowywania wiata:
390
Rozdzia 11. • Poprawa wydajnoci i kocowe modyfikacje
Aby dowiedzie si wicej o odwzorowywaniu wiata, zapoznaj si z odpowiedni dokumentacj rodowiska Unity: http://www.unity3d.com/support/documentation/Manual/Lightmap pingInDepth.html.
Odtwarzanie obiektów dynamicznych Poniewa pozwolilimy rodowisku Unity na wczenie opcji Static we wszystkich potomkach nalecych do obiektów outPost, coconutShy i campfire (a przez to doczylimy je do procedury wypalania), musimy ponownie zaj si niektórymi z nich i uczyni je dynamicznymi, aby umoliwi poprawne wykonywanie animacji. Odszukaj ponisze obiekty podrzdne i odznacz w nich opcj wyboru Static, znajdujc si w górnej czci panelu Inspector: Q door — potomek obiektu nadrzdnego outPost, Q target (trzy instancje) — potomkowie obiektu nadrzdnego coconutShy, Q SmokeSystem i FireSystem — potomkowie obiektu campfire.
Pamitaj, e gdyby jeszcze raz chcia przeprowadzi operacj wypalania sceny, powiniene tymczasowo wczy opcj Static w powyszych obiektach.
Kocowe upikszenia W tym podrozdziale postaramy si uzupeni gr o dodatkowe upikszenia, dziki czemu gracz bdzie mia wraenie, e uywa ukoczonej gry. Te dodatki nie maj wikszego wpywu na rozgrywk, lecz pomagaj ulepszy program jako produkt kocowy. Zajmiemy si: Q uzupenieniem wulkanu o system czstek w scenie Island, Q stworzeniem smug wietlnych, które prezentuj trajektori lotu orzechów kokosowych
w minigrze.
Wulkan! W rozdziale 3. przy uyciu edytora terenu zdefiniowalimy powierzchni wyspy, a na jednym z jej wybrzey utworzylimy wulkan. Aby wyglda on bardziej realistycznie, doczymy do niego pióropusz dymu oraz uzupenimy go o trójwymiarowy dwik gotujcej si lawy. Dziki uyciu elementów wizualnych i dwikowych uzyskamy bardziej dynamiczne i realistyczne wraenia, co pozwoli na zachowanie odpowiedniego poziomu immersji w naszej grze.
391
Projektowanie gier w rodowisku Unity 3.x
Rozpocznijmy od stworzenia nowego systemu czstek w rodowisku Unity. W tym celu kliknij przycisk Create (stwórz) w panelu Hierarchy (hierarchia), a nastpnie wybierz opcj Particle System (system czstek) z rozwijanego menu. Moesz take wybra opcj menu gównego GameObject/Create Other/Particle System (obiekt gry/stwórz inny/system czstek). Spowoduje to utworzenie nowego obiektu gry, nazwanego Particle System. Wybierz go i zmie t nazw na Volcano Smoke.
Zdefiniowanie pooenia systemu czstek Wulkan jest po prostu skadnikiem terenu, nie jest wic niezalenym obiektem gry widocznym w panelu Hierarchy. Oznacza to, e zdefiniowanie wzgldnego pooenia systemu czstek w odniesieniu do obiektu nadrzdnego nie jest moliwe. W zwykych przypadkach moglibymy utworzy nowy obiekt, który byby potomkiem obiektu nadrzdnego, a nastpnie zresetowa jego wzgldne pooenie do wartoci (0, 0, 0). Jednak w tej sytuacji musimy uy gadetu View (widok), znajdujcego si w panelu Scene (scena). Kliknij jego o Y (zielony uchwyt), aby zmieni widok z perspektywicznego na spojrzenie z góry (lub z lotu ptaka). Jeli poprawnie wykonasz t czynno , Twój gadet View powinien wywietla sowo Top (z góry).
Aby zlokalizowa obiekt Volcano Smoke, zaznacz go w panelu Hierarchy, a nastpnie wybierz narzdzie Translate (skrót klawiszowy W), by wywietli jego osie w oknie sceny. Uywajc widoku Top, moemy odpowiednio umieci system czstek na osi X i Z poprzez przecignicie jego uchwytów w widoku Scene a do krateru wulkanu. Aby si upewni , e widzisz zarówno osie systemu czstek, jak i sam wulkan, powiniene poszerzy sam widok. W tym celu wybierz narzdzie Hand (skrót klawiszowy Q), a nastpnie, przytrzymujc wcinity klawisz Alt, nacinij prawy przycisk myszy i przemie j w lewo, aby oddali widok. Po wykonaniu tej czynnoci wró do narzdzia Translate (skrót klawiszowy W), by ponownie wywietli uchwyty osi obiektów. Odpowiednio przecignij uchwyty osi X (czerwony) i Z (niebieski), dopóki nie stwierdzisz, e Twój system czstek znajduje si dokadnie w rodku krateru wulkanu widocznego z tej perspektywy. Twój ekran powinien by podobny do tego z poniszego rysunku. Nie martw si, e strzaki zmieniaj kolor na óty podczas ich wybierania — na pewno uywasz waciwego uchwytu!
392
Rozdzia 11. • Poprawa wydajnoci i kocowe modyfikacje
A teraz kliknij uchwyt osi X w gadecie View, by uzyska boczny widok wyspy. Uyj go razem z narzdziem Translate, aby przecign zielony uchwyt osi Y systemu czstek do centrum wulkanu, tak jak zaprezentowano na poniszym rysunku:
Wreszcie wró do widoku perspektywicznego, klikajc biay szecian znajdujcy si w rodku gadetu View, w prawym górnym naroniku widoku Scene.
393
Projektowanie gier w rodowisku Unity 3.x
Wymagane zasoby W folderze Book Assets (zasoby ksiki) znajduj si nastpujce zasoby: Q w folderze Textures (tekstury) tekstura Smoke, suca do zdefiniowania pióropusza
dymu z wulkanu, Q w folderze Sounds (dwiki) klip audio volcanoRumble, reprezentujcy wrzc law
w wulkanie.
Tworzenie materiau dymu W kolejnym kroku musimy stworzy materia dla tekstury dymu wulkanu. By zachowa porzdek, umiecimy go wewntrz istniejcego folderu Materials (materiay), zdefiniowanego dla gównego projektu, a nie w katalogu Book Assets. Wybierz folder Materials w panelu Project (projekt), a nastpnie kliknij przycisk Create (stwórz) i wska opcj Material (materia) z rozwijanego menu. Zmie nazw nowo utworzonego materiau na Volcano Smoke Material, a póniej upewnij si, e jest wybrany w panelu Project, by wywietli jego ustawienia w panelu Inspector (inspektor). Z menu Shader (procedura cieniowania) wybierz opcj Particles/Alpha Blended (systemy czstek/czenie kanau alfa). Spowoduje to zdefiniowanie stylu renderowania, który jest odpowiedni dla czstek. Opcja Alpha Blended pozwoli na wywietlenie przezroczystego ta (znanego jako kana alfa) tekstur definiujcych czstki, a take zaokrglonych krawdzi. Przecignij plik tekstury volcanoSmoke z katalogu Book Assets/Textures i upu go na pusty obszar po prawej stronie ustawienia Particle Texture (tekstura czstki), nie zmieniajc jednoczenie parametrów Tiling (kafelkowanie) i Offset (przesunicie). A teraz przecignij materia Volcano Smoke Material z folderu Materials w panelu Project, po czym upu go na obiekcie systemu czstek Volcano Smoke w panelu Hierarchy.
Ustawienia systemu czstek Podobnie jak ma to miejsce w przypadku kadego efektu wizualnego, równie systemy czstek wymagaj czstego eksperymentowania z nimi, aby osign dobrze wygldajcy rezultat. Biorc to pod uwag, zalecamy, by wykorzysta ponisze dane jako sugerowane ustawienia, a nastpnie powici troch czasu, eby uzyska efekt, który: Q podoba Ci si, Q dobrze wspógra z utworzonym przez Ciebie stylem krateru wulkanu.
Pamitaj, e tylko wymienione niej parametry powinny zosta przez Ciebie zmodyfikowane; inne zostaw niezmienione.
394
Rozdzia 11. • Poprawa wydajnoci i kocowe modyfikacje
Ustawienia komponentu Ellipsoid Particle Emitter Q Min Size (rozmiar minimalny): 40, Q Max Size (rozmiar maksymalny): 60, Q Min Energy (energia minimalna): 10, Q Max Energy (energia maksymalna): 30, Q Min Emission (minimalny poziom emisji): 2, Q Max Emission (maksymalny poziom emisji): 8, Q World Velocity Y-axis (prdko w osi Y dla wspórzdnych wiata): 30.
Ustawienia komponentu Particle Animator Q Color Animation[0] (kolor animacji, skadnik 0): kolor ciemnopomaraczowy,
70% kanau alfa, Q Color Animation[1] (kolor animacji, skadnik 1): kolor czerwonoszary, 50% kanau alfa, Q Color Animation[2] (kolor animacji, skadnik 2): redni odcie szaroci, 40% kanau alfa, Q Color Animation[3] (kolor animacji, skadnik 3): kolor ciemnoszary, 25% kanau alfa, Q Color Animation[4] (kolor animacji, skadnik 4): kolor czarny, 5% kanau alfa, Q Size Grow (zwikszanie rozmiaru): 0,05, Q Rnd Force (sia losowa): (10, 0, 10).
A teraz powi troch czasu, aby zmodyfikowa powysze parametry w celu lepszego dopasowania systemu czstek do Twojego terenu. Aby dowiedzie si wicej o systemach czstek, zapoznaj si z dokumentacj rodowiska Unity: http://www.unity3d.com/support/documentation/Manual/Particle%20Systems.html.
Dodawanie róda d wiku do wulkanu Ostatni etap tworzenia efektów prawdziwego wulkanu polega na dodaniu komponentu Audio Source, który w ptli bdzie odtwarza dwik wrzcej lawy. Jak wczeniej wspomniano, wulkan nie jest rzeczywistym obiektem gry, dlatego równie w tym przypadku nie moemy w prosty sposób doda do niego komponentu. Jednake teraz dysponujemy obiektem znajdujcym si w rodku wulkanu — jest nim system czstek. Oznacza to, e moemy go uzupeni o komponent audio. Upewnij si, e w panelu Hierarchy zosta wybrany obiekt Volcano Smoke, a nastpnie przejd do opcji menu gównego Component/Audio/Audio Source (komponent/dwik/ródo dwiku). Spowoduje to umieszczenie komponentu Audio Source na kocu listy komponentów w panelu Inspector. Poniewa system czstek zawiera ju szereg skadników umoliwiajcych jego dziaanie, by moe za pomoc paska przewijania bdziesz musia przej do dolnej czci panelu Inspector, aby znale komponent Audio Source.
395
Projektowanie gier w rodowisku Unity 3.x
Klip audio volcanoRumble, znajdujcy si w folderze Book Assets/Sounds (zasoby ksiki/dwiki), przypisz do parametru Audio Clip (klip audio): przecignij go z panelu Project. Nastpnie upewnij si, e zostaa wybrana opcja Play On Awake (automatyczne odtwarzanie). Dziki temu dwik nie wymaga specjalnego wczenia, lecz bdzie automatycznie odtwarzany po wczytaniu sceny. Rozwi ustawienia 3D Sound Settings (ustawienia dwiku trójwymiarowego) i zmodyfikuj wycznie ponisze parametry, w innych pozostawiajc ustawienia domylne: Q Min Distance (odlego minimalna): 50. Dziki temu dwik bdzie wyranie
syszalny na zewntrz wulkanu, a jego maksymalna amplituda wystpi w miejscu odlegym o 50 metrów od lokalizacji systemu czstek. Q Max Distance (odlego maksymalna): 500. Dziki temu ustawieniu dwik wulkanu
bdzie odbierany nawet na najbardziej odlegych kracach wyspy. Poniewa rozmiar wyspy wynosi 500×500 metrów, od dwiku wrzcej lawy nie mona uciec! Wreszcie zaznacz opcj wyboru Loop (ptla), aby upewni si, e dwik bdzie odtwarzany przez cay czas.
Testowanie dziaania wulkanu Poniewa wulkan jest gotowy, powinnimy przetestowa skuteczno jego dziaania. Najpierw wybierz opcj menu gównego File/Save Scene (plik/zapisz scen), aby upewni si, e nie utracisz nowo wprowadzonych zmian. Nastpnie kliknij przycisk Play (granie) i spróbuj i w kierunku wulkanu. Pióropusz dymu powinien unosi si w powietrzu. Podczas zbliania si do wulkanu powiniene sysze coraz goniejszy dwik gotujcej si lawy. Wskazówka Pamitaj, e zmiany w panelu Inspector wprowadzone podczas testowania gry zostan od razu wycofane po ponownym klikniciu przycisku Play w celu przerwania testów. Wykorzystaj t moliwo do przeprowadzenia rzeczywistych testów, a nastpnie upewnij si, e po zatrzymaniu dziaania gry odpowiednio zmodyfikowae waciwy komponent w panelu Inspector. Równie we pod uwag, e powysze stwierdzenie nie dotyczy zmian wprowadzonych w obszarze zasobów panelu Project (np. w folderze Materials), poniewa zmieniasz sam zasób, a nie waciwo obiektu na scenie.
Warto przypomnie , e w celach testowych moesz zwikszy prdko poruszania si obiektu First Person Controller, dziki czemu bdziesz móg szybciej chodzi po wyspie. Aby to zrobi , w panelu Hierarchy wybierz obiekt First Person Controller podczas dziaania gry testowej. Nastpnie przypisz odpowiedni warto do zmiennej publicznej Max Forward Speed, znajdujcej si w komponencie Character Motor (Script). Pamitaj, e modyfikacja zostaa wprowadzona wycznie w celach testowych, wic nie przejmuj si nadmiern prdkoci! Prawidowa warto zostanie przywrócona zaraz po klikniciu przycisku Play, który przerywa testowanie gry, co oznacza, e nie utracisz poprzednio ustawionych parametrów.
396
Rozdzia 11. • Poprawa wydajnoci i kocowe modyfikacje
Trajektorie lotu orzechów kokosowych A teraz upikszymy minigr poprzez dodanie smug wietlnych do prefabrykatów orzechów kokosowych. Dziki temu gracz bdzie widzia wietlny lad, odpowiadajcy trajektorii lotu kokosa, co powinno by interesujcym efektem wizualnym. W tym celu wykorzystamy dostpny w rodowisku Unity komponent Trail Renderer. Pozwala on na uzyskanie efektów, które rzeczywicie zwikszaj atrakcyjno poruszajcych si obiektów.
Edycja prefabrykatu Aby zaimplementowa wspomnian wyej modyfikacj, musimy wróci do prefabrykatu orzecha kokosowego z rozdziau 7., poniewa komponent Trail Renderer musi zosta do niego przypisany. Otwórz folder Prefabs (prefabrykaty) w panelu Project, a nastpnie odszukaj zasób prefabrykatu Coconut. Przecignij go na scen, abymy mogli go edytowa . Co prawda, zasoby mona modyfikowa bezporednio w folderze panelu Project, w którym si znajduj, lecz jeli chcielibymy mie moliwo uzyskania podgldu i testowania tworzonych efektów, najlepiej bdzie, gdy umiecimy kokos w scenie i zobaczymy „na ywo” jego dziaanie. Pamitaj, e nacinicie klawisza F przy jednoczesnym umieszczeniu kursora myszy nad widokiem Scene powoduje przyblienie wybranego obiektu. Wykonaj t operacj, jeeli nie widzisz orzecha kokosowego w oknie Scene.
Komponent Trail Renderer Aby doda komponent, upewnij si, e prefabrykat Coconut jest wci wybrany w panelu Hierarchy, a nastpnie wybierz opcj menu gównego Component/Particles/Trail Renderer (komponent/systemy czstek/renderer ladu). Zostaniesz poinformowany, e dziaanie spowoduje utrat poczenia z prefabrykatem. Kliknij przycisk Add (dodaj), by kontynuowa . Nasz prefabrykat zostanie odpowiednio zaktualizowany, gdy zakoczymy tworzenie ladu. Nowo dodany komponent po prostu wywietla krzyw wektorow w ksztacie uku, tworzc szereg punktów za obiektem poruszajcym si w wiecie trójwymiarowym. Poprzez zdefiniowanie okrelonego czasu trwania efektu, rodzaju materiau oraz pocztkowych i kocowych szerokoci krzywej moemy osign zamierzony rezultat. Aby zobaczy dziaanie komponentu przy domylnych wartociach parametrów, kliknij przycisk Play i przyjrzyj si upadkowi orzecha kokosowego. Za kokosem pojawi si róowy pas, niezawierajcy adnej tekstury. Nie wyglda to zbyt ciekawie! Najpierw zajmiemy si sprawami zwizanymi z wydajnoci. W przypadku uytkowników wersji Unity Pro moliwo uycia dynamicznych cieni jest standardem. Poniewa jednak nie chcemy, by krzywa rzucaa lub wywietlaa jakiekolwiek cienie, trzeba odznaczy dwa pierwsze parametry w komponencie Trail Renderer w panelu Inspector. Obsuga cieni jest, ogólnie rzecz biorc, kosztowna, a w zwizku z tym, e renderowanie ladu dodatkowo wykorzystuje moc przetwarzania komputera gracza, kada moliwo poprawienia wydajnoci jest dobrze widziana.
397
Projektowanie gier w rodowisku Unity 3.x
Rozwi parametr Materials (materiay), aby wywietli ustawienia Size (rozmiar) i Element 0 (element 0). W tym miejscu moemy zdefiniowa tekstur uywan do wywietlania ladu. Stworzylimy ju materia ognia, a wic moemy go ponownie uy , gdy wykorzystuje on odpowiedni rodzaj procedury cieniowania — Additive (soft) (cieniowanie addytywne mikkie). Otwórz folder Materials w panelu Project i wyszukaj materia Flame. W dalszej kolejnoci przecignij go na parametr Element 0 w miejsce, w którym w tej chwili widnieje napis None (Material) (brak wybranego materiau). Aby lad nie by zbyt dugi, przypisz parametrowi Time (czas) warto 0,25. Oznacza to, e lad bdzie pozostawa w powietrzu przez 0,25 sekundy. Punkty na kocu ladu s usuwane po upyniciu zdefiniowanego czasu. W polu Start Width (szeroko pocztkowa) wprowad warto 0,25, a w polu End Width (szeroko kocowa) — 0,1. Parametry te definiuj szeroko renderowanego materiau na pocztku i kocu ladu. Ogólnie mówic, sensowne jest przypisanie wikszej wartoci dla pocztku, by uzyska efekt zwania ladu. Wreszcie rozwi parametr Colors (kolory) — zostanie wywietlonych pi biaych obszarów koloru. Dziki opcji Colors moemy animowa wygld ladu poprzez zmian jego koloru i widocznoci, wykorzystujc w tym celu ustawienia kanau alfa. Poniewa tekstura ognia jest kolorowa, nie musimy tu modyfikowa odpowiednich barw, lecz sprawimy tylko, e lad bdzie zanika. Kliknij po kolei kady obszar koloru i wprowad w polu A (kana alfa) odpowiednie wartoci, poczynajc od 200 i za kadym razem zmniejszajc je o 50.
Pozostae pola mog zosta niezmienione. Parametr Min Vertex Distance (najmniejsza odlego midzy wierzchokami) okrela, jaka powinna by minimalna odlego midzy dwoma punktami tworzcymi lad. Wzrost liczby punktów powoduje, e lad zawiera wicej szczegóów, lecz jednoczenie wymaga wtedy dodatkowej mocy obliczeniowej. Parametr Autodestruct (samounicestwienie) nie moe zosta wczony, poniewa obiekt zawiera skrypt, który obsuguje usuwanie prefabrykatów ze wiata gry (jest nim skrypt Object Tidy, stworzony przez nas w rozdziale 7.).
398
Rozdzia 11. • Poprawa wydajnoci i kocowe modyfikacje
Aktualizacja prefabrykatu Przed chwil modyfikowalimy instancj prefabrykatu, która stracia poczenie ze swoim pierwotnym zasobem (std te komunikat wywietlany podczas dodawania komponentu renderera ladu). Dlatego bdziemy musieli jeszcze wprowadzi zmiany w oryginalnym prefabrykacie, aby kada jego nowa instancja zawieraa opcj tworzenia ladu. Masz dwie moliwoci wykonania powyszego zadania: wybierz obiekt Coconut w panelu Hierarchy, a nastpnie przejd do opcji menu gównego GameObject/Apply Changes to Prefab (obiekt gry/wprowad zmiany w prefabrykacie) lub uyj przycisku Apply (zastosuj), znajdujcego si na górze panelu Inspector, do naszego obiektu.
Poniewa uaktualnie oryginalny zasób prefabrykatu, nie musimy ju mie jego instancji w scenie. Po prostu wybierz obiekt Coconut w panelu Hierarchy, a nastpnie usu go za pomoc odpowiedniego skrótu klawiszowego (PC: Del, Mac: Command+Backspace). Aby sprawdzi dziaanie efektu, przetestuj gr: spróbuj rzuca orzechami kokosowymi w minigrze, któr wczeniej stworzylimy.
399
Projektowanie gier w rodowisku Unity 3.x
Powiniene widzie ogniste lady tworzce trajektorie lotu kadego z rzucanych kokosów! Po zakoczeniu testów nie zapomnij przerwa dziaania gry, a nastpnie wybierz opcj menu gównego File/Save Scene (plik/zapisz scen), by zapamita stan projektu.
Podsumowanie W tym rozdziale omawialimy zagadnienia zwizane z optymalizacj i tworzeniem efektów wizualnych oraz owietlenia. S one jedynie wierzchokiem góry lodowej w porównaniu z tym, co moesz robi w rodowisku Unity. Poniewa system pozwala na atw implementacj upikszajcych opcji, jest wane, aby pamita, e takie opcje powinny by brane pod uwag dopiero wówczas, gdy gra jest ju stworzona. Kocowe ulepszenia s idealnym sposobem na zakoczenie Twojego projektu, lecz waciwa rozgrywka powinna by zawsze na pierwszym miejscu. Skoro ukoczylimy gr, w nastpnym rozdziale zajmiemy si jej budowaniem i testowaniem, a take udostpnianiem uytkownikowi docelowemu. Przyjrzymy si równie metodom pozwalajcym na dalsz optymalizacj gry oraz zastanowimy si, jak moe by ona traktowana z punktu widzenia niezalenego projektanta.
400
12 Budowanie i udostpnianie Aby przeksztaci nasz gr z prostego przykadu w co, co moe zosta przekazane testerom, powinnimy rozway róne platformy docelowe i zastanowi si, w jaki sposób moemy j udostpni w sieci oraz wyeksportowa w postaci niezalenej aplikacji. Najlepsz metod rozwijania swoich umiejtnoci projektowych jest dzielenie si swoj prac. Jednymi z najwaniejszych elementów kreatywnoci s zdolno akceptowania innych punktów widzenia i pozwolenie, by wzbogaciy one Twoj twórcz osobowo projektanta. Dlatego te moliwo eksportowania aplikacji sieciowych jest bardzo wan opcj w rodowisku Unity. Z tego rozdziau dowiemy si, jak mona eksportowa gry na obie platformy docelowe. rodowisko Unity umoliwia zdefiniowanie rónych parametrów jakociowych kocowej wersji gry, a take przeprowadza kompresj tekstur oraz innych zasobów. Powiniene równie zdawa sobie spraw z tego, e w przypadku budowania wersji sieciowej nastpuje wykrywanie odpowiedniej platformy, gdy czasem moe zaistnie potrzeba wprowadzenia niewielkiej modyfikacji w grze przeznaczonej do internetu, w porównaniu z pen wersj samodzieln lub mobiln, jeli dysponujesz jednym z dodatków Unity, na przykad dla systemów iOS lub Android. Standardowa darmowa wersja Unity udostpnia moliwo budowania gier na takie platformy: Q PC i Mac (aplikacja samodzielna), Q Mac OS X (widget aplikacji Dashboard), Q internet (aplikacja Web Player).
Wersja Pro oraz dodatki zwizane z urzdzeniami mobilnymi i konsol mog by uywane do budowania gier na powysze platformy. S one jednoczenie wymagane w celu umoliwienia tworzenia projektów do konsoli i urzdze mobilnych. Dodatki mobilne pozwalaj równie tworzy wersje dla sprztu, który wykorzystuje systemy operacyjne iOS lub Android OS.
Projektowanie gier w rodowisku Unity 3.x
Od profesjonalnych projektantów dodatki konsolowe bd wymaga uycia sprztowych zestawów narzdzi, które pochodz od odpowiednich producentów. Z tego rozdziau dowiemy si, w jaki sposób mona zmodyfikowa zasoby, aby stworzy wersj gry jako aplikacj samodzieln lub przeznaczon do internetu. Omówimy nastpujce zagadnienia: Q opcje budowania, Q opcje Build Settings (ustawienia budowania), pozwalajce na doczanie scen
i wybranie platformy, Q panel Player Settings (ustawienia gracza), pozwalajcy na stworzenie wersji gry
bdcej aplikacj samodzieln lub przeznaczon do internetu, Q wykrywanie platformy w celu usunicia zbdnych elementów z wersji przeznaczonych do internetu, Q sposoby udostpniania gier innym osobom oraz uzyskiwanie dalszej pomocy w projektowaniu w rodowisku Unity.
Opcje budowania rodowisko Unity oferuje moliwo dokonania wyboru midzy rónymi platformami docelowymi. Rozwaajc swoj prac jako projektant Unity, powiniene wiedzie , e rodowisko to bdzie na pewno uzupeniane o dodatkowe opcje, gdy pojawi si nowe platformy programowe lub sprztowe. Aktualne opcje budowania s dostpne w oknie Build Settings (ustawienia budowania), które zaprezentowano na poniszym rysunku: Zanim zajmiemy si budowaniem docelowej wersji gry, zapoznajmy si z dostpnymi w tym oknie opcjami.
Web Player Podczas umieszczania w sieci dowolnych treci wykorzystujcych wtyczki naley je przesya w postaci pakietu, który wywouje zainstalowany dodatek. W celu uycia gier udostpnionych dla platformy sieciowej bdzie konieczne pobranie wtyczki Unity Web Player i zainstalowanie jej w przegldarce, podobnie jak ma to miejsce w przypadku treci Adobe Flash wymagajcych uycia aplikacji Flash Player. Aplikacja Web Player jest dostpna pod adresem http://www. unity3d.com/webplayer. Jeli jednak gracz bdzie chcia wczyta gr, a nie ma odtwarzacza Web Player, otrzyma informacj zachcajc go do jego zainstalowania, dlatego te prawdopodobnie bdzie musia odwiedzi powysz stron internetow.
402
Rozdzia 12. • Budowanie i udostpnianie
Docelowe pliki gier przeznaczonych do internetu maj rozszerzenie .unity3d. Uywaj one wtyczki Unity Web Player razem z towarzyszcym im plikiem HTML, zawierajcym niezbdny kod. Osadzony plik HTML moe zosta nastpnie pobrany razem z plikiem gry i umieszczony na stronie internetowej stworzonej przez uytkownika. Aplikacja Web Player wykorzystuje przegldark internetow do wczytania pliku HTML, który wywouje wtyczk Unity. Dlatego te dowolny komputer, na którym zostaa uruchomiona gra Unity stworzona dla rodowiska sieciowego, udostpnia swoj moc przetwarzania przegldarce, z czego pewna cz jest przeznaczona do wspierania odtwarzacza Web Player umieszczonego na stronie internetowej. Biorc to pod uwag, powinno si udostpnia gr w niszej rozdzielczoci dla rodowiska sieciowego w porównaniu z wersj samodzieln. Nasz gr zaprojektowalimy dla stosunkowo niskiej rozdzielczoci ekranu 1024×768 pikseli. Jednake podczas budowania wersji przeznaczonej dla odtwarzacza Web Player rozmiar ekranu powinien zosta zmniejszony do przykadowej rozdzielczoci 800×600 pikseli. Dziki temu obcienie procesora karty graficznej bdzie mniej intensywne, poniewa bdzie on musia renderowa klatki o niszej rozdzielczoci, a to pozwoli na uzyskanie wikszej wydajnoci. Z tego rozdziau dowiemy si, jakie parametry naley zmodyfikowa , aby zbudowa gr przeznaczon dla wspomnianej wyej rozdzielczoci.
Web Player Streamed Kolejna opcja budowania gry — Web Player Streamed (strumieniowa aplikacja Web Player) — pozwala na stworzenie gry przeznaczonej dla rodowiska sieciowego, która nie zmusza gracza do zbyt dugiego oczekiwania na wczytanie caej aplikacji.
403
Projektowanie gier w rodowisku Unity 3.x
Gdy w poczeniu sieciowym pojawia si jakie opónienie, uytkownicy najczciej zaczynaj traci cierpliwo . Dlatego bardzo wane staje si ograniczenie czasów wczytywania podczas tworzenia wersji gry przeznaczonej do internetu. Uycie opcji Web Player Streamed oznacza, e moesz rozpocz granie w gr, jeszcze zanim wszystkie jej zasoby zostan zaadowane. Gdy gracz jest zajty obsug pierwszej sceny, pozostae skadniki gry s wczytywane w tle. Takie zachowanie jest porównywalne z dziaaniem stron udostpniajcych strumieniowe przesyanie treci wideo, takich jak YouTube. Dziki temu, e dane s przekazywane w niewielkich pakietach, moliwe jest rozpoczcie ogldania klipów, zanim zostan one cakowicie wczytane do komputera. Czynnik ten jest szczególnie wany w sytuacji, gdy umieszczasz swój program na portalach powiconych grom komputerowym, takim jak www.kongregate.com, www.miniclip.com lub www.indiepubgames.com. Takie strony oczekuj, e Twoja gra zostanie uruchomiona po wczytaniu okoo 1 MB danych (dokadne parametry róni si w zalenoci od portalu). Dziki trzymaniu si tej zasady bdziesz prawdopodobnie móg umieci swoj gr na wyej wymienionych stronach i zyskasz moliwo zaprezentowania swojej pracy. Aby dowiedzie si wicej o strumieniowaniu w sieci, przeczytaj odpowiedni fragment dokumentacji Unity: http://unity3d. com/support/documentation/Manual/Web%20Player%20Streaming.html.
Aplikacje samodzielne dla komputerów PC i Mac Wersje samodzielne s penymi aplikacjami, które mog by dostarczane w postaci niezalenych plików wykonywalnych. Tworzenie gry w postaci samodzielnej aplikacji przeznaczonej dla komputera PC oznacza konieczno utworzenia folderu, w którym zostanie umieszczony plik wykonywalny (.exe) wraz z zwizanymi z nim zasobami, niezbdnymi do uruchomienia programu. W przypadku systemu Mac OS X nastpi wygenerowanie pojedynczego pliku aplikacji, zawierajcego ju w sobie wszystkie zasoby. Budowanie wersji samodzielnej jest najlepszym sposobem na zapewnienie najlepszej wydajnoci Twojej gry, poniewa wszystkie pliki s przechowywane lokalnie, a uytkownik w trakcie grania najczciej nie uruchamia innych aplikacji, co moe mie miejsce w przypadku wersji przeznaczonych do przegldarek internetowych. Jednake dziki duej sprawnoci systemu Unity wikszo gier zaprojektowanych za jego pomoc dziaa w odtwarzaczu Web Player tak samo wydajnie jak w postaci samodzielnego programu.
Widget aplikacji Dashboard dla OS X Systemy operacyjne Mac (wersja 10.4 i nowsze) dysponuj opcj zwan Dashboard. Jest to zestaw prostych narzdzi i programów, znanych pod nazw widgetów, które mog zosta wywietlone w kadej chwili na ekranie. rodowisko Unity moe utworzy gr w postaci widgetu, co jest po prostu kolejn moliwoci udostpnienia Twojej twórczoci innym osobom. Jeli tworzysz
404
Rozdzia 12. • Budowanie i udostpnianie
zwyk amigówk lub gr suc po prostu do zabijania czasu, bdzie to dla Ciebie odpowiedni sposób dostarczenia swoich prac kocowym uytkownikom. Jednake do gier, których wiat jest widziany z perspektywy pierwszej osoby (czyli przykad omawiany w tej ksice), aplikacja Dashboard nie jest zalecana. Gry udostpniane w postaci widgetu powinny by proste, poniewa unikamy wówczas adowania duej iloci danych do programu, a przez to rezerwowania odpowiedniej puli pamici. Nie moe ona zosta zwolniona, gdy gra dostpna jako widget musi mie moliwo natychmiastowego uruchamiania lub zatrzymywania.
Ustawienia budowania W rodowisku Unity wybierz opcj menu gównego File/Build Settings (plik/ustawienia budowania), a nastpnie przyjrzyj si dostpnym parametrom. Powiniene zobaczy opcje omówione w powyszych punktach. Kada platforma prezentowana w oknie Build Settings (ustawienia budowania) zawiera dodatkowe parametry, dostpne w postaci opcji wyboru i wywietlane po lewej stronie panelu. Moesz oczywicie wyeksportowa swój projekt poprzez wybranie (podwietlenie w kolorze niebieskim) docelowej platformy, a w dalszej kolejnoci kliknicie przycisku Build (buduj). Jednake w celu uzyskania najlepszej konfiguracji, dopasowanej do docelowej platformy, powiniene j wybra , a nastpnie klikn przycisk Switch Platform (zmie platform), umieszczony w dolnej czci okna Build Settings. Spowoduje to, e rodowisko Unity przystosuje si do wybranej przez Ciebie platformy. Jest to szczególnie wane, gdy chcesz udostpnia gry w rodowisku mobilnym. Wówczas rodowisko Unity odpowiednio zmodyfikuje wykorzystywane zasoby w celu dopasowania ich do wybranej platformy mobilnej, automatycznie zmieniajc dla nich ustawienia kompresji w panelu Inspector (inspektor). Inn wan zalet takiego wyboru jest to, i w widoku Game (gra) jest wówczas wywietlana docelowa platforma z rozdzielczoci ekranu w postaci odpowiedniego ustawienia. Pozwala to na przetestowanie gry przy uyciu poprawnej wielkoci ekranu, a dziki temu na wywietlenie elementów dwuwymiarowych w rzeczywistych pooeniach.
405
Projektowanie gier w rodowisku Unity 3.x
Na samej górze okna Build Settings znajduje si lista scen dodanych do projektu. Na pierwszym miejscu jest wywietlona scena Menu. Wane jest, aby scena, która powinna zosta najpierw zaprezentowana graczowi, znajdowaa si na pierwszym miejscu na licie Scenes In Build (sceny uwzgldniane w kompilacji). Jeli Twoja scena z menu gry nie jest pierwsza, moesz j po prostu przecign i upuci we waciwym miejscu. Zauwa równie, e sceny s ponumerowane, czyli zawieraj indeks rozpoczynajcy si od zera, który znajduje si po prawej stronie ich nazw. Te liczby mog by przydatne podczas wczytywania scen. W tym przypadku moesz te odwoa si do sceny, podajc jej nazw (acucha tekstowego), tak jak zrobilimy w ksice. Dopasujmy parametry budowania poprzez modyfikacj ustawie gracza, dziki czemu bd one pasowa do projektu Survival Island.
Ustawienia gracza Wyeksportowana wersja projektu jest znana w terminologii projektowania oprogramowania pod nazw kompilacji (ang. build). Tworzc kompilacj w rodowisku Unity, w rzeczywistoci umieszczasz odpowiednie treci w wewntrznej aplikacji, zwanej odtwarzaczem Unity. W grze przeznaczonej dla przegldarki internetowej wyeksportowany plik .unity3d wywouje odtwarzacz, który znajduje si ju w zainstalowanej wtyczce Unity. Aplikacja samodzielna dla komputerów PC lub Mac zawiera wbudowany odtwarzacz. Opcja Player Settings (ustawienia gracza) pozwala na modyfikacj takich parametrów, jak rozdzielczo ekranu, ikony i ustawienia renderowania. Aby je zmieni , wybierz opcj menu gównego Edit/Project Settings/Player (edycja/ustawienia projektu/gracz). Obszar Player Settings zosta podzielony na dwie czci: Cross-Platform Settings (ustawienia midzyplatformowe) oraz Per-Platform Settings (ustawienia wybranej platformy).
Ustawienia Cross-Platform Settings Ustawienia midzyplatformowe s wymagane we wszystkich kompilacjach i skadaj si z parametrów Product Name (nazwa projektu), Company Name (nazwa firmy) oraz Default Icon (domylna ikona). Ikona moe w razie koniecznoci zosta zmodyfikowana odpowiedni wartoci, dostpn w ustawieniach wybranej platformy, lecz zasadniczo akceptowane jest udostpnianie grafiki o wyszej rozdzielczoci (np. obrazu 128×128 pikseli uytego w tej ksice), która zostanie automatycznie przeskalowana przez rodowisko Unity. Inn opcj jest dostarczanie oddzielnych ikon dla kadej rozdzielczoci ekranu. Ta metoda pozwala na uzyskanie penej kontroli, lecz warto sprawdzi poprzedni sposób, poniewa jest prostszy, a moe si okaza , e po prostu jest wystarczajcy. Powi chwil na wypenienie pól zwizanych z nazw projektu i firmy, a nastpnie odszukaj tektur icon_large, znajdujc si w folderze Book Assets/Textures (zasoby ksiki/tekstury). Wybierz j, a w dalszej kolejnoci przejd do komponentu Texture Importer w panelu Inspector (inspektor) i wybierz GUI z menu Texture Type (rodzaj tekstury). Wreszcie kliknij przycisk Apply
406
Rozdzia 12. • Budowanie i udostpnianie
(zastosuj), aby zapisa wprowadzon zmian. Wró do ustawie Player Settings (Edit/Project Settings/Player) i przecignij ikon na obszar Default Icon.
Ustawienia Per-Platform Settings Ustawienia wybranej platformy zostay podzielone na cztery kategorie: Q Resolution and Presentation (rozdzielczo i sposób prezentacji), Q Icon (ikona), Q Splash Image (obraz tytuowy), Q Other Settings (inne ustawienia).
Poniewa obie wersje kompilacji, przeznaczone dla odtwarzacza Web Player i tworzce aplikacj samodzieln, wykorzystuj powysze kategorie, przyjrzymy si im po kolei, by przeanalizowa rónice midzy obiema platformami.
Rozdzielczo i sposób prezentacji Ustawienia dostpne w tej opcji menu pozwalaj na modyfikacj sposobu wywietlania gry i s szczególnie wane podczas definiowania docelowej rozdzielczoci ekranu.
Ustawienia odtwarzacza Web Player Kompilacja przeznaczona dla odtwarzacza Web Player powinna zosta zdefiniowana z nisz rozdzielczoci ni aplikacja samodzielna. Wynika to z wymogów sprawnociowych, poniewa im mniejszy jest obszar, na którym jest wykonywany rendering, tym wysz wydajno mona uzyska . Pomimo tego gracz moe klikn prawym klawiszem myszy ikon gry zainstalowan w przegldarce, aby uzyska tryb penoekranowy. Przypisz parametrowi Default Screen Width (domylna szeroko ekranu) warto 800, a Default Screen Height (domylna wysoko ekranu) — warto 600. W momencie pisania tej ksiki rozdzielczo 800×600 pikseli bya najlepsz opcj dla odtwarzacza sieciowego, dostpn na wielu portalach prezentujcych gry Unity, na przykad kongregate.com. Obszar Web Player Template (szablon odtwarzacza sieciowego) udostpnia moliwo wybrania sporód trzech podstawowych stylów strony HTML, która zostanie wyeksportowana w kompilacji
407
Projektowanie gier w rodowisku Unity 3.x
sieciowej. Poniewa gra, tak jak inne treci sieciowe, jest zawsze prezentowana w postaci strony internetowej, powysza opcja pozwala na wywietlenie jednej z trzech rónych stron HTML zawierajcych wbudowany plik .unity3d: Black Background (czarne to), Default (domylna) i No Context Menu (bez menu kontekstowego). Ostatni typ zabezpiecza przed wywietleniem menu podrcznego po klikniciu prawym klawiszem myszy obszaru okna w przegldarce. Dziki temu gracz nie moe wybra opcji przejcia do trybu penoekranowego. Moe to by przydatne dla niektórych projektantów, którzy chc, aby gracze grali w gr, uywajc w tym celu jedynie udostpnionego okna. Powodem moe by na przykad potrzeba upewnienia si, by uytkownik jednoczenie widzia elementy towarzyszcej strony internetowej. Dostpne szablony s poyteczne, gdy pozwalaj Ci przesa na serwer pliki HTML oraz .unity3d bez koniecznoci tworzenia wasnej strony internetowej. S one równie przykadami prezentujcymi wbudowanie pliku .unity3d w struktur HTML i zablokowanie menu kontekstowego. Jeli potrafisz projektowa strony internetowe, bdziesz chcia po prostu wbudowa plik .unity3d we wasn stron. Ponadto w przypadku przesyania gry na portal konieczne bdzie usunicie towarzyszcej jej strony HTML. Wybierz teraz jeden z trzech dostpnych stylów.
Ustawienia aplikacji samodzielnej Podczas adowania samodzielnego pliku z Twoj gr nastpi zaprezentowanie okna Resolution Dialog (wybór rozdzielczoci), w którym zostan przedstawione opcje zwizane z rozdzielczoci, urzdzeniami wejciowymi oraz jakoci wywietlania aplikacji. Moesz jednak nie dopuci do pojawienia si tego okna na ekranie. Do tego suy domylnie wybrana opcja Display Resolution Config (wywietl konfiguracj rozdzielczoci). Okno Resolution Dialog (w wersji przeznaczonej na komputery Mac) wyglda jak na poniszym rysunku. Ustawienia Default Screen Width (domylna szeroko ekranu) i Default Screen Height (domylna wysoko ekranu) definiuj domylne rozdzielczoci, jeli okno dialogowe nie jest wywietlane. Wprowad wic w powyszych polach wartoci 1024 i 768, aby uzyska najnisz akceptowan rozdzielczo , która powinna by wspierana w komputerach stacjonarnych lub laptopach. Pozostae ustawienia w obszarze Resolution and Presentation mona pozostawi niezmienione.
Ikona To ustawienie nie jest dostpne w wersji sieciowej, poniewa ikona odpowiadajca wczytanej stronie internetowej zostaa narzucona przez portal, na którym znajduje si uruchamiana gra.
Ustawienia aplikacji samodzielnej Zostay tu uyte i odpowiednio przeskalowane parametry domylnej ikony. Wykorzystujemy tutaj moliwo tworzenia domylnej ikony o rozdzielczoci wikszej ni 48×48 pikseli. W zasobach niniejszej ksiki zastosowalimy grafik o rozmiarach 128×128 pikseli.
408
Rozdzia 12. • Budowanie i udostpnianie
Jak wida , istnieje take moliwo dostarczenia rónych tekstur odpowiadajcych poszczególnym rozdzielczociom, co pozwala na zastosowanie prostszej grafiki dla mniejszych rozmiarów.
Obraz tytuowy To ustawienie równie nie jest dostpne w wersji sieciowej, poniewa obraz tytuowy jest zwizany z pierwsz scen, która znajduje si w grze, i by moe wykorzystuje animacj w celu zaprezentowania logo producenta, co zapewne widziae w wielu aplikacjach komercyjnych.
Ustawienia aplikacji samodzielnej W grach utworzonych w postaci aplikacji samodzielnej ustawienie Splash Image pozwala na przypisanie obrazu do parametru Config Dialog Banner (pasek okna dialogowego konfiguracji). Jest on prezentowany jako element omawianego wczeniej okna Resolution Dialog, jeli nie zostao ono zablokowane w obszarze Resolution and Presentation. Obraz tytuowy gry Survival Island zosta ju stworzony. Po prostu wybierz tekstur splash_image, dostpn w folderze Book Assets/Textures (zasoby ksiki/tekstury) w panelu Project (projekt). Nastpnie przejd do panelu Inspector i w komponencie Texture Importer zmie opcj Texture Type (rodzaj tekstury) na GUI oraz kliknij przycisk Apply (zastosuj), by zapamita wprowadzon
409
Projektowanie gier w rodowisku Unity 3.x
modyfikacj. Wró do opcji Player Settings (Edit/Project Settings/Player) i przecignij tekstur splash_image na pusty obszar Config Dialog Banner, prezentujcy tekst None (Texture 2D) (brak tekstury 2D). Uwaga Jeli chciaby sam zaprojektowa tekstur Config Dialog Banner, powiniene utworzy plik o rozdzielczoci 432×163 piksele, korzystajc ze swojego ulubionego programu graficznego.
Inne ustawienia Inne ustawienia dotycz renderingu i optymalizacji, a take — w przypadku odtwarzacza Web Player — strumieniowania.
Ustawienia odtwarzacza Web Player Mimo e te ustawienia maj pozosta niezmienione w przypadku odtwarzacza Web Player, warto wiedzie , i parametr Rendering Path (metoda renderingu) powinien by równy Forward (kompatybilno z wersj Unity 2.0) lub Vertex Lit (procedura cieniowania Vertex Lit), jeli zamierzasz uruchamia gr na starszym sprzcie. W celu uzyskania najlepszej wydajnoci wizualnej naley wybra opcj Deferred Lighting (opónione uycie owietlenia), cho nie wspiera ona antyaliasingu (wygadzanie ostrych krawdzi wystpujcych w grze). Powinno si wic wypróbowa powysze ustawienia, by wybra t opcj, dziki której uzyskamy akceptowany kompromis midzy wydajnoci i jakoci. Parametr First Streamed Level (pierwszy strumieniowany poziom) pozwala na okrelenie numeru sceny, która powinna zosta zaadowana jako pierwsza w czasie strumieniowania gry. W polu moesz wprowadzi dowolny indeks sceny, który znajduje si po prawej stronie listy scen w oknie Build Settings.
Ustawienia aplikacji samodzielnej Pamitaj, e wikszo projektów bdzie dziaa poprawnie przy domylnych ustawieniach renderingu i optymalizacji. Uwaga zwizana z pakietowaniem Darmowa wersja rodowiska Unity wykorzystuje opcj Dynamic Batching (dynamiczne pakietowanie) — pozwala ona na czenie obiektów w pakiety (grupowanie w celu renderingu) wykorzystujce wspódzielony materia i nisk zoono siatki, które mog by wywietlane za pomoc pojedynczego wywoania funkcji graficznej. Oznacza to lepsz wydajno podczas tworzenia wielu instancji tego samego obiektu, na przykad budynków. Dynamiczne pakietowanie jest realizowane automatycznie przy zaoeniu, e liczba wierzchoków w siatce obiektu jest nie wiksza od 300. Dodatkow opcj dostpn w wersji Unity Pro jest statyczne pakietowanie, które realizuje powysz funkcj w odniesieniu do statycznych obiektów.
410
Rozdzia 12. • Budowanie i udostpnianie
Ustawienia jakoci Podczas eksportowania gry ze rodowiska Unity nie jeste ograniczony pojedynczym poziomem jakoci. W obszarze Quality Settings (ustawienia jakoci), znajdujcym si w panelu Inspector (inspektor), umieszczono szereg parametrów pozwalajcych definiowa jako produktów. Aby go wywietli , wybierz opcj menu gównego Edit/Project Settings/Quality (edycja/ustawienia projektu/jako ). Istnieje tu moliwo przypisania trzech rónych kompilacji do jednego z szeciu wstpnie zdefiniowanych ustawie: Fastest (najszybsze), Fast (szybkie), Simple (proste), Good (poprawne), Beautiful (pikne) i Fantastic (fantastyczne). Moesz take przeprowadzi edycj danego zestawu ustawie, aby w razie potrzeby dopracowa szczegóy. By zrozumie , jaki zakres modyfikacji parametrów jakoci oferuje rodowisko Unity, przeanalizujmy dwa skrajne ustawienia: Fastest i Fantastic.
411
Projektowanie gier w rodowisku Unity 3.x
Jak wida , zestawy parametrów róni si znaczco, dlatego przyjrzyjmy si poszczególnym ustawieniom: Q Pixel Light Count (liczba wiate typu pikselowego). Liczba wiate pikselowych,
które mog zosta uyte w scenie. róda wiate w rodowisku Unity s renderowane w postaci pikseli lub wierzchoków. wiata typu pikselowego wygldaj lepiej, lecz s bardziej wymagajce wydajnociowo. Dziki temu parametrowi moesz zezwoli na zdefiniowanie okrelonej liczby wiate pikselowych, a pozostae zostawi w formie wiate wektorowych. Std te wynika warto 0 dla tego parametru w ustawieniu Fastest. Q Shadows (cienie). Ten parametr jest dostpny jedynie w wersji Unity Pro i pozwala
na wybranie sporód nastpujcych opcji: brak cieni dynamicznych, wycznie cienie twarde, cienie twarde i mikkie. Jednake, jak widzielimy, w wersji darmowej Unity cienie mog by wypalane podczas procesu odwzorowywania wiata. Q Shadow Resolution (rozdzielczo cieni). Ta opcja równie ma zastosowanie wycznie
w wersji Unity Pro i pozwala na okrelenie jakoci generowanych cieni. Moe ona zapewni wiksz wydajno gry podczas uywania wielu obiektów z dynamicznym cieniowaniem. Zdefiniowanie niskiej rozdzielczoci moe oznacza zauwaaln rónic pomidzy sytuacj, w której cienie zostan zupenie wyczone, oraz ustawieniem, gdy bd one wczone podczas optymalizacji. Q Shadow Cascades (kaskady cieni). Unity Pro moe wykorzystywa opcj Cascaded
Shadow Maps (kaskadowe mapy cieni), która poprawia w scenie wygld cieni wiate kierunkowych. Jako mapy cienia zaley od jego odlegoci od kamery gracza — im bliej si on znajduje, tym wicej zawiera szczegóów, co powoduje zwikszenie jakoci obrazu. Q Shadow Distance (zasig renderingu cieni). Ten parametr jest podobny
do optymalizacji zwizanej z ograniczeniem tylnej paszczyzny odcinajcej. Moe zosta uyty w celu zdefiniowania odlegoci, powyej której cienie nie bd renderowane. Q Blend Weights (wagi przenikania). To ustawienie jest wykorzystywane w postaciach
ze szkieletem zbudowanym z koci. Pozwala ono na ustalenie liczby wag (poziomów) animacji, które mog midzy sob przenika . Firma Unity Technologies zaleca uycie dwóch koci jako dobrego kompromisu pomidzy wydajnoci i jakoci prezentacji. Q Texture Quality (jako tekstur). Opcja ta definiuje poziom kompresji tekstur. Q Anisotropic Textures (tekstury anizotropowe). Ten parametr moe poprawi wygld
tekstur podczas spogldania na nie z duego kta (na przykad tekstur umieszczonych na wzgórzach). Jego wad jest to, i wpywa na wydajno gry. Pamitaj, e moesz go równie uy w odniesieniu do pojedynczych tekstur w opcji Import Settings (ustawienia importu), dostpnej dla zasobów. Q Anti Aliasing (antyaliasing). To ustawienie wygadza krawdzie elementów
trójwymiarowych, sprawiajc, e gra wyglda duo lepiej. Jednake, podobnie jak ma to miejsce w przypadku innych filtrów, wpywa na wydajno dziaania aplikacji.
412
Rozdzia 12. • Budowanie i udostpnianie
Q Soft Vegetation (zmikczenie rolinnoci). Ta opcja sprawia, e elementy terenu,
takie jako rolinno i drzewa, wykorzystuj opcj alpha blending (czenie kanau alfa), co znaczco poprawia wygld przezroczystych obszarów tekstur uywanych do tworzenia flory. Q Sync to VBL (synchronizuj z pionowym wygaszaniem ekranu). Powoduje to,
e wywietlanie obrazów gry bdzie zsynchronizowane z czstotliwoci odwieania monitora komputerowego. Ogólnie rzecz biorc, powoduje to pogorszenie wydajnoci, lecz przyczynia si do uniknicia zjawiska „zrywania” elementów gry, polegajcego na przesuniciu na ekranie pewnych fragmentów tekstur. Naley uywa tych opcji, które poprawi wraenia odbioru u gracza, poniewa moe on mie dostp do nich z okna Resolution Dialog (wybór rozdzielczoci) (patrz podrozdzia „Ustawienia gracza”), wywietlanego dla gry uruchamianej w postaci samodzielnej aplikacji. Jednake w wikszoci przypadków bezpieczne jest zastosowanie odpowiedniego zestawu ustawie Unity, a nastpnie, w razie koniecznoci, zmodyfikowanie wybranych opcji. Ustawienia znajdujce si na górze obszaru Quality Settings, które oferuj domylne konfiguracje, s równie przydatne, pozwalaj bowiem na zdefiniowanie jakoci w samym edytorze, co umoliwia uzyskanie bardziej realistycznej reprezentacji kocowego wygldu Twojej gry.
Ustawienia wej dla gracza Mimo e okno Resolution Dialog (wybór rozdzielczoci) w zakadce Inputs (wejcia) pozwala na zmodyfikowanie parametrów wej gry uruchamianej w postaci samodzielnej aplikacji, naley pamita , e moesz take zdefiniowa wasne ustawienia w menederze wej rodowiska Unity. Jest to szczególnie przydatne w kompilacjach przeznaczonych do uruchamiania w przegldarce internetowej, poniewa gracz nie ma w tym przypadku moliwoci zmiany urzdze wejciowych po zaadowaniu gry. Dlatego te naley je sensownie zdefiniowa i przekaza graczowi odpowiednie informacje poprzez interfejs GUI dostpny w grze. W rodowisku Unity przejd do opcji menu gównego Edit/Project Settings/Input, aby wywietli ustawienia Input Manager (meneder wej ) w panelu Inspector (inspektor). Zostan zaprezentowane rodzaje sygnaów wejciowych, które moesz kontrolowa . Warto Size (rozmiar) po prostu oznacza, ile sygnaów zdefiniowano. Poprzez zwikszenie tej wartoci moesz tworzy sygnay wejciowe. Aby zmodyfikowa ustawione parametry, wystarczy klikn szare strzaki, znajdujce si po prawej stronie ich nazw. Kliknij strzak przy pozycji Fire1, by j rozwin . Analizujc wywietlone parametry, moesz teraz zrozumie , w jaki sposób s one powizane z kodem, który wczeniej stworzylimy. W skrypcie CoconutThrower umiecilimy nastpujc instrukcj: if(Input.GetButtonUp("Fire1")){
413
Projektowanie gier w rodowisku Unity 3.x
W powyszym kodzie odwoujemy si do sygnau wejciowego Fire1 po jego nazwie. Zmieniajc parametr Name (nazwa) w ustawieniach wej , moesz zdefiniowa odpowiedni nazw, któr nastpnie bdziesz móg wykorzysta w skryptach. Aby dowiedzie si wicej o klawiszach, których moesz uywa w powyszych ustawieniach, zapoznaj si ze stron Input (wejcie) dokumentacji rodowiska Unity, dostpn pod adresem: http://unity3d.com/support/documentation/ Manual/Input.html.
Budowanie gry Poniewa jestemy prawie gotowi do zbudowania gry, powiniene rozway róne rodzaje kompilacji, które zostay wczeniej omówione, a nastpnie przystosowa projekt do dwóch docelowych postaci: gry uruchamianej w przegldarce internetowej, a take samodzielnej aplikacji.
Przystosowanie do wersji sieciowej wiat trójwymiarowy w rodowisku Unity jest w peni skalowalny za pomoc silnika gry i moe by prezentowany w takiej rozdzielczoci, która zostanie zdefiniowana w ustawieniach gracza. Menu naszej gry jest równie skalowalne, poniewa wykorzystuje klas Screen do umieszczania kontrolek GUI w pooeniach zalenych od biecej rozdzielczoci ekranu. Jednake by zapozna si ze sposobem wykrywania platform docelowych, usuniemy element, który nie powinien istnie w wersji gry przeznaczonej dla przegldarki internetowej. Bdzie to przycisk Quit (wyjcie). W folderze Scripts (skrypty) w panelu Project (projekt) kliknij dwukrotnie ikon skryptu MainMenuGUI, aby wczyta go do edytora.
Automatyzacja wywietlania przycisku Quit w zalenoci od platformy W grze przeznaczonej dla odtwarzacza Web Player istnienie przycisku Quit nie ma wikszego sensu. Wynika to std, e polecenie Application.Quit() nie dziaa, gdy gra Unity jest uruchomiona w przegldarce. Zamiast tego gracz po prostu zamyka zakadk lub okno z gr albo przechodzi do innej aplikacji po zakoczeniu grania. Powinnimy wykluczy przycisk Quit z naszego menu wywietlanego w przegldarce, ale nie moemy go zupenie usun ze skryptu, gdy wci go potrzebujemy w aplikacji samodzielnej. Aby rozwiza problem, uyjemy innej waciwoci klasy Application zwanej platform — pozwala ona na wykrywanie rodzaju platformy docelowej (komputer typu desktop, przegldarka internetowa, urzdzenie mobilne, konsola itd.), na której dziaa gra. Stworzymy nastpujce polecenie if: if(Application.platform != RuntimePlatform.OSXWebPlayer && Application.platform ´!= RuntimePlatform.WindowsWebPlayer){
414
Rozdzia 12. • Budowanie i udostpnianie
W powyszym kodzie sprawdzamy, czy warto waciwoci platform, nalecej do klasy Appli ´cation, jest róna od OSXWebPlayer (Mac) lub WindowsWebPlayer (PC). W tym celu uywamy zapisu !=, oznaczajcego „nie jest równy”. Jeli wic gra nie zostaa uruchomiona na komputerze typu Mac lub w odtwarzaczu Web Player, naley co zrobi ! Teraz powinnimy poczy t funkcjonalno z istniejcym poleceniem if, które wywietla klawisz Quit. W funkcji OnGUI() odszukaj polecenie if, które tworzy klawisz Quit. Powinno ono wyglda tak: Jzyk C#: if(GUI.Button(new Rect(quitButton), "Quit")){ StartCoroutine("ButtonAction", "quit"); }
Jzyk JavaScript: if(GUI.Button(Rect(quitButton), "Quit")){ ButtonAction("quit"); }
A teraz dodaj now instrukcj if, umieszczajc istniejce polecenie if wewntrz niego. Docelowy kod powinien wyglda tak jak poniej: Jzyk C#: if(Application.platform != RuntimePlatform.OSXWebPlayer && Application.platform ´!= RuntimePlatform.WindowsWebPlayer){ if(GUI.Button(new Rect(quitButton), "Quit")){ StartCoroutine("ButtonAction", "quit"); } }
Jzyk JavaScript: if(Application.platform != RuntimePlatform.OSXWebPlayer && Application.platform ´!= RuntimePlatform.WindowsWebPlayer){ if(GUI.Button(Rect(quitButton), "Quit")){ ButtonAction("quit"); } }
Oznacza to, e w przypadku kompilacji gry do aplikacji samodzielnej przycisk Quit bdzie widoczny na ekranie. Jeli jednak zostanie wykryta platforma typu Mac lub PC Web Player, wówczas przycisk nie pojawi si. Dziki funkcjonalnoci klasy Application, zwizanej z automatyzacj, któr zaimplementowalimy, dysponujemy teraz scen Menu — moe ona zosta umieszczona razem ze scen Island na licie Build Settings (ustawienia budowania), a nastpnie skompilowana do platformy Web
415
Projektowanie gier w rodowisku Unity 3.x
Player lub aplikacji samodzielnej bez potrzeby modyfikowania kodu. Ta technika moe by bardzo przydatna podczas tworzenia bardziej zoonych struktur menu oraz innych elementów i poszerza moliwoci wspierania wielu platform przez rodowisko Unity.
Przygotowanie do strumieniowania Aby poziom Island móg by wczytywany w postaci strumieniowanego zasobu, zmodyfikujemy kod w taki sposób, by po cakowitym zaadowaniu sceny udostpnia graczowi w menu wycznie przycisk Play (granie). Zapobiegnie to wczytywaniu caej gry przed wywietleniem menu. Zamiast tego moemy zaprezentowa menu zawierajce komunikat Loading... xx% Loaded (Trwa adowanie… Wczytano xx%) podczas adowania sceny Island. Wczytywanie treci Unity do odtwarzacza Web Player powoduje zazwyczaj wywietlenie domylnego paska postpu, chyba e przez projektanta zosta stworzony wasny mechanizm adowania gry.
Uzupenimy powysz funkcjonalno poprzez wywietlenie dodatkowej informacji w scenie Menu w czasie adowania sceny Island. W tym celu zastpimy przycisk Play komunikatem o wczytywaniu gry, który bdzie widoczny na ekranie a do cakowitego jej zaadowania (patrz poniszy rysunek).
Wywietlanie postpu wczytywania strumieniowego Poniewa bdziemy pracowa z menu gry, wczytaj scen Menu poprzez dwukrotne kliknicie jej ikony w panelu Project (projekt). A teraz otwórz skrypt MainMenuGUI i odszukaj kod odpowiedzialny za wywietlanie przycisku Play: Jzyk C#: if(GUI.Button(new Rect(playButton), "Play")){ StartCoroutine("ButtonAction", "Island"); }
416
Rozdzia 12. • Budowanie i udostpnianie
Jzyk JavaScript: if(GUI.Button(Rect(playButton), "Play")){ ButtonAction("Island"); }
Umie go w nowej instrukcji if, by sprawdzi , czy scena Island zostaa wczytana: Jzyk C#: if(Application.CanStreamedLevelBeLoaded("Island")){ if(GUI.Button(new Rect(playButton), "Play")){ StartCoroutine("ButtonAction", "Island"); } }
Jzyk JavaScript: if(Application.CanStreamedLevelBeLoaded("Island")){ if(GUI.Button(Rect(playButton), "Play")){ ButtonAction("Island"); } }
417
Projektowanie gier w rodowisku Unity 3.x
Powyszy kod sprawdza, czy scena Island jest gotowa do wczytania. Jeli tak, nastpuje wówczas rendering przycisku Play. Moemy teraz doda instrukcj else, która wywietli postp strumieniowego wczytywania poziomu Island, jeeli nie zostao ono jeszcze ukoczone. Umie nastpujc instrukcj else w dodanym wyej poleceniu if: Jzyk C#: else{ float percentLoaded = Application.GetStreamProgressForLevel(1) * 100; GUI.Box(new Rect(playButton), "Loading.. " + percentLoaded.ToString("f0") + ´"% Loaded"); }
Jzyk JavaScript: else{ var percentLoaded : float = Application.GetStreamProgressForLevel(1) * 100; GUI.Box(new Rect(playButton), "Loading.." + percentLoaded.ToString("f0") + ´"% Loaded"); }
W powyszym kodzie tworzymy zmienn percentLoaded, której przypisujemy wynik funkcji GetStreamProgressForLevel, wywoywanej z argumentem równym 1. Okrela on indeks sceny Island wywietlany w oknie Build Settings. Otrzymana wielko jest mnoona przez 100, aby uzyska warto procentow. Nastpnie jest wywietlana w kontrolce GUI.Box, której przekazujemy wartoci pooenia i skali, uywajc w tym celu parametru Rect klawisza playButton. Oznacza to, e dopóki scena Island nie bdzie gotowa do uruchomienia, informacja o jej wczytywaniu bdzie wywietlana w miejscu klawisza Play. Rzeczywisty tekst wywietlany w kontrolce Box jest wanym elementem kodu. Powstaje on przy uyciu nastpujcego wyraenia: "Loading.." + percentLoaded.ToString("f0") + "% Loaded"
Pocztek i koniec powyszego kodu skadaj si ze zwykych acuchów tekstowych: Loading.. i % Loaded. Wykorzystujemy jednak znak plusa, aby umieci polecenie wywietlajce midzy nimi zmienn percentLoaded. Jest ona formatowana za pomoc instrukcji ToString("f0"), która usuwa cz uamkow z wartoci przechowywanej w zmiennej. W rezultacie otrzymujemy przykadowy tekst: Loading.. 86% Loaded. Uwaga Uycie symbolu plusa w celu dodania do acucha tekstowego wartoci zmiennych i funkcji jest zwane konkatenacj (std te czasownik „konkatenowa”). Znajomo tego terminu moe by przydatna podczas analizy Twojego kodu, przeprowadzanej z udziaem innych projektantów.
418
Rozdzia 12. • Budowanie i udostpnianie
Modyfikacja stylu okna z informacj o postpie wczytywania Zanim zakoczymy tworzenie okna z informacj o postpie wczytywania, musimy jeszcze raz powróci do kompozycji graficznej GUI i za jej pomoc przypisa mu odpowiedni styl. Poniewa ta funkcjonalno jest widoczna jedynie wtedy, gdy tworzymy kompilacj przeznaczon dla przegldarki internetowej, nie dostrzeesz jej w edytorze Unity ani w testowej wersji sieciowej dziaajcej na Twoim komputerze. Proces wczytywania danych z dysku twardego trwa tak krótko, e aplikacja po prostu nie zdy wywietli adnej informacji o adowaniu. Aby nie musia przeprowadza testów na serwerze, prezentujemy rysunek ze zrzutem ekranu z informacj o adowaniu, której nie przypisano adnego stylu:
Wyglda to niezbyt adnie, nieprawda? Poniewa tekst nie odpowiada stylowi wykorzystywanemu w menu, spróbujmy poprawi wygld grafiki. Zapisz swój skrypt i wró do rodowiska Unity, a nastpnie wybierz obiekt Menu2 w panelu Hierarchy (hierarchia). Spowoduje to wywietlenie komponentu Main Menu GUI (Script), co z kolei pozwoli zauway , e uywamy konfiguracji graficznej GUISkin o nazwie Main Menu. Wybierz j w tym miejscu lub w panelu Project (projekt), aby wywietli waciwoci GUISkin w panelu Inspector (inspektor). Poniewa w naszym kodzie chcemy zmodyfikowa styl kontrolki GUI.Box, kliknij ikon szarej strzaki po prawej stronie kontrolki Box (ramka) w górnej czci listy stylów, co spowoduje wywietlenie dostpnych parametrów. S trzy parametry, które powinnimy zmieni w celu dopasowania stylu ramki wywietlajcej informacje o postpie wczytywania: Q to ramki, Q rozmiar czcionki i jej kolor, Q pooenie tekstu wewntrz ramki.
Aby to zrobi , najpierw upewnij si, e dla kontrolki Box rozwinito waciwo Normal (normalny), dziki czemu masz dostp do parametrów Background (to) oraz Text Color (kolor tekstu).
419
Projektowanie gier w rodowisku Unity 3.x
Przecignij tekstur guiBtnActive z folderu Book Assets/Textures (zasoby ksiki/tekstury) w panelu Project na waciwo Background kontrolki Box, aby podmieni domylne czarne to, zdefiniowane w rodowisku Unity. Ta tekstura bdzie odpowiednia dla ramki, poniewa ma odcie czerwieni, a przez to sugeruje graczowi, e co nie jest jeszcze gotowe. Kliknij obszar koloru Text Color i wybierz barw czarn z okna wyboru koloru, a nastpnie je zamknij. Przejd niej do dalszych ustawie kontrolki Box i przypisz wybran przez Ciebie czcionk do parametru Font (czcionka). Zmie take warto pola Font Size (rozmiar czcionki) na 22. Wreszcie odszukaj waciwo Alignment (justowanie). Okrela ona miejsce, w którym pojawi si tre wywietlana w ramce, czyli informacja o postpie adowania. Przypisz jej warto MiddleCenter (rodek, centrum), dziki czemu nie bdziemy si zajmowa odpowiednim wyrównaniem tekstu wewntrz ramki. Po zakoczeniu dziaa ustawienia GUISkin kontrolki Box powinny wyglda tak:
W praktyce spowoduje to, e Twój pasek postpu bdzie mia taki wygld:
420
Rozdzia 12. • Budowanie i udostpnianie
Gdy tylko licznik osignie warto 100%, zostanie automatycznie zastpiony przyciskiem Play, co pozwoli graczowi na rozpoczcie gry. I to wszystko! Dysponujesz teraz fragmentem kodu GUI, który bdzie prezentowa graczowi postp wczytywania gry. Podczas adowania poziomu pozwól mu w spokoju przeczyta instrukcj dostpn w menu. Pamitaj, e stworzona przed chwil wersja jest dostpna jedynie dla gry przeznaczonej do uruchamiania w przegldarce internetowej, dziki czemu bdzie moliwe wykorzystanie funkcjonalnoci strumieniowania. Nie przetestujesz jej w edytorze Unity ani w aplikacji samodzielnej. Zapamitaj swój projekt poprzez uycie opcji menu gównego File/Save Project (plik/zapisz projekt). A teraz spróbujmy stworzy kompilacj gry przeznaczonej do przegldarki internetowej oraz bdcej samodzieln aplikacj.
Pierwsza kompilacja Po dokonaniu pewnych zmian w naszym kodzie, zapewniajcych dziaanie gry w obu platformach docelowych, nadszed czas na stworzenie pierwszej kompilacji. Napicie ronie, nieprawda? Tak wic bez zbdnej zwoki utwórzmy wersj gry bdc samodzieln aplikacj, dziki czemu bdziesz mia okazj przyjrze si jej spoza rodowiska Unity.
Budowanie aplikacji samodzielnej Przejd do opcji menu gównego File/Build Settings (plik/ustawienia budowania) i upewnij si, e w obszarze Scenes In Build (sceny do kompilacji) znajduj si dwa ponisze pliki scen: Q Menu.unity, Q Island.unity. Uwaga Jeli jaka scena nie jest widoczna na licie, moesz j przecign z panelu Project i upuci w oknie Build Settings.
421
Projektowanie gier w rodowisku Unity 3.x
Wane jest, aby scena Menu bya pierwsza na licie, poniewa ona najpierw powinna zosta wczytana. Upewnij si wic, e jej indeks jest równy 0 i znajduje si ona na górze obszaru Scenes In Build. Jeli tak nie jest, moesz j po prostu przecign i upuci we waciwym miejscu listy. Logo Unity, wywietlone w obszarze Platform (platforma) okna Build Settings obok nazwy okrelonej platformy docelowej, informuje o wybraniu rodzaju kompilacji. Upewnij si, e zostaa podwietlona opcja PC and Mac Standalone (PC i Mac — aplikacja samodzielna), a nastpnie kliknij przycisk Switch Platform (zmie platform), znajdujcy si w dolnym lewym obszarze okna. Uwaga Zmieniamy platform w celu zachowania zgodnoci, poniewa umoliwi nam to wywietlenie rozdzielczoci w licie rozmiarów okien, dostpnej w widoku Game (gra). Nie jest to jednak konieczne, jeli pracujesz nad gr i regularnie przeczasz si midzy platformami. Pamitaj, e rodowisko Unity podczas kompilacji i tak potrafi automatycznie zmieni rodzaj platformy na t, która jest aktualnie wybrana.
Logo Unity powinno si znajdowa po prawej stronie napisu PC and Mac Standalone. A teraz po prostu wybierz odpowiedni opcj z menu Target Platform (platforma docelowa): Q Windows, Q Windows 64-bit, Q Mac OS X Universal (Mac OS X, kompilacja uniwersalna), Q Mac OS X Intel Only (Mac OS X, kompilacja tylko dla procesora Intel), Q Mac OS X Power PC Only (Mac OS X, kompilacja tylko dla procesora Power PC), Q Mac OS X Dashboard Widget (Mac OS X, widget aplikacji Dashboard).
Po klikniciu przycisku Build (buduj) w dolnej czci okna dialogowego pojawi si pytanie o lokalizacj docelowego pliku gry. Wybierz odpowiedni katalog i wprowad nazw gry w polu Save As (zapisz jako). Nastpnie kliknij przycisk Save (zapisz), aby zapisa plik. Czekaj cierpliwie, a Unity zakoczy proces budowania Twojej gry! W jego trakcie bd wywietlane informacje o aktualnie kompresowanych zasobach oraz pasek postpu, potwierdzajcy doczenie do kompilacji kadej ze scen. Po zakoczeniu budowania gry zostanie otwarte okno systemu operacyjnego, pokazujce gotowy plik gry w katalogu, w którym wybrano jego lokalizacj. Dwukrotnie kliknij plik gry, aby j uruchomi . Pamitaj, e gdy skompilujesz wersj PC w komputerze Mac (i odwrotnie), nie bdzie ona moga zosta przetestowana w rodowisku natywnym.
422
Rozdzia 12. • Budowanie i udostpnianie
Wersja darmowa kontra Pro Naley pamita , e gra skompilowana w darmowej wersji rodowiska Unity zawiera wstpny obraz tytuowy Powered by Unity (stworzono w rodowisku Unity). Nie jest on obecna w wersji Unity Pro.
Inne rónice, takie jak brak dynamicznych cieni w wersji darmowej, zostay zaprezentowane na stronie internetowej: http://unity3d.com/unity/licenses.html.
Budowanie dla sieci W rodowisku Unity otwórz okno Build Settings poprzez wybranie opcji menu gównego File/ Build Settings (plik/ustawienia budowania), a nastpnie na licie Platform (platforma) podwietl wiersz Web Player (odtwarzacz sieciowy). Upewnij si, e zostaa wczona opcja Streamed (strumieniowanie), znajdujca si po prawej stronie listy Platform. Jest ona niezbdna do zapewnienia strumieniowania poziomu Island w trakcie wywietlania menu gry. Jak wspomniano wczeniej, nie ma potrzeby klikania opcji Switch Platform, poniewa rodowisko Unity samo zmieni rodzaj platformy na t, która jest aktualnie wybrana. Biorc to pod uwag, kliknij po prostu przycisk Build. W oparciu o ustawienia dostpne w obszarze Player Settings rodowisko Unity przeprowadzi odpowiednie konwersje i kompresje, niezbdne do utworzenia kompilacji, która bdzie moga dziaa w przegldarce internetowej. Zostaniesz poproszony o wskazanie lokalizacji, w której pojawi si plik docelowy. Wybierz j, a nastpnie kliknij przycisk Save (zapisz).
423
Projektowanie gier w rodowisku Unity 3.x
Po ukoczeniu procesu system operacyjny wywietli katalog, w którym znajduje si Twoja kompilacja. Skada si ona z dwóch elementów: waciwej gry (pliku z rozszerzeniem .unity3d) oraz pliku HTML, zawierajcego wbudowany kod oraz wstawk w jzyku JavaScript, która jest niezbdna do wczytania pliku .unity3d lub gdy wtyczka Unity Web Player nie zostaa zainstalowana, do wywietlenia zachty do jej pobrania. Aby zagra w gr, otwórz plik HTML w swojej ulubionej przegldarce, co spowoduje uruchomienie aplikacji. Nie musisz instalowa wtyczki Web Player, poniewa zostaa ona automatycznie umieszczona w Twoim komputerze podczas instalowania rodowiska Unity.
Umieszczanie kompilacji sieciowych na wasnej stronie internetowej W tym podpunkcie nauczymy Ci, w jaki sposób mona umieci kompilacj sieciow na wasnej stronie internetowej. Jeli nie jeste tym zainteresowany, moesz od razu przej do kolejnego podrozdziau, zatytuowanego „Udostpnianie swoich prac”. Gdyby chcia umieci kod HTML lub JavaScript na swojej stronie internetowej, powiniene po prostu uy instrukcji zawartych pomidzy znacznikami i . Wynika to std, e domylna kompilacja Unity udostpnia niezbdny kod, który pozwala na doczenie pliku .unity3d do strony internetowej. Jeli nie jeste zainteresowany umieszczaniem odtwarzaczy sieciowych na swoich stronach internetowych, przejd do podrozdziau „Udostpnianie swoich prac”.
Kod JavaScript w obszarze znacznika Obszar znacznika zawiera dwa fragmenty kodu JavaScript. Pamitaj, e jest to specjalna wersja jzyka, przeznaczona dla sieci i rónica si od tej, której uywalimy w rodowisku Unity. Ma ona jednak podobn skadni. Na pocztku znajduje si skrypt pozwalajcy na pobranie odtwarzacza sieciowego z serwera Unity. Jest on przydatny, gdyby uytkownik nie zainstalowa go jeszcze w swoim systemie.
Nastpnie pojawia si skrypt, który zarzdza wczytywaniem treci w sytuacji, gdy wtyczka Web Player jest ju zainstalowana. Kod jest zapisany bezporednio na stronie HTML i wyglda tak:
Zwró uwag na to, e skrypt wczytuje zawarto o nazwie SurvivalIsland.unity3d. Twoja funkcja bdzie jednak uywa nazwy, któr podae w czasie zapisywania pliku w katalogu docelowym. Kod wyszukuje na stronie element zwany unityPlayer, wykorzystujc w tym celu funkcj getObjectById(). Jeli zostanie on znaleziony, przesya do niego zawarto pliku .unity3d.
Uczynienie kodu przenonym Upro my kod, aby uczyni go bardziej przenonym. Moglibymy skopiowa powysz funkcj na stron HTML, na której bd si znajdowa treci Unity. Jednak zamiast tego umiecimy j w pliku JavaScript, przez co bdziemy mogli go wywoa za pomoc pojedynczej instrukcji. Otwórz plik HTML zwizany z nasz kompilacj sieciow. W tym celu wykorzystaj domylny edytor Unity o nazwie MonoDevelop lub swój ulubiony edytor HTML, na przykad Dreamweaver, Coda, SciTE, TextMate lub TextWrangler1. Zaznacz cay kod JavaScript, który znajduje si w obszarze znacznika pliku HTML: function GetUnity() { if (typeofunityObject != "undefined") { return unityObject.getObjectById("unityPlayer"); } return null; } if (typeofunityObject != "undefined") { unityObject.embedUnity("unityPlayer", "SurvivalIsland.unity3d", 800, 600); }
Wklej go do nowego dokumentu JavaScript, a nastpnie zapisz pod nazw UnityLoader.js w folderze, w którym znajduje si Twoja strona internetowa. Umie jego wywoanie na swojej stronie, podajc w obszarze znacznika poniszy kod:
Proste, nieprawda? Jeli bdziesz chcia uy treci Unity, moesz po prostu doczy powyszy wiersz oraz istniejce wywoanie, wykrywajce obecno wtyczki Unity Player:
1
Moesz take uy uniwersalnego edytora tekstowego Notepad++, obsugujcego skadni HTML i JavaScript — przyp. tum.
425
Projektowanie gier w rodowisku Unity 3.x
Pamitaj, e w kodzie zaoono, i plik .unity3d znajduje si w tym samym katalogu co plik HMTL, który go wywouje. Jeli chciaby umieci swój plik .unity3d w innym miejscu, powiniene zmodyfikowa polecenie embedUnity, na przykad: unityObject.embedUnity("unityPlayer", "http://www.twojastrona.com/ ´nazwafolderu/SurvivalIsland.unity3d", 800, 600);
Osadzanie obiektu w obszarze znacznika Omówiony przez nas skrypt JavaScript poszukuje na stronie elementu zwanego unityPlayer. Technicznie rzecz biorc, jest to zazwyczaj znacznik , tworzcy now sekcj w dokumencie HTML o okrelonym identyfikatorze, bdcym acuchem tekstowym. Analizujc przykadow stron, której dostarcza Unity, bdziesz móg znale ten znacznik:
Powyszy fragment kodu umieszcza tre Unity na stronie HTML. Aby doczy odtwarzacz sieciowy do wasnej strony internetowej, powiniene po prostu go skopiowa . Moesz take zauway , e zawiera on znacznik z parametrem class o nazwie missing. Jest on potrzebny do utworzenia obszaru, który pozwala na wywietlenie przycisku sucego do zainstalowania odtwarzacza sieciowego, jeli nie ma go na Twoim komputerze. Nie musisz przechowywa pliku graficznego dla tego przycisku, poniewa znajduje si on take na serwerze Unity.
Modyfikacja stylu osadzonego obiektu Unity za pomoc CSS Moesz zauway , e w przykadowym pliku HTML znajduj si instrukcje CSS, które definiuj styl elementów osadzonych na stronie. CSS (ang. Cascading Style Sheets — kaskadowe arkusze stylów) to technika stosowana przez projektantów stron internetowych do definiowania stylów informacji opartych na treciach HTML. Na przykadowej stronie, eksportowanej przez rodowisko Unity, znajduje si dua liczba znaczników CSS typu . Jednake s dwie sprawy, o których naley pamita . Po pierwsze powiniene zawsze umieszcza swój styl CSS w specjalnym dokumencie, zwanym arkuszem stylów. Po drugie pewne fragmenty prezentowanego tu kodu s uywane w celu zaprojektowania strony i nie dotycz stylu osadzonego obiektu Unity. Pamitajc o powyszych uwagach, zaznacz nastpujcy fragment kodu CSS: div.missing { margin: auto; position: relative; top: 50%;
426
Rozdzia 12. • Budowanie i udostpnianie
width: 193px; } div.missing a { height: 63px; position: relative; top: -31px; } div.missing img { border-width: 0px; } div#unityPlayer { cursor: default; height: 600px; width: 800px; }
Teraz utwórz nowy plik z rozszerzeniem .css i zapamitaj go pod przykadow nazw UnityStyle.css. Wklej do niego powyszy kod. Plik ten moe zosta doczony do Twojej strony poprzez umieszczenie nastpujcego wiersza HTML w obszarze znacznika :
Zdefiniowalimy ju trzy niezbdne elementy, które sprawi, e Twoja gra, uruchamiana na stronie HTML, bdzie bardziej przenona! Obszar znacznika strony, w której osadzisz treci Unity, powinien wyglda tak:
Survival Island
Na pocztku powyszego kodu uywamy znacznika , który jest wymagany dla kadej strony internetowej. Nastpnie pojawia si wywoanie pliku JavaScript, obsugujcego odtwarzacz sieciowy i znajdujcego si na serwerze Unity. Za nim s umieszczone dwa odnoniki do lokalnych zasobów: pliku JavaScript UnityLoader.js oraz pliku arkusza stylów UnityStyle.css. Poprzez zdefiniowanie tych trzech elementów w obszarze znacznika oraz uycie kodu z osadzonym obiektem z obszaru moesz atwo umieszcza swoje treci na dowolnych stronach internetowych, które bdziesz tworzy .
427
Projektowanie gier w rodowisku Unity 3.x
Udostpnianie swoich prac Powiniene udostpnia swoje prace innym osobom. Jest to niezbdne nie tylko po to, by prezentowa swoje umiejtnoci deweloperskie, lecz take w celu otrzymywania informacji zwrotnych o stworzonych przez siebie grach i umoliwienia testowania Twoich projektów osobom, które ich wczeniej nie znay. Zastanów si take nad znaczeniem mediów spoecznociowych w Twojej pracy. Zarówno Facebook, jak i Twitter (#unity3d) wspieraj znaczc spoeczno zwizan z tworzeniem gier w rodowisku Unity. Oprócz udostpniania swoich prac na wasnej stronie internetowej moesz skorzysta z niezalenych portali powiconych grom, które równie skupiaj projektantów dzielcych si swoj twórczoci z innymi osobami. Oto kilka polecanych stron, które powiniene odwiedzi , gdy bdziesz ju gotowy do podzielenia si swoj prac ze spoecznoci internetow: Q www.kongregate.com, Q www.facebook.com (w postaci aplikacji), Q www.shockwave.com, Q www.indiegames.com, Q www.tigsource.com (forum Independend Gaming), Q forum.unity3d.com (panel Showcase), Q www.learnunity3d.com oraz www.unity3dstudent.com, Q www.unitybook.net (strona powicona niniejszej ksice).
Udostpnianie prac na portalu Kongregate.com Najprostsz metod, która pozwala pocztkujcym projektantom na udostpnianie swoich prac, jest wykorzystanie portalu Kongregate.com. Umoliwia on szybkie i atwe przesyanie wyeksportowanych plików .unity3d, a take uwalnia Ci od koniecznoci zarzdzania wasn stron HTML, zawierajc osadzone treci Unity. Po prostu wejd na portal, utwórz konto, a nastpnie wybierz opcj Games/Upload a Game (gry/przelij gr) z dostpnego menu gównego. Wypenij formularz pozwalajcy na przesanie treci do spoecznoci Kongregate i podziel si odnonikiem do swojej gry na Twitterze lub Facebooku. Udostpnianie gier w taki sposób jest wietnym sposobem na uzyskanie informacji zwrotnych. Moesz otrzymywa komentarze i oceny, jak równie przesya nowe wersje oprogramowania oraz rozmawia z osobami grajcymi aktualnie w Twoje gry.
428
Rozdzia 12. • Budowanie i udostpnianie
Ten rodzaj bezstronnego kontaktu z uytkownikami jest bardzo wany, pozwala bowiem na wykrywanie bdów oraz fragmentów gry, które moe s intuicyjne dla Ciebie, ale nie dla przecitnego gracza. Pamitaj równie, e niektóre portale nie maj moliwoci przechowywania Twoich gier w formacie .unity3d, lecz wymagaj podania odnonika do Twojego blogu, który zawiera osadzon gr, lub do serwera, który pozwala na pobranie samodzielnej aplikacji.
Podsumowanie Z tego rozdziau dowiedzielimy si, w jaki sposób mona eksportowa gr do rodowiska sieciowego oraz do postaci samodzielnej aplikacji. W ostatnim rozdziale zastanowimy si nad tym, czego nauczylimy si w trakcie czytania tej ksiki, a take zaprezentujemy moliwoci zdobywania dalszej wiedzy i rozwijania umiejtnoci. Poinformujemy równie, gdzie mona uzyska wsparcie w projektowaniu gier w rodowisku Unity.
429
Projektowanie gier w rodowisku Unity 3.x
430
13 Testy i dalsze zdobywanie wiedzy W niniejszej ksice omówilimy podstawowe zagadnienia, pozwalajce na rozpoczcie tworzenia projektów gier przy wykorzystaniu silnika Unity. Podczas pracy w rodowisku Unity odkryjesz, e kady zaprojektowany przez Ciebie element gry bdzie rozwija Twoje umiejtnoci i poszerza wiedz. Interesujce pomysy bd si pojawia coraz atwiej w miar zdobywania przez Ciebie dowiadczenia w obsudze rodowiska Unity oraz wiedzy zwizanej z tworzeniem skryptów. W tym rozdziale podsumujemy wprowadzenie do systemu Unity, analizujc nastpujce zagadnienia: Q sposoby testowania i finalizowania projektów, Q optymalizacja gry, Q otrzymywanie informacji o wydajnoci od uytkowników testowych, Q uzyskiwanie pomocy zwizanej ze rodowiskiem Unity, Q sugestie dalszego rozwoju.
Pamitajc o powyszych punktach, moesz zastanowi si nad dalszym poszerzaniem swojej wiedzy. Oto najwaniejsze obszary zagadnie, które powiniene uwzgldni w tym procesie: Q tworzenie skryptów, Q tworzenie skryptów, Q tworzenie skryptów.
Powysza lista jest prawidowa — to nie art. Mimo e rodowisko Unity synie z dostarczania intuicyjnych zestawów narzdzi do projektowania wizualnego, a take udostpnia graficzny interfejs, pozwalajcy na budowanie scen i obiektów gry, nic nie zastpi nauki klas i polece, które wykorzystuj waciwy silnik Unity.
Projektowanie gier w rodowisku Unity 3.x
Po przeczytaniu instrukcji uytkowania systemu, a nastpnie podrcznika komponentów i skryptów (dostpnych zarówno w internecie, jak i na dysku jako element instalacji systemu) zaczniesz rozumie , jakie s najlepsze metody tworzenia okrelonych elementów gry. Moe to nie mie znaczenia w Twoim biecym projekcie, ale powinno uzupeni posiadan przez Ciebie wiedz, by umoliwi Ci bardziej wydajn prac w przyszoci: Q podrcznik komponentów: http://www.unity3d.com/support/documentation/
Components/, Q podrcznik skryptów: http://www.unity3d.com/support/documentation/
ScriptReference/, Q instrukcja uytkowania rodowiska Unity: http://www.unity3d.com/support/
documentation/Manual/, Q dokumentacja jzyka C# na stronie MSDN (naley pomin informacj
o rodowisku Visual C#): http://msdn.microsoft.com/pl-pl/vstudio/hh341490.
Nauka poprzez dziaanie Oprócz korzystania z instrukcji uytkowania rodowiska Unity oraz podrcznika komponentów i skryptów jednym z najlepszych sposobów rozwijania umiejtnoci projektowania gier jest szybkie wykonywanie prototypów (ang. rapid prototyping). Jest to proces szybkiego tworzenia uproszczonych implementacji pomysów zwizanych z grami, przy uyciu prostych elementów graficznych i koncentrowaniu si na samej rozgrywce. Zastanów si nad prost mechanik gry, a nastpnie postaraj si wymyli , w jaki sposób mona j zbudowa . Wykorzystujc mechanizm ideacji, usprawniasz proces uczenia si, a take uzyskujesz motywacj, pomagajc w zachowaniu odpowiedniego poziomu koncentracji, poniewa masz do osignicia okrelony cel, a nie poszerzasz swojej wiedzy tylko ogólnie, bez adnej okrelonej zachty.
Testowanie i finalizowanie Podczas projektowania gier powiniene by wiadomy tego, e bardzo wanym elementem jest testowanie Twojej aplikacji przez uytkowników, którzy nie mieli z ni wczeniej do czynienia. W trakcie pracy nad dowolnym kreatywnym projektem powiniene wiedzie , e w celu zachowania twórczej obiektywnoci musisz by otwarty na sowa krytyki, które wynikaj z odpowiedniego procesu testowania, bdcego równie techniczn koniecznoci. Bardzo atwo mona si przyzwyczai do narracji lub mechaniki gry. Równie czsto nie jest moliwe obiektywne spojrzenie na wasn gr, tak jak mógby j potraktowa zwyky gracz. Zamiast traktowa gr wycznie z punktu widzenia jej projektanta, zawsze próbuj wciela si w rol gracza. By moe pewne fragmenty gry s oczywiste dla Ciebie, lecz mog nie mie sensu dla uytkownika.
432
Rozdzia 13. • Testy i dalsze zdobywanie wiedzy
Wykorzystanie uytkowników do testowania W celu przetestowania gry postaraj si udostpni kompilacje testowe rónym uytkownikom, którzy mog przekaza Ci wane informacje zwrotne. Q Specyfikacja sprztu. Upewnij si, e testujesz gr na rónym sprzcie i otrzymujesz
informacj zwrotn o jej wydajnoci. Q Format. Jeli uywasz aplikacji samodzielnej, postaraj si stworzy wersje dziaajce
w rodowisku PC i Mac. Q Jzyk. Czy Twoi uytkownicy testowi mówi w tym samym jzyku co Ty? Czy mog
Ci poinformowa , e interfejs gry jest logiczny i sensowny? Q Dowiadczenie. W jaki rodzaj gier zazwyczaj graj Twoi testerzy? Czy s to
przypadkowi lub naogowi gracze? Jak oceniaj Twoj gr pod wzgldem trudnoci? Jakie fragmenty gry sprawiaj im problemy? Po przetestowaniu gry w wersji alfa przez Ciebie i innych projektantów, powiniene przekaza j okrelonej grupie testerów publicznych. Bdzie to tak zwany test beta. Dziki sformalizowaniu tego procesu moesz sprawi , by otrzymane informacje zwrotne byy jak najbardziej przydatne. Stwórz kwestionariusz, w którym umiecisz pytania do testerów nie tylko o ich reakcje na gr, lecz take o nich samych. W ten sposób moesz wyciga pewne wnioski dotyczce swojej gry, na przykad: Gracze pomidzy 18 i 24 rokiem ycia rozumiej gr i podoba si im jej mechanika, lecz gracze w wieku 45 lat lub wicej nie rozumiej jej bez wczeniejszego przeczytania instrukcji. Przypadkowi gracze uwaaj, e gra nie zawiera interesujcych elementów, które mogyby zachci ich do grania w ni. Rozwa modyfikacj projektu poziomów. Oprócz tego pojawi si wnioski czysto techniczne: Gracze z komputerami z procesorem o czstotliwoci taktowania poniej 2,4 GHz twierdz, e gra dziaa zbyt wolno, przecitnie od 15 do 25 klatek na sekund. Rozwa przeprowadzenie kompresji tekstur i szczegóów modeli.
Informacja o szybkoci klatek Poniewa testujesz swoj gr w edytorze, masz dostp do informacji statystycznych o wydajnoci. S one widoczne w nakadce Statistics (statystyka), wywietlanej w widoku Game (gra) (kliknij przycisk Stats!). Publiczny tester nie bdzie jednak uywa edytora Unity, dlatego powinnimy rozway umieszczenie narzdzi statystycznych w samej grze. Aby udostpnia testerom gr i uzyskiwa od nich okrelone informacje zwrotne o parametrach technicznych, takich jak szybko klatek (liczba klatek wywietlanych przez gr na ekranie w cigu sekundy), moesz uzupeni swoj kompilacj testow o element GUI, który bdzie wywietla niezbdne dane.
433
Projektowanie gier w rodowisku Unity 3.x
Przyjrzyjmy si praktycznemu przykadowi, dziki czemu bdziesz móg wywietla interesujce Ci dane w dowolnej scenie. Otwórz scen, w której chcesz wywietla szybko klatek — w naszym przypadku bdzie to scena Island. Nastpnie stwórz nowy obiekt GUI Text, w którym pojawi si informacje. W tym celu przejd do opcji menu gównego GameObject/Create Other/ GUI Text (obiekt gry/stwórz inny/GUI Text) lub kliknij przycisk Create (stwórz) w panelu Hierarchy (hierarchia), a w dalszej kolejnoci wybierz opcj GUI Text. Zmie nazw nowo utworzonego obiektu na FPS display, po czym w komponencie GUI Text panelu Inspector (inspektor) przypisz parametrowi Anchor (zakotwiczenie) warto upper center (górna krawd, na rodku), a parametrowi Alignment (justowanie) — center (do rodka). Aby zachowa zgodno , przejd do panelu Project (projekt) i przecignij uywan przez Ciebie czcionk na parametr Font (czcionka). W komponencie Transform wprowad warto 0,9 w polu Y. A teraz stwórz nowy skrypt w panelu Project poprzez wybranie folderu Scripts (skrypty), a nastpnie kliknicie przycisku Create i wybranie opcji C# Script (skrypt jzyka C#) lub Javascript (skrypt jzyka JavaScript) z menu rozwijanego. Zmie nazw nowo utworzonego skryptu na FPSdisplay oraz dwukrotnie kliknij jego ikon, by wczyta go do edytora. Uytkownicy jzyka C# jak zwykle powinni si upewni , e ich klasa nazywa si równie FPSdisplay. Poniewa szybko klatek gry zaley od konfiguracji sprztu i oprogramowania, powinnimy wykonywa operacj sumowania, co oznacza dodawanie do siebie liczby klatek, renderowanych w kadej sekundzie trwania gry. Rozpoczniemy od zadeklarowania odpowiednich zmiennych na pocztku skryptu. Pamitaj, e w przypadku jzyka C# miejscem tym jest pocztek klasy: Jzyk C#: float frames = 0; float fps = 0;
Jzyk JavaScript: private var frames : float = 0; private var fps : float = 0;
Powysze dwie zmienne wykonuj takie czynnoci: Q frames: warto zmiennej jest zwikszana o 1 po kadej klatce, przez co zawiera
ona liczb wywietlonych klatek, Q fps: liczba klatek na sekund, wynikajca z zaokrglonej wartoci zmiennej frames podzielonej przez czas, który upyn od uruchomienia sceny. A teraz w funkcji Update() umie poniszy kod: Jzyk C# i JavaScript: frames++; fps = Mathf.Round(frames / Time.realtimeSinceStartup); guiText.text = "Frames Per Second: " + fps;
434
Rozdzia 13. • Testy i dalsze zdobywanie wiedzy
W tym kodzie wykonujemy nastpujce czynnoci: Q Zwikszamy zmienn frames o 1 po kadym wywoaniu funkcji Update()
(czyli po kadej klatce). Q Przypisujemy zmiennej fps zaokrglon warto zmiennej frames, podzielon przez
czas, który upyn od uruchomienia sceny. Dziki temu moesz uzyska realistyczn reprezentacj wydajnoci dziaania komputera, na którym dziaa gra. Q Uywamy waciwoci text komponentu guiText i przypisujemy jej acuch tekstowy Frames Per Second:, za którym umieszczamy warto zmiennej fps. Poniewa chcemy uywa naszego skryptu w dowolnej grze, powinnimy si upewni , e moe on zosta przecignity i upuszczony na obiekcie nalecym do innego projektu, a nastpnie poprawnie dziaa . W tym celu musimy umieci w skrypcie polecenie RequireComponent, które zapewni obecno komponentu GUI Text. Korzystalimy z niego ju wczeniej, wic prawdopodobnie pamitasz, jak go uy . Jeli nie, poniej prezentujemy odpowiedni instrukcj: Jzyk C#: Na pocztku skryptu, po wierszu using System.Collections;, umie instrukcj: [RequireComponent (typeof (GUIText))]
Jzyk JavaScript: Po zamykajcym nawiasie klamrowym funkcji Update() umie poniszy wiersz kodu: @script RequireComponent(GUIText)
Przejd do opcji menu gównego File/Save (plik/zapisz) w edytorze skryptów, a nastpnie wró do rodowiska Unity. Upewnij si, e w panelu Hierarchy zosta wybrany obiekt FPS display. Wybierz opcj menu gównego Component/Scripts/FPSdisplay (komponent/skrypty/FPSdisplay) lub po prostu przecignij skrypt z panelu Project na obiekt w panelu Hierarchy. A teraz przetestuj swoj scen. Powiniene zobaczy obiekt GUI Text, który wywietla szybko klatek gry w górnym obszarze okna. Twoja gra bdzie miaa inn wydajno poza edytorem Unity. Dlatego te szybko klatek powinna by brana pod uwag jedynie w kompilacji, która jest samodzieln aplikacj lub dziaa w przegldarce internetowej. Popro swoich testerów, aby zanotowali najnisze i najwysze wartoci prdkoci klatek, dziki czemu uzyskasz okrelone zakresy danych. Jeli w grze wystpuj szczególnie wymagajce fragmenty, na przykad zoona animacja lub system czstek, naleaoby równie dla nich sprawdzi prdkoci klatek. Poniewa gra dziaa z inn prdkoci klatek poza edytorem Unity, wywietlane wartoci bd si róniy od tych, które s prezentowane w nakadce Stats dla widoku Game:
435
Projektowanie gier w rodowisku Unity 3.x
Optymalizacja wydajnoci Usprawnianie wydajnoci Twojej gry w wyniku przeprowadzonych testów jest samo w sobie oddzielnym obszarem wiedzy. Jednake aby poprawi jako przyszych projektów, powiniene zna podstawowe metody optymalizacyjne: Q Rozpoznawanie ogranicze. Niska wydajno Twojej gry moe wynika z wielu
powodów. Kluczowe staje si przeprowadzenie analiz, majcych na celu uzyskanie informacji, w którym miejscu pojawiaj si tak zwane wskie garda. Czy dana scena powoduje zmniejszenie wydajnoci? Czy gra zaczyna wolniej dziaa jedynie wtedy, gdy pojawia si zoony model lub system czstek z wieloma obiektami? Staraj si by systematyczny w czasie poszukiwania przyczyn spowolnienia dziaania gry. Zawsze pro testerów o opis scenariusza, który moesz powtórzy na swoim komputerze w celu zauwaenia problemu. Q Liczba wieloktów. Modele trójwymiarowe powinny by projektowane z uyciem
niewielkiej liczby wieloktów. Upraszczaj wic swoje modele tak bardzo, jak to moliwe, aby poprawi wydajno . Q Zasig renderowania. Rozwa modyfikacj odlegoci w parametrze Far Clip Plane
(tylna paszczyzna odcinania) dla uywanych kamer, by zmniejszy wielko obszaru, który powinien by renderowany.
436
Rozdzia 13. • Testy i dalsze zdobywanie wiedzy
Q Usuwanie niewidocznych powierzchni. Opcja usuwania niewidocznych powierzchni
jest dostpna jedynie w wersji Unity Pro. Pozwala ona unikn renderowania zbdnych obiektów, które s zasaniane przez inne. Wicej o tym zagadnieniu moesz si dowiedzie z podrcznika Unity (http://unity3d.com/support/documentation/ Manual/OcclusionCulling.html). Q Rozmiary tekstur. Uywanie tekstur o wyszych rozdzielczociach moe poprawi
wraenia wizualne, lecz jednoczenie sprawi , e silnik gry bdzie pracowa przy wikszym obcieniu. Postaraj si wic maksymalnie zmniejszy rozmiary tekstur, uywajc zarówno aplikacji graficznej, jak i ustawie zwizanych z importowaniem zasobów. Q Wydajno skryptów. Poniewa jest wiele sposobów na rozwizanie danego
zagadnienia, staraj si uywa w swoich skryptach efektywnych procedur. Rozpocznij od przeczytania poradnika Unity na temat tworzenia wydajnych skryptów (http://unity3d .com/support/documentation/ScriptReference/index.Performance_Optimization.html).
Sposoby zdobywania wiedzy Po przeczytaniu tej ksiki bdziesz musia znale sposób na zdobywanie dalszej wiedzy, zachowujc jednoczenie równowag midzy chci samodzielnego rozwizania wszystkich problemów a potrzeb zwracania si z probami o pomoc do bardziej dowiadczonych projektantów Unity. Zastosuj si do podanych niej wskazówek, a gdy poszerzysz swoj wiedz, bdziesz móg suy pomoc innym osobom nalecym do spoecznoci Unity.
Studiuj róne zagadnienia Podczas poznawania nowego pakietu lub jzyka oprogramowania zdarza si czsto, e musisz pilnie wykona prac, gdy jeste czonkiem zespou lub niezalenym projektantem. Moe to czsto prowadzi do stosowania metody uczenia si „bierz tylko to, czego potrzebujesz”. Mimo e moe by ona czsto jedyn dostpn opcj ze wzgldu na ograniczenia czasowe, jest jednak szkodliwa dla procesu zdobywania wiedzy, poniewa moesz przyj ze nawyki, które bd obecne w trakcie tworzenia oprogramowania i ostatecznie doprowadz do wybrania niewaciwych rozwiza. Biorc powysze pod uwag, zalecamy, aby studiowa oficjaln dokumentacj produktu, gdy tylko masz czas i moliwo . Nawet jeli masz problem z rozwizaniem okrelonego problemu projektowego, pomoe Ci to zaj umys czym zupenie innym. Zapoznaj si z zagadnieniem niezwizanym z Twoj aktualn prac, a nastpnie wró do niej z odwieonym umysem.
437
Projektowanie gier w rodowisku Unity 3.x
Nie odkrywaj koa na nowo Tytu tego punktu moe si wydawa sprzeczny z poprzednim, lecz gdy tylko zaczniesz rozwizywa bardziej zoone problemy dotyczce projektowania gier, dowiesz si, e nie ma sensu odkrywa koa na nowo, czyli ponownie próbowa stworzy czego, co inny projektant ju rozwiza i udostpni spoecznoci. Na przykad jeli zastanawiasz si nad implementacj sztucznej inteligencji wroga czy cho by chcesz stworzy algorytm cieki poszukiwania, warto rozejrze si za istniejcymi rozwizaniami, zamiast pisa wasny kod od samego pocztku. Dla rodowiska Unity istnieje wiele wtyczek i gotowych do uycia zasobów, które mog rozwiza praktycznie kady problem. Dostp do nich jest moliwy poprzez opcj menu gównego Window/Asset Store (okno/magazyn zasobów) lub róne strony internetowe. Zalecamy, aby odwiedzi ponisze portale, zawierajce treci, które mog by przydatne podczas projektowania gier komputerowych: Q iTween — ta przydatna wtyczka, stworzona przez Boba Berkebile’a (pseudonim:
pixelplacement), udostpnia kilka rzeczywicie prostych klas, pozwalajcych na uzyskanie fantastycznych efektów animacyjnych przy uyciu minimalnej iloci kodu: http://itween.pixelplacement.com/. Q Prime32 — ta strona oferuje wiele przydatnych wtyczek, które poszerzaj
funkcjonalno rodowiska Unity, szczególnie w przypadku tworzenia gier na platformy mobilne: http://www.prime31.com/unity/.
Jeli czego nie wiesz, pytaj! Inn dobr metod uczenia si jest oczywicie zapoznawanie si z rozwizaniami stosowanymi przez innych uytkowników. Okazuje si, e podczas projektowania gier komputerowych istnieje czsto wiele rozwiza tego samego problemu, tak jak byo w naszym przypadku podczas wymylania sposobu na otwieranie drzwi placówki w rozdziale 5. Kuszce staje si wic wykorzystywanie wiedzy i algorytmów uytych podczas rozwizywania poprzedniego problemu. Zalecamy jednak, aby zawsze dokadnie sprawdzi, czy Twoja metoda jest najbardziej efektywna. Zadajc pytanie na forum Unity (forum.unity3d.com), stronie Answers (answers.unity3d.com) oraz kanale IRC (Internet Relay Chat) (irc.freenode.net, kana #unity3d), bdziesz móg otrzyma odpowied, pozwalajc na zastosowanie najbardziej efektywnego sposobu realizacji okrelonego zadania projektowego. Czasem okae si, e metoda, któr chciae zastosowa , bya niepotrzebnie zbyt skomplikowana! Pamitaj, aby przed sformuowaniem pytania zawsze przeszuka powysze strony, bo by moe kto ju je kiedy zada. Jest due prawdopodobiestwo, e tak wanie bdzie. Jeli nie, pamitaj, aby w swoim pytaniu zawrze w miar moliwoci ponisze punkty:
438
Rozdzia 13. • Testy i dalsze zdobywanie wiedzy
Q Co chcesz osign ? Q Jaki jest Twój pomys na rozwizanie? Q Co do tej pory zrobie?
Dziki przekazaniu jak najwikszej iloci informacji, nawet takiej, która wydaje Ci si niezwizana z tematem, zwikszasz prawdopodobiestwo uzyskania waciwej odpowiedzi i zrealizowania zadania projektowego. Podczas tworzenia pyta o skrypty pamitaj o wykorzystaniu odpowiedniej strony, pozwalajcej na wklejanie tekstu, na przykad http://www.pastebin.com, poniewa pozwoli to na zaprezentowanie Twojego kodu bez potrzeby zajmowania duej iloci miejsca na stronie forum. Wielk zalet spoecznoci Unity jest to, e pozwala na uczenie si dziki wykorzystaniu przykadów. Niezalena strona typu Wiki (www.unifycommunity.com/wiki) zawiera wiele rónych przykadów, poczynajc od skryptów, a koczc na wtyczkach i podrcznikach. Znajdziesz tam darmowe fragmenty kodów, które pozwalaj na rozwizanie przykadowych zagadnie skryptowych, a nawet informacje o sposobie ich implementacji razem z gotowymi projektami do pobrania.
Podsumowanie W tym rozdziale przedstawilimy propozycje dalszego rozwoju po ukoczeniu czytania niniejszej ksiki, a take zaproponowalimy, jak uzyska informacje od uytkowników testowych w celu ulepszenia Twojej gry. Pamitaj, e zdobywanie wiedzy nie koczy si na tej ksice. Moesz odwiedzi jej stron (http://www.unitybook.net) i zada pytanie, a take sprawdzi , czy pojawiy si jakie aktualizacje systemu Unity, których dziaanie jest odmienne od zaprezentowanego w tej publikacji. Na koniec chcielibymy yczy Ci powodzenia w projektowaniu gier komputerowych w rodowisku Unity. Dzikujemy za przeczytanie tej ksiki. Mamy nadziej, e podró bya interesujca — a przecie to dopiero pocztek!
439
Projektowanie gier w rodowisku Unity 3.x
440
A Sowniczek Aliasing — ostre krawdzie, które pojawiaj si podczas renderowania wieloktów. Antyaliasing — wygadzanie ostrych krawdzi, które s widoczne podczas renderowania wieloktów. Aplikacja samodzielna — wyeksportowana kompilacja gry Unity, która moe zosta uruchomiona jako zwyky program komputerowy. Arkusz stylów — patrz CSS. Bdne argumenty — dane przekazane do argumentów funkcji, które nie odpowiadaj ich typom. Problem pojawia si na przykad przy przekazywaniu wartoci typu GameObject do argumentu oczekujcego na liczb zmiennoprzecinkow. Bug — bd w skrypcie lub projekcie gry, który wymaga naprawienia! Celownik — tekstura uywana do wywietlania na ekranie „naprowadzaczy”, które uatwiaj graczowi celowanie w strzelankach. Cienie rzucane — cienie odwzorowywane w rodowisku gry. CSS (Cascading Style Sheets) — kaskadowe arkusze stylów, uywane w celu zdefiniowania stylu strony internetowej. Cubemap — materia skadajcy si z szeciu tekstur, uywany do tworzenia efektów, na przykad skyboksów. Cykl projektowania — faza projektowania gier. Mógby to by cykl prototypowania: byyby w nim testowane mechanika lub cykl finalny, w którym zostayby wprowadzone kocowe ulepszenia gry. Czas wykonania — czas dziaania gry. Czstka — pojedynczy element, emitowany przez system czstek (patrz rozdzia 8.). Dashboard — oddzielny ekran z nieduymi aplikacjami w systemie Mac OS X. Debugowanie — proces wyszukiwania i usuwania bdów w skrypcie.
Projektowanie gier w rodowisku Unity 3.x
Dynamiczne pakietowanie — grupowanie obiektów, które wykorzystuj podobne materiay i skal, w celu uzyskania wzrostu wydajnoci renderingu. D wik przestrzenny — trójwymiarowy dwik, który staje si goniejszy, gdy posta gracza (lub dokadniej komponent Audio Listener) zblia si do niego. Edytor (Unity) — rodowisko Unity, a nie edytor skryptów. Edytor skryptów — edytor tekstowy, zaprojektowany specjalnie w celu obsugi jzyków programowania, takich jak C# i JavaScript. Edytor terenu (zestaw narzdziowy) — zestaw narzdzi dostpny jako komponent, sucy do edycji terenu w rodowisku Unity. Ekstrapolacja — technika matematyczna, uywana do przewidywania wartoci na podstawie znanych pomiarów. FBX — format pliku uywany w celu przechowywania i importowania modeli trójwymiarowych w rodowisku Unity. Filtrowanie anizotropowe — metoda, która poprawia jako renderowania tekstur prezentowanych pod duymi ktami. FixedUpdate — funkcja, która jest wywoywana w kadej klatce fizycznej, niezalenie od aktualnej prdkoci klatek. Fog/Distance fog (mga/zasig tworzenia mgy) — efekt symulowania mgy, który moe zosta uyty w ustawieniach renderera rodowiska Unity, aby wspomaga ukrywanie obiektów znajdujcych si na granicy widocznoci kamery. FPS (klatki na sekund) — liczba klatek gry, które s renderowane w kadej sekundzie. Ogólny wskanik wydajnoci gier. Funkcja — zestaw instrukcji, który moe zosta wywoany w skrypcie. Gadet widoku — stoki i szecian, wywietlane w prawym górnym naroniku widoku Scene (scena), które pozwalaj na przeczanie si midzy widokiem perspektywicznym i rzutem prostoktnym. Geometria — ogólne pojcie dotyczce wierzchoków, trójktów i innych danych tworzcych trójwymiarowy model. Gsto mgy — parametr podobny do wartoci kanau alfa dla mgy. Definiuje on gsto mgy i poziom widocznoci znajdujcych si w niej obiektów. GUI (graficzny interfejs uytkownika) — menu, wywietlacze HUD i inne tego typu skadniki s przykadami elementów GUI. Graficzny interfejs uytkownika jest czsto dwuwymiarowy, ale spotyka si take trójwymiarowe. Elementy GUI pozwalaj graczowi na interakcj z gr, czasem jako dodatek do tego, co potrafi zrobi jego posta . GUI Text — przykadowy komponent, pozwalajcy na wywietlenie dwuwymiarowego tekstu na ekranie. GUI Texture — komponent pozwalajcy na rendering dwuwymiarowych tekstur na ekranie. HTML (Hypertext Markup Language) — jzyk, w którym s tworzone strony internetowe.
442
Sowniczek
HUD (Heads Up Display) — wywietlacz graficzny, niezwizany ze rodowiskiem, który prezentuje graczowi informacje o grze. W grze wykorzystujcej posta gracza moe to by wskanik poziomu zdrowia. W grze wycigowej — prdkociomierz lub wskanik pozycji samochodu gracza. Ikona ulubionej witryny — ikona widoczna po lewej stronie nazwy witryny, na górze przegldarki lub (w niektórych przegldarkach) po lewej stronie paska adresowego. Interpolacja liniowa — operacja matematyczna, która pozwala na wyznaczanie porednich elementów midzy dwoma wartociami przy uyciu wielomianów liniowych. Zakada si, e punkty bd poczone liniami prostymi. Inwentarz — elementy gromadzone przez posta gracza w trakcie trwania gry. IRC (Internet Relay Chat) — jedna z najstarszych usug sieciowych, umoliwiajca rozmow na kanaach komunikacyjnych. Aby z niej skorzysta , po prostu zainstaluj klienta mIRC (PC) lub Colloquy (Mac). Jzyk Boo — jzyk skryptowy uywany w rodowisku Unity. Poniewa nie wspiera on platform mobilnych, jest mniej popularny ni C# czy JavaScript. Patrz równie jzyk C# i jzyk JavaScript. Jzyk C# — jzyk skryptowy wykorzystywany w rodowisku Unity. Patrz równie jzyk JavaScript i jzyk Boo. Jzyk JavaScript — jzyk skryptowy uywany w rodowisku Unity. Kamera — okno widoku wiata gry. W scenie moe zosta uytych wicej kamer, które pozwalaj na renderowanie dodatkowych szczegóów. Kana UV — skadnik pliku modelu trójwymiarowego, zawierajcy informacje o tym, jak tekstura zostaa odwzorowana na ksztat siatki. Kartezjaski ukad wspórzdnych — wspórzdne w formacie X, Y i Z; na przykad Vector3(5, 10, 5). Klasa — sposób definiowania danych w skrypcie. Fragmentem klasy mog by take zmienne, funkcje i wspóprogramy. Klatki kluczowe — okrelone punkty na listwie czasu animacji, które s wykorzystywane przez mechanizm Tweening (animacji automatycznej) do interpolacji. Klony — duplikaty obiektów gry lub prefabrykatów. Kofeina — substancja uywana w okolicach ostatecznych terminów realizacji zada projektowych! Komentarze — kod w skrypcie, który zosta zabezpieczony przed wykonaniem. Kompilacja — gotowa lub testowa wersja gry, wyeksportowana w rodowisku Unity. Komponent — komponenty definiuj sposób zachowania Twoich obiektów; mog by skadnikiem systemu Unity lub skryptami. Kompozycja graficzna GUI — zasób stworzony przez rodowisko Unity i przechowywany w projekcie, który pozwala na modyfikowanie stylu obsugiwanych w skrypcie elementów GUI.
443
Projektowanie gier w rodowisku Unity 3.x
Konkatenacja — czenie wartoci zmiennych w celu utworzenia duszego acucha znaków. Konkretyzacja — czynno tworzenia instancji obiektu gry lub prefabrykatu w trakcie dziaania gry. Konsola — okno w rodowisku Unity, które wywietla informacje o bdach. Jest to najwaniejsze okno systemu! Aby je otworzy , uyj opcji menu gównego Window/Console (okno/ konsola) lub skrótu klawiszowego (PC: Ctrl+Shift+C, Mac: Command+Shift+C). Kosztowny — okrelenie skadnika, który wymaga duej mocy procesorów CPU i GPU do uruchomienia gry. Ksztat prosty — podstawowe ksztaty trójwymiarowe, takie jak szeciany, kule, paszczyzny i kapsuy. Liczba wierzchoków — liczba wierzchoków w siatce modelu.
czenie alfa — czenie ze sob przezroczystych i nieprzezroczystych obszarów materiaów. Macierz kolizji warstw — opcja dostpna w menederze parametrów fizycznych. Pozwala na wybranie okrelonych warstw w celu zabronienia wystpowania zdarze kolizji midzy znajdujcymi si na nich obiektami. Mapa wiata — plik tekstury, w którym jest przechowywane owietlenie sceny. Mapa wypalona — gotowa mapa wiata. Sformuowanie to jest czsto uywane do okrelenia gotowej tekstury lub wygldu rodowiska. Mapy wysokociowe — pliki graficzne zawierajce jasne i ciemne obszary; definiuj geometri wysokoci. Mesh Filter — komponent, który zawiera ksztat obiektu trójwymiarowego. Mesh Renderer — komponent, który zarzdza wizualnym wygldem obiektu siatkowego. MonoDevelop — domylny edytor skryptów, dostpny w rodowisku Unity. Movieclip — szablon danych w rodowisku projektowym Adobe Flash, porównywalny z koncepcj prefabrykatu w Unity. Normalizacja — matematyczna metoda standaryzacji wartoci. S one czsto znormalizowane w zakresie od 0 do 1. Normalizacja w przypadku wektora oznacza przypisanie mu dugoci jednostkowej. Null — jeli zmienna nie zostaa w skrypcie zainicjalizowana, wówczas jej warto jest równa null, czyli niezdefiniowana. Obiekt gry — obiekt w aktualnie otwartej scenie. Obiekty statyczne — obiekty, które nie poruszaj si, a przez to mog by uwzgldniane w procedurze odwzorowywania wiata lub — jeli uywaj tego samego materiau — w renderingu pakietowym. Obraz tytuowy — obraz powitalny, zawarty w samodzielnej aplikacji gry utworzonej w rodowisku Unity. Odlego widzenia — odlego , w jakiej kamera renderuje obiekt.
444
Sowniczek
Odtwarzacz sieciowy — wtyczka stworzona dla rodowiska Unity, która pozwala na uruchamianie gier w przegldarce internetowej. Odwzorowywacz wiata — narzdzie w rodowisku Unity, które realizuje operacj wypalania wiata w pliku tekstury, aby poprawi wydajno i uzyska lepsze wraenia wizualne. Odwzorowywanie wiata — zapisywanie wiata w scenie w pliku tekstury w celu optymalizacji wydajnoci. OnTriggerEnter — funkcja uywana do wykrywania kolizji midzy wyzwalaczami i innymi zderzaczami. Osadzanie kodu — umieszczanie kodu, takiego jak HTML, wewntrz innej strony. Taka czynno jest niezbdna na przykad podczas umieszczania treci wideo z portalu YouTube na innej stronie internetowej. Pakiet — sposób przechowywania treci projektu Unity i udostpniania ich innym osobom. Pakietowanie — czynno czenia ze sob wielu zada obliczeniowych. Particle Animator — komponent w rodowisku Unity, który decyduje, jak maj si zachowywa czstki w trakcie swojego ycia. Particle Emitter — komponent w rodowisku Unity, który zarzdza procesem emisji czstek. Particle Renderer — komponent w rodowisku Unity, który okrela wizualny wygld czstek. Perspektywa — trójwymiarowy widok sceny gry, w którym obiekty staj si coraz mniejsze wraz ze zwikszaniem si ich odlegoci od kamery. Ptla — sposób pozwalajcy na powtarzanie wywoywania tych samych instrukcji w skrypcie. Równie termin oznaczajcy powtórzenie animacji. PhysX — fizyczny silnik firmy nVidia, który zosta zastosowany w rodowisku Unity. Piksel — pojedynczy punkt; z pikseli jest tworzony komputerowy obraz na ekranie. Paszczyzna — paski, kwadratowy, prosty ksztat, który moe zosta utworzony w rodowisku Unity. Paszczyzny odcinania — dwie paszczyzny widoku, midzy którymi nastpuje rendering wiata trójwymiarowego za pomoc kamery. Pocztek — pooenie zerowe w wiecie trójwymiarowym, reprezentowane przez warto (0, 0, 0) we wspórzdnych kartezjaskich. Podmienianie tekstur — zamienianie jednej tekstury na inn w celu stworzenia efektu animacji tekstur. Pooenie zerowe — miejsce zerowe, zwane inaczej pocztkowym pooeniem w wiecie trójwymiarowym. Potomek — obiekt nalecy w hierarchii do obiektu nadrzdnego. Powielanie — patrz konkretyzacja. Poziom szczegóowoci — liczba szczegóów renderowanych na ekranie, która moe si zmniejsza wraz ze wzrostem odlegoci od kamery.
445
Projektowanie gier w rodowisku Unity 3.x
Prefabrykat — obiekt utworzony w scenie i przechowywany w projekcie. Moe by konkretyzowany w czasie trwania gry. Prdko — wielko fizyczna, reprezentujca szybko i kierunek poruszajcego si obiektu bryy sztywnej. Procedura — fragment skryptu, który jest aktualnie wykonywany przez silnik gry. Procedury cieniowania samowieccego materiau — procedury cieniowania definiujce wieccy materia, który nie wymaga owietlania. Prototyp — uproszczona prezentacja rozgrywki, wykorzystujca podstawowe ksztaty i proste efekty w celu sprawdzenia dziaania jakiego pomysu. Prototypowanie — czynno tworzenia prototypu. Przerywnik — fragment, który przerywa rozgrywk w celu zaprezentowania narracji lub widoku otoczenia (ogólnie czego, czego aktualnie nie widzi posta ), by wspomóc kontynuowanie akcji gry. Przestrze modelu — wspórzdne obiektu zdefiniowane w odniesieniu do jego rodzica. Przestrze obiektu — wspórzdne obiektu zdefiniowane w odniesieniu do jego rodzica. Publikowanie — proces kompilowania i udostpniania gry uytkownikom docelowym. Punkt rejestracji — punkt, od którego wystpuje rendering elementu GUI. Punkty — co, co mona zdoby w grze. Take inne okrelenie wierzchoków w siatce. Rect — typ danych, zawiera cztery wartoci float: X, Y, Width i Height. Rendering — czynno wywietlania grafiki komputerowej na ekranie. RequireComponent — funkcja pozwalajca na automatyczne doczanie komponentu do obiektu podczas przypisywania do niego skryptu. Rigidbody — sposób wykorzystywany w rodowisku Unity do doczania silnika fizycznego do obiektu. Rigidbody jest komponentem i klas skryptow. Rodzic lub obiekt nadrzdny — obiekt znajdujcy si na samej górze hierarchii. Rzucanie promieni — tworzenie wektora midzy punktami znajdujcymi si w wiecie gry w celu wykrycia przecinania si innych elementów. Rzut prostoktny — dwuwymiarowy widok Twojej sceny w grze. Sceny — sceny s metod stosowan w rodowisku Unity, która pozwala na oddzielanie od siebie treci. Mog by one uywane w celu tworzenia rónych poziomów lub po prostu zarzdzania dodatkowo wczytywanymi treciami. SendMessage — polecenie uywane w celu wywoania funkcji w skrypcie doczonym do innego obiektu. Siatka — ksztat zdefiniowany w przestrzeni trójwymiarowej przez poczenie punktów, zwanych wierzchokami.
446
Sowniczek
Silnik gry — oprogramowanie (takie jak na przykad Unity), które obsuguje rendering, odtwarzanie dwików i inne doczone biblioteki kodów, zarzdzajce na przykad parametrami fizycznymi; pozwala na tworzenie gier. Sia — sposób wprawiania w ruch bryy sztywnej w rodowisku trójwymiarowym. Równie oddziaywanie fizyczne, które nas otacza i wie, a take utrzymuje wszechwiat w caoci. Skalowanie zderzacza — czynno zmiany ksztatu zderzacza w celu zmodyfikowania obszaru wykrywania kolizji. Skrypt edytora — skrypt definiujcy zachowanie edytora. Skrypt Unity — sformuowanie uywane czsto podczas prezentacji kodu JavaScript w rodowisku Unity. Skrypty — programy napisane w jzykach C#, JavaScript lub Boo. Skrypty w rodowisku Unity s uywane do definiowania zachowania obiektów lub modyfikowania sposobu dziaania samego edytora Unity. Sposób dziaania — sposób, w jaki obiekt reaguje na okrelone sytuacje. Jest on definiowany za pomoc skryptu. Sprajty — pliki graficzne (tekstury), uywane w grze jako elementy dwuwymiarowe. Strafing — przemieszczanie si w bok podczas grania w gr, zazwyczaj w trakcie strzelania z broni. Strumieniowanie — pobieranie danych z internetu. W grze to czynno wczytywania dodatkowych treci w trakcie rozgrywki. System czstek — zestaw komponentów uywanych do tworzenia efektów wizualnych, takich jak dym, kurz, wybuchy itd. (patrz rozdzia 8.). Szybkie prototypowanie — szybka implementacja mechaniki gry w celu przeprowadzenia testów, bez definiowania elementów wizualnych o docelowej jakoci. rodowisko — miejsce rozgrywki. Moe to by na przykad teren, wntrze budynku lub przestrze kosmiczna. wiato — wiato w rodowisku Unity moe zosta dodane do obiektu w postaci komponentu. Tablica — sposób przechowywania w jednej zmiennej wielu elementów podobnego typu. Tagowanie — przypisywanie pojedynczego sowa do obiektu w polu znajdujcym si w górnej czci panelu Inspector. Tagowanie suy do identyfikacji obiektu. Jest take czsto uywane podczas doczania obiektu do grupy w rodowisku Unity. Tangens — trójwymiarowy wektor, który jest równolegy do powierzchni modelu. Tekstura — plik graficzny, renderowany w postaci fragmentu siatki trójwymiarowej lub dwuwymiarowego elementu GUI. Teren — geometria rodowiska; moe zosta utworzona w systemie Unity, zwykle uywana do modelowania gruntu i wzgórz, po których moe chodzi posta gracza. Tumienie — ogólny termin uywany do opisania procesu zmniejszania si wartoci.
447
Projektowanie gier w rodowisku Unity 3.x
Transform — nazwa komponentu w rodowisku Unity, który zarzdza pooeniem, obrotem i skal obiektu. Równie nazwa klasy skryptowej. Translacja — czynno przemieszczania obiektu w scenie. Translate — polecenie suce do przemieszczania obiektów w przestrzeni trójwymiarowej. Tryb odtwarzania animacji — tryb, w którym jest odtwarzana animacja; na przykad w ptli, jednorazowo, ping-pong (tam i z powrotem). Tweening — automatyczna animacja, która wykorzystuje przejcia midzy wartociami zdefiniowanymi przez klatki kluczowe. Typ cakowity (int) — numeryczny typ danych dla zmiennych, które zawieraj wartoci cakowite. Typ zmiennoprzecinkowy (float) — numeryczny typ danych dla zmiennych, które zawieraj przecinek dziesitny. Unity — silnik gry, który wanie poznajesz! Sowa „Unity” uywa si w tej ksice zazwyczaj w znaczeniu samego edytora. Unity 3D — nazwa czsto bdnie przypisywana rodowisku Unity przede wszystkim z powodu strony internetowej unity3d.com. Jeli kto uyje nazwy Unity 3D, bdzie mia na myli rodowisko Unity! Update — funkcja, która jest wywoywana w kadej klatce gry. Ustawienia kompilacji — panel rodowiska Unity wykorzystywany do wybrania platformy docelowej oraz parametrów kompilacji. Usuwanie niewidocznych powierzchni — metoda w rodowisku Unity, która pozwala na uniknicie renderowania niewidocznych obiektów, a wic znajdujcych si za innymi. Mówic prosto, metoda usuwa z procesu renderingu obiekty, które nie wystpuj w widoku. Warstwy — sposób odróniania obiektów w scenie zwizany z obsug kolizji i owietlenia. Warto alfa — warto kanau alfa (poziom przezroczystoci), uywana czsto, by uzyska efekt przyciemniania obszarów ekranu. Wskie gardo — skadnik oprogramowania lub sprztu, który pogarsza sprawno dziaania caego systemu przez to, e jest mniej wydajny od innych jego elementów. Wektor — linia rysowana w przestrzeni trójwymiarowej, charakteryzuje si kierunkiem i dugoci. Wektory normalne — wektory, które s prostopade do kadego wierzchoka w siatce. Wersja alfa — kompilacja, która moe zosta udostpniona innym projektantom lub zaufanym partnerom. Wersja beta — bardziej kompletna kompilacja, któr mógby ju udostpni innym uytkownikom. Patrz równie wersja alfa. Widget — niewielki program komputerowy. System operacyjny Mac OS X udostpnia widgety w aplikacji Dashboard. Wielokt — ksztat, który tworzy siatk; jest przewanie trójktem.
448
Sowniczek
Wierzchoek — punkt w przestrzeni trójwymiarowej, który definiuje naronik trójkta tworzcego model siatki. Wska nik odtwarzania — wskanik czasu w oknie animacji, który pokazuje wywietlan lub odtwarzan w danym momencie klatk. Wspóprogram — funkcja, która moe dziaa równolegle z innymi procedurami, wykonujc instrukcje spoza biecego algorytmu programu. Wstpne ustawienie — wczeniej zdefiniowana grupa ustawie. Wygaszanie — zmiana widocznoci w czasie. Wykrywanie kolizji — wykrywanie sytuacji zwanej kolizj, w której zderzacze dwóch obiektów zderzaj si ze sob. Wypalanie (inna nazwa: odwzorowywanie wiata) — proces zapisywania owietlenia sceny w teksturze w celu zoptymalizowania wydajnoci. Wywoanie procedury graficznej — danie renderingu, przesane do karty graficznej. Im wicej jest takich wywoa, tym bardziej obciony jest sprzt i wolniej dziaa aplikacja gry. Wyzwalacz lub tryb wyzwalania — wyzwalacze s zderzaczami z wczonym trybem wyzwalania, co oznacza, e nie s one obecne w sensie fizycznym, lecz mog by wykrywane przez inne zderzacze w trakcie kolizji z nimi. Wyzwalanie wykrywanie kolizji — wykrywanie sytuacji, w której zderzaj si ze sob zderzacze z wczonym trybem wyzwalania. Proces czsto uywany do wykrywania pojawiania si zderzaczy w okrelonym obszarze. Zasoby — modele, skrypty, rysunki, dwiki i inne elementy przechowywane w Twoim projekcie lub folderze zasobów. Zasoby kompozycji graficznej GUI — zasoby, które s tworzone w rodowisku Unity w celu modyfikowania stylu obsugiwanych w skryptach elementów GUI. Zdalna kamera — kamera nieprzypisana do gracza, lecz uywana do prezentowania innego fragmentu otoczenia jako elementu przerywnika. Zdarzenie zderzenia — wystpienie kolizji. Sformuowanie czsto uywane jako uproszczona nazwa zmiennej przechowujcej dane dotyczce kolizji. Zderzacz — zderzacze definiuj fizyczn obecno w obiektach rodowiska Unity. Dziki temu mog one oddziaywa na inne obiekty gry. Zmienne — sposób przechowywania informacji w skrypcie. Zmienne mog by modyfikowane w panelu Inspector, jeli zostan zadeklarowane jako publiczne. Zmienne logiczne — zmienne przyjmujce wartoci true (prawda) lub false (fasz), czsto nazywane „flagami”. S uywane do sprawdzenia, czy jaka akcja zostaa ju przeprowadzona. Zmienne lokalne — zmienne, które zostay zadeklarowane wewntrz funkcji i nie s dostpne poza ni. Patrz równie zmienne prywatne i zmienne publiczne. Zmienne prywatne — zmienne dostpne jedynie w danym skrypcie. Patrz równie zmienne lokalne i zmienne publiczne.
449
Projektowanie gier w rodowisku Unity 3.x
Zmienne publiczne — zmienne, które mog by modyfikowane w panelu Inspector (inspektor). Patrz równie zmienne lokalne i zmienne prywatne. Zmienne statyczne — zmienne publiczne, które mog by atwo dostpne z innych skryptów poprzez zastosowanie odpowiedniego zapisu, na przykad nazwaKlasy.nazwaZmiennej. Znacznik — unikatowy identyfikator, który moe zosta przypisany do obiektów gry w celu ich posortowania lub odszukania w scenie. Znak wodny — póprzezroczysta nakadka dwuwymiarowa, czsto zawierajca nazw firmy, widoczna w grze lub odtwarzanym pliku wideo.
450
Sowniczek
451