UNIVERZA V MARIBORU FAKULTETA ZA ELEKTROTEHNIKO, RAČUNALNIŠTVO IN INFORMATIKO Simon Slemenšek IZDELAVA 3D PLATFORMSKE IGRE V UNITY 3D Diplomsko delo Maribor, september 2018
UNIVERZA V MARIBORU
FAKULTETA ZA ELEKTROTEHNIKO,
RAČUNALNIŠTVO IN INFORMATIKO
Simon Slemenšek
IZDELAVA 3D PLATFORMSKE IGRE V UNITY 3D
Diplomsko delo
Maribor, september 2018
IZDELAVA 3D PLATFORMSKE IGRE V UNITY 3D Diplomsko delo
Študent: Simon Slemenšek
Študijski program: Bolonjski prvostopenjski visokošolski program
Računalništvo in informacijske tehnologije
Mentor: doc. dr. Simon Kolmanič
ii
ZAHVALA
Zahvaljujem se staršem za
podporo, vsem profesorjem za
veliko novega znanja, ki sem ga
pridobil do sedanjega študija in
še posebej mojemu mentorju
doc. dr. Simonu Kolmaniču, ki mi
je vedno nudil pomoč in nasvete
pri izdelavi te naloge.
iii
Izdelava 3D platformske igre v Unity 3D
Ključne besede: računalniška igra, Unity, razvoj igre, gibanje avatarja, plezalni sistem
UDK: 004.388.4(043.2)
Povzetek:
V diplomskem delu je predstavljen proces izdelave 3D platformske igre v igralnem pogonu
Unity®. Poudarek je na obširnem naboru akcij glavnega igralca, kot so plezanje, spust po
cevi in odboj od zidu med skokom. Za izdelavo je uporabljen programski jezik C#. Na začetku
so opisane uporabljene splošne funkcionalnosti tega igralnega pogona. Opisan je tudi žanr
platformskih iger. V praktičnem delu so predstavljene programske metode, ki so omogočile
razvoj takšne igre. Predstavljena je njihova uporabnost ter prednosti in slabosti teh metod.
Na koncu je predstavljena končna igra, ki izhaja iz našega dela ter problemi, ki so se pojavili
pri razvoju takšne 3D platformske igre.
iv
Development of 3D platform game in Unity 3D
Key words: computer game, Unity, game development, character movement, climbing
system
UDK: 004.388.4(043.2)
Abstract:
In this diploma thesis a process of a 3D platform game development in the Unity® game
engine was presented. The emphasis in the thesis was on a different kinds of movement the
character is able to do in the game like climbing, sliding down a pipe and bouncing from a
wall while in mid-air. The programming language used for the implementation of the game
is C#. Simpler functionalities of the game engine that were used are described in the
beginning of the thesis together with the platform game genre. After describing the game
engine the programming methods needed for the implementation of the game were
presented. At the end the gameplay was shown and the problems we encountered during
its development were presented.
v
KAZALO
1 UVOD .................................................................................................................................. 1
2 UNITY® ............................................................................................................................... 3
2.1 Splošen opis ............................................................................................................... 3
2.2 Uporabniški vmesnik .................................................................................................. 4
2.3 Orodje za grajenje okolja ........................................................................................... 6
2.4 Animator .................................................................................................................... 9
2.5 Mešalno drevo ......................................................................................................... 11
3 ŽANR PLATFORMSKE IGRE ............................................................................................... 15
3.1 Zgodovina ................................................................................................................. 15
3.2 Splošen opis ............................................................................................................. 15
4 IZDELAVA IGRE V STARODAVNE GLOBINE (INTO THE ANCIENT DEPTHS) ..................... 16
4.1 Zgodba igre .............................................................................................................. 16
4.2 Glavna ideja igre ...................................................................................................... 17
4.3 Glavni meni .............................................................................................................. 17
4.4 Grajenje okolja ......................................................................................................... 20
4.5 Glavni igralec ............................................................................................................ 20
4.6 Plezalni sistem .......................................................................................................... 21
4.7 Plezalni sistem za cevi .............................................................................................. 36
4.8 Sistem za spuščanje po ceveh .................................................................................. 37
4.9 Glavna kontrolna skripta .......................................................................................... 38
4.10 Povezovanje kode z animacijami ........................................................................... 40
5 PREDSTAVITEV REZULTATOV ........................................................................................... 44
6 SKLEP ................................................................................................................................ 49
7 VIRI IN LITERATURA ......................................................................................................... 50
vi
KAZALO SLIK
Slika 2.1 Logotip igralnega pogona Unity® [4] ....................................................................... 3
Slika 2.2 Uporabniški vmesnik v Unity® ................................................................................. 4
Slika 2.3 Zavihek za ustvarjanje hribov .................................................................................. 7
Slika 2.4 Ustvarjanje hribovja ................................................................................................ 7
Slika 2.5 Zavihek za kontrolo višine hribovja ......................................................................... 8
Slika 2.6 Spreminjanje višine hribovja ................................................................................... 8
Slika 2.7 Privzete spremenljivke v animatorju ....................................................................... 9
Slika 2.8 Graf animacij pred našimi spremembami ............................................................... 9
Slika 2.9 Prehod na animacijo v zraku ................................................................................. 10
Slika 2.10 Mešalno drevo animacij igralca .......................................................................... 12
Slika 2.11 Graf 2D mešalnega drevesa ................................................................................ 13
Slika 2.12 Predogled mešalnega drevesa ............................................................................ 14
Slika 4.1 Okno z zgodbo igre V starodavne globine ............................................................. 16
Slika 4.2 Hierarhija vseh objektov v meniju ........................................................................ 17
Slika 4.3 Primer nastavitev gumba za začetek ..................................................................... 19
Slika 4.4 Nastavitve za predvajanje zvokov ......................................................................... 19
Slika 4.5 Okolica v igri .......................................................................................................... 20
Slika 4.6 Glavni igralec v igri V starodavne globine ............................................................. 21
Slika 4.7 Nastavitve maske »Spot Layer« ............................................................................ 22
Slika 4.8 Izris nevidnih žarkov med skokom ........................................................................ 22
Slika 4.9 Igralec med odbijanjem med zidovi ...................................................................... 28
Slika 4.10 Plezanje igralca po robu ...................................................................................... 34
Slika 4.11 Plezanje igralca po cevi ....................................................................................... 36
Slika 4.12 Spust igralca po cevi ............................................................................................ 38
Slika 4.13 Prikaz teksta ob vseh najdenih ključih ................................................................ 39
Slika 4.14 Aktiviran portal .................................................................................................... 40
Slika 4.15 Graf animacij igralca ............................................................................................ 41
Slika 4.16 Prehod animacije za cevi ..................................................................................... 42
vii
Slika 4.17 Dodatne spremenljivke v animatorju .................................................................. 42
Slika 5.1 Glavni meni igre .................................................................................................... 44
Slika 5.2 Razgled z vrha začetnih vrat .................................................................................. 45
Slika 5.3 Skriti ključ v stolpu................................................................................................. 45
Slika 5.4 Skriti ključ v puščavi ............................................................................................... 46
Slika 5.5 Skrito zlato v zapuščeni hiši ................................................................................... 46
Slika 5.6 Pasti za igralca ....................................................................................................... 47
Slika 5.7 Zadnja scena igre ................................................................................................... 47
Slika 5.8 Statistika ob koncu igre ......................................................................................... 48
viii
KAZALO IZVORNE KODE
Izvorna koda 4.1 Prehod med scenami ............................................................................... 18
Izvorna koda 4.2 Pomožni podatkovni tipi .......................................................................... 23
Izvorna koda 4.3 Preverjanje stanja igralca ......................................................................... 25
Izvorna koda 4.4 Pričetek plezanja ...................................................................................... 26
Izvorna koda 4.5 Odboj igralca od zida................................................................................ 28
Izvorna koda 4.6 Iskanje točk v bližini roke igralca ............................................................. 29
Izvorna koda 4.7 Preverjanje za ovire do točke .................................................................. 31
Izvorna koda 4.8 Uporaba Lerp in Slerp za premik igralca proti točki ................................ 32
Izvorna koda 4.9 Update funkcija plezalnega sistema ........................................................ 35
Izvorna koda 4.10 Rotacija igralca okoli cevi ....................................................................... 37
Izvorna koda 4.11 Podprogram za čakanje.......................................................................... 40
Izvorna koda 4.12 Nastavljanje spremenljivke v animatorju .............................................. 43
Izdelava 3D platformske igre v Unity 3D
1
1 UVOD
Platformska igra je žanr virtualnih iger, v katerem je značilno, da igralec lahko nadzira lik, s
katerim je v okolju igre običajno možna hoja, tek, skakanje na razne podlage in plezanje po
ovirah. Te igre so običajno v 2D izvedbi [2]. Pojavile so se leta 1981 [7].
Primer starejše igre je Donkey Kong, ki smo jo podrobneje opisali v tretjem poglavju.
Modernejše je uspešna platformska igra Portal, ki jo je razvilo podjetje Valve Corporation.
Prodanih bi naj bilo približno štiri milijone izvodov iger. V to število niso šteti prenosi iz
spletne trgovine Steam, ki je ena izmed največjih prodajaln iger. V omenjeni igri
kontroliramo igralca, ki ima možnost ustvarjanja portalov s posebno napravo na njegovi
roki. [20].
Za izdelavo računalniških iger nam je danes na voljo veliko različnih igralnih pogonov.
Nekateri najbolj znani so Unreal Engine, Godot Engine, Cry Engine in Unity® [1], ki smo ga
tudi uporabili za razvoj naše platformske igre. Za razvijanje programske kode smo uporabili
razvojno okolje Visual Studio 2017, s katerim Unity® omogoča enostavno sinhronizacijo.
Namen diplomske naloge je izdelava igre platformskega žanra na nov moderen način - v 3D
in predstavitev korakov, kako smo to naredili. Igra vsebuje pet scen in sicer glavni meni,
prikaz zgodbe, ciljno okolje za igranje, končno okolje in prikaz informacij o igranju ob
zaključku. Igralec mora v glavnem okolju, ki je sestavljeno iz puščave, ruševin, piramide in
raznih ovir, ki jih mora premagati, najti štiri ključe, preden lahko napreduje v ciljno sceno,
ki je postavljena v podzemlju piramide. Hkrati lahko išče še zlato, ki vpliva na rezultat
uspešnosti igranja.
Diplomska naloga je razdeljena na šest poglavij. V drugem poglavju smo na splošno opisali,
kaj je igralni pogon Unity®, za katere platforme ga lahko uporabimo in kako ga lahko
pridobimo. Predstavili smo tudi vse tiste njegove lastnosti, ki smo jih potrebovali za razvoj
Izdelava 3D platformske igre v Unity 3D
2
naše 3D platformske igre. V tretjem poglavju smo predstavili in opisali žanr platformskih
iger in njegove značilnosti. Na kratko smo predstavili tudi zgodovino tega žanra. V četrtem
poglavju smo prestavili naš proces ustvarjanja vseh komponent naše igre. V petem poglavju
smo predstavili končno razvito 3D platformsko igro in njen potek igranja. Zaključke smo
strnili v šestem poglavju.
Izdelava 3D platformske igre v Unity 3D
3
2 UNITY®
2.1 Splošen opis
Unity® je igralni pogon, ki ga je razvilo podjetje Unity Technologies. Slika 2.1 prikazuje
logotip podjetja. Prva različica je bila izdana Junija 2005, ekskluzivno za operacijske sisteme
MacOS V letu 2018 podpira že 27 različnih platform kot so iOS, Android, Windows, Mac,
Linux, PlayStation 4, Xbox One, Wii U in Oculus Rift. Omogoča izdelavo iger v 2D in 3D
okoljih. V preteklosti je podpiral več različnih programskih jezikov, v letu 2018 pa se
osredotoča samo še na C# [3].
Slika 2.1 Logotip igralnega pogona Unity® [4]
Na izbiro imamo štiri različne licence. Unity Personal, ki je brezplačna in je namenjena
predvsem začetnikom, študentom in ljudem, ki jih zanima ta igralni pogon, pri čemer
dohodki le-teh ne smejo preseči 100000 $. Naslednja licenca je Unity Plus, ki stane 25 $ na
mesec. Prednost le-te so nekatere dodatne funkcionalnosti, kot so spremenljiv začetni
zaslon igre (Personal ga ima vnaprej nastavljenega in ga ne moremo spremeniti), dodatna
statistika za igro med njenim izdelovanjem, drugačna tema za uporabniški vmesnik in
dovoljen dohodek do 200000 $. Tretja licenca je Unity Pro, ki stane 125 $ na mesec. Ob le-
tej dobimo dodatno podporo ekspertov iz podjetja, ki nam hitro odgovarjajo na vprašanja
in nam pomagajo reševati morebitne težave. Ni omejitve dohodka, omogočen pa je tudi
dogovor glede cene za dostop do izvorne kode Unity® [5].
Izdelava 3D platformske igre v Unity 3D
4
Posebna in zadnja licenca, ki jo nudijo, je Unity Enterprise. Omogoča nam popolni dostop
do izvorne kode. Lahko spremenimo uporabniški vmesnik igralnega pogona, da čimbolj
ustreza našim potrebam. S tem lahko zelo pohitrimo proces izdelave ali nadgradnje
računalniških iger. Cena le-te je po dogovoru [6].
2.2 Uporabniški vmesnik
Slika 2.2 prikazuje Unity®-jev uporabniški vmesnik, ki nudi zelo veliko različnih
funkcionalnosti. Na kratko smo predstavili tiste, ki smo uporabili za razvoj igre. Podrobnejši
opis, kako smo jih uporabili, je podan v četrtem poglavju.
Slika 2.2 Uporabniški vmesnik v Unity®
Puščica številka 1 (slika 2.2) kaže na orodno vrstico, ki ima osem zavihkov, katere lahko
uporabimo pri delu z urejevalnikom in sicer od leve proti desni je prvi zavihek »datoteka«
(ang. File) v kateri lahko kreiramo, shranimo in odpremo projekt ali sceno. Spreminjamo
lahko tudi razne nastavitve zagona igre. Najbolj pomembna nastavitev je seznam scen, v
katerega smo morali napisati vse naše kreirane scene v igri, preden smo lahko na njih
naredili prehod iz programske kode. Drugi zavihek »uredi« (ang. Edit) vsebuje osnovne
Izdelava 3D platformske igre v Unity 3D
5
pomožne funkcije za delo v igralnem pogonu. Tretji »sredstva« (ang. Assets) nudi možnost
dodajanja raznih sredstev v naš projekt in osnovno delo z njimi kot je izvoz in uvoz. Četrti,
»igralni objekt« (ang. Game Object) ima možnost kreiranja objektov in njihovega splošnega
urejanja. Peti, »komponenta« (ang. Component) služi za dodajanje raznih komponent na
igralne objekte. Šesti zavihek, »mobilni vhod« služi za zagon igre na mobilnih telefonih.
Sedmi zavihek, »okno« (ang. Window) omogoča urejanje osnovnega izgleda igralnega
pogona in odpiranje vseh razpoložljivih oken. Zadnji zavihek, »pomoč« (ang. Help) se
uporablja za lažje iskanje pomoči ob morebitnih težavah ali vprašanjih o igralnem pogonu.
Puščica številka 2 na sliki 2.2 kaže na okno za scenski pogled (ang. Scene). Omogoča nam
dodajanje različnih objektov npr. igralca, raznih ovir, glavne kamere in okolja. Prav tako
lahko manipuliramo njihovo pozicijo, rotacijo in velikost.
Puščica številka 3 na sliki 2.2 kaže na zavihek animator. V njem lahko sestavimo graf, kjer
za izbrani objekt določimo pravila za prehode med animacijami. Kreiramo lahko različne
spremenljivke, do katerih imamo možnost dostopa iz vseh naših programskih skript
računalniške igre. Te uporabimo za tvorjenje pravil prehodov med animacijami. Vsebuje
tudi nastavitev za spreminjanje časa prehoda med njimi in njihovo dolžino predvajanja. Če
dolžine ne določimo, se bo animacija ponavljala, dokler ustreza našemu pogoju.
Puščica številka 4, slika 2.2, kaže na zavihek za trgovino sredstev (ang. Asset Store), kjer
lahko dobimo zelo veliko različnih brezplačnih in plačljivih komponent za lažjo sestavo
računalniških iger.
Puščica številka 5 na sliki 2.2 kaže na zavihek za animacijo (ang. Animation). V njem lahko
ustvarimo animacije za objekte in jih kasneje uporabimo v animatorju. To naredimo tako,
da ročno spreminjamo koordinate posameznega dela objekta (npr. roko glavnega igralca),
in povemo, na kateri položaj naj se ta v določenem trenutku, oz. okviru (ang. Frame)
postavi. Če pritisnemo na gumb za snemanje, se nam ob manipulaciji objekta v scenskem
pogledu avtomatsko shranijo akcije, ki smo jih izvedli.
Izdelava 3D platformske igre v Unity 3D
6
Puščica številka 6 na sliki 2.2, kaže na okno za igro (ang. Game). Tukaj poteka igranje naše
računalniške igre ob njenem zagonu.
Puščica številka 7, glej sliko 2.2, kaže na okno za hierarhijo (ang. Hierarchy), kjer vidimo vse
objekte, katere uporabljamo v trenutni sceni računalniške igre. Kreiramo lahko tudi nove
objekte, jih brišemo, spreminjamo njihovo ime in jih kopiramo.
Puščica številka 8 na sliki 2.2 kaže na okno za pogled projekta (ang. Project). Tukaj imamo
seznam vseh komponent, ki jih bomo v računalniški igri uporabili.
Puščica številka 9, slika 2.2, kaže na okno, imenovano inšpektor (ang. Inspector). Prikazuje
lastnosti objektov, ki jih lahko urejamo tudi v drugih zavihkih. Dodajamo jim lahko razne
komponente, kot so skripte, gravitacija, animacije, barva in teksture. Ima tudi možnost
spreminjanja vrednosti javnih spremenljivk iz skript.
2.3 Orodje za grajenje okolja
Za grajenje okolja nam Unity® nudi privzeti objekt tipa teren (ang. Terrain). Na njem lahko
preko inšpektorja uporabljamo posebno orodje, ki vsebuje razne šablone za risanje in
urejanje 3D hribovja v scenskem pogledu. Vsebuje sedem zavihkov, ki nudijo metode za
delo s terenom [19]. V nadaljevanju tega podpoglavja smo opisali dva zavihka, ki smo jih
uporabili.
Slika 2.3 prikazuje prvi zavihek, kjer lahko izberemo šablono za oblikovanje hriba, ki ga lahko
ustvarimo. Ko zavihek odpremo, se nam v scenskem pogledu del terena modro obarva, da
lahko vidimo, na kolikšnem delu le-tega bomo risali. Slika 2.4 prikazuje del terena, ki bo
podvržen spremembam. Pod nastavitvami (Settings) imamo kontrolo nad velikostjo čopiča
(Brush Size) in njegovo intenzivnost za risanje (Opacity). Večjo kot nastavimo intenzivnost,
večji hrib se ustvari ob levem kliku miške. Če levi klik miške držimo, intenzivnost risanja
Izdelava 3D platformske igre v Unity 3D
7
vpliva na hitrost rasti hribovja. Ob hkratnem držanju tipke shift na tipkovnici se hribovje
manjša.
Slika 2.3 Zavihek za ustvarjanje hribov
Slika 2.4 Ustvarjanje hribovja
Slika 2.5 prikazuje drugi zavihek, kjer lahko nastavljamo višino hribov. Uporabimo ga lahko
za ustvarjanje ravnine na izbrani višini terena. Slika 2.6 prikazuje način risanja, ki je enak
Izdelava 3D platformske igre v Unity 3D
8
kot v prvem zavihku za ustvarjanje hribovja. Ima dve dodatni funkcionalnosti in sicer
nastavitev višine (ang. Height), ki določa na kateri višini se bo teren ravnal, in gumb splošči
(ang. Flatten), ki izbrani teren spremeni v ravnino.
Slika 2.5 Zavihek za kontrolo višine hribovja
Slika 2.6 Spreminjanje višine hribovja
Izdelava 3D platformske igre v Unity 3D
9
2.4 Animator
Okno za animator se uporablja za sestavljanje pravil prehodov med različnimi animacijami.
Za določitev pravil se uporabljajo posebne spremenljivke, ki jih prikazuje slika 2.7 in graf,
ki ga prikazuje slika 2.8.
Slika 2.7 Privzete spremenljivke v animatorju
Slika 2.7 vsebuje privzete spremenljivke za animacije, ki so bile vključene v naš model
glavnega igralca. Tukaj lahko kreiramo spremenljivke različnih tipov, kot so: realna števila,
cela števila, logične spremenljivke in sprožilce, ki jih lahko sprožimo iz programske kode. Do
njih lahko dostopamo iz skript preko reference na okno za animator.
Slika 2.8 Graf animacij pred našimi spremembami
Izdelava 3D platformske igre v Unity 3D
10
Slika 2.8 prikazuje privzeti diagram prehajanja stanj animacij. Uporabili smo ga za lažjo
razlago funkcionalnosti tega okna. Vsak pravokotnik predstavlja eno stanje, predstavljeno
z animacijo, ali mešalno drevo (ang. Blend Tree), ki lahko vsebuje več različnih animacij.
Oranžni pravokotnik, ki smo ga poimenovali »Grounded«, je bil določen za privzeto
animacijo, ki se vedno predvaja, ko igralec ne izpolnjuje nobenega pogoja za prehod v drugo
stanje oz. je nedejaven.
Med pravokotniki se prehodi med animacijami ustvarijo s puščicami. Ob kliku nanje, se nam
pokažejo nastavitve za izbran prehod.
Slika 2.9 Prehod na animacijo v zraku
Izdelava 3D platformske igre v Unity 3D
11
Slika 2.9 prikazuje nastavitve prehoda iz privzete animacije v animacijo za čas, ko je igralec
v zraku. Stikalo z imenom »Ima čas izhoda« (ang. Has Exit Time) določa, ali bo animacija, ne
glede na naše spremenljivke v animatorju, samodejno naredila prehod v drugo. V kolikor je
stikalo vključeno, spremenljivka »Čas izhoda« (ang. Exit Time) določa, kako dolgo se bo
dogajal prehod v drugo animacijo. V našem primeru je stikalo »Ima čas izhoda« odkljukan,
saj želimo predvajati animacijo tako dolgo, dokler je igralec v zraku. Če odkljukamo stikalo
»Fiksna dolžina« (ang. Fixed Duration), se vrednost, vpisana v polje »Čas prehoda« (ang.
Transition Duration) interpretira v sekundah. V nasprotnem primeru se vrednost
interpretira kot odstotek (število nič pomeni začetek animacije, nič pa njen konec). Polje
»Zamik prehoda« (ang. Transition Offset) določa, ob katerem času pričnemo animacijo
predvajati - npr.: 0,5 bi pomenilo, da se animacija začne predvajati na sredini. Z izbirnim
poljem »Vir prekinitev« (ang. Interruption Source) lahko določimo, v katerih primerih je
animacijo možno prekiniti. Odkljukano stikalo »Ukazna prekinitev« (ang. Ordered
Interruption) pomeni, da lahko to animacijo prekine druga, neglede na katero animacijo
kažejo puščice. Skupek nastavitev »Pogoji« (ang. Conditions) določa pravila, kdaj se lahko
zgodi prehod glede na izbrano spremenljivko. V našem primeru nastavitve je določeno, da
v primeru, če ima spremenljivka OnGround vrednost false, se lahko prehod v animacijo
poimenovano »V zraku« (ang. Airborne) prične. Ta spremenljivka se privzeto nastavlja iz
priložene skripte za kontrolo glavnega igralca in nam pove, če je le-ta v določenem trenutku
v zraku.
2.5 Mešalno drevo
Unity® nudi v oknu animator možnost, da lahko v nekatere pravokotnike na grafu shranimo
več animacij hkrati z uporabo mešalnega drevesa.
Slika 2.10 prikazuje mešalno drevo [17], ki nam omogoča enostavno mešanje več različnih
animacij z uporabo različnih spremenljivk animatorja. Opisali smo že vgrajeno drevo v naš
model.
Izdelava 3D platformske igre v Unity 3D
12
Slika 2.10 Mešalno drevo animacij igralca
Največji pravokotnik je drevo. Vsak pravokotnik na desni strani predstavlja eno animacijo.
Vrsta drevesa, ki je bilo uporabljeno, je 2D prosto oblikovano kartezijsko drevo. Značilnost
tega drevesa je, da omogoča dodajanje vrednosti v parameter x in y grafa 2D mešalnega
drevesa. Mi smo dodali dva parametra in sicer »Jump« in »JumpLeg«, ki kontrolirata
prehode med animacijami. V »Jump« je bila shranjena trenutna pozicija igralca glede na os
y v igralnem svetu, v »JumpLeg« pa pozicija nog igralca.
Slika 2.11 prikazuje graf, ki se nam pokaže v inšpektorju zraven drevesa. Tukaj lahko za
vsako animacijo, ki jo želimo vključiti, dodamo premike (ang. Motion). Osi x in y na grafu
predstavljata prej omenjena dva parametra »Jump« in »JumpLeg«. Za vsako pozicijo točk x
in y na grafu, je bilo določeno, v katero animacijo se bo zgodil prehod in kolikšen bo čas
prehoda. Eden izmed primerov je, da sta »Jump« in »JumpLeg« na najmanjši možni
vrednosti, kar pomeni, da ko igralec pada, drevo naredi prehod v animacijo za padanje.
Izdelava 3D platformske igre v Unity 3D
13
Slika 2.11 Graf 2D mešalnega drevesa
Da bi lahko videli, kako bo drevo delovalo v igri, z miško premikamo rdečo karo, ki
predstavlja trenutni vrednosti parametrov. Ob njenem premikanju se v inšpektorju pod
nastavitvami premikov (ang. Motion) samodejno predvaja animacija, ki jo prikazuje slika
2.12.
Izdelava 3D platformske igre v Unity 3D
14
Slika 2.12 Predogled mešalnega drevesa
Izdelava 3D platformske igre v Unity 3D
15
3 ŽANR PLATFORMSKE IGRE
3.1 Zgodovina
Prva platformska igra je bila Donkey Kong, ki jo je leta 1981 izdalo podjetje Nintendo. Je
prva igra, ki je igralcem omogočala preskakovanje ovir in skakanje med platformami.
Naslednji napredek v tem žanru je bil razvoj igre Mario Bros. Igro sta lahko sočasno igrala
dva igralca [7]. Glavni lik igre, imenovan Mario, je še sedaj popularen in pogosto uporabljen
lik v igrah podjetja Nintendo [8].
Na začetku so bile igre tega žanra samo v 2D izvedbi. 3D izvedba se je začela pojavljati v
zgodnjih 1980-ih. Dober primer je igra Antarctic Adventure, ki jo je izdalo podjetje Sega. V
tej igri lahko nadzorujemo pingvina, ki preskakuje ovire in prepade. Imela je naprej
premikajočo grafiko, kar pomeni, da se ob igralčevem premikanju naprej zamenjujejo slike
oz. okvirji okolice bolj počasi kot glavni sprednji elementi igre. To je dalo občutek globine
in iluzijo premikanja po 3D prostoru.
3.2 Splošen opis
Za ta žanr je torej značilno preskakovanje in premagovanje ovir. Glavna značilnost je
možnost skakanja glavnega lika [7]. V modernih izvedbah tega žanra je lik zmožen veliko
več. Primer je plezanje po ceveh, skakanje med zidovi, plezanje po robovih, spuščanje po
žici, vožnja različnih vozil, nihanje po vrvi, letenje, plavanje in še mnogo več.
V preteklosti je bil ta žanr najbolj priljubljen žanr video iger. Ocenjeno je, da je bilo od ene
četrtine do ene tretjine vseh iger te vrste. Do takrat še ni bil nikoli dosežen tak delež
tovrstnih iger na trgu. Do leta 2010 je popularnost padala, nato pa spet narastla z razvojem
neskončnih tekalnih iger za mobilne naprave [7].
Izdelava 3D platformske igre v Unity 3D
16
4 IZDELAVA IGRE V STARODAVNE GLOBINE (INTO THE
ANCIENT DEPTHS)
4.1 Vodilna zgodba igre V starodavne globine
Za večji smisel igranja smo si izmislili za igro zgodbo, ki jo prikazuje slika 4.1. Igra je
postavljena v leto 5024. Po veliki globalni energetski krizi so ljudje morali zbežati z Zemlje,
da so lahko preživeli. Na Zemlji so ostale samo še ruševine. Po več kot 2000 letih so z Zemlje
zaznali skrivnostne magnetne valove. Skupina vesoljskih popotnikov je odšla raziskovat
izvor teh valov. Stik z njimi je bil izgubljen v trenutku, ko so prišli v Zemljino atmosfero.
Njihovo plovilo je strmoglavilo in že več mesecev potujejo po puščavi, ki prekriva večino
Zemljinega površja. Ko je njihova situacija postala nezdržna, se je skupina odločila ločiti od
glavnine. Tako so lahko preiskali več zemljišča hkrati. Nekdo iz skupine je našel sredi
puščave skrivnostna velika vrata. Od tukaj naprej se začnejo dogodivščine našega glavnega
junaka.
Slika 4.1 Okno z zgodbo igre V starodavne globine
Izdelava 3D platformske igre v Unity 3D
17
4.2 Glavna ideja igre
Glavna ideja je bila s pomočjo glavnega lika raziskati ruševine in najti skrite ključe, ki mu
omogočijo aktiviranje starodavnega portala za vstop v podzemlje piramide, hkrati lahko
poišče tudi zlato. Ključe in zlato doseže s plezanjem po ovirah in izmikanjem pastem.
4.3 Glavni meni
Ob zagonu igre smo prikazali glavni meni. Služi za pričetek igranja igre in izhod iz nje.
Vsebuje dve postavki: pričetek (ang. start) in izhod (ang. exit). Ob kliku na gumb za pričetek,
se pokaže zgodba igre (slika 4.1), da igralec izve, kaj je namen igranja. Ob kliku na gumb za
izhod se igra konča.
Za kreiranje gumbov smo uporabili kar privzete gumbe, ki jih nudi okolje Unity®. S klikom
in vlekom na njih v scenskem pogledu, smo jih prestavili na željeno pozicijo v sceni.
Spremenili smo jim barvo, pisavo in velikost s pomočjo inšpektorja. Slika 4.2 prikazuje, kako
smo vse elemente uporabniškega vmesnika vključili kot otroke avtomatsko generiranega
objekta »Canvas«, kar je omogočilo njihovo stalno pozicijo na ekranu (nastavljena resolucija
računalnika ne vpliva na njihovo postavitev).
Slika 4.2 Hierarhija vseh objektov v meniju
Izdelava 3D platformske igre v Unity 3D
18
Za prehod na naslednjo sceno in izhod iz igre ob kliku na ustrezen gumb, smo naredili
prazen objekt »SceneLoader« in za njega pripravili enostavno skripto.
Za prehode smo uporabili objekt iz Unity® knjižnice »SceneManager«. V parameter funkcije
»LoadScene« (izvorna koda 4.1), poimenovan »levelName«, smo napisali ime scene, na
katero želimo preiti. Funkcijo »QuitGame« smo ustvarili za izhod iz igre. To skripto smo
vključili na objekt »SceneLoader«.
Za proženje teh funkcij ob kliku na gumb za pričetek in izhod, smo v inšpektorju za vsakega
od gumbov pod nastavitvijo »On Click« izbrali naš objekt »SceneLoader«. Slika 4.3
prikazuje, kako smo nato iz seznama funkcij tega objekta izbrali našo funkcijo
»SceneLoader.LoadScene« in v okvir pod seznamom, ki predstavlja parameter
»levelName«, napisali ime želene scene.
public void LoadScene(string levelName) { SceneManager.LoadScene(levelName); } public void QuitGame() { Application.Quit(); }
Izvorna koda 4.1 Prehod med scenami
Izdelava 3D platformske igre v Unity 3D
19
Slika 4.3 Primer nastavitev gumba za začetek
Meniju smo še dodali zvok, kar smo naredili tako, da smo ustvarili nov prazen objekt,
imenovan »Scene Track«, in mu dodali komponento »Audio Source«. Komponenta »Audio
Source« v Unity® omogoča predvajanje zvokov med igranjem igre. V nastavitev »Audio
Clip« smo dodali naš želen zvok in odkljukali nastavitev »Play On Awake«, ki prične ob
vstopu v sceno predvajati zvok. Odkljukali smo še nastavitev Loop, ki poskrbi, da se zvok
predvaja neskončno mnogo krat. Vse nastavitve komponente »AudioSource«, ki smo jih
uporabili, prikazuje slika 4.4.
Slika 4.4 Nastavitve za predvajanje zvokov
Izdelava 3D platformske igre v Unity 3D
20
4.4 Gradnja igralnega okolja
Najprej smo potrebovali okolje, v katerem se je igralec lahko premikal. S pomočjo
ustreznega okolja smo lahko prikazali vse zmožnosti gibanja igralca, ki smo jih razvili. Slika
4.5 prikazuje kreiran teren. Za njegovo grajenje smo uporabili integrirano orodje za grajenje
okolja v Unity® in brezplačne modele, pridobljene iz trgovine sredstev.
Slika 4.5 Okolica v igri
Za ustvarjanje peščenega hribovja smo najprej kreirali privzeti objekt tipa »Terrain« in
uporabili čopič za risanje hribov. Dodali smo še teksturo peska. Teksture smo dodali s
klikom na njo in potegom na objekt v sceni. Na enak način smo vključili vse pridobljene
modele iz trgovine sredstev.
4.5 Glavni igralec
Slika 4.6 prikazuje model glavnega igralca, ki smo ga pridobili iz trgovine sredstev, iz
brezplačnega paketa »Standard Assets«, ki ga je izdalo podjetje Unity Technologies. Ima
vgrajene kontrole in animacije za premikanje, skakanje, počasno hojo in čepenje. Vse ostale
funkcionalnosti smo razvili samostojno in so opisane v nadaljevanju.
Izdelava 3D platformske igre v Unity 3D
21
Slika 4.6 Glavni igralec v igri V starodavne globine
4.6 Plezalni sistem
Plezalni sistem je glavna lastnost naše igre in zanjo lahko rečemo, da spada med moderne
izvedbe platformskega žanra. Sistem je igralcu omogočil plezanje po vseh ustreznih
robovih, preskakovanje med njimi, visenje, odboj od zidu in plezanje na vrh platojev.
Vsem objektom v igri smo v inšpektorju določili plast (ang. Layer). Plasti smo uporabili za
lažje prepoznavanje objektov med igranjem. Z uporabo integriranih metod v programski
kodi smo preverjali njihova imena. To nam je koristilo v situacijah, kot je igralčev odboj od
zidu v zraku, kjer smo preverili, če je plast zidu ustrezna, da nismo po nepotrebnem prožili
napačne funkcionalnosti plezalnega sistema, kot je prijem za rob.
Sistem deluje po principu izstreljevanja nevidnih žarkov.
Izstrelitev nevidnega žarka (ang. Raycast) je metoda v programski kodi, ki izstreli nevidni
žarek iz izbrane pozicije in hkrati preveri, ali smo z njim zadeli kakšen objekt v igri. Določimo
mu lahko dolžino, smer in masko. Z le-to lahko nastavimo, katere plasti naj žarki ignorirajo
[8]. Slika 4.7 prikazuje, kako smo v inšpektorju v skripti plezalnega sistema za masko
poimenovano »Spot Layer« nastavili plasti, ki jih vsebuje. Ti sta privzeta plast vseh objektov
v igri in naša pomožna plast iz skripte. S pomočjo maske »Spot Layer« smo v skripti določili,
na katerih objektih se naj preverja možnost za potencialno plezanje igralca.
Izdelava 3D platformske igre v Unity 3D
22
Slika 4.7 Nastavitve maske »Spot Layer«
Za lažje testiranje med izdelovanjem igre lahko s funkcijo »Debug.DrawRay« [10] žarek tudi
narišemo, kar prikazuje slika 4.8.
Slika 4.8 Izris nevidnih žarkov med skokom
Smer izstrelitve žarkov smo določali s pomočjo podatkovnega tipa Vector3, ki ga nudi
Unity®. »Vector3.forward« nam poda vektor, v katero smer je igralec trenutno obrnjen.
»Vector3.right« pa nam vrne vektor, ki kaže desno od tiste smeri, kamor je igralec trenutno
obrnjen. Nasprotno smer zgoraj omenjenih vektorjev dobimo, če dodamo predznak minus
[9].
Izdelava 3D platformske igre v Unity 3D
23
Za lažje sledenje igralčevih akcij, smo naredili v jeziku C# pomožne podatkovne tipe
imenovane »enum« in en razred poimenovan »RaycastInfo« (izvorna koda 4.2).
Zapis »System.Serializable« nad podatkovnim tipom nam je med igranjem igre v
inšpektorju omogočil pregled nad vsemi kreiranimi spremenljivkami tega tipa.
Za opazovanje trenutnega stanja igralca, smo ustvarili globalno spremenljivko našega tipa
»ClimbingSort«, poimenovano »currentSort«. Vanjo smo lahko shranjevali, kaj trenutno
igralec dela v obliki vseh pripadajočih zapisov (»Walking«, »Jumping«, »Falling«…) naštetih
v podatkovnem tipu »ClimbingSort«.
[System.Serializable] public enum ClimbingSort { Walking, Jumping, Falling, Climbing, ClimbingTowardsPoint, ClimbingTowardsPlateau } [System.Serializable] public class RayInfo { public Vector3 point; public Vector3 normal; public bool CanGoToPoint; } [System.Serializable] public enum CheckingSort { normal, turning, falling }
Izvorna koda 4.2 Pomožni podatkovni tipi
Izdelava 3D platformske igre v Unity 3D
24
V spremenljivke našega tipa »CheckingSort« smo shranjevali informacijo o tem, ali je igralec
trenutno v normalnem stanju (npr. hoja), se obrača, ali pada. To nam je pomagalo določiti,
v katero smer moramo izstreliti nevidne žarke za zaznavanje objektov.
Razred »RayInfo« smo kreirali za shranjevanje informacij o tem, kaj je zadel žarek. V
njegovo spremenljivko »point« smo shranjevali točko, ki jo je nevidni žarek zadel. V
spremenljivko »normal« pa smo shranili še normalni vektor podlage, ki je bila zadeta.
Razredu smo dodali še spremenljivko »CanGoToPoint«, v kateri smo označevali, če igralec
lahko pleza proti najdeni točki.
Za spremljanje stanja igralca smo pripravili funkcijo, ki nam posodablja trenutno stanje
igralca v spremenljivki »currentSort«. Preverjali smo, če igralec trenutno skače, ali hodi in
ustrezno posodobili stanje le-te (izvorna koda 4.3).
Izdelava 3D platformske igre v Unity 3D
25
Za preverjanje, kdaj je igralec v zraku, smo naredili globalno spremenljivko tipa
»ThirdPersonCharacter«, poimenovano »TPU«, ki je referenca na vgrajene avtomatizirane
kontrole igralca. Za dostop do informacije, če je igralec v zraku, smo preverjali s
spremenljivko, poimenovano »isGrounded«, ki je vgrajena v »TPU«. Za izklop uporabniških
kontrol, ki omogočajo premikanje igralca, smo kreirali globalno spremenljivko tipa
»ThirdPersonUserControl«, poimenovano »TPUC«.
Če igralec ne pleza in ni v zraku, smo stanje v spremenljivki »currentSort« spremenili na
hojo po podlagi, vključili integrirane kontrole igralca, ter izklopili statično stanje, da lahko
nanj spet vplivajo vse sile v igralnem svetu (npr. gravitacija, poskus premika igralca).
Statično stanje lahko objektu v Unity® nastavljamo s spremembo spremenljivke
»isKinematic«, ki je del vgrajene komponente neprožnega telesa (ang. RigidBody) igralca.
//posodabljamo trenutno stanje da vemo kakšno akcijo trenutno izvaja igralec public void UpdateStats() { //preverimo, če spet igralec hodi if (currentSort != ClimbingSort.Walking && TPC.m_IsGrounded && currentSort != ClimbingSort.ClimbingTowardsPoint) { //plezanje se je končalo, vklopimo nazaj vgrajene kontrole igralca currentSort = ClimbingSort.Walking; TPUC.enabled = true; rigid.isKinematic = false; animator.SetBool("Climb", false); } //preverimo če trenutno skačemo if (currentSort == ClimbingSort.Walking && !TPC.m_IsGrounded) { currentSort = ClimbingSort.Jumping; } }
Izvorna koda 4.3 Preverjanje stanja igralca
Izdelava 3D platformske igre v Unity 3D
26
Hkrati smo v animatorju še izklopili animacijo za plezanje. Če je igralec hodil in ni več na
tleh, smo stanje v spremenljivki »currentSort« spremenili na skakanje.
Naredili smo še funkcijo za pričetek plezanja igralca (izvorna koda 4.4). S pomočjo nevidnih
žarkov smo preverili, če je pred nami stena, proti kateri lahko igralec skoči. Med skokom
smo poiskali potencialne točke za pričetek plezanja s funkcijami, opisanimi v nadaljevanju.
Prvi parameter funkcije »Physics.Raycast« določa pozicijo, s katere smo izstrelili žarek.
Vektorju trenutne pozicije igralca smo prišteli njegovo rotacijo, in jo množili z majhnim
zamikom po osi y, s čimer smo ga izstrelili približno v višini rok igralca. Drugi parameter je
smer, kamor je trenutno igralec obrnjen. Tretji parameter nam pove, kam smo shranili
podatke v primeru zadetka z žarkom. Zadnji parameter pa določa dolžino izstreljenega
žarka. Preverili smo tudi, koliko časa je poteklo od zadnje izstrelitve. Določili smo, da mora
poteči vsaj 0,1 sekunde. To smo naredili iz optimizacijskih razlogov, saj je izstrelitev žarka
časovno potraten proces. Preverili smo še, če igralec trenutno hodi, saj v nasprotnem
primeru ne more skočiti.
public void StartClimbing() //zančnemo plezati, premaknemo se proti robu { RaycastHit rHitCheckForWallJump; //preverimo, če je pred nami zid if (Physics.Raycast(transform.position + transform.rotation * rayCastPosition, transform.forward, out rHitCheckForWallJump, 0.4f) && Time.time - lastTime > CoolDown && currentSort == ClimbingSort.Walking) { //ponovno preverimo, lahko se nam vrednost posodobi z zakasnitvijo if (currentSort == ClimbingSort.Walking && rHitCheckForWallJump.transform.gameObject.tag != "WallJump" && rHitCheckForWallJump.transform.gameObject.tag != "No Physics") { rigid.AddForce(transform.up * JumpForce); } lastTime = Time.time; } }
Izvorna koda 4.4 Pričetek plezanja
Izdelava 3D platformske igre v Unity 3D
27
Pri ponovnem preverjanju smo pogledali, če je ime sloja zadetega zidu tako, kot smo ga
določili za možnost plezanja. Če je pravi, smo s funkcijo »AddForce« trenutni sili premikanja
igralca dodali silo navzgor, kar je povzročilo skok v isto smer, v katero se trenutno premika.
Na koncu še v spremenljivko »lastTime« shranimo trenutni čas, ki smo ga na začetku
preverjali pred izstrelitvijo žarkov.
V nadaljevanju smo morali preveriti, če se igralec trenutno po svoji osi y premika navzgor
ali navzdol in ustrezno posodobiti stanje v spremenljivki »currentSort«. Zanimalo nas je
torej, če igralec trenutno skače ali pada, saj se smer za izstrelitev nevidnega žarka v teh
situacijah razlikuje. Unity® nam omogoča pogled na trenutno hitrost igralca s parametrom
»RigidBody.velocity« [11]. Najprej smo opazovali hitrost igralca po osi y. Če je bila
negativna, pomeni, da pada, pozitivna pa, da se vzpenja. Glede na ugotovljeno, smo
določili, v katero smer je bilo potrebno izstreliti žarek.
Optimalne vrednosti za izstrelitev žarka iz rok igralca za preverjanje bližnjih robov smo
dobili s poskušanjem. Če smo ob izstrelitvi rob našli, smo preverili potencialne točke za
prijem na zid s funkcijo, ki je opisana v nadaljevanju.
Funkciji za preverjanje stanja igralca v zraku smo dodali tudi možnost odbijanja od zidu z
dodatno izstrelitvijo žarka v tisto smer, v katero je igralec trenutno obrnjen (izvorna koda
4.5).
Izdelava 3D platformske igre v Unity 3D
28
V Unity® lahko objektu nastavimo tudi oznako (ang. Tag). Na tistih zidovih, kjer smo dovolili
odboj, smo jo spremenili na ime »WallJump«. Najprej smo preverili, če je žarek kaj zadel in
ali v tem trenutku igralec pada. Če smo takrat pritisnili tipko za skok, smo ponovno preverili,
če igralec pada in ali je oznaka zidu ustrezna za odboj. Hitrost igralca smo nastavili na nič in
ga obrnili za 180 stopinj ter dodali silo v smer, v katero je sedaj obrnjen, ter povzročili skok
od zidu. Slika 4.9 prikazuje igralca med odbijanjem od zidu.
Slika 4.9 Igralec med odbijanjem med zidovi
//preverjanje, če se lahko odbijemo od zida if (Input.GetButton("Jump") && currentSort == ClimbingSort.Falling && rHitCheckWall.transform.gameObject.tag == "WallJump") { lastTime = Time.time; currentSort = ClimbingSort.Jumping; rigid.velocity = Vector3.zero; transform.rotation = Quaternion.LookRotation(-transform.forward, Vector3.up); Vector3 jumpDirection = transform.forward + transform.up / 0.5f; rigid.AddForce(jumpDirection * JumpForce / 2); } Izvorna koda 4.5 Odboj igralca od zida
Izdelava 3D platformske igre v Unity 3D
29
Potrebovali smo metodo za analizo poljubne lokacije v okolju. Pripravili smo funkcijo, ki s
pomočjo žarkov preveri izbrano lokacijo, smer, razdaljo in trenutno stanje igralca, če imamo
v bližini potencialne točke, kamor se igralec lahko obesi (izvorna koda 4.6).
Če je žarek zadel kakšen objekt, smo zanj preverili točke v bližini obeh rok in za druge bližnje
robove. Za merjenje razdalj do točk, smo uporabili funkcijo »Vector3.distance«, ki je vrnila
razdaljo med našo trenutno lokacijo in potencialno zadeto točko žarka.
Če smo točko našli, smo označili, da vsa prej našteta preverjanja niso potrebna in naredili
klic funkcije, ki najdeno točko natančneje poišče in oceni, če se lahko do katere
pomaknemo. Kot parametra smo ji podali točko trka žarka, »RaycastHit«, in trenutno
stanje igralca s pomočjo spremenljivke »CheckingSort«.
Sedaj, ko smo našli potencialno točko na raziskani lokaciji, smo morali opraviti podrobnejšo
analizo, ali je točka ustrezna. Implementirali smo funkcijo, ki najprej z vgrajeno funkcijo
»Vector3.angle« preveri kot med trkom žarka in izbrano točko. Če je ta manjši od našega
izbranega maksimalnega kota, ki določa, kdaj se igralec lahko prime roba, smo glede na
stanje igralca (ta so lahko normalno, v obračanju ali padanju), shranjenega v
»CheckingSort«, poiskali najbližjo točko glede na roke igralca, s pomočjo klica naslednje
opisane funkcije, kamor smo igralca lahko premaknili. Če je ta funkcija sporočila, da lahko
premaknemo igralca na najdeno točko, smo preverili, če igralec trenutno že pleza. V
nasprotnem primeru smo izklopili vse integrirane funkcionalnosti premikanja glavnega
if (Physics.Raycast(spotLocation - transform.right * smallestEdge / 2, direction, out rHit, range, spotLayer)) { if (Vector3.Distance(handTransform.position, rHit.point) > minDistance) { foundSpot = true; FindSpot(rHit, sort); } }
Izvorna koda 4.6 Iskanje točk v bližini roke igralca
Izdelava 3D platformske igre v Unity 3D
30
igralca, da ga lahko kasneje premaknemo proti novi najdeni točki za plezanje. V
»CurrentSort« smo shranili, da se je igralec začel premikati proti točki.
Kot smo že omenili v zgornjem odstavku, smo potrebovali tudi funkcijo, ki preveri, če se na
potencialno točko plezanja igralec sploh lahko premakne (izvorna koda 4.7). V tej funkciji
smo poleg uporabe nevidnih žarkov vključili še izstrelitev nevidnega poltraka. Za izstrelitev
tega poltraka smo uporabili vgrajeno funkcijo »Physics.Linecast« [12]. Ta funkcija omogoča
zaznavanje ovir v izstreljeni smeri. Deluje zelo podobno kot izstreljevanje nevidnih žarkov.
Izdelava 3D platformske igre v Unity 3D
31
Izstrelitev poltraka ima enake parametre, kot prej omenjena izstrelitev nevidnih žarkov.
Vrednosti parametrov za izstrelitev poltraka so bile določene s poskušanjem. V primeru,
if (!Physics.Linecast(handTransform.position + transform.rotation * new Vector3(0, 0.05f, -0.05f), curray.point + new Vector3(0, 0.5f, 0), out rHit2, checkLayersReachable)) { //preverimo če lahko dosezemo rob oz. če je kje ovira, if (!Physics.Linecast(curray.point - Quaternion.Euler(new Vector3(0, 90, 0)) * curray.normal * 0.35f + 0.1f * curray.normal, curray.point + Quaternion.Euler(new Vector3(0, 90, 0)) * curray.normal * 0.35f + 0.1f * curray.normal, out rHit2, checkLayerForObstacle)) { //preverimo če lahko visimo, nekaj v levo, nekaj v desno, 0.35 je polovica, če da model igralca roke v zrak if (!Physics.Linecast(curray.point + Quaternion.Euler(new Vector3(0, 90, 0)) * curray.normal * 0.35f + 0.1f * curray.normal, curray.point – Quaternion.Euler(new Vector3(0, 90, 0)) * curray.normal * 0.35f + 0.1f * curray.normal, out rHit2, checkLayerForObstacle)) { curray.CanGoToPoint = true; } else { //nekaj smo zadeli z izstrelitvijo ravne črte, imamo oviro curray.CanGoToPoint = false; } } else { curray.CanGoToPoint = false; } } else { //nekaj smo zadeli z linecast curray.CanGoToPoint = false; } trans.gameObject.layer = oldLayer; return curray;
Izvorna koda 4.7 Preverjanje za ovire do točke
Izdelava 3D platformske igre v Unity 3D
32
da smo z izstrelitvijo poltraka ugotovili, da ni na poti premika igralca proti potencialni točki
plezanja nobenih ovir, smo naši spremenljivki »CanGoToPoint« v razredu »RayInfo«
nastavili stanje na vrednost true, da smo si shranili informacijo o tem, ali lahko igralca
pomaknemo proti točki. V ta razred smo shranili še koordinate točke zadetka izstrelitve
poltraka in normalo zadete podlage (izvorna koda 4.7).
Če se je izkazalo, da je potencialna točka za plezanje ustrezna, smo lahko igralca prestavili.
Naredili smo funkcijo, ki opravi dejanski premik igralca. Najprej smo preverili, če se bo ob
premiku igralec prestavil na naslednjo točko, ki je lahko rob ali vrh platoja. V primeru, da se
bo premaknil na plato, smo morali dodati dodatno silo na igralčevo os y, da smo podaljšali
krožni lok igralčevega skoka na vrh. S tem smo se izognili trku v zid med skokom. Za premik
smo najprej uporabili vgrajeno funkcijo »Vector3.Lerp« [13]. S to funkcijo lahko v ravni liniji
premikamo izbran objekt proti izbrani točki. Nato sledi klic »Vector3.Slerp« [14], ki
spreminja rotacijo izbranega objekta proti izbrani točki. Prav tako smo animatorju sporočili,
da igralec ni več na tleh (izvorna koda 4.8).
if (currentSort != ClimbingSort.ClimbingTowardsPlateau) transform.position = Vector3.Lerp(transform.position, (targetPoint – transform.rotation * handTransform.localPosition), Time.deltaTime * climbForce); //Lerp se priblizuje točki v ravni črti else transform.position = Vector3.Lerp(transform.position, (targetPoint – transform.rotation * handTransform.localPosition) + new Vector3(0, 1, 0), Time.deltaTime * climbForce); //če pležemo na vrh mora igralec skočiti malo višje, da ne trči v zid Quaternion lookRotation = Quaternion.LookRotation(-targetNormal); //normala je negativna os, da smo obrnjeni proti liku moramo dodati minus transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, Time.deltaTime * climbForce); //v animatorju povemo da je igralec v zraku animator.SetBool("OnGround", false);
Izvorna koda 4.8 Uporaba Lerp in Slerp za premik igralca proti točki
Izdelava 3D platformske igre v Unity 3D
33
Ob vsakem premiku smo preverili razdaljo do točke, proti kateri se premikamo. Če smo
glede na stanje igralca shranjenega v »currentSort« ugotovili, da smo prišli na vrh platoja,
smo v »currentSort« označili, da igralec zdaj spet hodi. Vključili smo tudi integrirane
kontrole igralca. Če smo ugotovili, da je igralec prispel na točko ob robu, smo to tudi
ustrezno označili in pustili integrirane kontrole izklopljene.
Potrebovali smo še funkcijo, ki preverja, če se lahko povzpnemo na vrh platoja in to označili
v »currentSort«. To smo naredili tako, da smo z izstrelitvijo žarka preverili, če je navpično
nad nami kakšna ovira. Na koncu smo animatorju še sporočili, da lahko prične animacijo za
padanje in klečanje, ko se igralec dotakne tal.
Za povezovanje vseh teh do sedaj opisanih funkcij, smo potrebovali funkcijo za izvajanje
plezanja igralca v horizontalni in vertikalni smeri med tem, ko visi na robu. Kako je to videti,
prikazuje slika 4.10. V primeru, da se igralec poskuša premikati navzgor, smo najprej
poiskali potencialne točke za plezanje v smeri navzgor. Če smo jih našli, smo preverili, če je
najdena točka vrh platoja, da izvemo, kakšen premik moramo sprožiti. V primeru
poskušanja premika levo ali desno, smo poiskali potencialne točke, ampak v tem primeru
le za rob, saj smo zagotovo vedeli, da se s horizontalnim premikom ne bomo premaknili na
vrh. Enako velja za poskušanje premika navzdol.
Izdelava 3D platformske igre v Unity 3D
34
Slika 4.10 Plezanje igralca po robu
Funkciji za premikanje igralca smo dodali še funkcionalnost, da lahko igralec ob pritisku na
preslednico izvede skok v nasprotno smer od te, v katero je obrnjen. Deluje na enak način,
kot prej omenjena koda za odbijanje od zida.
Izdelava 3D platformske igre v Unity 3D
35
Za sinhronizacijo zgoraj omenjene programske kode, smo uporabili vgrajeno funkcijo
»Update« (izvorna koda 4.9). Ta funkcija se ob izvajanju igre kliče v vsakem okviru. V Unity®
imamo možnost nastavljanja hitrosti menjavanja okvirjev ob igranju igre.
Najprej smo preverili, ali igralec hodi po podlagi in ali poskuša opraviti premik navzgor. V
tem primeru poskusimo začeti s plezanjem. Če igralec že pleza, kličemo funkcijo za plezanje
(premikanje igralca), nato preverimo trenutno stanje igralca. Če se premika proti platoju ali
pa neki točki, kličemo funkcijo za premikanje proti točki. Če igralec skače ali pada, pa
kličemo funkcijo, ki preverja vertikalno smer njegovega premikanja. Ta sistem je omogočil
plezanje po robovih, ki imajo pravi kot. Ker smo želeli dodati še vertikalno plezanje po
ceveh, ki so v obliki valja, smo razvili dodaten plezalni sistem za cevi.
void Update() { if (currentSort == ClimbingSort.Walking && Input.GetAxis("Vertical") > 0) { StartClimbing(); } if (currentSort == ClimbingSort.Climbing) { Climb(); } UpdateStats(); if (currentSort == ClimbingSort.ClimbingTowardsPoint || currentSort == ClimbingSort.ClimbingTowardsPlateau) { MoveTowardsPoint(); } if (currentSort == ClimbingSort.Jumping || currentSort == ClimbingSort.Falling) { Jumping(); } }
Izvorna koda 4.9 Update funkcija plezalnega sistema
Izdelava 3D platformske igre v Unity 3D
36
4.7 Plezalni sistem za cevi
Najprej smo morali ugotoviti, kdaj se je igralec dotaknil cevi, da smo vedeli, kdaj se naj
sproži ta plezalni sistem, za kar smo uporabili v Unity® vgrajeno funkcijo »OnTriggerEnter«,
ki ima parameter tipa »Collider« poimenovan »other« [15]. V tem parametru so
informacije, o tem kaj smo zadeli. Če objektu v inšpektorju pod komponento »RigidBody«
označimo »isTrigger«, se ta funkcija kliče vsakič, ko se ta objekt dotakne drugega objekta.
Ob trku z objektom smo preverili še oznako le-tega. Če je objekt, v katerega je trčil igralec
ustrezen, smo igralčeve integrirane kontrole izklopili, ga obrnili proti cevi, ter animatorju
sporočili, naj vključi našo animacijo za plezanje po cevi, ki jo prikazuje slika 4.11. Kreirali
smo tudi spremenljivko tipa boolean poimenovano »climbing«, s katero v funkcijo
»Update« sporočimo, kdaj se naj prične naša koda za plezanje po cevi.
Slika 4.11 Plezanje igralca po cevi
V funkciji »Update« preverjamo prej omenjeno spremenljivko »climbing«, da vemo, kdaj
smo pričeli plezati. Sedaj lahko igralca premikamo po vertikalni osi. Hkrati smo preverjali
razdaljo do vrha z metodo »Vector3.distance«, da se ne premakne predaleč. Ob pritisku
tipke q ali e se igralec prične glede na dlani obračati okoli cevi, s tem se lahko usmeri v
Izdelava 3D platformske igre v Unity 3D
37
katero smer bo kasneje skočil iz cevi. Obračanje igralca smo dosegli z uporabo vgrajene
funkcije »Transform.RotateAround«. Prvi parameter pove, okoli česa bomo vrteli našega
glavnega igralca - v našem primeru je to središče cevi. Drugi parameter pove, okoli katere
osi se vrtenje izvaja. Da smo igralca lahko rotirali, smo tukaj podali kot parameter igralčev
»Vector3.up«, kar pomeni os y njegovega lokalnega koordinatnega sistema. Tretji
parameter pove, za koliko stopinj želimo objekt rotirati. S poskušanjem smo izbrali vrednost
1,5 stopinje. Obračanje je omogočeno samo v primeru, če igralec na cevi miruje (izvorna
koda 4.10).
Ob pritisku gumba za skok smo igralcu dodali nasprotno silo, enako kot pri odboju od zida.
Skočimo lahko tudi v druge smeri, če držimo hkrati kontrolo za premikanje. Ob trku v cev
se je sedaj igralec zanjo prijel in med plezanjem okoli nje obračal, ter skočil z nje. Sedaj smo
končali sistem za vertikalno plezanje po ceveh. V igro smo tudi dodali cevi, ki so v okolici
pod ostrim kotom. Za spust po njih smo potrebovali nov sistem.
4.8 Sistem za spuščanje po ceveh
Ob trku igralnih objektov v cev smo preverili oznako objekta, ki je trčil v njo in v primeru,
da ima oznako za igralca smo izklopili vse integrirane kontrole igralca in animatorju
sporočili, naj vključi animacijo za spust, katero nam prikazuje slika 4.12. Ponovno smo v
//beremo vhod iz tipkovnice za vertikalno os keyBoardInput = Input.GetAxis("Vertical"); if (Input.GetKey(KeyCode.Q) && keyBoardInput == 0) { //obračanje levo wc.transform.RotateAround(center.transform.position, Vector3.up, 1.5f); } else if (Input.GetKey(KeyCode.E) && keyBoardInput == 0) { //obračanje desno wc.transform.RotateAround(center.transform.position, Vector3.up, -1.5f); }
Izvorna koda 4.10 Rotacija igralca okoli cevi
Izdelava 3D platformske igre v Unity 3D
38
funkciji »Update« kreirali eno spremenljivko tipa boolean poimenovano »sliding«, za
preverjanje, ali se že igralec spušča.
Slika 4.12 Spust igralca po cevi
Na cev smo dodali začetno in končno točko (krogli na koncu in začetku cevi, slika 4.12).
Igralca smo rotirali proti končni točki in ga začeli v ravni liniji s pomočjo funkcije
»Vector3.lerp« premikati od začetne proti končni točki. Bližje, kot je igralec končni točki,
počasneje se spušča. Ko je dovolj blizu končne točke, smo spet vključili vse integrirane
kontrole in izklopili animacijo za spust, da je igralec doskočil na tla. Sedaj smo zaključili vse
sisteme za igralčevo plezanje. Dodati smo morali še vsebino igre, da je igranje dobilo smisel.
4.9 Glavna kontrolna skripta
Cilj igre je napredovati v zadnjo sceno, za kar smo postavili pogoj, da mora igralec najti vse
ključe v sceni. Išče lahko tudi zlato, ki pa ni nujno za napredovanje. Igralec lahko tudi umre,
če trči v katero od pasti v igri. V primeru trčenja v past, smo igralca postavili na mesto, kjer
je našel zadnji ključ, oz. na začetno pozicijo, če ni našel še nobenega. Za vodenje evidence
vsega naštetega smo pripravili skripto. Uporabili smo preproste spremenljivke, s katerimi
štejemo trenutno število najdenih ključev in zlata. Ob vsakem najdenem objektu smo
povečali ustrezni števec in posodobili besedila na oknu, ki smo jih dodali v sceno za prikaz
Izdelava 3D platformske igre v Unity 3D
39
trenutnega napredka. Statistika najdenih objektov se shranjuje v »PlayerPrefs« [18]. To je
integrirana podatkovna struktura, v katero podamo tip podatka, njegov ključ in vrednost,
ki jo želimo shraniti na disk. Dostopne so ob vsakem zagonu igre, pobrisati pa jih moramo
sami.
Ko igralec najde vse ključe, se prikaže besedilo, ki ga prikazuje slika 4.13. Besedilo nas
opozori, da je portal v naslednjo sceno odprt. Vključili smo tudi animacijo za portal in zvok,
ki ga slišimo samo, ko smo dovolj blizu portala. Slika 4.14 prikazuje ta portal. Takšen učinek
predvajanja zvoka smo naredili tako, da smo v komponenti AudioSource objekta v
inšpektorju nastavili še vrednosti minimalne in maksimalne dolžine, ki vpliva na razdaljo, na
kateri lahko igralec sliši zvok. Spremenili smo nastavitev za spust zvoka na linearni spust, ki
avtomatizirano niža glasnost, ko se igralec oddaljuje. Ob trku z aktiviranim portalom smo
ekran pobarvali z belo barvo in naredili prehod na naslednjo sceno z objektom
SceneLoader. Učinek barvanja na belo smo dosegli tako, da smo naredili čez celotno glavno
kamero prosojno belo sliko. Vrednost alfa kontrolira prosojnost slike. Izkoristili smo
funkcijo »Vector3.lerp« in približevali alfa vrednost proti 1, ki pomeni brez prosojnosti. Ko
je prosojnost dosegla vrednost ena, smo pognali podprogram (ang. Coroutine) [16].
Podprogrami so posebne funkcije v Unity®, ki se ob klicu pričnejo izvajati v ozadju, ostala
programska koda pa se nadaljuje.
Slika 4.13 Prikaz teksta ob vseh najdenih ključih
Izdelava 3D platformske igre v Unity 3D
40
Slika 4.14 Aktiviran portal
Posebnost podprogramov je, da nudijo možnost zakasnitve kode. Preden smo preklopili na
naslednjo sceno, smo uporabili vgrajeno funkcijo »WaitForSeconds«, da smo zaradi lepšega
izgleda počakali eno sekundo pred menjavo scene (izvorna koda 4.11).
4.10 Povezovanje kode z animacijami
Za uporabo animacij iz programske kode smo v animatorju igralca nadgradili privzeti graf,
ki ga prikazuje slika 4.15 in določili dodatne spremenljivke, ki smo jih uporabili za prehode
med animacijami. Spremenljivke prikazuje slika 4.16, primer nastavitev prehoda pa slika
4.17. Animacije za skok, tek, hojo in nedejavnost igralca, so bile že integrirane v graf.
//rutina za prehod v naslednjo stopnjo public IEnumerator NextLevel() { yield return new WaitForSeconds(1); SceneManager.LoadScene(nextLevelName); }
Izvorna koda 4.11 Podprogram za čakanje
Izdelava 3D platformske igre v Unity 3D
41
Slika 4.15 Graf animacij igralca
Dodatne animacije, ki smo jih potrebovali za plezanje po robovih, med igralčevim visenjem
na njih in plezanju po ceveh ter spustu po njih, smo naredili v zavihku za animacijo.
Uporabili smo privzete gibe, ki so bili integrirani v model.
Da smo ustvarili prehode med animacijami, smo izvedli desni klik na posamezen
pravokotnik, izbrali možnost »ustvari prehod« (ang. Make Transition) in določili, v katero
animacijo se naj prehod zgodi. Ustvarile so se puščice, ki smo jih povezali na drug
pravokotnik oz. animacijo, v katero se naj zgodi prehod. Ob kliku na posamezno puščico, so
se odprle podrobne nastavitve prehoda.
Izdelava 3D platformske igre v Unity 3D
42
Slika 4.16 Prehod animacije za cevi
Slika 4.17 prikazuje podrobne nastavitve za prehod iz nedejavnega stanja ob držanju igralca
na cevi v premikanje po njej navzgor ali navzdol. Odkljukali smo stikali »Izhodni čas« (ang.
Has Exit Time) in »določena dolžina« (ang. Fixed Duration), da smo preprečili avtomatiziran
konec animacije. Na dnu smo definirali še pogoj za prehod. To animacijo smo glede na pogoj
sprožili vsakič, ko je vrednost naše spremenljivke »PipeClimbSpeed« večja od 0,01.
Slika 4.17 Dodatne spremenljivke v animatorju
Izdelava 3D platformske igre v Unity 3D
43
Da smo lahko spreminjali vrednosti vseh spremenljivk v animatorju, smo v skriptah naredili
referenco na objekt »Animator« in uporabili njegove vgrajene funkcije. V tem primeru je
številka v decimalnem zapisu, zato smo uporabili »Animator.SetFloat« in kot parameter
podali novo vrednost. Za to novo vrednost smo uporabili kar trenutno hitrost pomikanja po
cevi iz skripte za plezalni sistem za cevi.
Spremenljivka »wc« je referenca na našega igralca. Vrednost spremenljivke v animatorju
smo nastavili kar na absolutno vrednost poskusa premika iz tipkovnice (izvorna koda 4.12).
Vse enojne animacije smo povezali s kodo na zelo podoben način, kot je opisan v tem
podpoglavju.
wc.animator.SetFloat("PipeClimbSpeed", System.Math.Abs(keyBoardInput));
Izvorna koda 4.12 Nastavljanje spremenljivke v animatorju
Izdelava 3D platformske igre v Unity 3D
44
5 PREDSTAVITEV REZULTATOV
Ob zagonu igre smo pokazali glavni meni, ki je prikazan na sliki 5.1. Ob pritisku gumba za
zagon (Start), se nam pokaže zgodba igre. Ko pritisnemo v tej sceni gumb za nadaljevanje,
se prične igranje.
Slika 5.1 Glavni meni igre
Za začetek igre smo igralca postavili v sredo puščave pred velika vrata kar prikazuje slika
5.2. Igralcu smo postavili oprijeme, preko katerih mora splezati na vrh vrat in se spustiti po
cevi v notranjost okolja.
Izdelava 3D platformske igre v Unity 3D
45
Slika 5.2 Razgled z vrha začetnih vrat
Tu smo igralcu skrili štiri ključe, ki jih mora poiskati, da lahko napreduje v naslednjo sceno.
Prikazuje ju slika 5.3 in slika 5.4. Do njih pride s plezanjem po ovirah, med tem pa lahko
pobira tudi zlato, ki ga prikazuje slika 5.5. Koliko zlata je našel, smo prikazali ob koncu igre.
Slika 5.3 Skriti ključ v stolpu
Izdelava 3D platformske igre v Unity 3D
46
Slika 5.4 Skriti ključ v puščavi
Slika 5.5 Skrito zlato v zapuščeni hiši
Do skritega ključa lahko pridemo le, če nas ne ustavijo pasti, ki smo jih postavili v sceno.
Prikazuje jih slika 5.6.
Izdelava 3D platformske igre v Unity 3D
47
Slika 5.6 Pasti za igralca
Ko igralec najde vse ključe, se aktivira portal v naslednjo sceno. Ob vstopu smo ga prestavili
v podzemlje, ki je vhod v piramido. Ko prehodi hodnik do konca, se odprejo železna vrata.
Podzemlje prikazuje slika 5.7. Ob vstopu v temačni hodnik se igra konča in izpiše se
statistika, ki jo prikazuje slika 5.8.
Slika 5.7 Zadnja scena igre
Izdelava 3D platformske igre v Unity 3D
48
Slika 5.8 Statistika ob koncu igre
Po izteku treh sekund smo igralca vrnili v glavni meni.
Izdelava 3D platformske igre v Unity 3D
49
6 SKLEP
Ob implementaciji predstavljene igre smo izpolnili vse zastavljene cilje, ki so bili razvoj
celotne igre, smisel igranja in veliko zmožnosti gibanja igralca po okolju. Težavnost igre je
srednje zahtevna. Preizkusili smo jo tako, da smo jo večkrat preigrali sami in jo posredovali
nekaj igralcem za testiranje. Ključev v igri niso zlahka našli, prav tako so imeli težave pri
uporabi plezalnega sistema, saj so večkrat padli z različnih platform. Zlato je dobro skrito in
ga prav tako niso našli zlahka.
Delo v okolju Unity® je zelo enostavno. Na spletu je dostopno veliko literature za delo v
njem. Nudi enostavne rešitve, od katerih jih je veliko avtomatiziranih. Primer je veliko
vnaprej pripravljenih funkcionalnosti, ki nudijo npr. zaznavanje trkov med objekti, dostop
do drugih objektov iz vseh skript, do njih pridemo s preprostim klikom in vlekom na
spremenljivke iz naših skript v inšpektorju. Te vrednosti smo lahko kar od tam tudi urejali.
Nudi tudi avtomatizirano generiranje neba, svetlobe in senc ter veliko funkcij za lažje delo
v 3D prostorih iger in še mnogo več.
Med izdelovanjem igre smo pridobili veliko novega znanja. Največ za uporabo izstreljevanja
nevidnih žarkov. Naučili smo se tudi, kako optimizirati igro. Primer je omejitev zagona kode
v naprej narejeni funkciji »Update«, ki se neprestano izvaja.
Na izzive smo naleteli pri uporabi nevidnih žarkov za zaznavanje objektov. Upoštevati smo
morali veliko različnih faktorjev, da smo se res prepričali, če so pogoji za zagon skript
ustrezni. Veliko vrednosti parametrov funkcij za izstrelitev žarkov smo dobili s
poskušanjem, saj jih je skoraj nemogoče analitično določiti in so tudi zelo odvisni od
modelov, ki smo jih uporabili.
Možne nadgradnje igre bi bile: vpeljava sistema za bojevanje proti nasprotnikom, nihanje
po vrvi, bolj natančne animacije in možnost kratkega teka po zidovih.
Izdelava 3D platformske igre v Unity 3D
50
7 VIRI IN LITERATURA
[1] Instabug Blog, Top Game Engines In 2018. Dostopno na:
https://blog.instabug.com/2017/12/game-engines/ [05.07.2018]
[2] Lifewire, What is a platform game?, 2018. Dostopno na:
https://www.lifewire.com/what-is-a-platform-game-812371 [05.07.2018]
[3] Wikipedia, Unity (game engine), 2018. Dostopno na:
https://en.wikipedia.org/wiki/Unity_(game_engine) [05.07.2018]
[4] Unity Technologies, Brand, 2018. Dostopno na:
https://unity3d.com/public-relations/brand [05.07.2018]
[5] Unity Store, Unity Technologies, 2018. Dostopno na: https://store.unity.com/
[05.07.2018]
[6] Unity Enterprise, Unity Technologies, 2018. Dostopno na: https://store.unity.com/
[05.07.2018]
[7] Wikipedia, Platform game, 2018. Dostopno na:
https://en.wikipedia.org/wiki/Platform_game [05.07.2018]
[8] Wikipedia, Mario, 2018. Dostopno na: https://en.wikipedia.org/wiki/Mario
[05.07.2018]
Izdelava 3D platformske igre v Unity 3D
51
[9] Unity Documentation, Vector3, 2018. Dostopno na:
https://docs.unity3d.com/ScriptReference/Vector3.html [07.07.2018]
[10] Unity Documentation, Debug.DrawRay, 2018. Dostopno na:
https://docs.unity3d.com/ScriptReference/Debug.DrawRay.html [07.07.2018]
[11] Unity Documentation, RigidBody.velocity, 2018. Dostopno na:
https://docs.unity3d.com/ScriptReference/Rigidbody-velocity.html [07.07.2018]
[12] Unity Documentation, Physics.Linecast, 2018. Dostopno na:
https://docs.unity3d.com/ScriptReference/Physics.Linecast.html [07.07.2018]
[13] Unity Documentation, Vector3.Lerp, 2018. Dostopno na:
https://docs.unity3d.com/ScriptReference/Vector3.Lerp.html [07.07.2018]
[14] Unity Documentation, Vector3.Slerp, 2018. Dostopno na:
https://docs.unity3d.com/ScriptReference/Vector3.Slerp.html [07.07.2018]
[15] Unity Documentation, MonoBehaviour.OnTriggerEnter(Collider), 2018. Dostopno na:
https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnTriggerEnter.html
[07.07.2018]
[16] Unity Documentation, Coroutines, 2018. Dostopno na:
https://docs.unity3d.com/Manual/Coroutines.html [09.07.2018]
[17] Unity Documentation, Blend Trees, 2018. Dostopno na:
https://docs.unity3d.com/Manual/class-BlendTree.html [09.07.2018]
[18] Unity Documentation, PlayerPrefs, 2018. Dostopno na:
https://docs.unity3d.com/ScriptReference/PlayerPrefs.html [09.07.2018]
Izdelava 3D platformske igre v Unity 3D
52
[19] Unity Documentation, Terrain Engine, 2018. Dostopno na:
https://docs.unity3d.com/Manual/script-Terrain.html [15.07.2018]
[20] Wikipedia, Portal (video game), 2018. Dostopno na:
https://en.wikipedia.org/wiki/Portal_2 [15.07.2018]