izrada digitalnih 3d igara u razvojnoj okolini unity · brojem 2 na slici 2.2 stisne se desni klik...

56
SVEU ˇ CILIŠTE U ZAGREBU FAKULTET ELEKTROTEHNIKE I RA ˇ CUNARSTVA ZAVRŠNI RAD br. 5150 Izrada digitalnih 3D igara u razvojnoj okolini Unity Dobrila Šunde Zagreb, lipanj 2017.

Upload: others

Post on 31-Jan-2020

4 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

SVEUCILIŠTE U ZAGREBUFAKULTET ELEKTROTEHNIKE I RACUNARSTVA

ZAVRŠNI RAD br 5150

Izrada digitalnih 3D igara urazvojnoj okolini Unity

Dobrila Šunde

Zagreb lipanj 2017

Umjesto ove stranice umetnite izvornik Vašeg rada

Da bi ste uklonili ovu stranicu obrišite naredbu izvornik

Zahvala Nikoli Vuckovicu zbog velike pomoci sa izradom blend modela

iii

SADRŽAJ

1 Uvod 1

2 Postavljanje pocetne scene 221 Instalacija 2

22 Kreiranje prve scene 2

23 Razvojna okolina Unity 3

24 Konzola 4

25 Programski jezik 4

3 Unos glavnog lika u scenu 731 Skaliranje 7

32 Kreiranje osnovnih objekata 7

33 Unos Blender modela u Unity i pocetni problemi 8

4 Kamera 1241 Perspektivna i ortografska kamera 12

42 Pogled iz prvog lica u pogled iznad glave 13

43 Fiksirana kamera 15

44 Bacanje zraka (engl Ray casting) 16

5 Kretanje 1951 Navigacijski sustav u Unityu 19

52 Pronalazak puta 20

53 Kreiranje navigacijskog sustava 21

54 Programiranje kretanja 22

6 Korisnicko sucelje 3561 Platno 35

62 Osnovne komponente 36

iv

63 Korisnicko sucelje igraca 37

64 Korisnicko sucelje neprijatelja 38

7 Teren 4271 Kreiranje i uredivanje terena 42

72 Visinske mape 42

73 Teksture za teren 44

8 Zakljucak 46

9 Zasluge 47

Literatura 48

v

1 Uvod

Korištenje Unity razvojne okoline eksponencijalno raste zadnjih par godina Razlog

tomu vjerojatno leži u njegovoj jednostavnosti i poslovnom modelu koji omogucava

besplatno korištenje Unity 5 osobne licence za edukacijske svrhe te za tvrtke s priho-

dima manjim od 100000$ Ono što Unity je i ono što promovira je pojednostavljivanje

svih komponenata potrebnih za razvoj igre No takoder pruža svu slobodu programeru

da dodatno razvije i poboljša njihov sustav u obliku koji njemu najviše odgovara Rad

s animacijama teksturama i modelima je vrlo jednostavan i ne zahtijeva nikakvo zna-

nje programera o njihovom razvoju ili ucitavanju kako bi mogli raditi s njima Tako-

der postoje vec mnogi primjeri programskog koda ponudeni na službenim stranicama

Unitya za dizajnere koji nisu iskusni u programiranju Programski kodovi su odlicno

opisani i rješavaju u par linija teške probleme poput navigacije kamere osvjetljenja

itd Cilj ovog rada je pokazati kako se lako mogu savladati osnove rada u Unityu i

kako iskoristiti naše programersko predznanje dobiveno s dosadašnjim studiranjem za

dodatno poboljšavanje svega što Unity nudi te i za lakše razumijevanje kako vec im-

plementirani algoritmi Unitya funkcioniraju Svako poglavlje predstavlja svojevrsni

zadatak za cije se rješavanje nude razna rješenja i objašnjenje potrebne teorije te na

kraju i opis rješenja koje je iskorišteno u ovom projektu

1

2 Postavljanje pocetne scene

U ovom poglavlju je predstavljena instalacija razvojne okoline Unity te kreiranje po-

cetnog projekta u kojem ce se do kraja ovog rada izradivati zamišljena igra Upoznaje

se s radom konzole i odlucuje se koji programski jezik ce biti korišten Opisuje se i

objašnjava rad u razlicitim prozorima razvojne okoline te snalaženje u samoj sceni ra-

zvoja igre Nakon kraja ovog poglavlja želi se imati instaliran Unity i pokrenut prazan

projekt

21 Instalacija

Kao što je vec navedeno Unity je besplatan za korištenje za privatne edukacijske te

opcenito bilo kakve nekomercijalne svrhe Razvojni alat se može skinuti i instalirati sa

službene stranice Instalacija je prilicno jednostavna te ima detaljna uputstva koja se

mogu slijediti Verzija korištena tijekom ostatka ovog rada je Unity 56 Za kodiranje

skripti korišten je Microsoft Visual Studio 2017 Naravno može se koristiti i Mono

Develop koji dolazi skupa s instalacijom Unitya

22 Kreiranje prve scene

Nakon instalacije Unitya kreira se novi projekt kao što se vidi na slici 21 Odabere

se ime projekta te mjesto na disku gdje ce se spremiti Nakon kreiranja projekta otvara

se klasicna pocetna scena koja se sastoji od glavne kamere te usmjerenog svijetla koji

su oznaceni brojem 1 na slici 22 Brojem 2 na slici 22 je oznacen prozor projekt

(engl Project) gdje ce se nalaziti sve skripte objekti materijali i sl koje cemo kreirati

kroz izradu projekta Sve te komponente se zapravo spremaju na disku ovisno o tome

gdje je Unity instaliran i gdje je postavljeno spremanje projekata Npr za ovaj projekt

je korišteno DUnity ProjectsAlice Prazni projekt spremamo koristeci postupak

datoteka (engl File) -gt spremi scenu kao (engl Save Scene As) kako bi se kreirala

prva scena u Unityu Odabire se proizvoljno ime te se klikne spremi (engl Save)

2

Slika 21 Kreiranje projekta

23 Razvojna okolina Unity

Na slici 22 može se vidjeti ovaj projekt u nekoj kasnijoj fazi rada Koristi se ova slika

za lakše objašnjavanje dijelova razvojne okoline Unity Razlikuju se dva pogleda

pogled scene i pogled igre koji se vide i na slici 22 pod brojem 3 U pogledu scene

ureduje se scena igre dodaju se objekti skripte te sve ostalo što je potrebno Nakon

prebacivanja u pogled igre može se igrati dosad izradena verziju igre to je ono što ce

igrac zapravo vidjeti Na samom vrhu slike 22 oznaceno brojem 4 vidimo tri gumba

kao na slici 23 igraj (engl Play) pauziraj (engl Pause) i korak (engl Step) Ti

gumbi prebacuju pogled u pogled igre Sve promjene koje se naprave nad objektima

u pogledu igre su privremeni te ce se vratiti na staro kada se izade iz tog pogleda

Pritisak na gumb Play automatski prebacuje na prozor igra (engl Game) iz prozora

scena (engl Scene) ciji se nazivi mogu vidjeti ispod tih gumba

Dalje postoje gumbi oznaceni brojem 5 na slici 22 koji pomažu s kretanjem oko scene

i manipulacijom objekata u sceni koji su prikazani na slici 24 Prvi gumb sa slikom

ruke omogucava pomicanje po sceni dok drugi gumb omogucava pomicanje objekata

po sceni Treci gumb služi za rotaciju objekata cetvrti za skaliranje i peti služi za

korisnicko sucelje

3

Slika 22 Razvojna okolina Unity

Slika 23 Gumbi Pokreni Pauziraj i Korak

24 Konzola

Konzola u Unityu vecinom služi za pomoc pri traženju greški u programskom kodu

Može se vidjeti na slici 22 u donjem dijelu Unitya u obliku kartice pored kartice

Project Ako se ne nalazi tamo mora se dodati odlaskom na prozori (engl Windows)-

gt konzola (engl Console) Pritiskom na nju primjecuje se da je skroz prazna i da

imamo još par kartica ocisti (engl Clear) sruši (engl Collapse) ocisti pri pokretanju

(engl Clear On Play) i pri grešci pauziraj (engl Error Pause) Clear služi za cišce-

nje dosad ispisanih poruka Obicno se oznacava Clear On Play da uvijek ocisti stare

poruke te da svaki put kad se pokrene igra dobiju nove Collapse pomaže ako postoji

puno istih poruka npr je korištena while petlja i ceka se neka promjenu u sceni Nije

potrebno da se ispisuje poruka Cekam cijelo vrijeme dok se ceka nego samo jednom

25 Programski jezik

Unity podržava C i Javascript programske jezike te je kroz projekt korišten samo C

Pretpostavlja se da je citatelj upoznat barem sa sintaksom C-a te osnovama objektno

4

Slika 24 Alati za transformaciju

orijentiranog programiranja Nije potrebno veliko znanje C-a kako bi se kodiralo u

Unityu potrebno je samo razumjeti kako se radi s objektima te poznavati sintaksu C-

a zbog rada s razlicitim vrstama varijabli (za razliku od Python-a gdje nije potrebno

specificirati je li varijabla cijeli broj decimalni broj itd) Unutar prozora oznacenim

brojem 2 na slici 22 stisne se desni klik i odabere kreiraj (engl Create) i C skripta

(engl C Script) da se doda nova skripta Duplim klikom na novo-kreiranu skriptu

otvara se Microsoft Visual Studio ili neka druga razvojna okolina koja podržava C u

kojem se sad može pisati programski kod Programski kod 21 je primjer ispisivanja

jednostavne poruke u konzoli

Programski kod 21 HelloWorld1cs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class HelloWorld MonoBehaviour

koristi se za inicijalizaciju

void Start ()

print(Hello World)

Update se zove svaki okvir (engl Frame)

void Update ()

Sada kada se pritisne na gumb Play sa slike 23 može se vidjeti ispis u konzoli Hello

world Još jedan nacin ispisivanja u konzolu je prikazan programskim kodom 22

Programski kod 22 HelloWorld2cs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

5

public class HelloWorld MonoBehaviour

koristi se za inicijalizaciju

void Start ()

DebugLog(Hello world)

Update se zove svaki okvir (engl Frame)

void Update ()

Ne postoji nikakva bitne razlika izmedu ta dva nacina pa se koristi bilo koji

6

3 Unos glavnog lika u scenu

U ovom poglavlju opisuju se neki pocetni problemi s kojima se susrece pri ubacivanju

modela iz popularnog programa za modeliranje Blender Objašnjavaju se i modeli koji

su ponudeni unutar samog Unitya poput kocke i neke osnovne njihove transformacije

Nakon kraja ovog poglavlja želi se imati svojevrsno tlo i ubaceni glavni lik skupa s

njegovim teksturama i animacijama iz Blender-a koji nece propadati kroz tlo

31 Skaliranje

Jedno od osnovnih stvari o kojima se razmišlja prilikom kreiranja igre je koja ce se

brojcana skala koristiti Unity ima svoje mjerne jedinice koji predstavljaju metre u

njegovom fizickom sustavu Ovisno o tipu igre koja se kreira mora se paziti na skali-

ranje Izraduje li se neka igru u svemiru nece se koristiti naše realne mjerne jedinice

nego ce ih se naravno skalirati U ovom slucaju kreira se RPG (Role-playing game)

igra gdje nam je glavni lik covjek te ce se koristiti normalne Unity mjerne jedinice bez

skaliranja

32 Kreiranje osnovnih objekata

Za pocetak potrebno je kreirati jednostavno tlo Kocka se kreira s objekt igre (engl Ga-

meObject) -gt 3D objekt (engl 3D Object) -gt kocka (engl Cube) te se dobiva rezultat

kao na slici 31 Zasad se kocka skalira po x i z osi sa 100 Tlo je uobicajeno zelene

boje pa mu se dodaje novi materijal Pritisne se u prozor imovina (engl Asset) desnim

klikom miša i odabere se kreiraj (engl Create) -gt materijal (engl Material) kao što se

može vidjeti na slici 32 Klikom na novo-stvoreni materijal desno se pojavljuje novi

prozor Inspektor (engl Inspector) gdje se može odabrati boja Nakon toga samo se

povuce lijevim klikom miša materijal na skaliranu kocku tj tlo S obzirom na to

kako se želi da ta skalirana kocka glumi tlo želi se takoder da se i ostali objekti nalaze

7

Slika 31 Kreiranje tla

na njoj Zato ce se tlo morati pomaknuti po y osi za -05 kako bi se olakšalo daljnje

dodavanje objekata

33 Unos Blender modela u Unity i pocetni problemi

Krece se s ubacivanjem svog lika u igru Lik koji se koristi kroz ostatak ovog rada na-

pravljen je u programu Blender koji služi za 3D modeliranje blend objekt se može

samo povuci mišem u Unity iz datoteke u kojoj se nalazi

1 problem Kada se blend datoteka ubacuje u Unity on nece automatski ubaciti i

teksture koje su korištene u izradi tog modela Najlakši nacin bi bio izrada nove dato-

teku unutar Assets datoteke u Unityu i ubacivanje i blend modela i teksture koja je bila

korištena u izradi u tu novu datoteku Nakon toga klikom na model unutar prozora In-

spector pod Materials odabire se opcija od modelovih materijala (engl From Modelrsquos

Material) kao na slici33 kako bi Unity ucitavao korištene teksture Ponekad na žalost

ni to ne funkcionira pa ce se ovdje objasniti još jedan malo opcenitiji pristup Pri unosu

blend modela Unity kreira novu datoteku i nazove ju materijali (engl Materals) Ako

se dogodi da se korištene teksture na modelu ne vide treba se pogledati u tu datoteku

U njoj ce se nalaziti prazni materijali s istim imenima korištenih tekstura kao npr u

slucaju ovog projekta drvo (engl Wood) Tada se mora odabrati u desnom prozoru

materijala albedo (engl Albedo) kao na slici 34 i u ponudenim Assets naci teksturu

koja je korištena (u ovom slucaju Wood)

8

Slika 32 Kreiranje materijala

2 problem Sada kada je lik pozicioniran u ishodištu (x = 0 y = 0 z = 0) može se

dogoditi da se ne nalazi tocno na tlu koje je kreirano To dakako ovisi o modeliranju

koordinatama koje su korištene i skaliranju pri izradi modela Lik korišten u ovom

radu mora se pomaknuti na koordinatu x = 0 y = 15 z = 0 kako bi stajao tocno na tlu

3 problem Kada bi se igra sad pokrenula pritiskom na gumb Play pri vrhu Unitya

lik bi propao kroz tlo Zašto se to dogada Zbog necega što se zove sudarac (engl Col-

lider) u Unityu koji ce kasnije biti pomnije objašnjen Za sada se samo žele postaviti

neke pocetne stvari kako bi bilo lakše testirati osnovnu interakciju lika i objekata u

prostoru U desnom prozoru Inspector kada je lik oznacen vidi se opcija dodaj kom-

ponentu (engl Add Component) Stisne se na to i upiše sudarac u obliku kapsule

(engl Capsule Collider) kako bi se dodao novi sudarac To je zapravo samo sudarac

9

Slika 33 Unos blend modela u scenu

koji je u obliku kapsule te se igrajuci nekim njegovim osnovnim opcijama može na-

mjestiti vanjski oblik lika Dodaje se još jedna komponenta nad likom Ponovno se

stisne na Add Component te upiše kruto tijelo (engl Rigid Body) što ce takoder biti

naknadno objašnjeno Zasad je bitno razumijevanje da to omogucava liku da se ponaša

kao kruto tijelo u prostoru

4 problem Sada bi kada se igra pokrene trebao postojati lik koji ne propada kroz tlo

Naravno kao najosnovniju mehaniku želi se mogucnost kretanja po tom tlu Skripta

koja se treba napraviti kako bi se lik kretao po tlu nije zapravo komplicirana Sastoji

se samo od toga da se prilikom pritiska na odredeno slovo tipkovnice objekt translatira

po prostoru No ovaj model takoder sadrži i animacije za hodanje te se želi i to ukom-

ponirati Zato ce se takoder sada spomenuti još jedna nova komponenta kontrolor

animacija (engl Animator Controller) Dodaje se i ta komponenta na lika i prebacuje

se na prozor animator (engl Animator) koji se vidi na slici 35

U ovom prozoru postoji par novih opcija Mogu se dodavati nova stanja u kojima

ce se lik naci ovisno o nekim uvjetima koji se zadaju Pocetno stanje je ulazno stanje

(engl Entry State) i iz njega se želi da se lik nade u stanju mirovanja Stisne se desni

klik miša i odabere se novo stanje (engl New State) U ovom projektu je nazvano

Mirovanje Iz mirovanja ovisno o tome kada osoba pritisne neku tipku tipkovnice

želi se da se lik krene kretati Zato treba dodati novo stanje Hodanje Doda se

novo stanje istim postupkom kao i prvo Sada se naravno moraju dodati i usmjereni

prijelazi Stisne se desni klik miša na Mirovanje i odabere dodaj prijelaz (engl Add

10

Slika 34 Traženje tekstura Vašeg blend modela

Slika 35 Animator

Transition) To je sada kreiralo usmjerenu strelicu koja se može povuci prema Ho-

danje Isto to se napravi i u suprotnom smjeru Desni klik miša na Hodanje Add

Transition i povuce se strelica prema Mirovanje Naravno moraju se dodati uvjeti

koji ce odredivati kada ce objekt prijeci iz jednog stanja u drugo U ovom slucaju je

korišten cijeli broj (engl Integer) Ostatak problema kretanja rješavat ce se u poglavlju

4 Bacanje zraka i kretanje po mapi s mišem

11

4 Kamera

U ovom poglavlju se postavlja i bira prava kamera za igru Tijekom izrade igre treba se

takoder razmišljati i iz kojeg kuta ce se imati pogled na nju te hoce li se kamera pomi-

cati s kretanjem lika hoce li se moci rotirati itd Pri kreiranju 3D igre u pogledu scene

primjecuje se da su svi objekti i transformacije u 3D-prostoru No s obzirom na to da je

zaslon monitora igraca 2-dimenzionalan te se ne može prikazati tijela kao takva mora

se moci prikazati sve te objekte u jednoj ravnini i zadržati dojam 3-dimenzionalnosti

To se u Unityu postiže s kamerom Kamera je objekt koja definira pogled i njegov

smjer u prostoru scene Pozicija kamere definira ocište z os definira smjer gledanja

(gledište) te y os definira vrh ekrana Kamera takoder definira velicinu i oblik dijela

koji možemo vidjeti Kamera nam pokazuje ono što ona vidi Kako se ona rotira

translatira itd prikaz scene ce se takoder jednako transformirati Nakon kraja ovog

poglavlja želi se imati kamera koja ce pratiti kretnje lika i imati pogled na njega odoz-

gora

41 Perspektivna i ortografska kamera

Kamerom se zapravo objekte 3D prostora projicira na ravninu u 2D prostor Projek-

cije su matematicki modeli koji govore na koji nacin treba tocke 3D prostora preslikati

u ravninu u tocke 2D prostora Postoji više vrsta projekcija no Unity koristi dvije or-

tografsku projekciju i perspektivnu projekciju Kod ortografskih projekcija kamera je

okomita na ravninu projekcije dok je perspektivna projekcija bliža našem nacinu gle-

danja objekata Možda je najlakše primijetiti razliku koristeci slike Dakle na slici 41

možemo vidjeti blend model koji je modeliran u Blenderu u ortografskoj projekciji te

na slici 42 isti taj model pod istim kutem samo prebacen u perspektivnu projekciju

[6]

Perspektivna projekcija uvodi dvije tocke ocište i gledište Ocište je tocka u ko-

joj se nalazi promatrac Gledište odreduje smjer prema kojem promatrac gleda U

12

Slika 41 Ortografska projekcija blend modela

tocki gledišta stvara se ravnina projekcije koja je okomita na spojnicu ocište-gledište

[6] I perspektivna i ortografska kamera imaju granicu do koje mogu vidjeti od svoje

trenutne pozicije Ona je definirana upravo tom ravninom projekcije Tocka gledišta

pripada toj ravnini i ona tipicno postaje ishodište lokalnog dvodimenzijskog koordi-

natnog sustava koji razapinjemo u ravnini projekcije Ta ravnina se još naziva i daleka

ravnina podrezivanja zato što svi objekti koji se nalaze na vecoj udaljenosti od nje se

odrežu te ih kamera ne prikazuje Takoder postoji i ravnina podrezivanja blizu ka-

meri [1] Dio koji se prikazuje se nalazi izmedu te dvije ravnine

42 Pogled iz prvog lica u pogled iznad glave

U igrama se cesto koristi prebacivanje iz jednog u drugi pogled kamere Kako se

to postiže Koristeci veci broj kamera U ovom slucaju obradit ce se samo kratki

primjer kako se prebacivati iz pogleda prvog lica u pogled iznad glave U unity-u je

zadano da jedna kamera pokriva cijeli ekran te se zato samo pogled jedne kamere može

vidjeti u jednom trenutku Kamera koju vidimo je ona koja ima najvecu vrijednost

za svoje svojstvo dubine[1] Zato se želi napraviti skripta koja ce se prebacivati s

jedne kamere na drugu da bi se dobili drukciji pogledi na scenu koja je prikazana

programskim kodom 41

Programski kod 41 PrimjerViseKameracs

13

Slika 42 Perspektivna projekcija blend modela

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kameraPrvogLica

public Camera kameraIznadGlave

funkcija koja se poziva kada se prebacujemo u pogled iznad

glave

public void prikaziPogledIznadGlave()

kameraPrvogLicaenabled = false gasimo kameru prvog

lica

kameraIznadGlaveenabled = true palimo kameru iznad

glave

funkcija koja se poziva kada se prebacujemo u pogled iz

prvog lica

public void prikaziPogledIzPrvogLica()

kameraPrvogLicaenabled = true palimo kameru prvog

lica

overheadCameraenabled = false gasimo kameru iznad

glave

14

43 Fiksirana kamera

U sceni projekta vec postoji glavna kamera (engl Main Camera) koju Unity automat-

ski dodaje u scenu Kako bi ta kamera pratila lika može se samo povuci u lijevom

prozoru hijerarhije u hijerarhiju lika kako bi postala njegovo dijete Tako ce se postici

da kamera stalno prati njegove transformacije (translaciju rotaciju) prilikom pokreta-

nja igre No kako bi se postiglo da kamera ostane uvijek fiksirana te se samo krece s

njime umjesto da se kamera rotira skupa s likom dodaje se novi prazni objekt sa Game

Object -gt kreiraj prazan (engl Create Empty) Njegova pozicija se postavlja na x =

0 y = 0 z = 0 ako vec nije tamo te se postavlja taj prazan objekt kao roditelj glavne

kamere Sada kamera ostaje fiksirana na mjestu te se nece ni kretati s likom Kako bi

se krenula kretati mora se dodati nova skripta na taj prazan objekt koji se odsad u pro-

jektu zove Kamera s obzirom na to da zaista i je roditelj glavne kamere Kako bi se u

skripti lakše locirao objekt igraca oznacava ga se u njegovom polju oznaka (engl Tag)

u desnom prozoru Inspector s igrac (engl Player) kao što se može vidjeti na slici 43

zaokruženo plavom bojom

U programskom kodu se želi napraviti varijabla tipa Game Object kako bi se spremilo

igraca kada ga se pronade Unity takoder ima funkciju FindGameObjectWithTag pa

je onda ostatak koda prilicno intuitivan Kada se igrac pronade pomocu njegove oz-

nake Player prilikom svakog osvježavanja poziciji našeg igraca pridružuje se pozicija

kamere kao što je prikazano programskim kodom 42

Programski kod 42 pratiLikacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class pratiLika MonoBehaviour

GameObject igrac

void Start ()

trazi se objekt putem njegove oznake

igrac = GameObjectFindGameObjectWithTag(Player)

15

Slika 43 Oznacavanje lika radi lakšeg pronalaska u skripti

void LateUpdate ()

trenutni objekt mijenja svoju poziciju u skladu s

pozicijom objekta oznacenog oznakom Player

transformposition = igractransformposition

44 Bacanje zraka (engl Ray casting)

Perspektivna kamera u Unityu koristi oblik krnje piramide za dio koji prikazuje u pros-

toru Svaka tocka nekog objekta kojeg kamera prikazuje zapravo odgovara liniji u pros-

toru svijeta te je nama samo jedna tocka duž te linije vidljiva na objektu Sve iza te

tocke na liniji je zamraceno Vanjski rubovi objekta su definirani razilazecim linijama

16

koje odgovaraju kutevima objekta Kada bi se te linije pratile unazad prema kameri

sve bi na kraju konvergirale u jednu tocku U Unityu se ta tocka nalazi tocno na pozi-

ciji kamere i naziva se centrom perspektive Kut naspram linija koje konvergiraju od

gornjeg i donjeg centra ekrana u centru perspektive se zove vidno polje (engl Field Of

View) Sve što pada izvan tih razilazecih linija na rubovima objekta nece biti vidljivo

kameri uz vec prethodno spomenuta ogranicenja ravnina podrezivanja

U igrama je jako korisno imati matematicku reprezentaciju linije koja predstavlja tocku

u pogledu kamere Unity to omogucava u obliku objekta zrake Zraka uvijek odgo-

vara tocki u pogledu pa klasa Kamera (engl Camera) sadrži dvije korisne funkcije

ScreenPointToRay i ViewportPointToRay Razlika izmedu njih je da ScreenPointToRay

ocekuje tocku s koordinatama piksela dok ViewportPointToRay uzima normalizirane

koordinate (od 0 dolje ili lijevo do 1 gore ili desno) Obje funkcije vracaju zraku

koja se sastoji od tocke ishodišta i vektora koji pokazuje smjer linije od tog ishodišta

Zraka izlazi iz ravnine podrezivanja bliže kameri Najcešce se zrake koriste kako bi ih

bacali u scenu Bacanje zraka pošalje imaginarnu liniju uz zraku od njenog ishodišta

dok ne udari u neki sudarac u sceni Tada vraca informaciju o tocki koju je udarila

u objektu RaycastHit To je vrlo korisno kako bi se locirao objekt ovisno o njegovoj

poziciji na zaslonu npr lociranje kursora prikazano programskim kodom 43

Programski kod 43 lociranjeKursoracs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kamera

void Start()

RaycastHit udar

u objekt Ray se sprema pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

ako zraka udara u neki objekt spremi u objektUdaren to

mjesto

if (PhysicsRaycast(zraka out udar))

Transform objektUdaren = udartransform

17

Ponekad je takoder korisno dobiti zraku koja odgovara poziciji na zaslonu te onda

pomicati kameru uz tu zraku Npr želi se dozvoliti igracu da može selektirati objekt

mišem i onda ga povecati dok se objekt nalazi cijelo vrijeme na istoj poziciji na zaslonu

ispod miša prikazano programskim kodom 44 [1]

Programski kod 44 povecavanjeSlikecs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public bool povecavanje

public float brzinaPovecavanja

public Camera kamera

void Update()

ako netko koristi povecavanje slike (engl Zooming)

if (povecavanje)

u objekt Ray sprema se pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(Input

mousePosition)

udaljenost povecavanja ce biti jednaka umnosku

brzine povecavanja vremena i vertikalnog smjera

float udaljenostPovecavanja = brzinaPovecavanja

InputGetAxis(Vertical) TimedeltaTime

pomakni kameru u smjeru kursora misa za udaljenost

povecavanja u koordinatnom sustavu svijeta

kameratransformTranslate(zrakadirection

udaljenostPovecavanja SpaceWorld)

18

5 Kretanje

Pronalazak puta je zapravo pokušaj aplikacije na racunalu ili algoritma da nade naj-

kracu rutu izmedu dvije tocke To je recimo prakticna verzija rješavanja labirinta Ni

danas ne postoji optimalan algoritam koji ce u svakom slucaju u nekom realno krat-

kom vremenu naci najkraci put U ovom poglavlju objasnit ce se koje algoritme Unity

koristi za svoj navigacijski sustav Objašnjavat ce se i neki osnovni koncepti i obrasci

potrebni za ubrzavanje cijele ideje dojavljivanja promjena u sceni Bit ce prikazani i

programski kodovi potrebni za implementiranje kretanja mišem iili tipkovnicom Na

kraju ovog poglavlja želi se imati lika koji ce se slobodno kretati po sceni na mjesto

koje se odredi klikom miša i mogucnost prebacivanja na upravljanje tipkovnicom

51 Navigacijski sustav u Unityu

U Unityu je problem pronalaska puta vec riješen s necim što se zove navigacijska

mreža (engl NavMesh) To je navigacijski sustav koji ima svoje algoritme pronala-

ska puta i puno pojednostavljuje programiranje kretanja lika Sastoji se od cetiri di-

jela NavMesh agent navigacijske mreže (engl NavMesh Agent) izvanmrežna pove-

zanost(engl Off - Mesh Link) i prepreka navigacijske mreže(engl NavMesh Obstacle)

NavMesh je podatkovna struktura koja opisuje površine po kojima se može kretati

u igri i omogucava pronalazak put od jedne lokacije do druge Navigacijski sustav

treba svoje podatke kako bi predstavio prohodna podrucja u sceni Prohodna podru-

cja definiraju se kao mjesta gdje agent može stajati i kretati se Prohodno podrucje se

automatski izgraduje iz geometrije u sceni testirajuci sva podrucja gdje bi agent mo-

gao stajati Onda se te lokacije spajaju s površinom na vrhu geometrije Ta površina se

naziva onda NavMesh te je možemo vidjeti na 51 NavMesh tada sprema tu površinu

kao konveksne poligone te informacije koji su poligoni susjedni Komponenta Nav-

Mesh Agent pomaže pri kreiranju likova koji se medusobno izbjegavaju dok se krecu

prema cilju U Unityu se agenti opisuju kao valjci Koriste NavMesh kako bi se kretali

i znali koje objekte moraju zaobici te kako da se medusobno zaobidu Off-Mesh Link

19

omogucava dodavanje navigacijskih precaca koji se ne mogu predstaviti kao površina

po kojoj se može hodati npr skakanje preko ograde ili otvaranje vrata prije nego što

se ude u neku prostoriju NavMesh Obstacle opisuje prepreke koje se krecu te koje bi

agenti trebali izbjegavati dok hodaju svijetom npr neke bacve koje se kotrljaju prema

igracu Dok se bacva krece agent ce izracunati put oko nje najbolje što može no nakon

što ona naposljetku stane postat ce dio neprohodnog NavMesha te ce se agenti kretati

oko nje [3]

Slika 51 Prikaz navigacijskog sustava u Unityu

52 Pronalazak puta

Dva glavna problema postoje kod pronalaženja puta kako pronaci destinaciju na ni-

vou na kojem se igrac nalazi te kako se onda tamo pomaknuti Pronalaženje destinacije

uzima u obzir cijelu scenu Pomicanje tamo je dinamicnije u obzir uzima samo smjer

kretanja i kako da sprijeci sudaranje s drugim agentima Da bi se pronašao put izmedu

dvije lokacije prvo se moraju oznaciti pocetna i konacna lokacija njihovim najbližim

poligonima Tada se krece tražiti od pocetne lokacije posjecujuci sve susjedne dok se

ne dode do zadane destinacije Onda se prati unatrag vec posjecene poligone kako bi

se našao konacan niz poligona koji vode od pocetka do kraja Algoritam koji Unity

koristi te se cesto koristi za pronalazak puta naziva se A (A zvjezdica) Taj niz po-

ligona koji opisuje put od pocetka do kraja se naziva hodnik Agent ce doci do svoje

20

destinacije tako da se uvijek usmjerava prema sljedecem vidljivom kutu hodnika Ta

logika usmjeravanja uvijek uzima poziciju sljedeceg kuta i ovisno o tome nade željeni

smjer i brzinu potrebnu za dolazak na destinaciju Korištenje brzine po želji progra-

mera bi moglo dovesti do sudara s ostalim agentima Izbjegavanje prepreka takoder

pronalazi svoju novu brzinu koja traži ravnotežu izmedu kretanja prema destinaciji i

sprjecavanja buducih sudara s ostalim agentima i kutevima u navigacijskom sustavu

Nakon usmjeravanja i izbjegavanja prepreka izracuna se konacna brzina Unity ta-

koder uzima u obzir i akceleraciju kako bi simulirao realisticnije kretanje Takoder

treba razumjeti razliku izmedu globalne i lokalne navigacije Globalna navigacija se

koristi za pronalazak hodnika u svijetu Linearna lista poligona koja opisuje taj put je

podatkovna struktura koja se koristi za usmjeravanje te se može lokalno prilagodavati

i mijenjati kako se pozicija agenta mijenja Lokalna navigacija pokušava naci efika-

san nacin kako da se igrac pomakne prema sljedecem kutu bez da se sudari s ostalim

agentima ili objektima koji se krecu [3]

53 Kreiranje navigacijskog sustava

Proces kreiranja NavMesha iz geometrije nivoa se naziva pecenje navigacijske mreže

(engl NavMesh Baking) Skuplja sve terene i mreže objekata koji su oznaceni kao

navigacijski staticko (engl Navigation Static) i onda ih procesira kako bi kreirao navi-

gacijski sustav koji aproksimira prohodne površine nivoa Izgradnja (engl NavMesha)

je vrlo jednostavna Prvo se selektira geometrija koja bi trebala utjecati na navigaciju

tj površine po kojima možemo hodati i prepreke Oznaci se Navigation Static da bi ih

ukljucili u NavMesh Baking proces Prilagode se postavke kako bi odgovarale velicini

agenta - radijus (npr koliko blizu se može doci zidovima) visina (koliko su nisko

prostori koje agent može doseci) maksimalni nagib (koliko su kose rampe po kojima

se agent može uspeti) visina stube(koliko su visoke prepreke na koje agent može za-

koraciti) Onda jednostavno stisnemo ispeci (engl Bake) da izgradimo svoj NavMesh

Izgradeni NavMesh cemo moci vidjeti kao plavu površinu kao na slici 51 te ce se stvo-

riti nova datoteka s nazivom trenutne scene (ako vec ne postoji) i unutra ce se spremiti

kreiran navigacijski sustav [3]

21

54 Programiranje kretanja

Na liku se trenutno nalazi par stvari Animator Capsule Collider i Rigid Body Sada

je cilj isprogramirati mogucnost odredivanja gdje ce se lik kretati klikom miša na to

mjesto Dodaje se nova komponenta na lika NavMesh Agent Ta komponenta za-

pravo vec ima svoj sudarac te se slobodno može obrisati Capsule Collider jer postaje

nepotreban Igranjem s opcijama pomak od baze (engl Base Offset) te pod izbjegava-

nje prepreka (engl Obstacle Avoidance) radijus (engl Radius) i visina (engl Height)

prilagodi se sudarac od (engl NavMesh Agent-a) kako bi se obujmilo njime igraca i

sprijecilo propadanje kroz tlo od prije Sada kada postoji komponenta navigacije mora

se dodati skripta koja ce odrediti kada se lik krece te kada se pokrecu njegove anima-

cije iz Animator-a

Da bi se znalo gdje se miš nalazi mora se takoder dodati nova skriptu na kameru Kako

bi se izracunalo gdje trenutno kursor pokazuje Unity koristi vec prethodno spomenuto

bacanje zraka Da bi se moglo koristiti navigaciju putem klika mišem mora se napisati

skripta za glavnu kameru koja ce omoguciti bacanje zraka Skripta BacanjeZraka

dodaje se na objekt Main Camera koja se dodala pod prazni objekt Kamera Ova

skriptu se takoder koristi za razlikovanje raznih vrsta objekata Naime svaki objekt

kao što ima i Tag ima i sloj (engl Layer) Sloj služi kako bi mogli npr razlikovati

neprijatelje od obicnih objekata ili mjesto na koje želimo doci hodanjem Zato cemo

takoder dodati i jednu enumeraciju koja ce nam zasad služiti samo da razlikujemo je li

mjesto prohodno ili ne te jesmo li kliknuli na neprijatelja Kako bi dodali svoje nove

slojeve za objekte moramo kliknuti na Layer i dodaj sloj (engl Add Layer) kao na slici

52 što nas dovodi do novog prozora prikazanog na slici 53

Programski kod 51 bacanjeZrakacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

sluzi za dodavanje novih slojeva u Unity

public enum Sloj

Prohodno = 8

Neprijatelj = 9

KrajSvijeta = -1

22

Slika 52 Dodavanje novog sloja

public class BacanjeZraka MonoBehaviour

hijerarhija slojeva tj koji ima veci prioritet

public Sloj[] prioritetiSlojeva =

SlojNeprijatelj

SlojProhodno

SlojKrajSvijeta

udaljenost do pozadine je neka izmisljena vrijednost nakon

koje se prestane provjeravati zraka

public float udaljenostDoPozadine = 100f

Camera kamera

RaycastHit _udara

dohvaca varijable ove klase

public RaycastHit udara

get return _udara

Sloj _udaraSloj

23

Slika 53 Prozor za dodavanje novog sloja

public Sloj udaraSloj

get return _udaraSloj

deklariraj novi tip delegata

public delegate void priPromjeniSloja(Sloj noviSloj)

instanciraj skup promatraca

public event priPromjeniSloja promatraciPromjeneSloja

void Start ()

dohvat glavne kamere

kamera = Cameramain

void Update ()

nadi sloj po prioritetu u koji zraka udara

foreach(Sloj sloj in prioritetiSlojeva)

provjeravamo udara li zraka u neki od slojeva

24

var udar = BacanjeZrakaZaSloj(sloj)

if(udarHasValue)

_udara = udarValue

ako se sloj promjenio

if(_udaraSloj = sloj)

spremi novi sloj u varijablu trenutnog sloja

_udaraSloj = sloj

obavijesti promatrace da se sloj promjenio

promatraciPromjeneSloja(sloj)

spremi novi sloj u varijablu trenutnog sloja

ali ne moras obavjestavati promatrace jer je

sloj jednak starom sloju

_udaraSloj = sloj

return

inace vrati da zraka udara u pozadinu i obavijesti

promatrace

_udaradistance = udaljenostDoPozadine

_udaraSloj = SlojKrajSvijeta

promatraciPromjeneSloja(udaraSloj)

RaycastHit BacanjeZrakaZaSloj(Sloj sloj)

kreira se maska za slojeve bit se pomice ulijevo za

onoliko mjesta koliki je redni broj prioriteta sloja

int maska = 1 ltlt (int)sloj

sprema se mjesto pozicije kursora pretvoreno iz tocke u

zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

RaycastHit udar

PhysicsRaycast sprema zraku u varijablu tipa

RaycastHit prima jos i maksimalnu udaljenost za koju

provjerava zraku i masku sloja i potom vraca istinu (

engl True) ili laz (engl False) ako je zraka udarila

u sloj

25

bool udarioJe = PhysicsRaycast(zraka out udar

udaljenostDoPozadine maska)

ako zraka udara u sloj vrati vrijednost udarca

if(udarioJe)

return udar

return null

U programskom kodu 51 se koristi funkcija za primjenu obrasca promatraca pod

nazivom delegat (engl Delegate) Što je obrazac promatraca (engl Observer) To je

oblikovni obrazac koji se u programiranju koristi

bull kad promjena jednog objekta zahtijeva promjene u drugim objektima koji nisu

unaprijed poznati

bull kad objekt treba obavještavati druge objekte

bull uz uvjet da bude što neovisniji o njima

bull kad je potrebno prikazivati razlicite aspekte nekog dinamickog stanja a želimo

izbjeci ciklicku ovisnost izmedu stanja i pogleda

bull kad postoje dva koncepta jedan ovisan o drugome a zgodno ih je razdvojiti

S obzirom na to da mi samo pri promjeni sloja želimo obavještavati pretplacene pro-

matrace uvodenje delegata nam dosta ubrzava kod Obrazac promatraca funkcionira

tako da glavni objekt igra ulogu izdavaca (izvora informacija) u ovom slucaju to je

glavna kamera Ostali ovisni objekti (promatraci) pretplacuju se kod izdavaca te iz-

davaci obavještavaju pretplatnike o promjenama Promatraci prekidaju pretplatu kad

više ne trebaju obavještavanje Funkcija priPromjeniSloja se definira kao delegat i u

ovom slucaju prima sloj Nakon toga se definira dogadaj (engl Event) tipa tog delegata

(priPromjeniSloja) u ovom slucaju naziva promatraciPromjeneSloja i odsad se unutar

subjekta tim nazivom i poziva Kako bi se neki promatrac pretplatio na informacije

koje izdaje kamera dodaje ove dvije linije koda u svoju skriptu

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

Programski kod 52 služi za kretanje korištenjem NavMesha i lijevog klika miša

26

Programski kod 52 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

public float dovoljnoBlizu = 01f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora

[SerializeField] float hodajKreciStaniRadijus = 02f

void Start ()

pronadi igraca koji je tipa agenta navigacijskog sustava

(engl NavMeshAgent)

agent = GetComponentltUnityEngineAINavMeshAgentgt()

pronadi prethodno napisanu klasu BacanjeZraka

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

spremi trenutnu poziciju kursora

trenutnaPozicijaKursora = transformposition

void Update()

ako je igrac dosao na zeljeno mjesto zaustavi animaciju

hodanja

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

ako je stisnut lijevi klik misa

if (InputGetMouseButtonDown(0))

ovisno o sloju primjeni akciju

switch(bacanjeZrakaudaraSloj)

ako se po objektu na koji je igrac kliknuo moze

hodati

27

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 2: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

Umjesto ove stranice umetnite izvornik Vašeg rada

Da bi ste uklonili ovu stranicu obrišite naredbu izvornik

Zahvala Nikoli Vuckovicu zbog velike pomoci sa izradom blend modela

iii

SADRŽAJ

1 Uvod 1

2 Postavljanje pocetne scene 221 Instalacija 2

22 Kreiranje prve scene 2

23 Razvojna okolina Unity 3

24 Konzola 4

25 Programski jezik 4

3 Unos glavnog lika u scenu 731 Skaliranje 7

32 Kreiranje osnovnih objekata 7

33 Unos Blender modela u Unity i pocetni problemi 8

4 Kamera 1241 Perspektivna i ortografska kamera 12

42 Pogled iz prvog lica u pogled iznad glave 13

43 Fiksirana kamera 15

44 Bacanje zraka (engl Ray casting) 16

5 Kretanje 1951 Navigacijski sustav u Unityu 19

52 Pronalazak puta 20

53 Kreiranje navigacijskog sustava 21

54 Programiranje kretanja 22

6 Korisnicko sucelje 3561 Platno 35

62 Osnovne komponente 36

iv

63 Korisnicko sucelje igraca 37

64 Korisnicko sucelje neprijatelja 38

7 Teren 4271 Kreiranje i uredivanje terena 42

72 Visinske mape 42

73 Teksture za teren 44

8 Zakljucak 46

9 Zasluge 47

Literatura 48

v

1 Uvod

Korištenje Unity razvojne okoline eksponencijalno raste zadnjih par godina Razlog

tomu vjerojatno leži u njegovoj jednostavnosti i poslovnom modelu koji omogucava

besplatno korištenje Unity 5 osobne licence za edukacijske svrhe te za tvrtke s priho-

dima manjim od 100000$ Ono što Unity je i ono što promovira je pojednostavljivanje

svih komponenata potrebnih za razvoj igre No takoder pruža svu slobodu programeru

da dodatno razvije i poboljša njihov sustav u obliku koji njemu najviše odgovara Rad

s animacijama teksturama i modelima je vrlo jednostavan i ne zahtijeva nikakvo zna-

nje programera o njihovom razvoju ili ucitavanju kako bi mogli raditi s njima Tako-

der postoje vec mnogi primjeri programskog koda ponudeni na službenim stranicama

Unitya za dizajnere koji nisu iskusni u programiranju Programski kodovi su odlicno

opisani i rješavaju u par linija teške probleme poput navigacije kamere osvjetljenja

itd Cilj ovog rada je pokazati kako se lako mogu savladati osnove rada u Unityu i

kako iskoristiti naše programersko predznanje dobiveno s dosadašnjim studiranjem za

dodatno poboljšavanje svega što Unity nudi te i za lakše razumijevanje kako vec im-

plementirani algoritmi Unitya funkcioniraju Svako poglavlje predstavlja svojevrsni

zadatak za cije se rješavanje nude razna rješenja i objašnjenje potrebne teorije te na

kraju i opis rješenja koje je iskorišteno u ovom projektu

1

2 Postavljanje pocetne scene

U ovom poglavlju je predstavljena instalacija razvojne okoline Unity te kreiranje po-

cetnog projekta u kojem ce se do kraja ovog rada izradivati zamišljena igra Upoznaje

se s radom konzole i odlucuje se koji programski jezik ce biti korišten Opisuje se i

objašnjava rad u razlicitim prozorima razvojne okoline te snalaženje u samoj sceni ra-

zvoja igre Nakon kraja ovog poglavlja želi se imati instaliran Unity i pokrenut prazan

projekt

21 Instalacija

Kao što je vec navedeno Unity je besplatan za korištenje za privatne edukacijske te

opcenito bilo kakve nekomercijalne svrhe Razvojni alat se može skinuti i instalirati sa

službene stranice Instalacija je prilicno jednostavna te ima detaljna uputstva koja se

mogu slijediti Verzija korištena tijekom ostatka ovog rada je Unity 56 Za kodiranje

skripti korišten je Microsoft Visual Studio 2017 Naravno može se koristiti i Mono

Develop koji dolazi skupa s instalacijom Unitya

22 Kreiranje prve scene

Nakon instalacije Unitya kreira se novi projekt kao što se vidi na slici 21 Odabere

se ime projekta te mjesto na disku gdje ce se spremiti Nakon kreiranja projekta otvara

se klasicna pocetna scena koja se sastoji od glavne kamere te usmjerenog svijetla koji

su oznaceni brojem 1 na slici 22 Brojem 2 na slici 22 je oznacen prozor projekt

(engl Project) gdje ce se nalaziti sve skripte objekti materijali i sl koje cemo kreirati

kroz izradu projekta Sve te komponente se zapravo spremaju na disku ovisno o tome

gdje je Unity instaliran i gdje je postavljeno spremanje projekata Npr za ovaj projekt

je korišteno DUnity ProjectsAlice Prazni projekt spremamo koristeci postupak

datoteka (engl File) -gt spremi scenu kao (engl Save Scene As) kako bi se kreirala

prva scena u Unityu Odabire se proizvoljno ime te se klikne spremi (engl Save)

2

Slika 21 Kreiranje projekta

23 Razvojna okolina Unity

Na slici 22 može se vidjeti ovaj projekt u nekoj kasnijoj fazi rada Koristi se ova slika

za lakše objašnjavanje dijelova razvojne okoline Unity Razlikuju se dva pogleda

pogled scene i pogled igre koji se vide i na slici 22 pod brojem 3 U pogledu scene

ureduje se scena igre dodaju se objekti skripte te sve ostalo što je potrebno Nakon

prebacivanja u pogled igre može se igrati dosad izradena verziju igre to je ono što ce

igrac zapravo vidjeti Na samom vrhu slike 22 oznaceno brojem 4 vidimo tri gumba

kao na slici 23 igraj (engl Play) pauziraj (engl Pause) i korak (engl Step) Ti

gumbi prebacuju pogled u pogled igre Sve promjene koje se naprave nad objektima

u pogledu igre su privremeni te ce se vratiti na staro kada se izade iz tog pogleda

Pritisak na gumb Play automatski prebacuje na prozor igra (engl Game) iz prozora

scena (engl Scene) ciji se nazivi mogu vidjeti ispod tih gumba

Dalje postoje gumbi oznaceni brojem 5 na slici 22 koji pomažu s kretanjem oko scene

i manipulacijom objekata u sceni koji su prikazani na slici 24 Prvi gumb sa slikom

ruke omogucava pomicanje po sceni dok drugi gumb omogucava pomicanje objekata

po sceni Treci gumb služi za rotaciju objekata cetvrti za skaliranje i peti služi za

korisnicko sucelje

3

Slika 22 Razvojna okolina Unity

Slika 23 Gumbi Pokreni Pauziraj i Korak

24 Konzola

Konzola u Unityu vecinom služi za pomoc pri traženju greški u programskom kodu

Može se vidjeti na slici 22 u donjem dijelu Unitya u obliku kartice pored kartice

Project Ako se ne nalazi tamo mora se dodati odlaskom na prozori (engl Windows)-

gt konzola (engl Console) Pritiskom na nju primjecuje se da je skroz prazna i da

imamo još par kartica ocisti (engl Clear) sruši (engl Collapse) ocisti pri pokretanju

(engl Clear On Play) i pri grešci pauziraj (engl Error Pause) Clear služi za cišce-

nje dosad ispisanih poruka Obicno se oznacava Clear On Play da uvijek ocisti stare

poruke te da svaki put kad se pokrene igra dobiju nove Collapse pomaže ako postoji

puno istih poruka npr je korištena while petlja i ceka se neka promjenu u sceni Nije

potrebno da se ispisuje poruka Cekam cijelo vrijeme dok se ceka nego samo jednom

25 Programski jezik

Unity podržava C i Javascript programske jezike te je kroz projekt korišten samo C

Pretpostavlja se da je citatelj upoznat barem sa sintaksom C-a te osnovama objektno

4

Slika 24 Alati za transformaciju

orijentiranog programiranja Nije potrebno veliko znanje C-a kako bi se kodiralo u

Unityu potrebno je samo razumjeti kako se radi s objektima te poznavati sintaksu C-

a zbog rada s razlicitim vrstama varijabli (za razliku od Python-a gdje nije potrebno

specificirati je li varijabla cijeli broj decimalni broj itd) Unutar prozora oznacenim

brojem 2 na slici 22 stisne se desni klik i odabere kreiraj (engl Create) i C skripta

(engl C Script) da se doda nova skripta Duplim klikom na novo-kreiranu skriptu

otvara se Microsoft Visual Studio ili neka druga razvojna okolina koja podržava C u

kojem se sad može pisati programski kod Programski kod 21 je primjer ispisivanja

jednostavne poruke u konzoli

Programski kod 21 HelloWorld1cs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class HelloWorld MonoBehaviour

koristi se za inicijalizaciju

void Start ()

print(Hello World)

Update se zove svaki okvir (engl Frame)

void Update ()

Sada kada se pritisne na gumb Play sa slike 23 može se vidjeti ispis u konzoli Hello

world Još jedan nacin ispisivanja u konzolu je prikazan programskim kodom 22

Programski kod 22 HelloWorld2cs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

5

public class HelloWorld MonoBehaviour

koristi se za inicijalizaciju

void Start ()

DebugLog(Hello world)

Update se zove svaki okvir (engl Frame)

void Update ()

Ne postoji nikakva bitne razlika izmedu ta dva nacina pa se koristi bilo koji

6

3 Unos glavnog lika u scenu

U ovom poglavlju opisuju se neki pocetni problemi s kojima se susrece pri ubacivanju

modela iz popularnog programa za modeliranje Blender Objašnjavaju se i modeli koji

su ponudeni unutar samog Unitya poput kocke i neke osnovne njihove transformacije

Nakon kraja ovog poglavlja želi se imati svojevrsno tlo i ubaceni glavni lik skupa s

njegovim teksturama i animacijama iz Blender-a koji nece propadati kroz tlo

31 Skaliranje

Jedno od osnovnih stvari o kojima se razmišlja prilikom kreiranja igre je koja ce se

brojcana skala koristiti Unity ima svoje mjerne jedinice koji predstavljaju metre u

njegovom fizickom sustavu Ovisno o tipu igre koja se kreira mora se paziti na skali-

ranje Izraduje li se neka igru u svemiru nece se koristiti naše realne mjerne jedinice

nego ce ih se naravno skalirati U ovom slucaju kreira se RPG (Role-playing game)

igra gdje nam je glavni lik covjek te ce se koristiti normalne Unity mjerne jedinice bez

skaliranja

32 Kreiranje osnovnih objekata

Za pocetak potrebno je kreirati jednostavno tlo Kocka se kreira s objekt igre (engl Ga-

meObject) -gt 3D objekt (engl 3D Object) -gt kocka (engl Cube) te se dobiva rezultat

kao na slici 31 Zasad se kocka skalira po x i z osi sa 100 Tlo je uobicajeno zelene

boje pa mu se dodaje novi materijal Pritisne se u prozor imovina (engl Asset) desnim

klikom miša i odabere se kreiraj (engl Create) -gt materijal (engl Material) kao što se

može vidjeti na slici 32 Klikom na novo-stvoreni materijal desno se pojavljuje novi

prozor Inspektor (engl Inspector) gdje se može odabrati boja Nakon toga samo se

povuce lijevim klikom miša materijal na skaliranu kocku tj tlo S obzirom na to

kako se želi da ta skalirana kocka glumi tlo želi se takoder da se i ostali objekti nalaze

7

Slika 31 Kreiranje tla

na njoj Zato ce se tlo morati pomaknuti po y osi za -05 kako bi se olakšalo daljnje

dodavanje objekata

33 Unos Blender modela u Unity i pocetni problemi

Krece se s ubacivanjem svog lika u igru Lik koji se koristi kroz ostatak ovog rada na-

pravljen je u programu Blender koji služi za 3D modeliranje blend objekt se može

samo povuci mišem u Unity iz datoteke u kojoj se nalazi

1 problem Kada se blend datoteka ubacuje u Unity on nece automatski ubaciti i

teksture koje su korištene u izradi tog modela Najlakši nacin bi bio izrada nove dato-

teku unutar Assets datoteke u Unityu i ubacivanje i blend modela i teksture koja je bila

korištena u izradi u tu novu datoteku Nakon toga klikom na model unutar prozora In-

spector pod Materials odabire se opcija od modelovih materijala (engl From Modelrsquos

Material) kao na slici33 kako bi Unity ucitavao korištene teksture Ponekad na žalost

ni to ne funkcionira pa ce se ovdje objasniti još jedan malo opcenitiji pristup Pri unosu

blend modela Unity kreira novu datoteku i nazove ju materijali (engl Materals) Ako

se dogodi da se korištene teksture na modelu ne vide treba se pogledati u tu datoteku

U njoj ce se nalaziti prazni materijali s istim imenima korištenih tekstura kao npr u

slucaju ovog projekta drvo (engl Wood) Tada se mora odabrati u desnom prozoru

materijala albedo (engl Albedo) kao na slici 34 i u ponudenim Assets naci teksturu

koja je korištena (u ovom slucaju Wood)

8

Slika 32 Kreiranje materijala

2 problem Sada kada je lik pozicioniran u ishodištu (x = 0 y = 0 z = 0) može se

dogoditi da se ne nalazi tocno na tlu koje je kreirano To dakako ovisi o modeliranju

koordinatama koje su korištene i skaliranju pri izradi modela Lik korišten u ovom

radu mora se pomaknuti na koordinatu x = 0 y = 15 z = 0 kako bi stajao tocno na tlu

3 problem Kada bi se igra sad pokrenula pritiskom na gumb Play pri vrhu Unitya

lik bi propao kroz tlo Zašto se to dogada Zbog necega što se zove sudarac (engl Col-

lider) u Unityu koji ce kasnije biti pomnije objašnjen Za sada se samo žele postaviti

neke pocetne stvari kako bi bilo lakše testirati osnovnu interakciju lika i objekata u

prostoru U desnom prozoru Inspector kada je lik oznacen vidi se opcija dodaj kom-

ponentu (engl Add Component) Stisne se na to i upiše sudarac u obliku kapsule

(engl Capsule Collider) kako bi se dodao novi sudarac To je zapravo samo sudarac

9

Slika 33 Unos blend modela u scenu

koji je u obliku kapsule te se igrajuci nekim njegovim osnovnim opcijama može na-

mjestiti vanjski oblik lika Dodaje se još jedna komponenta nad likom Ponovno se

stisne na Add Component te upiše kruto tijelo (engl Rigid Body) što ce takoder biti

naknadno objašnjeno Zasad je bitno razumijevanje da to omogucava liku da se ponaša

kao kruto tijelo u prostoru

4 problem Sada bi kada se igra pokrene trebao postojati lik koji ne propada kroz tlo

Naravno kao najosnovniju mehaniku želi se mogucnost kretanja po tom tlu Skripta

koja se treba napraviti kako bi se lik kretao po tlu nije zapravo komplicirana Sastoji

se samo od toga da se prilikom pritiska na odredeno slovo tipkovnice objekt translatira

po prostoru No ovaj model takoder sadrži i animacije za hodanje te se želi i to ukom-

ponirati Zato ce se takoder sada spomenuti još jedna nova komponenta kontrolor

animacija (engl Animator Controller) Dodaje se i ta komponenta na lika i prebacuje

se na prozor animator (engl Animator) koji se vidi na slici 35

U ovom prozoru postoji par novih opcija Mogu se dodavati nova stanja u kojima

ce se lik naci ovisno o nekim uvjetima koji se zadaju Pocetno stanje je ulazno stanje

(engl Entry State) i iz njega se želi da se lik nade u stanju mirovanja Stisne se desni

klik miša i odabere se novo stanje (engl New State) U ovom projektu je nazvano

Mirovanje Iz mirovanja ovisno o tome kada osoba pritisne neku tipku tipkovnice

želi se da se lik krene kretati Zato treba dodati novo stanje Hodanje Doda se

novo stanje istim postupkom kao i prvo Sada se naravno moraju dodati i usmjereni

prijelazi Stisne se desni klik miša na Mirovanje i odabere dodaj prijelaz (engl Add

10

Slika 34 Traženje tekstura Vašeg blend modela

Slika 35 Animator

Transition) To je sada kreiralo usmjerenu strelicu koja se može povuci prema Ho-

danje Isto to se napravi i u suprotnom smjeru Desni klik miša na Hodanje Add

Transition i povuce se strelica prema Mirovanje Naravno moraju se dodati uvjeti

koji ce odredivati kada ce objekt prijeci iz jednog stanja u drugo U ovom slucaju je

korišten cijeli broj (engl Integer) Ostatak problema kretanja rješavat ce se u poglavlju

4 Bacanje zraka i kretanje po mapi s mišem

11

4 Kamera

U ovom poglavlju se postavlja i bira prava kamera za igru Tijekom izrade igre treba se

takoder razmišljati i iz kojeg kuta ce se imati pogled na nju te hoce li se kamera pomi-

cati s kretanjem lika hoce li se moci rotirati itd Pri kreiranju 3D igre u pogledu scene

primjecuje se da su svi objekti i transformacije u 3D-prostoru No s obzirom na to da je

zaslon monitora igraca 2-dimenzionalan te se ne može prikazati tijela kao takva mora

se moci prikazati sve te objekte u jednoj ravnini i zadržati dojam 3-dimenzionalnosti

To se u Unityu postiže s kamerom Kamera je objekt koja definira pogled i njegov

smjer u prostoru scene Pozicija kamere definira ocište z os definira smjer gledanja

(gledište) te y os definira vrh ekrana Kamera takoder definira velicinu i oblik dijela

koji možemo vidjeti Kamera nam pokazuje ono što ona vidi Kako se ona rotira

translatira itd prikaz scene ce se takoder jednako transformirati Nakon kraja ovog

poglavlja želi se imati kamera koja ce pratiti kretnje lika i imati pogled na njega odoz-

gora

41 Perspektivna i ortografska kamera

Kamerom se zapravo objekte 3D prostora projicira na ravninu u 2D prostor Projek-

cije su matematicki modeli koji govore na koji nacin treba tocke 3D prostora preslikati

u ravninu u tocke 2D prostora Postoji više vrsta projekcija no Unity koristi dvije or-

tografsku projekciju i perspektivnu projekciju Kod ortografskih projekcija kamera je

okomita na ravninu projekcije dok je perspektivna projekcija bliža našem nacinu gle-

danja objekata Možda je najlakše primijetiti razliku koristeci slike Dakle na slici 41

možemo vidjeti blend model koji je modeliran u Blenderu u ortografskoj projekciji te

na slici 42 isti taj model pod istim kutem samo prebacen u perspektivnu projekciju

[6]

Perspektivna projekcija uvodi dvije tocke ocište i gledište Ocište je tocka u ko-

joj se nalazi promatrac Gledište odreduje smjer prema kojem promatrac gleda U

12

Slika 41 Ortografska projekcija blend modela

tocki gledišta stvara se ravnina projekcije koja je okomita na spojnicu ocište-gledište

[6] I perspektivna i ortografska kamera imaju granicu do koje mogu vidjeti od svoje

trenutne pozicije Ona je definirana upravo tom ravninom projekcije Tocka gledišta

pripada toj ravnini i ona tipicno postaje ishodište lokalnog dvodimenzijskog koordi-

natnog sustava koji razapinjemo u ravnini projekcije Ta ravnina se još naziva i daleka

ravnina podrezivanja zato što svi objekti koji se nalaze na vecoj udaljenosti od nje se

odrežu te ih kamera ne prikazuje Takoder postoji i ravnina podrezivanja blizu ka-

meri [1] Dio koji se prikazuje se nalazi izmedu te dvije ravnine

42 Pogled iz prvog lica u pogled iznad glave

U igrama se cesto koristi prebacivanje iz jednog u drugi pogled kamere Kako se

to postiže Koristeci veci broj kamera U ovom slucaju obradit ce se samo kratki

primjer kako se prebacivati iz pogleda prvog lica u pogled iznad glave U unity-u je

zadano da jedna kamera pokriva cijeli ekran te se zato samo pogled jedne kamere može

vidjeti u jednom trenutku Kamera koju vidimo je ona koja ima najvecu vrijednost

za svoje svojstvo dubine[1] Zato se želi napraviti skripta koja ce se prebacivati s

jedne kamere na drugu da bi se dobili drukciji pogledi na scenu koja je prikazana

programskim kodom 41

Programski kod 41 PrimjerViseKameracs

13

Slika 42 Perspektivna projekcija blend modela

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kameraPrvogLica

public Camera kameraIznadGlave

funkcija koja se poziva kada se prebacujemo u pogled iznad

glave

public void prikaziPogledIznadGlave()

kameraPrvogLicaenabled = false gasimo kameru prvog

lica

kameraIznadGlaveenabled = true palimo kameru iznad

glave

funkcija koja se poziva kada se prebacujemo u pogled iz

prvog lica

public void prikaziPogledIzPrvogLica()

kameraPrvogLicaenabled = true palimo kameru prvog

lica

overheadCameraenabled = false gasimo kameru iznad

glave

14

43 Fiksirana kamera

U sceni projekta vec postoji glavna kamera (engl Main Camera) koju Unity automat-

ski dodaje u scenu Kako bi ta kamera pratila lika može se samo povuci u lijevom

prozoru hijerarhije u hijerarhiju lika kako bi postala njegovo dijete Tako ce se postici

da kamera stalno prati njegove transformacije (translaciju rotaciju) prilikom pokreta-

nja igre No kako bi se postiglo da kamera ostane uvijek fiksirana te se samo krece s

njime umjesto da se kamera rotira skupa s likom dodaje se novi prazni objekt sa Game

Object -gt kreiraj prazan (engl Create Empty) Njegova pozicija se postavlja na x =

0 y = 0 z = 0 ako vec nije tamo te se postavlja taj prazan objekt kao roditelj glavne

kamere Sada kamera ostaje fiksirana na mjestu te se nece ni kretati s likom Kako bi

se krenula kretati mora se dodati nova skripta na taj prazan objekt koji se odsad u pro-

jektu zove Kamera s obzirom na to da zaista i je roditelj glavne kamere Kako bi se u

skripti lakše locirao objekt igraca oznacava ga se u njegovom polju oznaka (engl Tag)

u desnom prozoru Inspector s igrac (engl Player) kao što se može vidjeti na slici 43

zaokruženo plavom bojom

U programskom kodu se želi napraviti varijabla tipa Game Object kako bi se spremilo

igraca kada ga se pronade Unity takoder ima funkciju FindGameObjectWithTag pa

je onda ostatak koda prilicno intuitivan Kada se igrac pronade pomocu njegove oz-

nake Player prilikom svakog osvježavanja poziciji našeg igraca pridružuje se pozicija

kamere kao što je prikazano programskim kodom 42

Programski kod 42 pratiLikacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class pratiLika MonoBehaviour

GameObject igrac

void Start ()

trazi se objekt putem njegove oznake

igrac = GameObjectFindGameObjectWithTag(Player)

15

Slika 43 Oznacavanje lika radi lakšeg pronalaska u skripti

void LateUpdate ()

trenutni objekt mijenja svoju poziciju u skladu s

pozicijom objekta oznacenog oznakom Player

transformposition = igractransformposition

44 Bacanje zraka (engl Ray casting)

Perspektivna kamera u Unityu koristi oblik krnje piramide za dio koji prikazuje u pros-

toru Svaka tocka nekog objekta kojeg kamera prikazuje zapravo odgovara liniji u pros-

toru svijeta te je nama samo jedna tocka duž te linije vidljiva na objektu Sve iza te

tocke na liniji je zamraceno Vanjski rubovi objekta su definirani razilazecim linijama

16

koje odgovaraju kutevima objekta Kada bi se te linije pratile unazad prema kameri

sve bi na kraju konvergirale u jednu tocku U Unityu se ta tocka nalazi tocno na pozi-

ciji kamere i naziva se centrom perspektive Kut naspram linija koje konvergiraju od

gornjeg i donjeg centra ekrana u centru perspektive se zove vidno polje (engl Field Of

View) Sve što pada izvan tih razilazecih linija na rubovima objekta nece biti vidljivo

kameri uz vec prethodno spomenuta ogranicenja ravnina podrezivanja

U igrama je jako korisno imati matematicku reprezentaciju linije koja predstavlja tocku

u pogledu kamere Unity to omogucava u obliku objekta zrake Zraka uvijek odgo-

vara tocki u pogledu pa klasa Kamera (engl Camera) sadrži dvije korisne funkcije

ScreenPointToRay i ViewportPointToRay Razlika izmedu njih je da ScreenPointToRay

ocekuje tocku s koordinatama piksela dok ViewportPointToRay uzima normalizirane

koordinate (od 0 dolje ili lijevo do 1 gore ili desno) Obje funkcije vracaju zraku

koja se sastoji od tocke ishodišta i vektora koji pokazuje smjer linije od tog ishodišta

Zraka izlazi iz ravnine podrezivanja bliže kameri Najcešce se zrake koriste kako bi ih

bacali u scenu Bacanje zraka pošalje imaginarnu liniju uz zraku od njenog ishodišta

dok ne udari u neki sudarac u sceni Tada vraca informaciju o tocki koju je udarila

u objektu RaycastHit To je vrlo korisno kako bi se locirao objekt ovisno o njegovoj

poziciji na zaslonu npr lociranje kursora prikazano programskim kodom 43

Programski kod 43 lociranjeKursoracs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kamera

void Start()

RaycastHit udar

u objekt Ray se sprema pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

ako zraka udara u neki objekt spremi u objektUdaren to

mjesto

if (PhysicsRaycast(zraka out udar))

Transform objektUdaren = udartransform

17

Ponekad je takoder korisno dobiti zraku koja odgovara poziciji na zaslonu te onda

pomicati kameru uz tu zraku Npr želi se dozvoliti igracu da može selektirati objekt

mišem i onda ga povecati dok se objekt nalazi cijelo vrijeme na istoj poziciji na zaslonu

ispod miša prikazano programskim kodom 44 [1]

Programski kod 44 povecavanjeSlikecs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public bool povecavanje

public float brzinaPovecavanja

public Camera kamera

void Update()

ako netko koristi povecavanje slike (engl Zooming)

if (povecavanje)

u objekt Ray sprema se pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(Input

mousePosition)

udaljenost povecavanja ce biti jednaka umnosku

brzine povecavanja vremena i vertikalnog smjera

float udaljenostPovecavanja = brzinaPovecavanja

InputGetAxis(Vertical) TimedeltaTime

pomakni kameru u smjeru kursora misa za udaljenost

povecavanja u koordinatnom sustavu svijeta

kameratransformTranslate(zrakadirection

udaljenostPovecavanja SpaceWorld)

18

5 Kretanje

Pronalazak puta je zapravo pokušaj aplikacije na racunalu ili algoritma da nade naj-

kracu rutu izmedu dvije tocke To je recimo prakticna verzija rješavanja labirinta Ni

danas ne postoji optimalan algoritam koji ce u svakom slucaju u nekom realno krat-

kom vremenu naci najkraci put U ovom poglavlju objasnit ce se koje algoritme Unity

koristi za svoj navigacijski sustav Objašnjavat ce se i neki osnovni koncepti i obrasci

potrebni za ubrzavanje cijele ideje dojavljivanja promjena u sceni Bit ce prikazani i

programski kodovi potrebni za implementiranje kretanja mišem iili tipkovnicom Na

kraju ovog poglavlja želi se imati lika koji ce se slobodno kretati po sceni na mjesto

koje se odredi klikom miša i mogucnost prebacivanja na upravljanje tipkovnicom

51 Navigacijski sustav u Unityu

U Unityu je problem pronalaska puta vec riješen s necim što se zove navigacijska

mreža (engl NavMesh) To je navigacijski sustav koji ima svoje algoritme pronala-

ska puta i puno pojednostavljuje programiranje kretanja lika Sastoji se od cetiri di-

jela NavMesh agent navigacijske mreže (engl NavMesh Agent) izvanmrežna pove-

zanost(engl Off - Mesh Link) i prepreka navigacijske mreže(engl NavMesh Obstacle)

NavMesh je podatkovna struktura koja opisuje površine po kojima se može kretati

u igri i omogucava pronalazak put od jedne lokacije do druge Navigacijski sustav

treba svoje podatke kako bi predstavio prohodna podrucja u sceni Prohodna podru-

cja definiraju se kao mjesta gdje agent može stajati i kretati se Prohodno podrucje se

automatski izgraduje iz geometrije u sceni testirajuci sva podrucja gdje bi agent mo-

gao stajati Onda se te lokacije spajaju s površinom na vrhu geometrije Ta površina se

naziva onda NavMesh te je možemo vidjeti na 51 NavMesh tada sprema tu površinu

kao konveksne poligone te informacije koji su poligoni susjedni Komponenta Nav-

Mesh Agent pomaže pri kreiranju likova koji se medusobno izbjegavaju dok se krecu

prema cilju U Unityu se agenti opisuju kao valjci Koriste NavMesh kako bi se kretali

i znali koje objekte moraju zaobici te kako da se medusobno zaobidu Off-Mesh Link

19

omogucava dodavanje navigacijskih precaca koji se ne mogu predstaviti kao površina

po kojoj se može hodati npr skakanje preko ograde ili otvaranje vrata prije nego što

se ude u neku prostoriju NavMesh Obstacle opisuje prepreke koje se krecu te koje bi

agenti trebali izbjegavati dok hodaju svijetom npr neke bacve koje se kotrljaju prema

igracu Dok se bacva krece agent ce izracunati put oko nje najbolje što može no nakon

što ona naposljetku stane postat ce dio neprohodnog NavMesha te ce se agenti kretati

oko nje [3]

Slika 51 Prikaz navigacijskog sustava u Unityu

52 Pronalazak puta

Dva glavna problema postoje kod pronalaženja puta kako pronaci destinaciju na ni-

vou na kojem se igrac nalazi te kako se onda tamo pomaknuti Pronalaženje destinacije

uzima u obzir cijelu scenu Pomicanje tamo je dinamicnije u obzir uzima samo smjer

kretanja i kako da sprijeci sudaranje s drugim agentima Da bi se pronašao put izmedu

dvije lokacije prvo se moraju oznaciti pocetna i konacna lokacija njihovim najbližim

poligonima Tada se krece tražiti od pocetne lokacije posjecujuci sve susjedne dok se

ne dode do zadane destinacije Onda se prati unatrag vec posjecene poligone kako bi

se našao konacan niz poligona koji vode od pocetka do kraja Algoritam koji Unity

koristi te se cesto koristi za pronalazak puta naziva se A (A zvjezdica) Taj niz po-

ligona koji opisuje put od pocetka do kraja se naziva hodnik Agent ce doci do svoje

20

destinacije tako da se uvijek usmjerava prema sljedecem vidljivom kutu hodnika Ta

logika usmjeravanja uvijek uzima poziciju sljedeceg kuta i ovisno o tome nade željeni

smjer i brzinu potrebnu za dolazak na destinaciju Korištenje brzine po želji progra-

mera bi moglo dovesti do sudara s ostalim agentima Izbjegavanje prepreka takoder

pronalazi svoju novu brzinu koja traži ravnotežu izmedu kretanja prema destinaciji i

sprjecavanja buducih sudara s ostalim agentima i kutevima u navigacijskom sustavu

Nakon usmjeravanja i izbjegavanja prepreka izracuna se konacna brzina Unity ta-

koder uzima u obzir i akceleraciju kako bi simulirao realisticnije kretanje Takoder

treba razumjeti razliku izmedu globalne i lokalne navigacije Globalna navigacija se

koristi za pronalazak hodnika u svijetu Linearna lista poligona koja opisuje taj put je

podatkovna struktura koja se koristi za usmjeravanje te se može lokalno prilagodavati

i mijenjati kako se pozicija agenta mijenja Lokalna navigacija pokušava naci efika-

san nacin kako da se igrac pomakne prema sljedecem kutu bez da se sudari s ostalim

agentima ili objektima koji se krecu [3]

53 Kreiranje navigacijskog sustava

Proces kreiranja NavMesha iz geometrije nivoa se naziva pecenje navigacijske mreže

(engl NavMesh Baking) Skuplja sve terene i mreže objekata koji su oznaceni kao

navigacijski staticko (engl Navigation Static) i onda ih procesira kako bi kreirao navi-

gacijski sustav koji aproksimira prohodne površine nivoa Izgradnja (engl NavMesha)

je vrlo jednostavna Prvo se selektira geometrija koja bi trebala utjecati na navigaciju

tj površine po kojima možemo hodati i prepreke Oznaci se Navigation Static da bi ih

ukljucili u NavMesh Baking proces Prilagode se postavke kako bi odgovarale velicini

agenta - radijus (npr koliko blizu se može doci zidovima) visina (koliko su nisko

prostori koje agent može doseci) maksimalni nagib (koliko su kose rampe po kojima

se agent može uspeti) visina stube(koliko su visoke prepreke na koje agent može za-

koraciti) Onda jednostavno stisnemo ispeci (engl Bake) da izgradimo svoj NavMesh

Izgradeni NavMesh cemo moci vidjeti kao plavu površinu kao na slici 51 te ce se stvo-

riti nova datoteka s nazivom trenutne scene (ako vec ne postoji) i unutra ce se spremiti

kreiran navigacijski sustav [3]

21

54 Programiranje kretanja

Na liku se trenutno nalazi par stvari Animator Capsule Collider i Rigid Body Sada

je cilj isprogramirati mogucnost odredivanja gdje ce se lik kretati klikom miša na to

mjesto Dodaje se nova komponenta na lika NavMesh Agent Ta komponenta za-

pravo vec ima svoj sudarac te se slobodno može obrisati Capsule Collider jer postaje

nepotreban Igranjem s opcijama pomak od baze (engl Base Offset) te pod izbjegava-

nje prepreka (engl Obstacle Avoidance) radijus (engl Radius) i visina (engl Height)

prilagodi se sudarac od (engl NavMesh Agent-a) kako bi se obujmilo njime igraca i

sprijecilo propadanje kroz tlo od prije Sada kada postoji komponenta navigacije mora

se dodati skripta koja ce odrediti kada se lik krece te kada se pokrecu njegove anima-

cije iz Animator-a

Da bi se znalo gdje se miš nalazi mora se takoder dodati nova skriptu na kameru Kako

bi se izracunalo gdje trenutno kursor pokazuje Unity koristi vec prethodno spomenuto

bacanje zraka Da bi se moglo koristiti navigaciju putem klika mišem mora se napisati

skripta za glavnu kameru koja ce omoguciti bacanje zraka Skripta BacanjeZraka

dodaje se na objekt Main Camera koja se dodala pod prazni objekt Kamera Ova

skriptu se takoder koristi za razlikovanje raznih vrsta objekata Naime svaki objekt

kao što ima i Tag ima i sloj (engl Layer) Sloj služi kako bi mogli npr razlikovati

neprijatelje od obicnih objekata ili mjesto na koje želimo doci hodanjem Zato cemo

takoder dodati i jednu enumeraciju koja ce nam zasad služiti samo da razlikujemo je li

mjesto prohodno ili ne te jesmo li kliknuli na neprijatelja Kako bi dodali svoje nove

slojeve za objekte moramo kliknuti na Layer i dodaj sloj (engl Add Layer) kao na slici

52 što nas dovodi do novog prozora prikazanog na slici 53

Programski kod 51 bacanjeZrakacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

sluzi za dodavanje novih slojeva u Unity

public enum Sloj

Prohodno = 8

Neprijatelj = 9

KrajSvijeta = -1

22

Slika 52 Dodavanje novog sloja

public class BacanjeZraka MonoBehaviour

hijerarhija slojeva tj koji ima veci prioritet

public Sloj[] prioritetiSlojeva =

SlojNeprijatelj

SlojProhodno

SlojKrajSvijeta

udaljenost do pozadine je neka izmisljena vrijednost nakon

koje se prestane provjeravati zraka

public float udaljenostDoPozadine = 100f

Camera kamera

RaycastHit _udara

dohvaca varijable ove klase

public RaycastHit udara

get return _udara

Sloj _udaraSloj

23

Slika 53 Prozor za dodavanje novog sloja

public Sloj udaraSloj

get return _udaraSloj

deklariraj novi tip delegata

public delegate void priPromjeniSloja(Sloj noviSloj)

instanciraj skup promatraca

public event priPromjeniSloja promatraciPromjeneSloja

void Start ()

dohvat glavne kamere

kamera = Cameramain

void Update ()

nadi sloj po prioritetu u koji zraka udara

foreach(Sloj sloj in prioritetiSlojeva)

provjeravamo udara li zraka u neki od slojeva

24

var udar = BacanjeZrakaZaSloj(sloj)

if(udarHasValue)

_udara = udarValue

ako se sloj promjenio

if(_udaraSloj = sloj)

spremi novi sloj u varijablu trenutnog sloja

_udaraSloj = sloj

obavijesti promatrace da se sloj promjenio

promatraciPromjeneSloja(sloj)

spremi novi sloj u varijablu trenutnog sloja

ali ne moras obavjestavati promatrace jer je

sloj jednak starom sloju

_udaraSloj = sloj

return

inace vrati da zraka udara u pozadinu i obavijesti

promatrace

_udaradistance = udaljenostDoPozadine

_udaraSloj = SlojKrajSvijeta

promatraciPromjeneSloja(udaraSloj)

RaycastHit BacanjeZrakaZaSloj(Sloj sloj)

kreira se maska za slojeve bit se pomice ulijevo za

onoliko mjesta koliki je redni broj prioriteta sloja

int maska = 1 ltlt (int)sloj

sprema se mjesto pozicije kursora pretvoreno iz tocke u

zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

RaycastHit udar

PhysicsRaycast sprema zraku u varijablu tipa

RaycastHit prima jos i maksimalnu udaljenost za koju

provjerava zraku i masku sloja i potom vraca istinu (

engl True) ili laz (engl False) ako je zraka udarila

u sloj

25

bool udarioJe = PhysicsRaycast(zraka out udar

udaljenostDoPozadine maska)

ako zraka udara u sloj vrati vrijednost udarca

if(udarioJe)

return udar

return null

U programskom kodu 51 se koristi funkcija za primjenu obrasca promatraca pod

nazivom delegat (engl Delegate) Što je obrazac promatraca (engl Observer) To je

oblikovni obrazac koji se u programiranju koristi

bull kad promjena jednog objekta zahtijeva promjene u drugim objektima koji nisu

unaprijed poznati

bull kad objekt treba obavještavati druge objekte

bull uz uvjet da bude što neovisniji o njima

bull kad je potrebno prikazivati razlicite aspekte nekog dinamickog stanja a želimo

izbjeci ciklicku ovisnost izmedu stanja i pogleda

bull kad postoje dva koncepta jedan ovisan o drugome a zgodno ih je razdvojiti

S obzirom na to da mi samo pri promjeni sloja želimo obavještavati pretplacene pro-

matrace uvodenje delegata nam dosta ubrzava kod Obrazac promatraca funkcionira

tako da glavni objekt igra ulogu izdavaca (izvora informacija) u ovom slucaju to je

glavna kamera Ostali ovisni objekti (promatraci) pretplacuju se kod izdavaca te iz-

davaci obavještavaju pretplatnike o promjenama Promatraci prekidaju pretplatu kad

više ne trebaju obavještavanje Funkcija priPromjeniSloja se definira kao delegat i u

ovom slucaju prima sloj Nakon toga se definira dogadaj (engl Event) tipa tog delegata

(priPromjeniSloja) u ovom slucaju naziva promatraciPromjeneSloja i odsad se unutar

subjekta tim nazivom i poziva Kako bi se neki promatrac pretplatio na informacije

koje izdaje kamera dodaje ove dvije linije koda u svoju skriptu

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

Programski kod 52 služi za kretanje korištenjem NavMesha i lijevog klika miša

26

Programski kod 52 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

public float dovoljnoBlizu = 01f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora

[SerializeField] float hodajKreciStaniRadijus = 02f

void Start ()

pronadi igraca koji je tipa agenta navigacijskog sustava

(engl NavMeshAgent)

agent = GetComponentltUnityEngineAINavMeshAgentgt()

pronadi prethodno napisanu klasu BacanjeZraka

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

spremi trenutnu poziciju kursora

trenutnaPozicijaKursora = transformposition

void Update()

ako je igrac dosao na zeljeno mjesto zaustavi animaciju

hodanja

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

ako je stisnut lijevi klik misa

if (InputGetMouseButtonDown(0))

ovisno o sloju primjeni akciju

switch(bacanjeZrakaudaraSloj)

ako se po objektu na koji je igrac kliknuo moze

hodati

27

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 3: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

Zahvala Nikoli Vuckovicu zbog velike pomoci sa izradom blend modela

iii

SADRŽAJ

1 Uvod 1

2 Postavljanje pocetne scene 221 Instalacija 2

22 Kreiranje prve scene 2

23 Razvojna okolina Unity 3

24 Konzola 4

25 Programski jezik 4

3 Unos glavnog lika u scenu 731 Skaliranje 7

32 Kreiranje osnovnih objekata 7

33 Unos Blender modela u Unity i pocetni problemi 8

4 Kamera 1241 Perspektivna i ortografska kamera 12

42 Pogled iz prvog lica u pogled iznad glave 13

43 Fiksirana kamera 15

44 Bacanje zraka (engl Ray casting) 16

5 Kretanje 1951 Navigacijski sustav u Unityu 19

52 Pronalazak puta 20

53 Kreiranje navigacijskog sustava 21

54 Programiranje kretanja 22

6 Korisnicko sucelje 3561 Platno 35

62 Osnovne komponente 36

iv

63 Korisnicko sucelje igraca 37

64 Korisnicko sucelje neprijatelja 38

7 Teren 4271 Kreiranje i uredivanje terena 42

72 Visinske mape 42

73 Teksture za teren 44

8 Zakljucak 46

9 Zasluge 47

Literatura 48

v

1 Uvod

Korištenje Unity razvojne okoline eksponencijalno raste zadnjih par godina Razlog

tomu vjerojatno leži u njegovoj jednostavnosti i poslovnom modelu koji omogucava

besplatno korištenje Unity 5 osobne licence za edukacijske svrhe te za tvrtke s priho-

dima manjim od 100000$ Ono što Unity je i ono što promovira je pojednostavljivanje

svih komponenata potrebnih za razvoj igre No takoder pruža svu slobodu programeru

da dodatno razvije i poboljša njihov sustav u obliku koji njemu najviše odgovara Rad

s animacijama teksturama i modelima je vrlo jednostavan i ne zahtijeva nikakvo zna-

nje programera o njihovom razvoju ili ucitavanju kako bi mogli raditi s njima Tako-

der postoje vec mnogi primjeri programskog koda ponudeni na službenim stranicama

Unitya za dizajnere koji nisu iskusni u programiranju Programski kodovi su odlicno

opisani i rješavaju u par linija teške probleme poput navigacije kamere osvjetljenja

itd Cilj ovog rada je pokazati kako se lako mogu savladati osnove rada u Unityu i

kako iskoristiti naše programersko predznanje dobiveno s dosadašnjim studiranjem za

dodatno poboljšavanje svega što Unity nudi te i za lakše razumijevanje kako vec im-

plementirani algoritmi Unitya funkcioniraju Svako poglavlje predstavlja svojevrsni

zadatak za cije se rješavanje nude razna rješenja i objašnjenje potrebne teorije te na

kraju i opis rješenja koje je iskorišteno u ovom projektu

1

2 Postavljanje pocetne scene

U ovom poglavlju je predstavljena instalacija razvojne okoline Unity te kreiranje po-

cetnog projekta u kojem ce se do kraja ovog rada izradivati zamišljena igra Upoznaje

se s radom konzole i odlucuje se koji programski jezik ce biti korišten Opisuje se i

objašnjava rad u razlicitim prozorima razvojne okoline te snalaženje u samoj sceni ra-

zvoja igre Nakon kraja ovog poglavlja želi se imati instaliran Unity i pokrenut prazan

projekt

21 Instalacija

Kao što je vec navedeno Unity je besplatan za korištenje za privatne edukacijske te

opcenito bilo kakve nekomercijalne svrhe Razvojni alat se može skinuti i instalirati sa

službene stranice Instalacija je prilicno jednostavna te ima detaljna uputstva koja se

mogu slijediti Verzija korištena tijekom ostatka ovog rada je Unity 56 Za kodiranje

skripti korišten je Microsoft Visual Studio 2017 Naravno može se koristiti i Mono

Develop koji dolazi skupa s instalacijom Unitya

22 Kreiranje prve scene

Nakon instalacije Unitya kreira se novi projekt kao što se vidi na slici 21 Odabere

se ime projekta te mjesto na disku gdje ce se spremiti Nakon kreiranja projekta otvara

se klasicna pocetna scena koja se sastoji od glavne kamere te usmjerenog svijetla koji

su oznaceni brojem 1 na slici 22 Brojem 2 na slici 22 je oznacen prozor projekt

(engl Project) gdje ce se nalaziti sve skripte objekti materijali i sl koje cemo kreirati

kroz izradu projekta Sve te komponente se zapravo spremaju na disku ovisno o tome

gdje je Unity instaliran i gdje je postavljeno spremanje projekata Npr za ovaj projekt

je korišteno DUnity ProjectsAlice Prazni projekt spremamo koristeci postupak

datoteka (engl File) -gt spremi scenu kao (engl Save Scene As) kako bi se kreirala

prva scena u Unityu Odabire se proizvoljno ime te se klikne spremi (engl Save)

2

Slika 21 Kreiranje projekta

23 Razvojna okolina Unity

Na slici 22 može se vidjeti ovaj projekt u nekoj kasnijoj fazi rada Koristi se ova slika

za lakše objašnjavanje dijelova razvojne okoline Unity Razlikuju se dva pogleda

pogled scene i pogled igre koji se vide i na slici 22 pod brojem 3 U pogledu scene

ureduje se scena igre dodaju se objekti skripte te sve ostalo što je potrebno Nakon

prebacivanja u pogled igre može se igrati dosad izradena verziju igre to je ono što ce

igrac zapravo vidjeti Na samom vrhu slike 22 oznaceno brojem 4 vidimo tri gumba

kao na slici 23 igraj (engl Play) pauziraj (engl Pause) i korak (engl Step) Ti

gumbi prebacuju pogled u pogled igre Sve promjene koje se naprave nad objektima

u pogledu igre su privremeni te ce se vratiti na staro kada se izade iz tog pogleda

Pritisak na gumb Play automatski prebacuje na prozor igra (engl Game) iz prozora

scena (engl Scene) ciji se nazivi mogu vidjeti ispod tih gumba

Dalje postoje gumbi oznaceni brojem 5 na slici 22 koji pomažu s kretanjem oko scene

i manipulacijom objekata u sceni koji su prikazani na slici 24 Prvi gumb sa slikom

ruke omogucava pomicanje po sceni dok drugi gumb omogucava pomicanje objekata

po sceni Treci gumb služi za rotaciju objekata cetvrti za skaliranje i peti služi za

korisnicko sucelje

3

Slika 22 Razvojna okolina Unity

Slika 23 Gumbi Pokreni Pauziraj i Korak

24 Konzola

Konzola u Unityu vecinom služi za pomoc pri traženju greški u programskom kodu

Može se vidjeti na slici 22 u donjem dijelu Unitya u obliku kartice pored kartice

Project Ako se ne nalazi tamo mora se dodati odlaskom na prozori (engl Windows)-

gt konzola (engl Console) Pritiskom na nju primjecuje se da je skroz prazna i da

imamo još par kartica ocisti (engl Clear) sruši (engl Collapse) ocisti pri pokretanju

(engl Clear On Play) i pri grešci pauziraj (engl Error Pause) Clear služi za cišce-

nje dosad ispisanih poruka Obicno se oznacava Clear On Play da uvijek ocisti stare

poruke te da svaki put kad se pokrene igra dobiju nove Collapse pomaže ako postoji

puno istih poruka npr je korištena while petlja i ceka se neka promjenu u sceni Nije

potrebno da se ispisuje poruka Cekam cijelo vrijeme dok se ceka nego samo jednom

25 Programski jezik

Unity podržava C i Javascript programske jezike te je kroz projekt korišten samo C

Pretpostavlja se da je citatelj upoznat barem sa sintaksom C-a te osnovama objektno

4

Slika 24 Alati za transformaciju

orijentiranog programiranja Nije potrebno veliko znanje C-a kako bi se kodiralo u

Unityu potrebno je samo razumjeti kako se radi s objektima te poznavati sintaksu C-

a zbog rada s razlicitim vrstama varijabli (za razliku od Python-a gdje nije potrebno

specificirati je li varijabla cijeli broj decimalni broj itd) Unutar prozora oznacenim

brojem 2 na slici 22 stisne se desni klik i odabere kreiraj (engl Create) i C skripta

(engl C Script) da se doda nova skripta Duplim klikom na novo-kreiranu skriptu

otvara se Microsoft Visual Studio ili neka druga razvojna okolina koja podržava C u

kojem se sad može pisati programski kod Programski kod 21 je primjer ispisivanja

jednostavne poruke u konzoli

Programski kod 21 HelloWorld1cs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class HelloWorld MonoBehaviour

koristi se za inicijalizaciju

void Start ()

print(Hello World)

Update se zove svaki okvir (engl Frame)

void Update ()

Sada kada se pritisne na gumb Play sa slike 23 može se vidjeti ispis u konzoli Hello

world Još jedan nacin ispisivanja u konzolu je prikazan programskim kodom 22

Programski kod 22 HelloWorld2cs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

5

public class HelloWorld MonoBehaviour

koristi se za inicijalizaciju

void Start ()

DebugLog(Hello world)

Update se zove svaki okvir (engl Frame)

void Update ()

Ne postoji nikakva bitne razlika izmedu ta dva nacina pa se koristi bilo koji

6

3 Unos glavnog lika u scenu

U ovom poglavlju opisuju se neki pocetni problemi s kojima se susrece pri ubacivanju

modela iz popularnog programa za modeliranje Blender Objašnjavaju se i modeli koji

su ponudeni unutar samog Unitya poput kocke i neke osnovne njihove transformacije

Nakon kraja ovog poglavlja želi se imati svojevrsno tlo i ubaceni glavni lik skupa s

njegovim teksturama i animacijama iz Blender-a koji nece propadati kroz tlo

31 Skaliranje

Jedno od osnovnih stvari o kojima se razmišlja prilikom kreiranja igre je koja ce se

brojcana skala koristiti Unity ima svoje mjerne jedinice koji predstavljaju metre u

njegovom fizickom sustavu Ovisno o tipu igre koja se kreira mora se paziti na skali-

ranje Izraduje li se neka igru u svemiru nece se koristiti naše realne mjerne jedinice

nego ce ih se naravno skalirati U ovom slucaju kreira se RPG (Role-playing game)

igra gdje nam je glavni lik covjek te ce se koristiti normalne Unity mjerne jedinice bez

skaliranja

32 Kreiranje osnovnih objekata

Za pocetak potrebno je kreirati jednostavno tlo Kocka se kreira s objekt igre (engl Ga-

meObject) -gt 3D objekt (engl 3D Object) -gt kocka (engl Cube) te se dobiva rezultat

kao na slici 31 Zasad se kocka skalira po x i z osi sa 100 Tlo je uobicajeno zelene

boje pa mu se dodaje novi materijal Pritisne se u prozor imovina (engl Asset) desnim

klikom miša i odabere se kreiraj (engl Create) -gt materijal (engl Material) kao što se

može vidjeti na slici 32 Klikom na novo-stvoreni materijal desno se pojavljuje novi

prozor Inspektor (engl Inspector) gdje se može odabrati boja Nakon toga samo se

povuce lijevim klikom miša materijal na skaliranu kocku tj tlo S obzirom na to

kako se želi da ta skalirana kocka glumi tlo želi se takoder da se i ostali objekti nalaze

7

Slika 31 Kreiranje tla

na njoj Zato ce se tlo morati pomaknuti po y osi za -05 kako bi se olakšalo daljnje

dodavanje objekata

33 Unos Blender modela u Unity i pocetni problemi

Krece se s ubacivanjem svog lika u igru Lik koji se koristi kroz ostatak ovog rada na-

pravljen je u programu Blender koji služi za 3D modeliranje blend objekt se može

samo povuci mišem u Unity iz datoteke u kojoj se nalazi

1 problem Kada se blend datoteka ubacuje u Unity on nece automatski ubaciti i

teksture koje su korištene u izradi tog modela Najlakši nacin bi bio izrada nove dato-

teku unutar Assets datoteke u Unityu i ubacivanje i blend modela i teksture koja je bila

korištena u izradi u tu novu datoteku Nakon toga klikom na model unutar prozora In-

spector pod Materials odabire se opcija od modelovih materijala (engl From Modelrsquos

Material) kao na slici33 kako bi Unity ucitavao korištene teksture Ponekad na žalost

ni to ne funkcionira pa ce se ovdje objasniti još jedan malo opcenitiji pristup Pri unosu

blend modela Unity kreira novu datoteku i nazove ju materijali (engl Materals) Ako

se dogodi da se korištene teksture na modelu ne vide treba se pogledati u tu datoteku

U njoj ce se nalaziti prazni materijali s istim imenima korištenih tekstura kao npr u

slucaju ovog projekta drvo (engl Wood) Tada se mora odabrati u desnom prozoru

materijala albedo (engl Albedo) kao na slici 34 i u ponudenim Assets naci teksturu

koja je korištena (u ovom slucaju Wood)

8

Slika 32 Kreiranje materijala

2 problem Sada kada je lik pozicioniran u ishodištu (x = 0 y = 0 z = 0) može se

dogoditi da se ne nalazi tocno na tlu koje je kreirano To dakako ovisi o modeliranju

koordinatama koje su korištene i skaliranju pri izradi modela Lik korišten u ovom

radu mora se pomaknuti na koordinatu x = 0 y = 15 z = 0 kako bi stajao tocno na tlu

3 problem Kada bi se igra sad pokrenula pritiskom na gumb Play pri vrhu Unitya

lik bi propao kroz tlo Zašto se to dogada Zbog necega što se zove sudarac (engl Col-

lider) u Unityu koji ce kasnije biti pomnije objašnjen Za sada se samo žele postaviti

neke pocetne stvari kako bi bilo lakše testirati osnovnu interakciju lika i objekata u

prostoru U desnom prozoru Inspector kada je lik oznacen vidi se opcija dodaj kom-

ponentu (engl Add Component) Stisne se na to i upiše sudarac u obliku kapsule

(engl Capsule Collider) kako bi se dodao novi sudarac To je zapravo samo sudarac

9

Slika 33 Unos blend modela u scenu

koji je u obliku kapsule te se igrajuci nekim njegovim osnovnim opcijama može na-

mjestiti vanjski oblik lika Dodaje se još jedna komponenta nad likom Ponovno se

stisne na Add Component te upiše kruto tijelo (engl Rigid Body) što ce takoder biti

naknadno objašnjeno Zasad je bitno razumijevanje da to omogucava liku da se ponaša

kao kruto tijelo u prostoru

4 problem Sada bi kada se igra pokrene trebao postojati lik koji ne propada kroz tlo

Naravno kao najosnovniju mehaniku želi se mogucnost kretanja po tom tlu Skripta

koja se treba napraviti kako bi se lik kretao po tlu nije zapravo komplicirana Sastoji

se samo od toga da se prilikom pritiska na odredeno slovo tipkovnice objekt translatira

po prostoru No ovaj model takoder sadrži i animacije za hodanje te se želi i to ukom-

ponirati Zato ce se takoder sada spomenuti još jedna nova komponenta kontrolor

animacija (engl Animator Controller) Dodaje se i ta komponenta na lika i prebacuje

se na prozor animator (engl Animator) koji se vidi na slici 35

U ovom prozoru postoji par novih opcija Mogu se dodavati nova stanja u kojima

ce se lik naci ovisno o nekim uvjetima koji se zadaju Pocetno stanje je ulazno stanje

(engl Entry State) i iz njega se želi da se lik nade u stanju mirovanja Stisne se desni

klik miša i odabere se novo stanje (engl New State) U ovom projektu je nazvano

Mirovanje Iz mirovanja ovisno o tome kada osoba pritisne neku tipku tipkovnice

želi se da se lik krene kretati Zato treba dodati novo stanje Hodanje Doda se

novo stanje istim postupkom kao i prvo Sada se naravno moraju dodati i usmjereni

prijelazi Stisne se desni klik miša na Mirovanje i odabere dodaj prijelaz (engl Add

10

Slika 34 Traženje tekstura Vašeg blend modela

Slika 35 Animator

Transition) To je sada kreiralo usmjerenu strelicu koja se može povuci prema Ho-

danje Isto to se napravi i u suprotnom smjeru Desni klik miša na Hodanje Add

Transition i povuce se strelica prema Mirovanje Naravno moraju se dodati uvjeti

koji ce odredivati kada ce objekt prijeci iz jednog stanja u drugo U ovom slucaju je

korišten cijeli broj (engl Integer) Ostatak problema kretanja rješavat ce se u poglavlju

4 Bacanje zraka i kretanje po mapi s mišem

11

4 Kamera

U ovom poglavlju se postavlja i bira prava kamera za igru Tijekom izrade igre treba se

takoder razmišljati i iz kojeg kuta ce se imati pogled na nju te hoce li se kamera pomi-

cati s kretanjem lika hoce li se moci rotirati itd Pri kreiranju 3D igre u pogledu scene

primjecuje se da su svi objekti i transformacije u 3D-prostoru No s obzirom na to da je

zaslon monitora igraca 2-dimenzionalan te se ne može prikazati tijela kao takva mora

se moci prikazati sve te objekte u jednoj ravnini i zadržati dojam 3-dimenzionalnosti

To se u Unityu postiže s kamerom Kamera je objekt koja definira pogled i njegov

smjer u prostoru scene Pozicija kamere definira ocište z os definira smjer gledanja

(gledište) te y os definira vrh ekrana Kamera takoder definira velicinu i oblik dijela

koji možemo vidjeti Kamera nam pokazuje ono što ona vidi Kako se ona rotira

translatira itd prikaz scene ce se takoder jednako transformirati Nakon kraja ovog

poglavlja želi se imati kamera koja ce pratiti kretnje lika i imati pogled na njega odoz-

gora

41 Perspektivna i ortografska kamera

Kamerom se zapravo objekte 3D prostora projicira na ravninu u 2D prostor Projek-

cije su matematicki modeli koji govore na koji nacin treba tocke 3D prostora preslikati

u ravninu u tocke 2D prostora Postoji više vrsta projekcija no Unity koristi dvije or-

tografsku projekciju i perspektivnu projekciju Kod ortografskih projekcija kamera je

okomita na ravninu projekcije dok je perspektivna projekcija bliža našem nacinu gle-

danja objekata Možda je najlakše primijetiti razliku koristeci slike Dakle na slici 41

možemo vidjeti blend model koji je modeliran u Blenderu u ortografskoj projekciji te

na slici 42 isti taj model pod istim kutem samo prebacen u perspektivnu projekciju

[6]

Perspektivna projekcija uvodi dvije tocke ocište i gledište Ocište je tocka u ko-

joj se nalazi promatrac Gledište odreduje smjer prema kojem promatrac gleda U

12

Slika 41 Ortografska projekcija blend modela

tocki gledišta stvara se ravnina projekcije koja je okomita na spojnicu ocište-gledište

[6] I perspektivna i ortografska kamera imaju granicu do koje mogu vidjeti od svoje

trenutne pozicije Ona je definirana upravo tom ravninom projekcije Tocka gledišta

pripada toj ravnini i ona tipicno postaje ishodište lokalnog dvodimenzijskog koordi-

natnog sustava koji razapinjemo u ravnini projekcije Ta ravnina se još naziva i daleka

ravnina podrezivanja zato što svi objekti koji se nalaze na vecoj udaljenosti od nje se

odrežu te ih kamera ne prikazuje Takoder postoji i ravnina podrezivanja blizu ka-

meri [1] Dio koji se prikazuje se nalazi izmedu te dvije ravnine

42 Pogled iz prvog lica u pogled iznad glave

U igrama se cesto koristi prebacivanje iz jednog u drugi pogled kamere Kako se

to postiže Koristeci veci broj kamera U ovom slucaju obradit ce se samo kratki

primjer kako se prebacivati iz pogleda prvog lica u pogled iznad glave U unity-u je

zadano da jedna kamera pokriva cijeli ekran te se zato samo pogled jedne kamere može

vidjeti u jednom trenutku Kamera koju vidimo je ona koja ima najvecu vrijednost

za svoje svojstvo dubine[1] Zato se želi napraviti skripta koja ce se prebacivati s

jedne kamere na drugu da bi se dobili drukciji pogledi na scenu koja je prikazana

programskim kodom 41

Programski kod 41 PrimjerViseKameracs

13

Slika 42 Perspektivna projekcija blend modela

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kameraPrvogLica

public Camera kameraIznadGlave

funkcija koja se poziva kada se prebacujemo u pogled iznad

glave

public void prikaziPogledIznadGlave()

kameraPrvogLicaenabled = false gasimo kameru prvog

lica

kameraIznadGlaveenabled = true palimo kameru iznad

glave

funkcija koja se poziva kada se prebacujemo u pogled iz

prvog lica

public void prikaziPogledIzPrvogLica()

kameraPrvogLicaenabled = true palimo kameru prvog

lica

overheadCameraenabled = false gasimo kameru iznad

glave

14

43 Fiksirana kamera

U sceni projekta vec postoji glavna kamera (engl Main Camera) koju Unity automat-

ski dodaje u scenu Kako bi ta kamera pratila lika može se samo povuci u lijevom

prozoru hijerarhije u hijerarhiju lika kako bi postala njegovo dijete Tako ce se postici

da kamera stalno prati njegove transformacije (translaciju rotaciju) prilikom pokreta-

nja igre No kako bi se postiglo da kamera ostane uvijek fiksirana te se samo krece s

njime umjesto da se kamera rotira skupa s likom dodaje se novi prazni objekt sa Game

Object -gt kreiraj prazan (engl Create Empty) Njegova pozicija se postavlja na x =

0 y = 0 z = 0 ako vec nije tamo te se postavlja taj prazan objekt kao roditelj glavne

kamere Sada kamera ostaje fiksirana na mjestu te se nece ni kretati s likom Kako bi

se krenula kretati mora se dodati nova skripta na taj prazan objekt koji se odsad u pro-

jektu zove Kamera s obzirom na to da zaista i je roditelj glavne kamere Kako bi se u

skripti lakše locirao objekt igraca oznacava ga se u njegovom polju oznaka (engl Tag)

u desnom prozoru Inspector s igrac (engl Player) kao što se može vidjeti na slici 43

zaokruženo plavom bojom

U programskom kodu se želi napraviti varijabla tipa Game Object kako bi se spremilo

igraca kada ga se pronade Unity takoder ima funkciju FindGameObjectWithTag pa

je onda ostatak koda prilicno intuitivan Kada se igrac pronade pomocu njegove oz-

nake Player prilikom svakog osvježavanja poziciji našeg igraca pridružuje se pozicija

kamere kao što je prikazano programskim kodom 42

Programski kod 42 pratiLikacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class pratiLika MonoBehaviour

GameObject igrac

void Start ()

trazi se objekt putem njegove oznake

igrac = GameObjectFindGameObjectWithTag(Player)

15

Slika 43 Oznacavanje lika radi lakšeg pronalaska u skripti

void LateUpdate ()

trenutni objekt mijenja svoju poziciju u skladu s

pozicijom objekta oznacenog oznakom Player

transformposition = igractransformposition

44 Bacanje zraka (engl Ray casting)

Perspektivna kamera u Unityu koristi oblik krnje piramide za dio koji prikazuje u pros-

toru Svaka tocka nekog objekta kojeg kamera prikazuje zapravo odgovara liniji u pros-

toru svijeta te je nama samo jedna tocka duž te linije vidljiva na objektu Sve iza te

tocke na liniji je zamraceno Vanjski rubovi objekta su definirani razilazecim linijama

16

koje odgovaraju kutevima objekta Kada bi se te linije pratile unazad prema kameri

sve bi na kraju konvergirale u jednu tocku U Unityu se ta tocka nalazi tocno na pozi-

ciji kamere i naziva se centrom perspektive Kut naspram linija koje konvergiraju od

gornjeg i donjeg centra ekrana u centru perspektive se zove vidno polje (engl Field Of

View) Sve što pada izvan tih razilazecih linija na rubovima objekta nece biti vidljivo

kameri uz vec prethodno spomenuta ogranicenja ravnina podrezivanja

U igrama je jako korisno imati matematicku reprezentaciju linije koja predstavlja tocku

u pogledu kamere Unity to omogucava u obliku objekta zrake Zraka uvijek odgo-

vara tocki u pogledu pa klasa Kamera (engl Camera) sadrži dvije korisne funkcije

ScreenPointToRay i ViewportPointToRay Razlika izmedu njih je da ScreenPointToRay

ocekuje tocku s koordinatama piksela dok ViewportPointToRay uzima normalizirane

koordinate (od 0 dolje ili lijevo do 1 gore ili desno) Obje funkcije vracaju zraku

koja se sastoji od tocke ishodišta i vektora koji pokazuje smjer linije od tog ishodišta

Zraka izlazi iz ravnine podrezivanja bliže kameri Najcešce se zrake koriste kako bi ih

bacali u scenu Bacanje zraka pošalje imaginarnu liniju uz zraku od njenog ishodišta

dok ne udari u neki sudarac u sceni Tada vraca informaciju o tocki koju je udarila

u objektu RaycastHit To je vrlo korisno kako bi se locirao objekt ovisno o njegovoj

poziciji na zaslonu npr lociranje kursora prikazano programskim kodom 43

Programski kod 43 lociranjeKursoracs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kamera

void Start()

RaycastHit udar

u objekt Ray se sprema pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

ako zraka udara u neki objekt spremi u objektUdaren to

mjesto

if (PhysicsRaycast(zraka out udar))

Transform objektUdaren = udartransform

17

Ponekad je takoder korisno dobiti zraku koja odgovara poziciji na zaslonu te onda

pomicati kameru uz tu zraku Npr želi se dozvoliti igracu da može selektirati objekt

mišem i onda ga povecati dok se objekt nalazi cijelo vrijeme na istoj poziciji na zaslonu

ispod miša prikazano programskim kodom 44 [1]

Programski kod 44 povecavanjeSlikecs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public bool povecavanje

public float brzinaPovecavanja

public Camera kamera

void Update()

ako netko koristi povecavanje slike (engl Zooming)

if (povecavanje)

u objekt Ray sprema se pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(Input

mousePosition)

udaljenost povecavanja ce biti jednaka umnosku

brzine povecavanja vremena i vertikalnog smjera

float udaljenostPovecavanja = brzinaPovecavanja

InputGetAxis(Vertical) TimedeltaTime

pomakni kameru u smjeru kursora misa za udaljenost

povecavanja u koordinatnom sustavu svijeta

kameratransformTranslate(zrakadirection

udaljenostPovecavanja SpaceWorld)

18

5 Kretanje

Pronalazak puta je zapravo pokušaj aplikacije na racunalu ili algoritma da nade naj-

kracu rutu izmedu dvije tocke To je recimo prakticna verzija rješavanja labirinta Ni

danas ne postoji optimalan algoritam koji ce u svakom slucaju u nekom realno krat-

kom vremenu naci najkraci put U ovom poglavlju objasnit ce se koje algoritme Unity

koristi za svoj navigacijski sustav Objašnjavat ce se i neki osnovni koncepti i obrasci

potrebni za ubrzavanje cijele ideje dojavljivanja promjena u sceni Bit ce prikazani i

programski kodovi potrebni za implementiranje kretanja mišem iili tipkovnicom Na

kraju ovog poglavlja želi se imati lika koji ce se slobodno kretati po sceni na mjesto

koje se odredi klikom miša i mogucnost prebacivanja na upravljanje tipkovnicom

51 Navigacijski sustav u Unityu

U Unityu je problem pronalaska puta vec riješen s necim što se zove navigacijska

mreža (engl NavMesh) To je navigacijski sustav koji ima svoje algoritme pronala-

ska puta i puno pojednostavljuje programiranje kretanja lika Sastoji se od cetiri di-

jela NavMesh agent navigacijske mreže (engl NavMesh Agent) izvanmrežna pove-

zanost(engl Off - Mesh Link) i prepreka navigacijske mreže(engl NavMesh Obstacle)

NavMesh je podatkovna struktura koja opisuje površine po kojima se može kretati

u igri i omogucava pronalazak put od jedne lokacije do druge Navigacijski sustav

treba svoje podatke kako bi predstavio prohodna podrucja u sceni Prohodna podru-

cja definiraju se kao mjesta gdje agent može stajati i kretati se Prohodno podrucje se

automatski izgraduje iz geometrije u sceni testirajuci sva podrucja gdje bi agent mo-

gao stajati Onda se te lokacije spajaju s površinom na vrhu geometrije Ta površina se

naziva onda NavMesh te je možemo vidjeti na 51 NavMesh tada sprema tu površinu

kao konveksne poligone te informacije koji su poligoni susjedni Komponenta Nav-

Mesh Agent pomaže pri kreiranju likova koji se medusobno izbjegavaju dok se krecu

prema cilju U Unityu se agenti opisuju kao valjci Koriste NavMesh kako bi se kretali

i znali koje objekte moraju zaobici te kako da se medusobno zaobidu Off-Mesh Link

19

omogucava dodavanje navigacijskih precaca koji se ne mogu predstaviti kao površina

po kojoj se može hodati npr skakanje preko ograde ili otvaranje vrata prije nego što

se ude u neku prostoriju NavMesh Obstacle opisuje prepreke koje se krecu te koje bi

agenti trebali izbjegavati dok hodaju svijetom npr neke bacve koje se kotrljaju prema

igracu Dok se bacva krece agent ce izracunati put oko nje najbolje što može no nakon

što ona naposljetku stane postat ce dio neprohodnog NavMesha te ce se agenti kretati

oko nje [3]

Slika 51 Prikaz navigacijskog sustava u Unityu

52 Pronalazak puta

Dva glavna problema postoje kod pronalaženja puta kako pronaci destinaciju na ni-

vou na kojem se igrac nalazi te kako se onda tamo pomaknuti Pronalaženje destinacije

uzima u obzir cijelu scenu Pomicanje tamo je dinamicnije u obzir uzima samo smjer

kretanja i kako da sprijeci sudaranje s drugim agentima Da bi se pronašao put izmedu

dvije lokacije prvo se moraju oznaciti pocetna i konacna lokacija njihovim najbližim

poligonima Tada se krece tražiti od pocetne lokacije posjecujuci sve susjedne dok se

ne dode do zadane destinacije Onda se prati unatrag vec posjecene poligone kako bi

se našao konacan niz poligona koji vode od pocetka do kraja Algoritam koji Unity

koristi te se cesto koristi za pronalazak puta naziva se A (A zvjezdica) Taj niz po-

ligona koji opisuje put od pocetka do kraja se naziva hodnik Agent ce doci do svoje

20

destinacije tako da se uvijek usmjerava prema sljedecem vidljivom kutu hodnika Ta

logika usmjeravanja uvijek uzima poziciju sljedeceg kuta i ovisno o tome nade željeni

smjer i brzinu potrebnu za dolazak na destinaciju Korištenje brzine po želji progra-

mera bi moglo dovesti do sudara s ostalim agentima Izbjegavanje prepreka takoder

pronalazi svoju novu brzinu koja traži ravnotežu izmedu kretanja prema destinaciji i

sprjecavanja buducih sudara s ostalim agentima i kutevima u navigacijskom sustavu

Nakon usmjeravanja i izbjegavanja prepreka izracuna se konacna brzina Unity ta-

koder uzima u obzir i akceleraciju kako bi simulirao realisticnije kretanje Takoder

treba razumjeti razliku izmedu globalne i lokalne navigacije Globalna navigacija se

koristi za pronalazak hodnika u svijetu Linearna lista poligona koja opisuje taj put je

podatkovna struktura koja se koristi za usmjeravanje te se može lokalno prilagodavati

i mijenjati kako se pozicija agenta mijenja Lokalna navigacija pokušava naci efika-

san nacin kako da se igrac pomakne prema sljedecem kutu bez da se sudari s ostalim

agentima ili objektima koji se krecu [3]

53 Kreiranje navigacijskog sustava

Proces kreiranja NavMesha iz geometrije nivoa se naziva pecenje navigacijske mreže

(engl NavMesh Baking) Skuplja sve terene i mreže objekata koji su oznaceni kao

navigacijski staticko (engl Navigation Static) i onda ih procesira kako bi kreirao navi-

gacijski sustav koji aproksimira prohodne površine nivoa Izgradnja (engl NavMesha)

je vrlo jednostavna Prvo se selektira geometrija koja bi trebala utjecati na navigaciju

tj površine po kojima možemo hodati i prepreke Oznaci se Navigation Static da bi ih

ukljucili u NavMesh Baking proces Prilagode se postavke kako bi odgovarale velicini

agenta - radijus (npr koliko blizu se može doci zidovima) visina (koliko su nisko

prostori koje agent može doseci) maksimalni nagib (koliko su kose rampe po kojima

se agent može uspeti) visina stube(koliko su visoke prepreke na koje agent može za-

koraciti) Onda jednostavno stisnemo ispeci (engl Bake) da izgradimo svoj NavMesh

Izgradeni NavMesh cemo moci vidjeti kao plavu površinu kao na slici 51 te ce se stvo-

riti nova datoteka s nazivom trenutne scene (ako vec ne postoji) i unutra ce se spremiti

kreiran navigacijski sustav [3]

21

54 Programiranje kretanja

Na liku se trenutno nalazi par stvari Animator Capsule Collider i Rigid Body Sada

je cilj isprogramirati mogucnost odredivanja gdje ce se lik kretati klikom miša na to

mjesto Dodaje se nova komponenta na lika NavMesh Agent Ta komponenta za-

pravo vec ima svoj sudarac te se slobodno može obrisati Capsule Collider jer postaje

nepotreban Igranjem s opcijama pomak od baze (engl Base Offset) te pod izbjegava-

nje prepreka (engl Obstacle Avoidance) radijus (engl Radius) i visina (engl Height)

prilagodi se sudarac od (engl NavMesh Agent-a) kako bi se obujmilo njime igraca i

sprijecilo propadanje kroz tlo od prije Sada kada postoji komponenta navigacije mora

se dodati skripta koja ce odrediti kada se lik krece te kada se pokrecu njegove anima-

cije iz Animator-a

Da bi se znalo gdje se miš nalazi mora se takoder dodati nova skriptu na kameru Kako

bi se izracunalo gdje trenutno kursor pokazuje Unity koristi vec prethodno spomenuto

bacanje zraka Da bi se moglo koristiti navigaciju putem klika mišem mora se napisati

skripta za glavnu kameru koja ce omoguciti bacanje zraka Skripta BacanjeZraka

dodaje se na objekt Main Camera koja se dodala pod prazni objekt Kamera Ova

skriptu se takoder koristi za razlikovanje raznih vrsta objekata Naime svaki objekt

kao što ima i Tag ima i sloj (engl Layer) Sloj služi kako bi mogli npr razlikovati

neprijatelje od obicnih objekata ili mjesto na koje želimo doci hodanjem Zato cemo

takoder dodati i jednu enumeraciju koja ce nam zasad služiti samo da razlikujemo je li

mjesto prohodno ili ne te jesmo li kliknuli na neprijatelja Kako bi dodali svoje nove

slojeve za objekte moramo kliknuti na Layer i dodaj sloj (engl Add Layer) kao na slici

52 što nas dovodi do novog prozora prikazanog na slici 53

Programski kod 51 bacanjeZrakacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

sluzi za dodavanje novih slojeva u Unity

public enum Sloj

Prohodno = 8

Neprijatelj = 9

KrajSvijeta = -1

22

Slika 52 Dodavanje novog sloja

public class BacanjeZraka MonoBehaviour

hijerarhija slojeva tj koji ima veci prioritet

public Sloj[] prioritetiSlojeva =

SlojNeprijatelj

SlojProhodno

SlojKrajSvijeta

udaljenost do pozadine je neka izmisljena vrijednost nakon

koje se prestane provjeravati zraka

public float udaljenostDoPozadine = 100f

Camera kamera

RaycastHit _udara

dohvaca varijable ove klase

public RaycastHit udara

get return _udara

Sloj _udaraSloj

23

Slika 53 Prozor za dodavanje novog sloja

public Sloj udaraSloj

get return _udaraSloj

deklariraj novi tip delegata

public delegate void priPromjeniSloja(Sloj noviSloj)

instanciraj skup promatraca

public event priPromjeniSloja promatraciPromjeneSloja

void Start ()

dohvat glavne kamere

kamera = Cameramain

void Update ()

nadi sloj po prioritetu u koji zraka udara

foreach(Sloj sloj in prioritetiSlojeva)

provjeravamo udara li zraka u neki od slojeva

24

var udar = BacanjeZrakaZaSloj(sloj)

if(udarHasValue)

_udara = udarValue

ako se sloj promjenio

if(_udaraSloj = sloj)

spremi novi sloj u varijablu trenutnog sloja

_udaraSloj = sloj

obavijesti promatrace da se sloj promjenio

promatraciPromjeneSloja(sloj)

spremi novi sloj u varijablu trenutnog sloja

ali ne moras obavjestavati promatrace jer je

sloj jednak starom sloju

_udaraSloj = sloj

return

inace vrati da zraka udara u pozadinu i obavijesti

promatrace

_udaradistance = udaljenostDoPozadine

_udaraSloj = SlojKrajSvijeta

promatraciPromjeneSloja(udaraSloj)

RaycastHit BacanjeZrakaZaSloj(Sloj sloj)

kreira se maska za slojeve bit se pomice ulijevo za

onoliko mjesta koliki je redni broj prioriteta sloja

int maska = 1 ltlt (int)sloj

sprema se mjesto pozicije kursora pretvoreno iz tocke u

zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

RaycastHit udar

PhysicsRaycast sprema zraku u varijablu tipa

RaycastHit prima jos i maksimalnu udaljenost za koju

provjerava zraku i masku sloja i potom vraca istinu (

engl True) ili laz (engl False) ako je zraka udarila

u sloj

25

bool udarioJe = PhysicsRaycast(zraka out udar

udaljenostDoPozadine maska)

ako zraka udara u sloj vrati vrijednost udarca

if(udarioJe)

return udar

return null

U programskom kodu 51 se koristi funkcija za primjenu obrasca promatraca pod

nazivom delegat (engl Delegate) Što je obrazac promatraca (engl Observer) To je

oblikovni obrazac koji se u programiranju koristi

bull kad promjena jednog objekta zahtijeva promjene u drugim objektima koji nisu

unaprijed poznati

bull kad objekt treba obavještavati druge objekte

bull uz uvjet da bude što neovisniji o njima

bull kad je potrebno prikazivati razlicite aspekte nekog dinamickog stanja a želimo

izbjeci ciklicku ovisnost izmedu stanja i pogleda

bull kad postoje dva koncepta jedan ovisan o drugome a zgodno ih je razdvojiti

S obzirom na to da mi samo pri promjeni sloja želimo obavještavati pretplacene pro-

matrace uvodenje delegata nam dosta ubrzava kod Obrazac promatraca funkcionira

tako da glavni objekt igra ulogu izdavaca (izvora informacija) u ovom slucaju to je

glavna kamera Ostali ovisni objekti (promatraci) pretplacuju se kod izdavaca te iz-

davaci obavještavaju pretplatnike o promjenama Promatraci prekidaju pretplatu kad

više ne trebaju obavještavanje Funkcija priPromjeniSloja se definira kao delegat i u

ovom slucaju prima sloj Nakon toga se definira dogadaj (engl Event) tipa tog delegata

(priPromjeniSloja) u ovom slucaju naziva promatraciPromjeneSloja i odsad se unutar

subjekta tim nazivom i poziva Kako bi se neki promatrac pretplatio na informacije

koje izdaje kamera dodaje ove dvije linije koda u svoju skriptu

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

Programski kod 52 služi za kretanje korištenjem NavMesha i lijevog klika miša

26

Programski kod 52 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

public float dovoljnoBlizu = 01f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora

[SerializeField] float hodajKreciStaniRadijus = 02f

void Start ()

pronadi igraca koji je tipa agenta navigacijskog sustava

(engl NavMeshAgent)

agent = GetComponentltUnityEngineAINavMeshAgentgt()

pronadi prethodno napisanu klasu BacanjeZraka

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

spremi trenutnu poziciju kursora

trenutnaPozicijaKursora = transformposition

void Update()

ako je igrac dosao na zeljeno mjesto zaustavi animaciju

hodanja

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

ako je stisnut lijevi klik misa

if (InputGetMouseButtonDown(0))

ovisno o sloju primjeni akciju

switch(bacanjeZrakaudaraSloj)

ako se po objektu na koji je igrac kliknuo moze

hodati

27

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 4: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

SADRŽAJ

1 Uvod 1

2 Postavljanje pocetne scene 221 Instalacija 2

22 Kreiranje prve scene 2

23 Razvojna okolina Unity 3

24 Konzola 4

25 Programski jezik 4

3 Unos glavnog lika u scenu 731 Skaliranje 7

32 Kreiranje osnovnih objekata 7

33 Unos Blender modela u Unity i pocetni problemi 8

4 Kamera 1241 Perspektivna i ortografska kamera 12

42 Pogled iz prvog lica u pogled iznad glave 13

43 Fiksirana kamera 15

44 Bacanje zraka (engl Ray casting) 16

5 Kretanje 1951 Navigacijski sustav u Unityu 19

52 Pronalazak puta 20

53 Kreiranje navigacijskog sustava 21

54 Programiranje kretanja 22

6 Korisnicko sucelje 3561 Platno 35

62 Osnovne komponente 36

iv

63 Korisnicko sucelje igraca 37

64 Korisnicko sucelje neprijatelja 38

7 Teren 4271 Kreiranje i uredivanje terena 42

72 Visinske mape 42

73 Teksture za teren 44

8 Zakljucak 46

9 Zasluge 47

Literatura 48

v

1 Uvod

Korištenje Unity razvojne okoline eksponencijalno raste zadnjih par godina Razlog

tomu vjerojatno leži u njegovoj jednostavnosti i poslovnom modelu koji omogucava

besplatno korištenje Unity 5 osobne licence za edukacijske svrhe te za tvrtke s priho-

dima manjim od 100000$ Ono što Unity je i ono što promovira je pojednostavljivanje

svih komponenata potrebnih za razvoj igre No takoder pruža svu slobodu programeru

da dodatno razvije i poboljša njihov sustav u obliku koji njemu najviše odgovara Rad

s animacijama teksturama i modelima je vrlo jednostavan i ne zahtijeva nikakvo zna-

nje programera o njihovom razvoju ili ucitavanju kako bi mogli raditi s njima Tako-

der postoje vec mnogi primjeri programskog koda ponudeni na službenim stranicama

Unitya za dizajnere koji nisu iskusni u programiranju Programski kodovi su odlicno

opisani i rješavaju u par linija teške probleme poput navigacije kamere osvjetljenja

itd Cilj ovog rada je pokazati kako se lako mogu savladati osnove rada u Unityu i

kako iskoristiti naše programersko predznanje dobiveno s dosadašnjim studiranjem za

dodatno poboljšavanje svega što Unity nudi te i za lakše razumijevanje kako vec im-

plementirani algoritmi Unitya funkcioniraju Svako poglavlje predstavlja svojevrsni

zadatak za cije se rješavanje nude razna rješenja i objašnjenje potrebne teorije te na

kraju i opis rješenja koje je iskorišteno u ovom projektu

1

2 Postavljanje pocetne scene

U ovom poglavlju je predstavljena instalacija razvojne okoline Unity te kreiranje po-

cetnog projekta u kojem ce se do kraja ovog rada izradivati zamišljena igra Upoznaje

se s radom konzole i odlucuje se koji programski jezik ce biti korišten Opisuje se i

objašnjava rad u razlicitim prozorima razvojne okoline te snalaženje u samoj sceni ra-

zvoja igre Nakon kraja ovog poglavlja želi se imati instaliran Unity i pokrenut prazan

projekt

21 Instalacija

Kao što je vec navedeno Unity je besplatan za korištenje za privatne edukacijske te

opcenito bilo kakve nekomercijalne svrhe Razvojni alat se može skinuti i instalirati sa

službene stranice Instalacija je prilicno jednostavna te ima detaljna uputstva koja se

mogu slijediti Verzija korištena tijekom ostatka ovog rada je Unity 56 Za kodiranje

skripti korišten je Microsoft Visual Studio 2017 Naravno može se koristiti i Mono

Develop koji dolazi skupa s instalacijom Unitya

22 Kreiranje prve scene

Nakon instalacije Unitya kreira se novi projekt kao što se vidi na slici 21 Odabere

se ime projekta te mjesto na disku gdje ce se spremiti Nakon kreiranja projekta otvara

se klasicna pocetna scena koja se sastoji od glavne kamere te usmjerenog svijetla koji

su oznaceni brojem 1 na slici 22 Brojem 2 na slici 22 je oznacen prozor projekt

(engl Project) gdje ce se nalaziti sve skripte objekti materijali i sl koje cemo kreirati

kroz izradu projekta Sve te komponente se zapravo spremaju na disku ovisno o tome

gdje je Unity instaliran i gdje je postavljeno spremanje projekata Npr za ovaj projekt

je korišteno DUnity ProjectsAlice Prazni projekt spremamo koristeci postupak

datoteka (engl File) -gt spremi scenu kao (engl Save Scene As) kako bi se kreirala

prva scena u Unityu Odabire se proizvoljno ime te se klikne spremi (engl Save)

2

Slika 21 Kreiranje projekta

23 Razvojna okolina Unity

Na slici 22 može se vidjeti ovaj projekt u nekoj kasnijoj fazi rada Koristi se ova slika

za lakše objašnjavanje dijelova razvojne okoline Unity Razlikuju se dva pogleda

pogled scene i pogled igre koji se vide i na slici 22 pod brojem 3 U pogledu scene

ureduje se scena igre dodaju se objekti skripte te sve ostalo što je potrebno Nakon

prebacivanja u pogled igre može se igrati dosad izradena verziju igre to je ono što ce

igrac zapravo vidjeti Na samom vrhu slike 22 oznaceno brojem 4 vidimo tri gumba

kao na slici 23 igraj (engl Play) pauziraj (engl Pause) i korak (engl Step) Ti

gumbi prebacuju pogled u pogled igre Sve promjene koje se naprave nad objektima

u pogledu igre su privremeni te ce se vratiti na staro kada se izade iz tog pogleda

Pritisak na gumb Play automatski prebacuje na prozor igra (engl Game) iz prozora

scena (engl Scene) ciji se nazivi mogu vidjeti ispod tih gumba

Dalje postoje gumbi oznaceni brojem 5 na slici 22 koji pomažu s kretanjem oko scene

i manipulacijom objekata u sceni koji su prikazani na slici 24 Prvi gumb sa slikom

ruke omogucava pomicanje po sceni dok drugi gumb omogucava pomicanje objekata

po sceni Treci gumb služi za rotaciju objekata cetvrti za skaliranje i peti služi za

korisnicko sucelje

3

Slika 22 Razvojna okolina Unity

Slika 23 Gumbi Pokreni Pauziraj i Korak

24 Konzola

Konzola u Unityu vecinom služi za pomoc pri traženju greški u programskom kodu

Može se vidjeti na slici 22 u donjem dijelu Unitya u obliku kartice pored kartice

Project Ako se ne nalazi tamo mora se dodati odlaskom na prozori (engl Windows)-

gt konzola (engl Console) Pritiskom na nju primjecuje se da je skroz prazna i da

imamo još par kartica ocisti (engl Clear) sruši (engl Collapse) ocisti pri pokretanju

(engl Clear On Play) i pri grešci pauziraj (engl Error Pause) Clear služi za cišce-

nje dosad ispisanih poruka Obicno se oznacava Clear On Play da uvijek ocisti stare

poruke te da svaki put kad se pokrene igra dobiju nove Collapse pomaže ako postoji

puno istih poruka npr je korištena while petlja i ceka se neka promjenu u sceni Nije

potrebno da se ispisuje poruka Cekam cijelo vrijeme dok se ceka nego samo jednom

25 Programski jezik

Unity podržava C i Javascript programske jezike te je kroz projekt korišten samo C

Pretpostavlja se da je citatelj upoznat barem sa sintaksom C-a te osnovama objektno

4

Slika 24 Alati za transformaciju

orijentiranog programiranja Nije potrebno veliko znanje C-a kako bi se kodiralo u

Unityu potrebno je samo razumjeti kako se radi s objektima te poznavati sintaksu C-

a zbog rada s razlicitim vrstama varijabli (za razliku od Python-a gdje nije potrebno

specificirati je li varijabla cijeli broj decimalni broj itd) Unutar prozora oznacenim

brojem 2 na slici 22 stisne se desni klik i odabere kreiraj (engl Create) i C skripta

(engl C Script) da se doda nova skripta Duplim klikom na novo-kreiranu skriptu

otvara se Microsoft Visual Studio ili neka druga razvojna okolina koja podržava C u

kojem se sad može pisati programski kod Programski kod 21 je primjer ispisivanja

jednostavne poruke u konzoli

Programski kod 21 HelloWorld1cs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class HelloWorld MonoBehaviour

koristi se za inicijalizaciju

void Start ()

print(Hello World)

Update se zove svaki okvir (engl Frame)

void Update ()

Sada kada se pritisne na gumb Play sa slike 23 može se vidjeti ispis u konzoli Hello

world Još jedan nacin ispisivanja u konzolu je prikazan programskim kodom 22

Programski kod 22 HelloWorld2cs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

5

public class HelloWorld MonoBehaviour

koristi se za inicijalizaciju

void Start ()

DebugLog(Hello world)

Update se zove svaki okvir (engl Frame)

void Update ()

Ne postoji nikakva bitne razlika izmedu ta dva nacina pa se koristi bilo koji

6

3 Unos glavnog lika u scenu

U ovom poglavlju opisuju se neki pocetni problemi s kojima se susrece pri ubacivanju

modela iz popularnog programa za modeliranje Blender Objašnjavaju se i modeli koji

su ponudeni unutar samog Unitya poput kocke i neke osnovne njihove transformacije

Nakon kraja ovog poglavlja želi se imati svojevrsno tlo i ubaceni glavni lik skupa s

njegovim teksturama i animacijama iz Blender-a koji nece propadati kroz tlo

31 Skaliranje

Jedno od osnovnih stvari o kojima se razmišlja prilikom kreiranja igre je koja ce se

brojcana skala koristiti Unity ima svoje mjerne jedinice koji predstavljaju metre u

njegovom fizickom sustavu Ovisno o tipu igre koja se kreira mora se paziti na skali-

ranje Izraduje li se neka igru u svemiru nece se koristiti naše realne mjerne jedinice

nego ce ih se naravno skalirati U ovom slucaju kreira se RPG (Role-playing game)

igra gdje nam je glavni lik covjek te ce se koristiti normalne Unity mjerne jedinice bez

skaliranja

32 Kreiranje osnovnih objekata

Za pocetak potrebno je kreirati jednostavno tlo Kocka se kreira s objekt igre (engl Ga-

meObject) -gt 3D objekt (engl 3D Object) -gt kocka (engl Cube) te se dobiva rezultat

kao na slici 31 Zasad se kocka skalira po x i z osi sa 100 Tlo je uobicajeno zelene

boje pa mu se dodaje novi materijal Pritisne se u prozor imovina (engl Asset) desnim

klikom miša i odabere se kreiraj (engl Create) -gt materijal (engl Material) kao što se

može vidjeti na slici 32 Klikom na novo-stvoreni materijal desno se pojavljuje novi

prozor Inspektor (engl Inspector) gdje se može odabrati boja Nakon toga samo se

povuce lijevim klikom miša materijal na skaliranu kocku tj tlo S obzirom na to

kako se želi da ta skalirana kocka glumi tlo želi se takoder da se i ostali objekti nalaze

7

Slika 31 Kreiranje tla

na njoj Zato ce se tlo morati pomaknuti po y osi za -05 kako bi se olakšalo daljnje

dodavanje objekata

33 Unos Blender modela u Unity i pocetni problemi

Krece se s ubacivanjem svog lika u igru Lik koji se koristi kroz ostatak ovog rada na-

pravljen je u programu Blender koji služi za 3D modeliranje blend objekt se može

samo povuci mišem u Unity iz datoteke u kojoj se nalazi

1 problem Kada se blend datoteka ubacuje u Unity on nece automatski ubaciti i

teksture koje su korištene u izradi tog modela Najlakši nacin bi bio izrada nove dato-

teku unutar Assets datoteke u Unityu i ubacivanje i blend modela i teksture koja je bila

korištena u izradi u tu novu datoteku Nakon toga klikom na model unutar prozora In-

spector pod Materials odabire se opcija od modelovih materijala (engl From Modelrsquos

Material) kao na slici33 kako bi Unity ucitavao korištene teksture Ponekad na žalost

ni to ne funkcionira pa ce se ovdje objasniti još jedan malo opcenitiji pristup Pri unosu

blend modela Unity kreira novu datoteku i nazove ju materijali (engl Materals) Ako

se dogodi da se korištene teksture na modelu ne vide treba se pogledati u tu datoteku

U njoj ce se nalaziti prazni materijali s istim imenima korištenih tekstura kao npr u

slucaju ovog projekta drvo (engl Wood) Tada se mora odabrati u desnom prozoru

materijala albedo (engl Albedo) kao na slici 34 i u ponudenim Assets naci teksturu

koja je korištena (u ovom slucaju Wood)

8

Slika 32 Kreiranje materijala

2 problem Sada kada je lik pozicioniran u ishodištu (x = 0 y = 0 z = 0) može se

dogoditi da se ne nalazi tocno na tlu koje je kreirano To dakako ovisi o modeliranju

koordinatama koje su korištene i skaliranju pri izradi modela Lik korišten u ovom

radu mora se pomaknuti na koordinatu x = 0 y = 15 z = 0 kako bi stajao tocno na tlu

3 problem Kada bi se igra sad pokrenula pritiskom na gumb Play pri vrhu Unitya

lik bi propao kroz tlo Zašto se to dogada Zbog necega što se zove sudarac (engl Col-

lider) u Unityu koji ce kasnije biti pomnije objašnjen Za sada se samo žele postaviti

neke pocetne stvari kako bi bilo lakše testirati osnovnu interakciju lika i objekata u

prostoru U desnom prozoru Inspector kada je lik oznacen vidi se opcija dodaj kom-

ponentu (engl Add Component) Stisne se na to i upiše sudarac u obliku kapsule

(engl Capsule Collider) kako bi se dodao novi sudarac To je zapravo samo sudarac

9

Slika 33 Unos blend modela u scenu

koji je u obliku kapsule te se igrajuci nekim njegovim osnovnim opcijama može na-

mjestiti vanjski oblik lika Dodaje se još jedna komponenta nad likom Ponovno se

stisne na Add Component te upiše kruto tijelo (engl Rigid Body) što ce takoder biti

naknadno objašnjeno Zasad je bitno razumijevanje da to omogucava liku da se ponaša

kao kruto tijelo u prostoru

4 problem Sada bi kada se igra pokrene trebao postojati lik koji ne propada kroz tlo

Naravno kao najosnovniju mehaniku želi se mogucnost kretanja po tom tlu Skripta

koja se treba napraviti kako bi se lik kretao po tlu nije zapravo komplicirana Sastoji

se samo od toga da se prilikom pritiska na odredeno slovo tipkovnice objekt translatira

po prostoru No ovaj model takoder sadrži i animacije za hodanje te se želi i to ukom-

ponirati Zato ce se takoder sada spomenuti još jedna nova komponenta kontrolor

animacija (engl Animator Controller) Dodaje se i ta komponenta na lika i prebacuje

se na prozor animator (engl Animator) koji se vidi na slici 35

U ovom prozoru postoji par novih opcija Mogu se dodavati nova stanja u kojima

ce se lik naci ovisno o nekim uvjetima koji se zadaju Pocetno stanje je ulazno stanje

(engl Entry State) i iz njega se želi da se lik nade u stanju mirovanja Stisne se desni

klik miša i odabere se novo stanje (engl New State) U ovom projektu je nazvano

Mirovanje Iz mirovanja ovisno o tome kada osoba pritisne neku tipku tipkovnice

želi se da se lik krene kretati Zato treba dodati novo stanje Hodanje Doda se

novo stanje istim postupkom kao i prvo Sada se naravno moraju dodati i usmjereni

prijelazi Stisne se desni klik miša na Mirovanje i odabere dodaj prijelaz (engl Add

10

Slika 34 Traženje tekstura Vašeg blend modela

Slika 35 Animator

Transition) To je sada kreiralo usmjerenu strelicu koja se može povuci prema Ho-

danje Isto to se napravi i u suprotnom smjeru Desni klik miša na Hodanje Add

Transition i povuce se strelica prema Mirovanje Naravno moraju se dodati uvjeti

koji ce odredivati kada ce objekt prijeci iz jednog stanja u drugo U ovom slucaju je

korišten cijeli broj (engl Integer) Ostatak problema kretanja rješavat ce se u poglavlju

4 Bacanje zraka i kretanje po mapi s mišem

11

4 Kamera

U ovom poglavlju se postavlja i bira prava kamera za igru Tijekom izrade igre treba se

takoder razmišljati i iz kojeg kuta ce se imati pogled na nju te hoce li se kamera pomi-

cati s kretanjem lika hoce li se moci rotirati itd Pri kreiranju 3D igre u pogledu scene

primjecuje se da su svi objekti i transformacije u 3D-prostoru No s obzirom na to da je

zaslon monitora igraca 2-dimenzionalan te se ne može prikazati tijela kao takva mora

se moci prikazati sve te objekte u jednoj ravnini i zadržati dojam 3-dimenzionalnosti

To se u Unityu postiže s kamerom Kamera je objekt koja definira pogled i njegov

smjer u prostoru scene Pozicija kamere definira ocište z os definira smjer gledanja

(gledište) te y os definira vrh ekrana Kamera takoder definira velicinu i oblik dijela

koji možemo vidjeti Kamera nam pokazuje ono što ona vidi Kako se ona rotira

translatira itd prikaz scene ce se takoder jednako transformirati Nakon kraja ovog

poglavlja želi se imati kamera koja ce pratiti kretnje lika i imati pogled na njega odoz-

gora

41 Perspektivna i ortografska kamera

Kamerom se zapravo objekte 3D prostora projicira na ravninu u 2D prostor Projek-

cije su matematicki modeli koji govore na koji nacin treba tocke 3D prostora preslikati

u ravninu u tocke 2D prostora Postoji više vrsta projekcija no Unity koristi dvije or-

tografsku projekciju i perspektivnu projekciju Kod ortografskih projekcija kamera je

okomita na ravninu projekcije dok je perspektivna projekcija bliža našem nacinu gle-

danja objekata Možda je najlakše primijetiti razliku koristeci slike Dakle na slici 41

možemo vidjeti blend model koji je modeliran u Blenderu u ortografskoj projekciji te

na slici 42 isti taj model pod istim kutem samo prebacen u perspektivnu projekciju

[6]

Perspektivna projekcija uvodi dvije tocke ocište i gledište Ocište je tocka u ko-

joj se nalazi promatrac Gledište odreduje smjer prema kojem promatrac gleda U

12

Slika 41 Ortografska projekcija blend modela

tocki gledišta stvara se ravnina projekcije koja je okomita na spojnicu ocište-gledište

[6] I perspektivna i ortografska kamera imaju granicu do koje mogu vidjeti od svoje

trenutne pozicije Ona je definirana upravo tom ravninom projekcije Tocka gledišta

pripada toj ravnini i ona tipicno postaje ishodište lokalnog dvodimenzijskog koordi-

natnog sustava koji razapinjemo u ravnini projekcije Ta ravnina se još naziva i daleka

ravnina podrezivanja zato što svi objekti koji se nalaze na vecoj udaljenosti od nje se

odrežu te ih kamera ne prikazuje Takoder postoji i ravnina podrezivanja blizu ka-

meri [1] Dio koji se prikazuje se nalazi izmedu te dvije ravnine

42 Pogled iz prvog lica u pogled iznad glave

U igrama se cesto koristi prebacivanje iz jednog u drugi pogled kamere Kako se

to postiže Koristeci veci broj kamera U ovom slucaju obradit ce se samo kratki

primjer kako se prebacivati iz pogleda prvog lica u pogled iznad glave U unity-u je

zadano da jedna kamera pokriva cijeli ekran te se zato samo pogled jedne kamere može

vidjeti u jednom trenutku Kamera koju vidimo je ona koja ima najvecu vrijednost

za svoje svojstvo dubine[1] Zato se želi napraviti skripta koja ce se prebacivati s

jedne kamere na drugu da bi se dobili drukciji pogledi na scenu koja je prikazana

programskim kodom 41

Programski kod 41 PrimjerViseKameracs

13

Slika 42 Perspektivna projekcija blend modela

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kameraPrvogLica

public Camera kameraIznadGlave

funkcija koja se poziva kada se prebacujemo u pogled iznad

glave

public void prikaziPogledIznadGlave()

kameraPrvogLicaenabled = false gasimo kameru prvog

lica

kameraIznadGlaveenabled = true palimo kameru iznad

glave

funkcija koja se poziva kada se prebacujemo u pogled iz

prvog lica

public void prikaziPogledIzPrvogLica()

kameraPrvogLicaenabled = true palimo kameru prvog

lica

overheadCameraenabled = false gasimo kameru iznad

glave

14

43 Fiksirana kamera

U sceni projekta vec postoji glavna kamera (engl Main Camera) koju Unity automat-

ski dodaje u scenu Kako bi ta kamera pratila lika može se samo povuci u lijevom

prozoru hijerarhije u hijerarhiju lika kako bi postala njegovo dijete Tako ce se postici

da kamera stalno prati njegove transformacije (translaciju rotaciju) prilikom pokreta-

nja igre No kako bi se postiglo da kamera ostane uvijek fiksirana te se samo krece s

njime umjesto da se kamera rotira skupa s likom dodaje se novi prazni objekt sa Game

Object -gt kreiraj prazan (engl Create Empty) Njegova pozicija se postavlja na x =

0 y = 0 z = 0 ako vec nije tamo te se postavlja taj prazan objekt kao roditelj glavne

kamere Sada kamera ostaje fiksirana na mjestu te se nece ni kretati s likom Kako bi

se krenula kretati mora se dodati nova skripta na taj prazan objekt koji se odsad u pro-

jektu zove Kamera s obzirom na to da zaista i je roditelj glavne kamere Kako bi se u

skripti lakše locirao objekt igraca oznacava ga se u njegovom polju oznaka (engl Tag)

u desnom prozoru Inspector s igrac (engl Player) kao što se može vidjeti na slici 43

zaokruženo plavom bojom

U programskom kodu se želi napraviti varijabla tipa Game Object kako bi se spremilo

igraca kada ga se pronade Unity takoder ima funkciju FindGameObjectWithTag pa

je onda ostatak koda prilicno intuitivan Kada se igrac pronade pomocu njegove oz-

nake Player prilikom svakog osvježavanja poziciji našeg igraca pridružuje se pozicija

kamere kao što je prikazano programskim kodom 42

Programski kod 42 pratiLikacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class pratiLika MonoBehaviour

GameObject igrac

void Start ()

trazi se objekt putem njegove oznake

igrac = GameObjectFindGameObjectWithTag(Player)

15

Slika 43 Oznacavanje lika radi lakšeg pronalaska u skripti

void LateUpdate ()

trenutni objekt mijenja svoju poziciju u skladu s

pozicijom objekta oznacenog oznakom Player

transformposition = igractransformposition

44 Bacanje zraka (engl Ray casting)

Perspektivna kamera u Unityu koristi oblik krnje piramide za dio koji prikazuje u pros-

toru Svaka tocka nekog objekta kojeg kamera prikazuje zapravo odgovara liniji u pros-

toru svijeta te je nama samo jedna tocka duž te linije vidljiva na objektu Sve iza te

tocke na liniji je zamraceno Vanjski rubovi objekta su definirani razilazecim linijama

16

koje odgovaraju kutevima objekta Kada bi se te linije pratile unazad prema kameri

sve bi na kraju konvergirale u jednu tocku U Unityu se ta tocka nalazi tocno na pozi-

ciji kamere i naziva se centrom perspektive Kut naspram linija koje konvergiraju od

gornjeg i donjeg centra ekrana u centru perspektive se zove vidno polje (engl Field Of

View) Sve što pada izvan tih razilazecih linija na rubovima objekta nece biti vidljivo

kameri uz vec prethodno spomenuta ogranicenja ravnina podrezivanja

U igrama je jako korisno imati matematicku reprezentaciju linije koja predstavlja tocku

u pogledu kamere Unity to omogucava u obliku objekta zrake Zraka uvijek odgo-

vara tocki u pogledu pa klasa Kamera (engl Camera) sadrži dvije korisne funkcije

ScreenPointToRay i ViewportPointToRay Razlika izmedu njih je da ScreenPointToRay

ocekuje tocku s koordinatama piksela dok ViewportPointToRay uzima normalizirane

koordinate (od 0 dolje ili lijevo do 1 gore ili desno) Obje funkcije vracaju zraku

koja se sastoji od tocke ishodišta i vektora koji pokazuje smjer linije od tog ishodišta

Zraka izlazi iz ravnine podrezivanja bliže kameri Najcešce se zrake koriste kako bi ih

bacali u scenu Bacanje zraka pošalje imaginarnu liniju uz zraku od njenog ishodišta

dok ne udari u neki sudarac u sceni Tada vraca informaciju o tocki koju je udarila

u objektu RaycastHit To je vrlo korisno kako bi se locirao objekt ovisno o njegovoj

poziciji na zaslonu npr lociranje kursora prikazano programskim kodom 43

Programski kod 43 lociranjeKursoracs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kamera

void Start()

RaycastHit udar

u objekt Ray se sprema pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

ako zraka udara u neki objekt spremi u objektUdaren to

mjesto

if (PhysicsRaycast(zraka out udar))

Transform objektUdaren = udartransform

17

Ponekad je takoder korisno dobiti zraku koja odgovara poziciji na zaslonu te onda

pomicati kameru uz tu zraku Npr želi se dozvoliti igracu da može selektirati objekt

mišem i onda ga povecati dok se objekt nalazi cijelo vrijeme na istoj poziciji na zaslonu

ispod miša prikazano programskim kodom 44 [1]

Programski kod 44 povecavanjeSlikecs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public bool povecavanje

public float brzinaPovecavanja

public Camera kamera

void Update()

ako netko koristi povecavanje slike (engl Zooming)

if (povecavanje)

u objekt Ray sprema se pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(Input

mousePosition)

udaljenost povecavanja ce biti jednaka umnosku

brzine povecavanja vremena i vertikalnog smjera

float udaljenostPovecavanja = brzinaPovecavanja

InputGetAxis(Vertical) TimedeltaTime

pomakni kameru u smjeru kursora misa za udaljenost

povecavanja u koordinatnom sustavu svijeta

kameratransformTranslate(zrakadirection

udaljenostPovecavanja SpaceWorld)

18

5 Kretanje

Pronalazak puta je zapravo pokušaj aplikacije na racunalu ili algoritma da nade naj-

kracu rutu izmedu dvije tocke To je recimo prakticna verzija rješavanja labirinta Ni

danas ne postoji optimalan algoritam koji ce u svakom slucaju u nekom realno krat-

kom vremenu naci najkraci put U ovom poglavlju objasnit ce se koje algoritme Unity

koristi za svoj navigacijski sustav Objašnjavat ce se i neki osnovni koncepti i obrasci

potrebni za ubrzavanje cijele ideje dojavljivanja promjena u sceni Bit ce prikazani i

programski kodovi potrebni za implementiranje kretanja mišem iili tipkovnicom Na

kraju ovog poglavlja želi se imati lika koji ce se slobodno kretati po sceni na mjesto

koje se odredi klikom miša i mogucnost prebacivanja na upravljanje tipkovnicom

51 Navigacijski sustav u Unityu

U Unityu je problem pronalaska puta vec riješen s necim što se zove navigacijska

mreža (engl NavMesh) To je navigacijski sustav koji ima svoje algoritme pronala-

ska puta i puno pojednostavljuje programiranje kretanja lika Sastoji se od cetiri di-

jela NavMesh agent navigacijske mreže (engl NavMesh Agent) izvanmrežna pove-

zanost(engl Off - Mesh Link) i prepreka navigacijske mreže(engl NavMesh Obstacle)

NavMesh je podatkovna struktura koja opisuje površine po kojima se može kretati

u igri i omogucava pronalazak put od jedne lokacije do druge Navigacijski sustav

treba svoje podatke kako bi predstavio prohodna podrucja u sceni Prohodna podru-

cja definiraju se kao mjesta gdje agent može stajati i kretati se Prohodno podrucje se

automatski izgraduje iz geometrije u sceni testirajuci sva podrucja gdje bi agent mo-

gao stajati Onda se te lokacije spajaju s površinom na vrhu geometrije Ta površina se

naziva onda NavMesh te je možemo vidjeti na 51 NavMesh tada sprema tu površinu

kao konveksne poligone te informacije koji su poligoni susjedni Komponenta Nav-

Mesh Agent pomaže pri kreiranju likova koji se medusobno izbjegavaju dok se krecu

prema cilju U Unityu se agenti opisuju kao valjci Koriste NavMesh kako bi se kretali

i znali koje objekte moraju zaobici te kako da se medusobno zaobidu Off-Mesh Link

19

omogucava dodavanje navigacijskih precaca koji se ne mogu predstaviti kao površina

po kojoj se može hodati npr skakanje preko ograde ili otvaranje vrata prije nego što

se ude u neku prostoriju NavMesh Obstacle opisuje prepreke koje se krecu te koje bi

agenti trebali izbjegavati dok hodaju svijetom npr neke bacve koje se kotrljaju prema

igracu Dok se bacva krece agent ce izracunati put oko nje najbolje što može no nakon

što ona naposljetku stane postat ce dio neprohodnog NavMesha te ce se agenti kretati

oko nje [3]

Slika 51 Prikaz navigacijskog sustava u Unityu

52 Pronalazak puta

Dva glavna problema postoje kod pronalaženja puta kako pronaci destinaciju na ni-

vou na kojem se igrac nalazi te kako se onda tamo pomaknuti Pronalaženje destinacije

uzima u obzir cijelu scenu Pomicanje tamo je dinamicnije u obzir uzima samo smjer

kretanja i kako da sprijeci sudaranje s drugim agentima Da bi se pronašao put izmedu

dvije lokacije prvo se moraju oznaciti pocetna i konacna lokacija njihovim najbližim

poligonima Tada se krece tražiti od pocetne lokacije posjecujuci sve susjedne dok se

ne dode do zadane destinacije Onda se prati unatrag vec posjecene poligone kako bi

se našao konacan niz poligona koji vode od pocetka do kraja Algoritam koji Unity

koristi te se cesto koristi za pronalazak puta naziva se A (A zvjezdica) Taj niz po-

ligona koji opisuje put od pocetka do kraja se naziva hodnik Agent ce doci do svoje

20

destinacije tako da se uvijek usmjerava prema sljedecem vidljivom kutu hodnika Ta

logika usmjeravanja uvijek uzima poziciju sljedeceg kuta i ovisno o tome nade željeni

smjer i brzinu potrebnu za dolazak na destinaciju Korištenje brzine po želji progra-

mera bi moglo dovesti do sudara s ostalim agentima Izbjegavanje prepreka takoder

pronalazi svoju novu brzinu koja traži ravnotežu izmedu kretanja prema destinaciji i

sprjecavanja buducih sudara s ostalim agentima i kutevima u navigacijskom sustavu

Nakon usmjeravanja i izbjegavanja prepreka izracuna se konacna brzina Unity ta-

koder uzima u obzir i akceleraciju kako bi simulirao realisticnije kretanje Takoder

treba razumjeti razliku izmedu globalne i lokalne navigacije Globalna navigacija se

koristi za pronalazak hodnika u svijetu Linearna lista poligona koja opisuje taj put je

podatkovna struktura koja se koristi za usmjeravanje te se može lokalno prilagodavati

i mijenjati kako se pozicija agenta mijenja Lokalna navigacija pokušava naci efika-

san nacin kako da se igrac pomakne prema sljedecem kutu bez da se sudari s ostalim

agentima ili objektima koji se krecu [3]

53 Kreiranje navigacijskog sustava

Proces kreiranja NavMesha iz geometrije nivoa se naziva pecenje navigacijske mreže

(engl NavMesh Baking) Skuplja sve terene i mreže objekata koji su oznaceni kao

navigacijski staticko (engl Navigation Static) i onda ih procesira kako bi kreirao navi-

gacijski sustav koji aproksimira prohodne površine nivoa Izgradnja (engl NavMesha)

je vrlo jednostavna Prvo se selektira geometrija koja bi trebala utjecati na navigaciju

tj površine po kojima možemo hodati i prepreke Oznaci se Navigation Static da bi ih

ukljucili u NavMesh Baking proces Prilagode se postavke kako bi odgovarale velicini

agenta - radijus (npr koliko blizu se može doci zidovima) visina (koliko su nisko

prostori koje agent može doseci) maksimalni nagib (koliko su kose rampe po kojima

se agent može uspeti) visina stube(koliko su visoke prepreke na koje agent može za-

koraciti) Onda jednostavno stisnemo ispeci (engl Bake) da izgradimo svoj NavMesh

Izgradeni NavMesh cemo moci vidjeti kao plavu površinu kao na slici 51 te ce se stvo-

riti nova datoteka s nazivom trenutne scene (ako vec ne postoji) i unutra ce se spremiti

kreiran navigacijski sustav [3]

21

54 Programiranje kretanja

Na liku se trenutno nalazi par stvari Animator Capsule Collider i Rigid Body Sada

je cilj isprogramirati mogucnost odredivanja gdje ce se lik kretati klikom miša na to

mjesto Dodaje se nova komponenta na lika NavMesh Agent Ta komponenta za-

pravo vec ima svoj sudarac te se slobodno može obrisati Capsule Collider jer postaje

nepotreban Igranjem s opcijama pomak od baze (engl Base Offset) te pod izbjegava-

nje prepreka (engl Obstacle Avoidance) radijus (engl Radius) i visina (engl Height)

prilagodi se sudarac od (engl NavMesh Agent-a) kako bi se obujmilo njime igraca i

sprijecilo propadanje kroz tlo od prije Sada kada postoji komponenta navigacije mora

se dodati skripta koja ce odrediti kada se lik krece te kada se pokrecu njegove anima-

cije iz Animator-a

Da bi se znalo gdje se miš nalazi mora se takoder dodati nova skriptu na kameru Kako

bi se izracunalo gdje trenutno kursor pokazuje Unity koristi vec prethodno spomenuto

bacanje zraka Da bi se moglo koristiti navigaciju putem klika mišem mora se napisati

skripta za glavnu kameru koja ce omoguciti bacanje zraka Skripta BacanjeZraka

dodaje se na objekt Main Camera koja se dodala pod prazni objekt Kamera Ova

skriptu se takoder koristi za razlikovanje raznih vrsta objekata Naime svaki objekt

kao što ima i Tag ima i sloj (engl Layer) Sloj služi kako bi mogli npr razlikovati

neprijatelje od obicnih objekata ili mjesto na koje želimo doci hodanjem Zato cemo

takoder dodati i jednu enumeraciju koja ce nam zasad služiti samo da razlikujemo je li

mjesto prohodno ili ne te jesmo li kliknuli na neprijatelja Kako bi dodali svoje nove

slojeve za objekte moramo kliknuti na Layer i dodaj sloj (engl Add Layer) kao na slici

52 što nas dovodi do novog prozora prikazanog na slici 53

Programski kod 51 bacanjeZrakacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

sluzi za dodavanje novih slojeva u Unity

public enum Sloj

Prohodno = 8

Neprijatelj = 9

KrajSvijeta = -1

22

Slika 52 Dodavanje novog sloja

public class BacanjeZraka MonoBehaviour

hijerarhija slojeva tj koji ima veci prioritet

public Sloj[] prioritetiSlojeva =

SlojNeprijatelj

SlojProhodno

SlojKrajSvijeta

udaljenost do pozadine je neka izmisljena vrijednost nakon

koje se prestane provjeravati zraka

public float udaljenostDoPozadine = 100f

Camera kamera

RaycastHit _udara

dohvaca varijable ove klase

public RaycastHit udara

get return _udara

Sloj _udaraSloj

23

Slika 53 Prozor za dodavanje novog sloja

public Sloj udaraSloj

get return _udaraSloj

deklariraj novi tip delegata

public delegate void priPromjeniSloja(Sloj noviSloj)

instanciraj skup promatraca

public event priPromjeniSloja promatraciPromjeneSloja

void Start ()

dohvat glavne kamere

kamera = Cameramain

void Update ()

nadi sloj po prioritetu u koji zraka udara

foreach(Sloj sloj in prioritetiSlojeva)

provjeravamo udara li zraka u neki od slojeva

24

var udar = BacanjeZrakaZaSloj(sloj)

if(udarHasValue)

_udara = udarValue

ako se sloj promjenio

if(_udaraSloj = sloj)

spremi novi sloj u varijablu trenutnog sloja

_udaraSloj = sloj

obavijesti promatrace da se sloj promjenio

promatraciPromjeneSloja(sloj)

spremi novi sloj u varijablu trenutnog sloja

ali ne moras obavjestavati promatrace jer je

sloj jednak starom sloju

_udaraSloj = sloj

return

inace vrati da zraka udara u pozadinu i obavijesti

promatrace

_udaradistance = udaljenostDoPozadine

_udaraSloj = SlojKrajSvijeta

promatraciPromjeneSloja(udaraSloj)

RaycastHit BacanjeZrakaZaSloj(Sloj sloj)

kreira se maska za slojeve bit se pomice ulijevo za

onoliko mjesta koliki je redni broj prioriteta sloja

int maska = 1 ltlt (int)sloj

sprema se mjesto pozicije kursora pretvoreno iz tocke u

zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

RaycastHit udar

PhysicsRaycast sprema zraku u varijablu tipa

RaycastHit prima jos i maksimalnu udaljenost za koju

provjerava zraku i masku sloja i potom vraca istinu (

engl True) ili laz (engl False) ako je zraka udarila

u sloj

25

bool udarioJe = PhysicsRaycast(zraka out udar

udaljenostDoPozadine maska)

ako zraka udara u sloj vrati vrijednost udarca

if(udarioJe)

return udar

return null

U programskom kodu 51 se koristi funkcija za primjenu obrasca promatraca pod

nazivom delegat (engl Delegate) Što je obrazac promatraca (engl Observer) To je

oblikovni obrazac koji se u programiranju koristi

bull kad promjena jednog objekta zahtijeva promjene u drugim objektima koji nisu

unaprijed poznati

bull kad objekt treba obavještavati druge objekte

bull uz uvjet da bude što neovisniji o njima

bull kad je potrebno prikazivati razlicite aspekte nekog dinamickog stanja a želimo

izbjeci ciklicku ovisnost izmedu stanja i pogleda

bull kad postoje dva koncepta jedan ovisan o drugome a zgodno ih je razdvojiti

S obzirom na to da mi samo pri promjeni sloja želimo obavještavati pretplacene pro-

matrace uvodenje delegata nam dosta ubrzava kod Obrazac promatraca funkcionira

tako da glavni objekt igra ulogu izdavaca (izvora informacija) u ovom slucaju to je

glavna kamera Ostali ovisni objekti (promatraci) pretplacuju se kod izdavaca te iz-

davaci obavještavaju pretplatnike o promjenama Promatraci prekidaju pretplatu kad

više ne trebaju obavještavanje Funkcija priPromjeniSloja se definira kao delegat i u

ovom slucaju prima sloj Nakon toga se definira dogadaj (engl Event) tipa tog delegata

(priPromjeniSloja) u ovom slucaju naziva promatraciPromjeneSloja i odsad se unutar

subjekta tim nazivom i poziva Kako bi se neki promatrac pretplatio na informacije

koje izdaje kamera dodaje ove dvije linije koda u svoju skriptu

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

Programski kod 52 služi za kretanje korištenjem NavMesha i lijevog klika miša

26

Programski kod 52 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

public float dovoljnoBlizu = 01f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora

[SerializeField] float hodajKreciStaniRadijus = 02f

void Start ()

pronadi igraca koji je tipa agenta navigacijskog sustava

(engl NavMeshAgent)

agent = GetComponentltUnityEngineAINavMeshAgentgt()

pronadi prethodno napisanu klasu BacanjeZraka

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

spremi trenutnu poziciju kursora

trenutnaPozicijaKursora = transformposition

void Update()

ako je igrac dosao na zeljeno mjesto zaustavi animaciju

hodanja

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

ako je stisnut lijevi klik misa

if (InputGetMouseButtonDown(0))

ovisno o sloju primjeni akciju

switch(bacanjeZrakaudaraSloj)

ako se po objektu na koji je igrac kliknuo moze

hodati

27

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 5: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

63 Korisnicko sucelje igraca 37

64 Korisnicko sucelje neprijatelja 38

7 Teren 4271 Kreiranje i uredivanje terena 42

72 Visinske mape 42

73 Teksture za teren 44

8 Zakljucak 46

9 Zasluge 47

Literatura 48

v

1 Uvod

Korištenje Unity razvojne okoline eksponencijalno raste zadnjih par godina Razlog

tomu vjerojatno leži u njegovoj jednostavnosti i poslovnom modelu koji omogucava

besplatno korištenje Unity 5 osobne licence za edukacijske svrhe te za tvrtke s priho-

dima manjim od 100000$ Ono što Unity je i ono što promovira je pojednostavljivanje

svih komponenata potrebnih za razvoj igre No takoder pruža svu slobodu programeru

da dodatno razvije i poboljša njihov sustav u obliku koji njemu najviše odgovara Rad

s animacijama teksturama i modelima je vrlo jednostavan i ne zahtijeva nikakvo zna-

nje programera o njihovom razvoju ili ucitavanju kako bi mogli raditi s njima Tako-

der postoje vec mnogi primjeri programskog koda ponudeni na službenim stranicama

Unitya za dizajnere koji nisu iskusni u programiranju Programski kodovi su odlicno

opisani i rješavaju u par linija teške probleme poput navigacije kamere osvjetljenja

itd Cilj ovog rada je pokazati kako se lako mogu savladati osnove rada u Unityu i

kako iskoristiti naše programersko predznanje dobiveno s dosadašnjim studiranjem za

dodatno poboljšavanje svega što Unity nudi te i za lakše razumijevanje kako vec im-

plementirani algoritmi Unitya funkcioniraju Svako poglavlje predstavlja svojevrsni

zadatak za cije se rješavanje nude razna rješenja i objašnjenje potrebne teorije te na

kraju i opis rješenja koje je iskorišteno u ovom projektu

1

2 Postavljanje pocetne scene

U ovom poglavlju je predstavljena instalacija razvojne okoline Unity te kreiranje po-

cetnog projekta u kojem ce se do kraja ovog rada izradivati zamišljena igra Upoznaje

se s radom konzole i odlucuje se koji programski jezik ce biti korišten Opisuje se i

objašnjava rad u razlicitim prozorima razvojne okoline te snalaženje u samoj sceni ra-

zvoja igre Nakon kraja ovog poglavlja želi se imati instaliran Unity i pokrenut prazan

projekt

21 Instalacija

Kao što je vec navedeno Unity je besplatan za korištenje za privatne edukacijske te

opcenito bilo kakve nekomercijalne svrhe Razvojni alat se može skinuti i instalirati sa

službene stranice Instalacija je prilicno jednostavna te ima detaljna uputstva koja se

mogu slijediti Verzija korištena tijekom ostatka ovog rada je Unity 56 Za kodiranje

skripti korišten je Microsoft Visual Studio 2017 Naravno može se koristiti i Mono

Develop koji dolazi skupa s instalacijom Unitya

22 Kreiranje prve scene

Nakon instalacije Unitya kreira se novi projekt kao što se vidi na slici 21 Odabere

se ime projekta te mjesto na disku gdje ce se spremiti Nakon kreiranja projekta otvara

se klasicna pocetna scena koja se sastoji od glavne kamere te usmjerenog svijetla koji

su oznaceni brojem 1 na slici 22 Brojem 2 na slici 22 je oznacen prozor projekt

(engl Project) gdje ce se nalaziti sve skripte objekti materijali i sl koje cemo kreirati

kroz izradu projekta Sve te komponente se zapravo spremaju na disku ovisno o tome

gdje je Unity instaliran i gdje je postavljeno spremanje projekata Npr za ovaj projekt

je korišteno DUnity ProjectsAlice Prazni projekt spremamo koristeci postupak

datoteka (engl File) -gt spremi scenu kao (engl Save Scene As) kako bi se kreirala

prva scena u Unityu Odabire se proizvoljno ime te se klikne spremi (engl Save)

2

Slika 21 Kreiranje projekta

23 Razvojna okolina Unity

Na slici 22 može se vidjeti ovaj projekt u nekoj kasnijoj fazi rada Koristi se ova slika

za lakše objašnjavanje dijelova razvojne okoline Unity Razlikuju se dva pogleda

pogled scene i pogled igre koji se vide i na slici 22 pod brojem 3 U pogledu scene

ureduje se scena igre dodaju se objekti skripte te sve ostalo što je potrebno Nakon

prebacivanja u pogled igre može se igrati dosad izradena verziju igre to je ono što ce

igrac zapravo vidjeti Na samom vrhu slike 22 oznaceno brojem 4 vidimo tri gumba

kao na slici 23 igraj (engl Play) pauziraj (engl Pause) i korak (engl Step) Ti

gumbi prebacuju pogled u pogled igre Sve promjene koje se naprave nad objektima

u pogledu igre su privremeni te ce se vratiti na staro kada se izade iz tog pogleda

Pritisak na gumb Play automatski prebacuje na prozor igra (engl Game) iz prozora

scena (engl Scene) ciji se nazivi mogu vidjeti ispod tih gumba

Dalje postoje gumbi oznaceni brojem 5 na slici 22 koji pomažu s kretanjem oko scene

i manipulacijom objekata u sceni koji su prikazani na slici 24 Prvi gumb sa slikom

ruke omogucava pomicanje po sceni dok drugi gumb omogucava pomicanje objekata

po sceni Treci gumb služi za rotaciju objekata cetvrti za skaliranje i peti služi za

korisnicko sucelje

3

Slika 22 Razvojna okolina Unity

Slika 23 Gumbi Pokreni Pauziraj i Korak

24 Konzola

Konzola u Unityu vecinom služi za pomoc pri traženju greški u programskom kodu

Može se vidjeti na slici 22 u donjem dijelu Unitya u obliku kartice pored kartice

Project Ako se ne nalazi tamo mora se dodati odlaskom na prozori (engl Windows)-

gt konzola (engl Console) Pritiskom na nju primjecuje se da je skroz prazna i da

imamo još par kartica ocisti (engl Clear) sruši (engl Collapse) ocisti pri pokretanju

(engl Clear On Play) i pri grešci pauziraj (engl Error Pause) Clear služi za cišce-

nje dosad ispisanih poruka Obicno se oznacava Clear On Play da uvijek ocisti stare

poruke te da svaki put kad se pokrene igra dobiju nove Collapse pomaže ako postoji

puno istih poruka npr je korištena while petlja i ceka se neka promjenu u sceni Nije

potrebno da se ispisuje poruka Cekam cijelo vrijeme dok se ceka nego samo jednom

25 Programski jezik

Unity podržava C i Javascript programske jezike te je kroz projekt korišten samo C

Pretpostavlja se da je citatelj upoznat barem sa sintaksom C-a te osnovama objektno

4

Slika 24 Alati za transformaciju

orijentiranog programiranja Nije potrebno veliko znanje C-a kako bi se kodiralo u

Unityu potrebno je samo razumjeti kako se radi s objektima te poznavati sintaksu C-

a zbog rada s razlicitim vrstama varijabli (za razliku od Python-a gdje nije potrebno

specificirati je li varijabla cijeli broj decimalni broj itd) Unutar prozora oznacenim

brojem 2 na slici 22 stisne se desni klik i odabere kreiraj (engl Create) i C skripta

(engl C Script) da se doda nova skripta Duplim klikom na novo-kreiranu skriptu

otvara se Microsoft Visual Studio ili neka druga razvojna okolina koja podržava C u

kojem se sad može pisati programski kod Programski kod 21 je primjer ispisivanja

jednostavne poruke u konzoli

Programski kod 21 HelloWorld1cs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class HelloWorld MonoBehaviour

koristi se za inicijalizaciju

void Start ()

print(Hello World)

Update se zove svaki okvir (engl Frame)

void Update ()

Sada kada se pritisne na gumb Play sa slike 23 može se vidjeti ispis u konzoli Hello

world Još jedan nacin ispisivanja u konzolu je prikazan programskim kodom 22

Programski kod 22 HelloWorld2cs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

5

public class HelloWorld MonoBehaviour

koristi se za inicijalizaciju

void Start ()

DebugLog(Hello world)

Update se zove svaki okvir (engl Frame)

void Update ()

Ne postoji nikakva bitne razlika izmedu ta dva nacina pa se koristi bilo koji

6

3 Unos glavnog lika u scenu

U ovom poglavlju opisuju se neki pocetni problemi s kojima se susrece pri ubacivanju

modela iz popularnog programa za modeliranje Blender Objašnjavaju se i modeli koji

su ponudeni unutar samog Unitya poput kocke i neke osnovne njihove transformacije

Nakon kraja ovog poglavlja želi se imati svojevrsno tlo i ubaceni glavni lik skupa s

njegovim teksturama i animacijama iz Blender-a koji nece propadati kroz tlo

31 Skaliranje

Jedno od osnovnih stvari o kojima se razmišlja prilikom kreiranja igre je koja ce se

brojcana skala koristiti Unity ima svoje mjerne jedinice koji predstavljaju metre u

njegovom fizickom sustavu Ovisno o tipu igre koja se kreira mora se paziti na skali-

ranje Izraduje li se neka igru u svemiru nece se koristiti naše realne mjerne jedinice

nego ce ih se naravno skalirati U ovom slucaju kreira se RPG (Role-playing game)

igra gdje nam je glavni lik covjek te ce se koristiti normalne Unity mjerne jedinice bez

skaliranja

32 Kreiranje osnovnih objekata

Za pocetak potrebno je kreirati jednostavno tlo Kocka se kreira s objekt igre (engl Ga-

meObject) -gt 3D objekt (engl 3D Object) -gt kocka (engl Cube) te se dobiva rezultat

kao na slici 31 Zasad se kocka skalira po x i z osi sa 100 Tlo je uobicajeno zelene

boje pa mu se dodaje novi materijal Pritisne se u prozor imovina (engl Asset) desnim

klikom miša i odabere se kreiraj (engl Create) -gt materijal (engl Material) kao što se

može vidjeti na slici 32 Klikom na novo-stvoreni materijal desno se pojavljuje novi

prozor Inspektor (engl Inspector) gdje se može odabrati boja Nakon toga samo se

povuce lijevim klikom miša materijal na skaliranu kocku tj tlo S obzirom na to

kako se želi da ta skalirana kocka glumi tlo želi se takoder da se i ostali objekti nalaze

7

Slika 31 Kreiranje tla

na njoj Zato ce se tlo morati pomaknuti po y osi za -05 kako bi se olakšalo daljnje

dodavanje objekata

33 Unos Blender modela u Unity i pocetni problemi

Krece se s ubacivanjem svog lika u igru Lik koji se koristi kroz ostatak ovog rada na-

pravljen je u programu Blender koji služi za 3D modeliranje blend objekt se može

samo povuci mišem u Unity iz datoteke u kojoj se nalazi

1 problem Kada se blend datoteka ubacuje u Unity on nece automatski ubaciti i

teksture koje su korištene u izradi tog modela Najlakši nacin bi bio izrada nove dato-

teku unutar Assets datoteke u Unityu i ubacivanje i blend modela i teksture koja je bila

korištena u izradi u tu novu datoteku Nakon toga klikom na model unutar prozora In-

spector pod Materials odabire se opcija od modelovih materijala (engl From Modelrsquos

Material) kao na slici33 kako bi Unity ucitavao korištene teksture Ponekad na žalost

ni to ne funkcionira pa ce se ovdje objasniti još jedan malo opcenitiji pristup Pri unosu

blend modela Unity kreira novu datoteku i nazove ju materijali (engl Materals) Ako

se dogodi da se korištene teksture na modelu ne vide treba se pogledati u tu datoteku

U njoj ce se nalaziti prazni materijali s istim imenima korištenih tekstura kao npr u

slucaju ovog projekta drvo (engl Wood) Tada se mora odabrati u desnom prozoru

materijala albedo (engl Albedo) kao na slici 34 i u ponudenim Assets naci teksturu

koja je korištena (u ovom slucaju Wood)

8

Slika 32 Kreiranje materijala

2 problem Sada kada je lik pozicioniran u ishodištu (x = 0 y = 0 z = 0) može se

dogoditi da se ne nalazi tocno na tlu koje je kreirano To dakako ovisi o modeliranju

koordinatama koje su korištene i skaliranju pri izradi modela Lik korišten u ovom

radu mora se pomaknuti na koordinatu x = 0 y = 15 z = 0 kako bi stajao tocno na tlu

3 problem Kada bi se igra sad pokrenula pritiskom na gumb Play pri vrhu Unitya

lik bi propao kroz tlo Zašto se to dogada Zbog necega što se zove sudarac (engl Col-

lider) u Unityu koji ce kasnije biti pomnije objašnjen Za sada se samo žele postaviti

neke pocetne stvari kako bi bilo lakše testirati osnovnu interakciju lika i objekata u

prostoru U desnom prozoru Inspector kada je lik oznacen vidi se opcija dodaj kom-

ponentu (engl Add Component) Stisne se na to i upiše sudarac u obliku kapsule

(engl Capsule Collider) kako bi se dodao novi sudarac To je zapravo samo sudarac

9

Slika 33 Unos blend modela u scenu

koji je u obliku kapsule te se igrajuci nekim njegovim osnovnim opcijama može na-

mjestiti vanjski oblik lika Dodaje se još jedna komponenta nad likom Ponovno se

stisne na Add Component te upiše kruto tijelo (engl Rigid Body) što ce takoder biti

naknadno objašnjeno Zasad je bitno razumijevanje da to omogucava liku da se ponaša

kao kruto tijelo u prostoru

4 problem Sada bi kada se igra pokrene trebao postojati lik koji ne propada kroz tlo

Naravno kao najosnovniju mehaniku želi se mogucnost kretanja po tom tlu Skripta

koja se treba napraviti kako bi se lik kretao po tlu nije zapravo komplicirana Sastoji

se samo od toga da se prilikom pritiska na odredeno slovo tipkovnice objekt translatira

po prostoru No ovaj model takoder sadrži i animacije za hodanje te se želi i to ukom-

ponirati Zato ce se takoder sada spomenuti još jedna nova komponenta kontrolor

animacija (engl Animator Controller) Dodaje se i ta komponenta na lika i prebacuje

se na prozor animator (engl Animator) koji se vidi na slici 35

U ovom prozoru postoji par novih opcija Mogu se dodavati nova stanja u kojima

ce se lik naci ovisno o nekim uvjetima koji se zadaju Pocetno stanje je ulazno stanje

(engl Entry State) i iz njega se želi da se lik nade u stanju mirovanja Stisne se desni

klik miša i odabere se novo stanje (engl New State) U ovom projektu je nazvano

Mirovanje Iz mirovanja ovisno o tome kada osoba pritisne neku tipku tipkovnice

želi se da se lik krene kretati Zato treba dodati novo stanje Hodanje Doda se

novo stanje istim postupkom kao i prvo Sada se naravno moraju dodati i usmjereni

prijelazi Stisne se desni klik miša na Mirovanje i odabere dodaj prijelaz (engl Add

10

Slika 34 Traženje tekstura Vašeg blend modela

Slika 35 Animator

Transition) To je sada kreiralo usmjerenu strelicu koja se može povuci prema Ho-

danje Isto to se napravi i u suprotnom smjeru Desni klik miša na Hodanje Add

Transition i povuce se strelica prema Mirovanje Naravno moraju se dodati uvjeti

koji ce odredivati kada ce objekt prijeci iz jednog stanja u drugo U ovom slucaju je

korišten cijeli broj (engl Integer) Ostatak problema kretanja rješavat ce se u poglavlju

4 Bacanje zraka i kretanje po mapi s mišem

11

4 Kamera

U ovom poglavlju se postavlja i bira prava kamera za igru Tijekom izrade igre treba se

takoder razmišljati i iz kojeg kuta ce se imati pogled na nju te hoce li se kamera pomi-

cati s kretanjem lika hoce li se moci rotirati itd Pri kreiranju 3D igre u pogledu scene

primjecuje se da su svi objekti i transformacije u 3D-prostoru No s obzirom na to da je

zaslon monitora igraca 2-dimenzionalan te se ne može prikazati tijela kao takva mora

se moci prikazati sve te objekte u jednoj ravnini i zadržati dojam 3-dimenzionalnosti

To se u Unityu postiže s kamerom Kamera je objekt koja definira pogled i njegov

smjer u prostoru scene Pozicija kamere definira ocište z os definira smjer gledanja

(gledište) te y os definira vrh ekrana Kamera takoder definira velicinu i oblik dijela

koji možemo vidjeti Kamera nam pokazuje ono što ona vidi Kako se ona rotira

translatira itd prikaz scene ce se takoder jednako transformirati Nakon kraja ovog

poglavlja želi se imati kamera koja ce pratiti kretnje lika i imati pogled na njega odoz-

gora

41 Perspektivna i ortografska kamera

Kamerom se zapravo objekte 3D prostora projicira na ravninu u 2D prostor Projek-

cije su matematicki modeli koji govore na koji nacin treba tocke 3D prostora preslikati

u ravninu u tocke 2D prostora Postoji više vrsta projekcija no Unity koristi dvije or-

tografsku projekciju i perspektivnu projekciju Kod ortografskih projekcija kamera je

okomita na ravninu projekcije dok je perspektivna projekcija bliža našem nacinu gle-

danja objekata Možda je najlakše primijetiti razliku koristeci slike Dakle na slici 41

možemo vidjeti blend model koji je modeliran u Blenderu u ortografskoj projekciji te

na slici 42 isti taj model pod istim kutem samo prebacen u perspektivnu projekciju

[6]

Perspektivna projekcija uvodi dvije tocke ocište i gledište Ocište je tocka u ko-

joj se nalazi promatrac Gledište odreduje smjer prema kojem promatrac gleda U

12

Slika 41 Ortografska projekcija blend modela

tocki gledišta stvara se ravnina projekcije koja je okomita na spojnicu ocište-gledište

[6] I perspektivna i ortografska kamera imaju granicu do koje mogu vidjeti od svoje

trenutne pozicije Ona je definirana upravo tom ravninom projekcije Tocka gledišta

pripada toj ravnini i ona tipicno postaje ishodište lokalnog dvodimenzijskog koordi-

natnog sustava koji razapinjemo u ravnini projekcije Ta ravnina se još naziva i daleka

ravnina podrezivanja zato što svi objekti koji se nalaze na vecoj udaljenosti od nje se

odrežu te ih kamera ne prikazuje Takoder postoji i ravnina podrezivanja blizu ka-

meri [1] Dio koji se prikazuje se nalazi izmedu te dvije ravnine

42 Pogled iz prvog lica u pogled iznad glave

U igrama se cesto koristi prebacivanje iz jednog u drugi pogled kamere Kako se

to postiže Koristeci veci broj kamera U ovom slucaju obradit ce se samo kratki

primjer kako se prebacivati iz pogleda prvog lica u pogled iznad glave U unity-u je

zadano da jedna kamera pokriva cijeli ekran te se zato samo pogled jedne kamere može

vidjeti u jednom trenutku Kamera koju vidimo je ona koja ima najvecu vrijednost

za svoje svojstvo dubine[1] Zato se želi napraviti skripta koja ce se prebacivati s

jedne kamere na drugu da bi se dobili drukciji pogledi na scenu koja je prikazana

programskim kodom 41

Programski kod 41 PrimjerViseKameracs

13

Slika 42 Perspektivna projekcija blend modela

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kameraPrvogLica

public Camera kameraIznadGlave

funkcija koja se poziva kada se prebacujemo u pogled iznad

glave

public void prikaziPogledIznadGlave()

kameraPrvogLicaenabled = false gasimo kameru prvog

lica

kameraIznadGlaveenabled = true palimo kameru iznad

glave

funkcija koja se poziva kada se prebacujemo u pogled iz

prvog lica

public void prikaziPogledIzPrvogLica()

kameraPrvogLicaenabled = true palimo kameru prvog

lica

overheadCameraenabled = false gasimo kameru iznad

glave

14

43 Fiksirana kamera

U sceni projekta vec postoji glavna kamera (engl Main Camera) koju Unity automat-

ski dodaje u scenu Kako bi ta kamera pratila lika može se samo povuci u lijevom

prozoru hijerarhije u hijerarhiju lika kako bi postala njegovo dijete Tako ce se postici

da kamera stalno prati njegove transformacije (translaciju rotaciju) prilikom pokreta-

nja igre No kako bi se postiglo da kamera ostane uvijek fiksirana te se samo krece s

njime umjesto da se kamera rotira skupa s likom dodaje se novi prazni objekt sa Game

Object -gt kreiraj prazan (engl Create Empty) Njegova pozicija se postavlja na x =

0 y = 0 z = 0 ako vec nije tamo te se postavlja taj prazan objekt kao roditelj glavne

kamere Sada kamera ostaje fiksirana na mjestu te se nece ni kretati s likom Kako bi

se krenula kretati mora se dodati nova skripta na taj prazan objekt koji se odsad u pro-

jektu zove Kamera s obzirom na to da zaista i je roditelj glavne kamere Kako bi se u

skripti lakše locirao objekt igraca oznacava ga se u njegovom polju oznaka (engl Tag)

u desnom prozoru Inspector s igrac (engl Player) kao što se može vidjeti na slici 43

zaokruženo plavom bojom

U programskom kodu se želi napraviti varijabla tipa Game Object kako bi se spremilo

igraca kada ga se pronade Unity takoder ima funkciju FindGameObjectWithTag pa

je onda ostatak koda prilicno intuitivan Kada se igrac pronade pomocu njegove oz-

nake Player prilikom svakog osvježavanja poziciji našeg igraca pridružuje se pozicija

kamere kao što je prikazano programskim kodom 42

Programski kod 42 pratiLikacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class pratiLika MonoBehaviour

GameObject igrac

void Start ()

trazi se objekt putem njegove oznake

igrac = GameObjectFindGameObjectWithTag(Player)

15

Slika 43 Oznacavanje lika radi lakšeg pronalaska u skripti

void LateUpdate ()

trenutni objekt mijenja svoju poziciju u skladu s

pozicijom objekta oznacenog oznakom Player

transformposition = igractransformposition

44 Bacanje zraka (engl Ray casting)

Perspektivna kamera u Unityu koristi oblik krnje piramide za dio koji prikazuje u pros-

toru Svaka tocka nekog objekta kojeg kamera prikazuje zapravo odgovara liniji u pros-

toru svijeta te je nama samo jedna tocka duž te linije vidljiva na objektu Sve iza te

tocke na liniji je zamraceno Vanjski rubovi objekta su definirani razilazecim linijama

16

koje odgovaraju kutevima objekta Kada bi se te linije pratile unazad prema kameri

sve bi na kraju konvergirale u jednu tocku U Unityu se ta tocka nalazi tocno na pozi-

ciji kamere i naziva se centrom perspektive Kut naspram linija koje konvergiraju od

gornjeg i donjeg centra ekrana u centru perspektive se zove vidno polje (engl Field Of

View) Sve što pada izvan tih razilazecih linija na rubovima objekta nece biti vidljivo

kameri uz vec prethodno spomenuta ogranicenja ravnina podrezivanja

U igrama je jako korisno imati matematicku reprezentaciju linije koja predstavlja tocku

u pogledu kamere Unity to omogucava u obliku objekta zrake Zraka uvijek odgo-

vara tocki u pogledu pa klasa Kamera (engl Camera) sadrži dvije korisne funkcije

ScreenPointToRay i ViewportPointToRay Razlika izmedu njih je da ScreenPointToRay

ocekuje tocku s koordinatama piksela dok ViewportPointToRay uzima normalizirane

koordinate (od 0 dolje ili lijevo do 1 gore ili desno) Obje funkcije vracaju zraku

koja se sastoji od tocke ishodišta i vektora koji pokazuje smjer linije od tog ishodišta

Zraka izlazi iz ravnine podrezivanja bliže kameri Najcešce se zrake koriste kako bi ih

bacali u scenu Bacanje zraka pošalje imaginarnu liniju uz zraku od njenog ishodišta

dok ne udari u neki sudarac u sceni Tada vraca informaciju o tocki koju je udarila

u objektu RaycastHit To je vrlo korisno kako bi se locirao objekt ovisno o njegovoj

poziciji na zaslonu npr lociranje kursora prikazano programskim kodom 43

Programski kod 43 lociranjeKursoracs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kamera

void Start()

RaycastHit udar

u objekt Ray se sprema pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

ako zraka udara u neki objekt spremi u objektUdaren to

mjesto

if (PhysicsRaycast(zraka out udar))

Transform objektUdaren = udartransform

17

Ponekad je takoder korisno dobiti zraku koja odgovara poziciji na zaslonu te onda

pomicati kameru uz tu zraku Npr želi se dozvoliti igracu da može selektirati objekt

mišem i onda ga povecati dok se objekt nalazi cijelo vrijeme na istoj poziciji na zaslonu

ispod miša prikazano programskim kodom 44 [1]

Programski kod 44 povecavanjeSlikecs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public bool povecavanje

public float brzinaPovecavanja

public Camera kamera

void Update()

ako netko koristi povecavanje slike (engl Zooming)

if (povecavanje)

u objekt Ray sprema se pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(Input

mousePosition)

udaljenost povecavanja ce biti jednaka umnosku

brzine povecavanja vremena i vertikalnog smjera

float udaljenostPovecavanja = brzinaPovecavanja

InputGetAxis(Vertical) TimedeltaTime

pomakni kameru u smjeru kursora misa za udaljenost

povecavanja u koordinatnom sustavu svijeta

kameratransformTranslate(zrakadirection

udaljenostPovecavanja SpaceWorld)

18

5 Kretanje

Pronalazak puta je zapravo pokušaj aplikacije na racunalu ili algoritma da nade naj-

kracu rutu izmedu dvije tocke To je recimo prakticna verzija rješavanja labirinta Ni

danas ne postoji optimalan algoritam koji ce u svakom slucaju u nekom realno krat-

kom vremenu naci najkraci put U ovom poglavlju objasnit ce se koje algoritme Unity

koristi za svoj navigacijski sustav Objašnjavat ce se i neki osnovni koncepti i obrasci

potrebni za ubrzavanje cijele ideje dojavljivanja promjena u sceni Bit ce prikazani i

programski kodovi potrebni za implementiranje kretanja mišem iili tipkovnicom Na

kraju ovog poglavlja želi se imati lika koji ce se slobodno kretati po sceni na mjesto

koje se odredi klikom miša i mogucnost prebacivanja na upravljanje tipkovnicom

51 Navigacijski sustav u Unityu

U Unityu je problem pronalaska puta vec riješen s necim što se zove navigacijska

mreža (engl NavMesh) To je navigacijski sustav koji ima svoje algoritme pronala-

ska puta i puno pojednostavljuje programiranje kretanja lika Sastoji se od cetiri di-

jela NavMesh agent navigacijske mreže (engl NavMesh Agent) izvanmrežna pove-

zanost(engl Off - Mesh Link) i prepreka navigacijske mreže(engl NavMesh Obstacle)

NavMesh je podatkovna struktura koja opisuje površine po kojima se može kretati

u igri i omogucava pronalazak put od jedne lokacije do druge Navigacijski sustav

treba svoje podatke kako bi predstavio prohodna podrucja u sceni Prohodna podru-

cja definiraju se kao mjesta gdje agent može stajati i kretati se Prohodno podrucje se

automatski izgraduje iz geometrije u sceni testirajuci sva podrucja gdje bi agent mo-

gao stajati Onda se te lokacije spajaju s površinom na vrhu geometrije Ta površina se

naziva onda NavMesh te je možemo vidjeti na 51 NavMesh tada sprema tu površinu

kao konveksne poligone te informacije koji su poligoni susjedni Komponenta Nav-

Mesh Agent pomaže pri kreiranju likova koji se medusobno izbjegavaju dok se krecu

prema cilju U Unityu se agenti opisuju kao valjci Koriste NavMesh kako bi se kretali

i znali koje objekte moraju zaobici te kako da se medusobno zaobidu Off-Mesh Link

19

omogucava dodavanje navigacijskih precaca koji se ne mogu predstaviti kao površina

po kojoj se može hodati npr skakanje preko ograde ili otvaranje vrata prije nego što

se ude u neku prostoriju NavMesh Obstacle opisuje prepreke koje se krecu te koje bi

agenti trebali izbjegavati dok hodaju svijetom npr neke bacve koje se kotrljaju prema

igracu Dok se bacva krece agent ce izracunati put oko nje najbolje što može no nakon

što ona naposljetku stane postat ce dio neprohodnog NavMesha te ce se agenti kretati

oko nje [3]

Slika 51 Prikaz navigacijskog sustava u Unityu

52 Pronalazak puta

Dva glavna problema postoje kod pronalaženja puta kako pronaci destinaciju na ni-

vou na kojem se igrac nalazi te kako se onda tamo pomaknuti Pronalaženje destinacije

uzima u obzir cijelu scenu Pomicanje tamo je dinamicnije u obzir uzima samo smjer

kretanja i kako da sprijeci sudaranje s drugim agentima Da bi se pronašao put izmedu

dvije lokacije prvo se moraju oznaciti pocetna i konacna lokacija njihovim najbližim

poligonima Tada se krece tražiti od pocetne lokacije posjecujuci sve susjedne dok se

ne dode do zadane destinacije Onda se prati unatrag vec posjecene poligone kako bi

se našao konacan niz poligona koji vode od pocetka do kraja Algoritam koji Unity

koristi te se cesto koristi za pronalazak puta naziva se A (A zvjezdica) Taj niz po-

ligona koji opisuje put od pocetka do kraja se naziva hodnik Agent ce doci do svoje

20

destinacije tako da se uvijek usmjerava prema sljedecem vidljivom kutu hodnika Ta

logika usmjeravanja uvijek uzima poziciju sljedeceg kuta i ovisno o tome nade željeni

smjer i brzinu potrebnu za dolazak na destinaciju Korištenje brzine po želji progra-

mera bi moglo dovesti do sudara s ostalim agentima Izbjegavanje prepreka takoder

pronalazi svoju novu brzinu koja traži ravnotežu izmedu kretanja prema destinaciji i

sprjecavanja buducih sudara s ostalim agentima i kutevima u navigacijskom sustavu

Nakon usmjeravanja i izbjegavanja prepreka izracuna se konacna brzina Unity ta-

koder uzima u obzir i akceleraciju kako bi simulirao realisticnije kretanje Takoder

treba razumjeti razliku izmedu globalne i lokalne navigacije Globalna navigacija se

koristi za pronalazak hodnika u svijetu Linearna lista poligona koja opisuje taj put je

podatkovna struktura koja se koristi za usmjeravanje te se može lokalno prilagodavati

i mijenjati kako se pozicija agenta mijenja Lokalna navigacija pokušava naci efika-

san nacin kako da se igrac pomakne prema sljedecem kutu bez da se sudari s ostalim

agentima ili objektima koji se krecu [3]

53 Kreiranje navigacijskog sustava

Proces kreiranja NavMesha iz geometrije nivoa se naziva pecenje navigacijske mreže

(engl NavMesh Baking) Skuplja sve terene i mreže objekata koji su oznaceni kao

navigacijski staticko (engl Navigation Static) i onda ih procesira kako bi kreirao navi-

gacijski sustav koji aproksimira prohodne površine nivoa Izgradnja (engl NavMesha)

je vrlo jednostavna Prvo se selektira geometrija koja bi trebala utjecati na navigaciju

tj površine po kojima možemo hodati i prepreke Oznaci se Navigation Static da bi ih

ukljucili u NavMesh Baking proces Prilagode se postavke kako bi odgovarale velicini

agenta - radijus (npr koliko blizu se može doci zidovima) visina (koliko su nisko

prostori koje agent može doseci) maksimalni nagib (koliko su kose rampe po kojima

se agent može uspeti) visina stube(koliko su visoke prepreke na koje agent može za-

koraciti) Onda jednostavno stisnemo ispeci (engl Bake) da izgradimo svoj NavMesh

Izgradeni NavMesh cemo moci vidjeti kao plavu površinu kao na slici 51 te ce se stvo-

riti nova datoteka s nazivom trenutne scene (ako vec ne postoji) i unutra ce se spremiti

kreiran navigacijski sustav [3]

21

54 Programiranje kretanja

Na liku se trenutno nalazi par stvari Animator Capsule Collider i Rigid Body Sada

je cilj isprogramirati mogucnost odredivanja gdje ce se lik kretati klikom miša na to

mjesto Dodaje se nova komponenta na lika NavMesh Agent Ta komponenta za-

pravo vec ima svoj sudarac te se slobodno može obrisati Capsule Collider jer postaje

nepotreban Igranjem s opcijama pomak od baze (engl Base Offset) te pod izbjegava-

nje prepreka (engl Obstacle Avoidance) radijus (engl Radius) i visina (engl Height)

prilagodi se sudarac od (engl NavMesh Agent-a) kako bi se obujmilo njime igraca i

sprijecilo propadanje kroz tlo od prije Sada kada postoji komponenta navigacije mora

se dodati skripta koja ce odrediti kada se lik krece te kada se pokrecu njegove anima-

cije iz Animator-a

Da bi se znalo gdje se miš nalazi mora se takoder dodati nova skriptu na kameru Kako

bi se izracunalo gdje trenutno kursor pokazuje Unity koristi vec prethodno spomenuto

bacanje zraka Da bi se moglo koristiti navigaciju putem klika mišem mora se napisati

skripta za glavnu kameru koja ce omoguciti bacanje zraka Skripta BacanjeZraka

dodaje se na objekt Main Camera koja se dodala pod prazni objekt Kamera Ova

skriptu se takoder koristi za razlikovanje raznih vrsta objekata Naime svaki objekt

kao što ima i Tag ima i sloj (engl Layer) Sloj služi kako bi mogli npr razlikovati

neprijatelje od obicnih objekata ili mjesto na koje želimo doci hodanjem Zato cemo

takoder dodati i jednu enumeraciju koja ce nam zasad služiti samo da razlikujemo je li

mjesto prohodno ili ne te jesmo li kliknuli na neprijatelja Kako bi dodali svoje nove

slojeve za objekte moramo kliknuti na Layer i dodaj sloj (engl Add Layer) kao na slici

52 što nas dovodi do novog prozora prikazanog na slici 53

Programski kod 51 bacanjeZrakacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

sluzi za dodavanje novih slojeva u Unity

public enum Sloj

Prohodno = 8

Neprijatelj = 9

KrajSvijeta = -1

22

Slika 52 Dodavanje novog sloja

public class BacanjeZraka MonoBehaviour

hijerarhija slojeva tj koji ima veci prioritet

public Sloj[] prioritetiSlojeva =

SlojNeprijatelj

SlojProhodno

SlojKrajSvijeta

udaljenost do pozadine je neka izmisljena vrijednost nakon

koje se prestane provjeravati zraka

public float udaljenostDoPozadine = 100f

Camera kamera

RaycastHit _udara

dohvaca varijable ove klase

public RaycastHit udara

get return _udara

Sloj _udaraSloj

23

Slika 53 Prozor za dodavanje novog sloja

public Sloj udaraSloj

get return _udaraSloj

deklariraj novi tip delegata

public delegate void priPromjeniSloja(Sloj noviSloj)

instanciraj skup promatraca

public event priPromjeniSloja promatraciPromjeneSloja

void Start ()

dohvat glavne kamere

kamera = Cameramain

void Update ()

nadi sloj po prioritetu u koji zraka udara

foreach(Sloj sloj in prioritetiSlojeva)

provjeravamo udara li zraka u neki od slojeva

24

var udar = BacanjeZrakaZaSloj(sloj)

if(udarHasValue)

_udara = udarValue

ako se sloj promjenio

if(_udaraSloj = sloj)

spremi novi sloj u varijablu trenutnog sloja

_udaraSloj = sloj

obavijesti promatrace da se sloj promjenio

promatraciPromjeneSloja(sloj)

spremi novi sloj u varijablu trenutnog sloja

ali ne moras obavjestavati promatrace jer je

sloj jednak starom sloju

_udaraSloj = sloj

return

inace vrati da zraka udara u pozadinu i obavijesti

promatrace

_udaradistance = udaljenostDoPozadine

_udaraSloj = SlojKrajSvijeta

promatraciPromjeneSloja(udaraSloj)

RaycastHit BacanjeZrakaZaSloj(Sloj sloj)

kreira se maska za slojeve bit se pomice ulijevo za

onoliko mjesta koliki je redni broj prioriteta sloja

int maska = 1 ltlt (int)sloj

sprema se mjesto pozicije kursora pretvoreno iz tocke u

zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

RaycastHit udar

PhysicsRaycast sprema zraku u varijablu tipa

RaycastHit prima jos i maksimalnu udaljenost za koju

provjerava zraku i masku sloja i potom vraca istinu (

engl True) ili laz (engl False) ako je zraka udarila

u sloj

25

bool udarioJe = PhysicsRaycast(zraka out udar

udaljenostDoPozadine maska)

ako zraka udara u sloj vrati vrijednost udarca

if(udarioJe)

return udar

return null

U programskom kodu 51 se koristi funkcija za primjenu obrasca promatraca pod

nazivom delegat (engl Delegate) Što je obrazac promatraca (engl Observer) To je

oblikovni obrazac koji se u programiranju koristi

bull kad promjena jednog objekta zahtijeva promjene u drugim objektima koji nisu

unaprijed poznati

bull kad objekt treba obavještavati druge objekte

bull uz uvjet da bude što neovisniji o njima

bull kad je potrebno prikazivati razlicite aspekte nekog dinamickog stanja a želimo

izbjeci ciklicku ovisnost izmedu stanja i pogleda

bull kad postoje dva koncepta jedan ovisan o drugome a zgodno ih je razdvojiti

S obzirom na to da mi samo pri promjeni sloja želimo obavještavati pretplacene pro-

matrace uvodenje delegata nam dosta ubrzava kod Obrazac promatraca funkcionira

tako da glavni objekt igra ulogu izdavaca (izvora informacija) u ovom slucaju to je

glavna kamera Ostali ovisni objekti (promatraci) pretplacuju se kod izdavaca te iz-

davaci obavještavaju pretplatnike o promjenama Promatraci prekidaju pretplatu kad

više ne trebaju obavještavanje Funkcija priPromjeniSloja se definira kao delegat i u

ovom slucaju prima sloj Nakon toga se definira dogadaj (engl Event) tipa tog delegata

(priPromjeniSloja) u ovom slucaju naziva promatraciPromjeneSloja i odsad se unutar

subjekta tim nazivom i poziva Kako bi se neki promatrac pretplatio na informacije

koje izdaje kamera dodaje ove dvije linije koda u svoju skriptu

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

Programski kod 52 služi za kretanje korištenjem NavMesha i lijevog klika miša

26

Programski kod 52 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

public float dovoljnoBlizu = 01f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora

[SerializeField] float hodajKreciStaniRadijus = 02f

void Start ()

pronadi igraca koji je tipa agenta navigacijskog sustava

(engl NavMeshAgent)

agent = GetComponentltUnityEngineAINavMeshAgentgt()

pronadi prethodno napisanu klasu BacanjeZraka

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

spremi trenutnu poziciju kursora

trenutnaPozicijaKursora = transformposition

void Update()

ako je igrac dosao na zeljeno mjesto zaustavi animaciju

hodanja

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

ako je stisnut lijevi klik misa

if (InputGetMouseButtonDown(0))

ovisno o sloju primjeni akciju

switch(bacanjeZrakaudaraSloj)

ako se po objektu na koji je igrac kliknuo moze

hodati

27

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 6: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

1 Uvod

Korištenje Unity razvojne okoline eksponencijalno raste zadnjih par godina Razlog

tomu vjerojatno leži u njegovoj jednostavnosti i poslovnom modelu koji omogucava

besplatno korištenje Unity 5 osobne licence za edukacijske svrhe te za tvrtke s priho-

dima manjim od 100000$ Ono što Unity je i ono što promovira je pojednostavljivanje

svih komponenata potrebnih za razvoj igre No takoder pruža svu slobodu programeru

da dodatno razvije i poboljša njihov sustav u obliku koji njemu najviše odgovara Rad

s animacijama teksturama i modelima je vrlo jednostavan i ne zahtijeva nikakvo zna-

nje programera o njihovom razvoju ili ucitavanju kako bi mogli raditi s njima Tako-

der postoje vec mnogi primjeri programskog koda ponudeni na službenim stranicama

Unitya za dizajnere koji nisu iskusni u programiranju Programski kodovi su odlicno

opisani i rješavaju u par linija teške probleme poput navigacije kamere osvjetljenja

itd Cilj ovog rada je pokazati kako se lako mogu savladati osnove rada u Unityu i

kako iskoristiti naše programersko predznanje dobiveno s dosadašnjim studiranjem za

dodatno poboljšavanje svega što Unity nudi te i za lakše razumijevanje kako vec im-

plementirani algoritmi Unitya funkcioniraju Svako poglavlje predstavlja svojevrsni

zadatak za cije se rješavanje nude razna rješenja i objašnjenje potrebne teorije te na

kraju i opis rješenja koje je iskorišteno u ovom projektu

1

2 Postavljanje pocetne scene

U ovom poglavlju je predstavljena instalacija razvojne okoline Unity te kreiranje po-

cetnog projekta u kojem ce se do kraja ovog rada izradivati zamišljena igra Upoznaje

se s radom konzole i odlucuje se koji programski jezik ce biti korišten Opisuje se i

objašnjava rad u razlicitim prozorima razvojne okoline te snalaženje u samoj sceni ra-

zvoja igre Nakon kraja ovog poglavlja želi se imati instaliran Unity i pokrenut prazan

projekt

21 Instalacija

Kao što je vec navedeno Unity je besplatan za korištenje za privatne edukacijske te

opcenito bilo kakve nekomercijalne svrhe Razvojni alat se može skinuti i instalirati sa

službene stranice Instalacija je prilicno jednostavna te ima detaljna uputstva koja se

mogu slijediti Verzija korištena tijekom ostatka ovog rada je Unity 56 Za kodiranje

skripti korišten je Microsoft Visual Studio 2017 Naravno može se koristiti i Mono

Develop koji dolazi skupa s instalacijom Unitya

22 Kreiranje prve scene

Nakon instalacije Unitya kreira se novi projekt kao što se vidi na slici 21 Odabere

se ime projekta te mjesto na disku gdje ce se spremiti Nakon kreiranja projekta otvara

se klasicna pocetna scena koja se sastoji od glavne kamere te usmjerenog svijetla koji

su oznaceni brojem 1 na slici 22 Brojem 2 na slici 22 je oznacen prozor projekt

(engl Project) gdje ce se nalaziti sve skripte objekti materijali i sl koje cemo kreirati

kroz izradu projekta Sve te komponente se zapravo spremaju na disku ovisno o tome

gdje je Unity instaliran i gdje je postavljeno spremanje projekata Npr za ovaj projekt

je korišteno DUnity ProjectsAlice Prazni projekt spremamo koristeci postupak

datoteka (engl File) -gt spremi scenu kao (engl Save Scene As) kako bi se kreirala

prva scena u Unityu Odabire se proizvoljno ime te se klikne spremi (engl Save)

2

Slika 21 Kreiranje projekta

23 Razvojna okolina Unity

Na slici 22 može se vidjeti ovaj projekt u nekoj kasnijoj fazi rada Koristi se ova slika

za lakše objašnjavanje dijelova razvojne okoline Unity Razlikuju se dva pogleda

pogled scene i pogled igre koji se vide i na slici 22 pod brojem 3 U pogledu scene

ureduje se scena igre dodaju se objekti skripte te sve ostalo što je potrebno Nakon

prebacivanja u pogled igre može se igrati dosad izradena verziju igre to je ono što ce

igrac zapravo vidjeti Na samom vrhu slike 22 oznaceno brojem 4 vidimo tri gumba

kao na slici 23 igraj (engl Play) pauziraj (engl Pause) i korak (engl Step) Ti

gumbi prebacuju pogled u pogled igre Sve promjene koje se naprave nad objektima

u pogledu igre su privremeni te ce se vratiti na staro kada se izade iz tog pogleda

Pritisak na gumb Play automatski prebacuje na prozor igra (engl Game) iz prozora

scena (engl Scene) ciji se nazivi mogu vidjeti ispod tih gumba

Dalje postoje gumbi oznaceni brojem 5 na slici 22 koji pomažu s kretanjem oko scene

i manipulacijom objekata u sceni koji su prikazani na slici 24 Prvi gumb sa slikom

ruke omogucava pomicanje po sceni dok drugi gumb omogucava pomicanje objekata

po sceni Treci gumb služi za rotaciju objekata cetvrti za skaliranje i peti služi za

korisnicko sucelje

3

Slika 22 Razvojna okolina Unity

Slika 23 Gumbi Pokreni Pauziraj i Korak

24 Konzola

Konzola u Unityu vecinom služi za pomoc pri traženju greški u programskom kodu

Može se vidjeti na slici 22 u donjem dijelu Unitya u obliku kartice pored kartice

Project Ako se ne nalazi tamo mora se dodati odlaskom na prozori (engl Windows)-

gt konzola (engl Console) Pritiskom na nju primjecuje se da je skroz prazna i da

imamo još par kartica ocisti (engl Clear) sruši (engl Collapse) ocisti pri pokretanju

(engl Clear On Play) i pri grešci pauziraj (engl Error Pause) Clear služi za cišce-

nje dosad ispisanih poruka Obicno se oznacava Clear On Play da uvijek ocisti stare

poruke te da svaki put kad se pokrene igra dobiju nove Collapse pomaže ako postoji

puno istih poruka npr je korištena while petlja i ceka se neka promjenu u sceni Nije

potrebno da se ispisuje poruka Cekam cijelo vrijeme dok se ceka nego samo jednom

25 Programski jezik

Unity podržava C i Javascript programske jezike te je kroz projekt korišten samo C

Pretpostavlja se da je citatelj upoznat barem sa sintaksom C-a te osnovama objektno

4

Slika 24 Alati za transformaciju

orijentiranog programiranja Nije potrebno veliko znanje C-a kako bi se kodiralo u

Unityu potrebno je samo razumjeti kako se radi s objektima te poznavati sintaksu C-

a zbog rada s razlicitim vrstama varijabli (za razliku od Python-a gdje nije potrebno

specificirati je li varijabla cijeli broj decimalni broj itd) Unutar prozora oznacenim

brojem 2 na slici 22 stisne se desni klik i odabere kreiraj (engl Create) i C skripta

(engl C Script) da se doda nova skripta Duplim klikom na novo-kreiranu skriptu

otvara se Microsoft Visual Studio ili neka druga razvojna okolina koja podržava C u

kojem se sad može pisati programski kod Programski kod 21 je primjer ispisivanja

jednostavne poruke u konzoli

Programski kod 21 HelloWorld1cs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class HelloWorld MonoBehaviour

koristi se za inicijalizaciju

void Start ()

print(Hello World)

Update se zove svaki okvir (engl Frame)

void Update ()

Sada kada se pritisne na gumb Play sa slike 23 može se vidjeti ispis u konzoli Hello

world Još jedan nacin ispisivanja u konzolu je prikazan programskim kodom 22

Programski kod 22 HelloWorld2cs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

5

public class HelloWorld MonoBehaviour

koristi se za inicijalizaciju

void Start ()

DebugLog(Hello world)

Update se zove svaki okvir (engl Frame)

void Update ()

Ne postoji nikakva bitne razlika izmedu ta dva nacina pa se koristi bilo koji

6

3 Unos glavnog lika u scenu

U ovom poglavlju opisuju se neki pocetni problemi s kojima se susrece pri ubacivanju

modela iz popularnog programa za modeliranje Blender Objašnjavaju se i modeli koji

su ponudeni unutar samog Unitya poput kocke i neke osnovne njihove transformacije

Nakon kraja ovog poglavlja želi se imati svojevrsno tlo i ubaceni glavni lik skupa s

njegovim teksturama i animacijama iz Blender-a koji nece propadati kroz tlo

31 Skaliranje

Jedno od osnovnih stvari o kojima se razmišlja prilikom kreiranja igre je koja ce se

brojcana skala koristiti Unity ima svoje mjerne jedinice koji predstavljaju metre u

njegovom fizickom sustavu Ovisno o tipu igre koja se kreira mora se paziti na skali-

ranje Izraduje li se neka igru u svemiru nece se koristiti naše realne mjerne jedinice

nego ce ih se naravno skalirati U ovom slucaju kreira se RPG (Role-playing game)

igra gdje nam je glavni lik covjek te ce se koristiti normalne Unity mjerne jedinice bez

skaliranja

32 Kreiranje osnovnih objekata

Za pocetak potrebno je kreirati jednostavno tlo Kocka se kreira s objekt igre (engl Ga-

meObject) -gt 3D objekt (engl 3D Object) -gt kocka (engl Cube) te se dobiva rezultat

kao na slici 31 Zasad se kocka skalira po x i z osi sa 100 Tlo je uobicajeno zelene

boje pa mu se dodaje novi materijal Pritisne se u prozor imovina (engl Asset) desnim

klikom miša i odabere se kreiraj (engl Create) -gt materijal (engl Material) kao što se

može vidjeti na slici 32 Klikom na novo-stvoreni materijal desno se pojavljuje novi

prozor Inspektor (engl Inspector) gdje se može odabrati boja Nakon toga samo se

povuce lijevim klikom miša materijal na skaliranu kocku tj tlo S obzirom na to

kako se želi da ta skalirana kocka glumi tlo želi se takoder da se i ostali objekti nalaze

7

Slika 31 Kreiranje tla

na njoj Zato ce se tlo morati pomaknuti po y osi za -05 kako bi se olakšalo daljnje

dodavanje objekata

33 Unos Blender modela u Unity i pocetni problemi

Krece se s ubacivanjem svog lika u igru Lik koji se koristi kroz ostatak ovog rada na-

pravljen je u programu Blender koji služi za 3D modeliranje blend objekt se može

samo povuci mišem u Unity iz datoteke u kojoj se nalazi

1 problem Kada se blend datoteka ubacuje u Unity on nece automatski ubaciti i

teksture koje su korištene u izradi tog modela Najlakši nacin bi bio izrada nove dato-

teku unutar Assets datoteke u Unityu i ubacivanje i blend modela i teksture koja je bila

korištena u izradi u tu novu datoteku Nakon toga klikom na model unutar prozora In-

spector pod Materials odabire se opcija od modelovih materijala (engl From Modelrsquos

Material) kao na slici33 kako bi Unity ucitavao korištene teksture Ponekad na žalost

ni to ne funkcionira pa ce se ovdje objasniti još jedan malo opcenitiji pristup Pri unosu

blend modela Unity kreira novu datoteku i nazove ju materijali (engl Materals) Ako

se dogodi da se korištene teksture na modelu ne vide treba se pogledati u tu datoteku

U njoj ce se nalaziti prazni materijali s istim imenima korištenih tekstura kao npr u

slucaju ovog projekta drvo (engl Wood) Tada se mora odabrati u desnom prozoru

materijala albedo (engl Albedo) kao na slici 34 i u ponudenim Assets naci teksturu

koja je korištena (u ovom slucaju Wood)

8

Slika 32 Kreiranje materijala

2 problem Sada kada je lik pozicioniran u ishodištu (x = 0 y = 0 z = 0) može se

dogoditi da se ne nalazi tocno na tlu koje je kreirano To dakako ovisi o modeliranju

koordinatama koje su korištene i skaliranju pri izradi modela Lik korišten u ovom

radu mora se pomaknuti na koordinatu x = 0 y = 15 z = 0 kako bi stajao tocno na tlu

3 problem Kada bi se igra sad pokrenula pritiskom na gumb Play pri vrhu Unitya

lik bi propao kroz tlo Zašto se to dogada Zbog necega što se zove sudarac (engl Col-

lider) u Unityu koji ce kasnije biti pomnije objašnjen Za sada se samo žele postaviti

neke pocetne stvari kako bi bilo lakše testirati osnovnu interakciju lika i objekata u

prostoru U desnom prozoru Inspector kada je lik oznacen vidi se opcija dodaj kom-

ponentu (engl Add Component) Stisne se na to i upiše sudarac u obliku kapsule

(engl Capsule Collider) kako bi se dodao novi sudarac To je zapravo samo sudarac

9

Slika 33 Unos blend modela u scenu

koji je u obliku kapsule te se igrajuci nekim njegovim osnovnim opcijama može na-

mjestiti vanjski oblik lika Dodaje se još jedna komponenta nad likom Ponovno se

stisne na Add Component te upiše kruto tijelo (engl Rigid Body) što ce takoder biti

naknadno objašnjeno Zasad je bitno razumijevanje da to omogucava liku da se ponaša

kao kruto tijelo u prostoru

4 problem Sada bi kada se igra pokrene trebao postojati lik koji ne propada kroz tlo

Naravno kao najosnovniju mehaniku želi se mogucnost kretanja po tom tlu Skripta

koja se treba napraviti kako bi se lik kretao po tlu nije zapravo komplicirana Sastoji

se samo od toga da se prilikom pritiska na odredeno slovo tipkovnice objekt translatira

po prostoru No ovaj model takoder sadrži i animacije za hodanje te se želi i to ukom-

ponirati Zato ce se takoder sada spomenuti još jedna nova komponenta kontrolor

animacija (engl Animator Controller) Dodaje se i ta komponenta na lika i prebacuje

se na prozor animator (engl Animator) koji se vidi na slici 35

U ovom prozoru postoji par novih opcija Mogu se dodavati nova stanja u kojima

ce se lik naci ovisno o nekim uvjetima koji se zadaju Pocetno stanje je ulazno stanje

(engl Entry State) i iz njega se želi da se lik nade u stanju mirovanja Stisne se desni

klik miša i odabere se novo stanje (engl New State) U ovom projektu je nazvano

Mirovanje Iz mirovanja ovisno o tome kada osoba pritisne neku tipku tipkovnice

želi se da se lik krene kretati Zato treba dodati novo stanje Hodanje Doda se

novo stanje istim postupkom kao i prvo Sada se naravno moraju dodati i usmjereni

prijelazi Stisne se desni klik miša na Mirovanje i odabere dodaj prijelaz (engl Add

10

Slika 34 Traženje tekstura Vašeg blend modela

Slika 35 Animator

Transition) To je sada kreiralo usmjerenu strelicu koja se može povuci prema Ho-

danje Isto to se napravi i u suprotnom smjeru Desni klik miša na Hodanje Add

Transition i povuce se strelica prema Mirovanje Naravno moraju se dodati uvjeti

koji ce odredivati kada ce objekt prijeci iz jednog stanja u drugo U ovom slucaju je

korišten cijeli broj (engl Integer) Ostatak problema kretanja rješavat ce se u poglavlju

4 Bacanje zraka i kretanje po mapi s mišem

11

4 Kamera

U ovom poglavlju se postavlja i bira prava kamera za igru Tijekom izrade igre treba se

takoder razmišljati i iz kojeg kuta ce se imati pogled na nju te hoce li se kamera pomi-

cati s kretanjem lika hoce li se moci rotirati itd Pri kreiranju 3D igre u pogledu scene

primjecuje se da su svi objekti i transformacije u 3D-prostoru No s obzirom na to da je

zaslon monitora igraca 2-dimenzionalan te se ne može prikazati tijela kao takva mora

se moci prikazati sve te objekte u jednoj ravnini i zadržati dojam 3-dimenzionalnosti

To se u Unityu postiže s kamerom Kamera je objekt koja definira pogled i njegov

smjer u prostoru scene Pozicija kamere definira ocište z os definira smjer gledanja

(gledište) te y os definira vrh ekrana Kamera takoder definira velicinu i oblik dijela

koji možemo vidjeti Kamera nam pokazuje ono što ona vidi Kako se ona rotira

translatira itd prikaz scene ce se takoder jednako transformirati Nakon kraja ovog

poglavlja želi se imati kamera koja ce pratiti kretnje lika i imati pogled na njega odoz-

gora

41 Perspektivna i ortografska kamera

Kamerom se zapravo objekte 3D prostora projicira na ravninu u 2D prostor Projek-

cije su matematicki modeli koji govore na koji nacin treba tocke 3D prostora preslikati

u ravninu u tocke 2D prostora Postoji više vrsta projekcija no Unity koristi dvije or-

tografsku projekciju i perspektivnu projekciju Kod ortografskih projekcija kamera je

okomita na ravninu projekcije dok je perspektivna projekcija bliža našem nacinu gle-

danja objekata Možda je najlakše primijetiti razliku koristeci slike Dakle na slici 41

možemo vidjeti blend model koji je modeliran u Blenderu u ortografskoj projekciji te

na slici 42 isti taj model pod istim kutem samo prebacen u perspektivnu projekciju

[6]

Perspektivna projekcija uvodi dvije tocke ocište i gledište Ocište je tocka u ko-

joj se nalazi promatrac Gledište odreduje smjer prema kojem promatrac gleda U

12

Slika 41 Ortografska projekcija blend modela

tocki gledišta stvara se ravnina projekcije koja je okomita na spojnicu ocište-gledište

[6] I perspektivna i ortografska kamera imaju granicu do koje mogu vidjeti od svoje

trenutne pozicije Ona je definirana upravo tom ravninom projekcije Tocka gledišta

pripada toj ravnini i ona tipicno postaje ishodište lokalnog dvodimenzijskog koordi-

natnog sustava koji razapinjemo u ravnini projekcije Ta ravnina se još naziva i daleka

ravnina podrezivanja zato što svi objekti koji se nalaze na vecoj udaljenosti od nje se

odrežu te ih kamera ne prikazuje Takoder postoji i ravnina podrezivanja blizu ka-

meri [1] Dio koji se prikazuje se nalazi izmedu te dvije ravnine

42 Pogled iz prvog lica u pogled iznad glave

U igrama se cesto koristi prebacivanje iz jednog u drugi pogled kamere Kako se

to postiže Koristeci veci broj kamera U ovom slucaju obradit ce se samo kratki

primjer kako se prebacivati iz pogleda prvog lica u pogled iznad glave U unity-u je

zadano da jedna kamera pokriva cijeli ekran te se zato samo pogled jedne kamere može

vidjeti u jednom trenutku Kamera koju vidimo je ona koja ima najvecu vrijednost

za svoje svojstvo dubine[1] Zato se želi napraviti skripta koja ce se prebacivati s

jedne kamere na drugu da bi se dobili drukciji pogledi na scenu koja je prikazana

programskim kodom 41

Programski kod 41 PrimjerViseKameracs

13

Slika 42 Perspektivna projekcija blend modela

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kameraPrvogLica

public Camera kameraIznadGlave

funkcija koja se poziva kada se prebacujemo u pogled iznad

glave

public void prikaziPogledIznadGlave()

kameraPrvogLicaenabled = false gasimo kameru prvog

lica

kameraIznadGlaveenabled = true palimo kameru iznad

glave

funkcija koja se poziva kada se prebacujemo u pogled iz

prvog lica

public void prikaziPogledIzPrvogLica()

kameraPrvogLicaenabled = true palimo kameru prvog

lica

overheadCameraenabled = false gasimo kameru iznad

glave

14

43 Fiksirana kamera

U sceni projekta vec postoji glavna kamera (engl Main Camera) koju Unity automat-

ski dodaje u scenu Kako bi ta kamera pratila lika može se samo povuci u lijevom

prozoru hijerarhije u hijerarhiju lika kako bi postala njegovo dijete Tako ce se postici

da kamera stalno prati njegove transformacije (translaciju rotaciju) prilikom pokreta-

nja igre No kako bi se postiglo da kamera ostane uvijek fiksirana te se samo krece s

njime umjesto da se kamera rotira skupa s likom dodaje se novi prazni objekt sa Game

Object -gt kreiraj prazan (engl Create Empty) Njegova pozicija se postavlja na x =

0 y = 0 z = 0 ako vec nije tamo te se postavlja taj prazan objekt kao roditelj glavne

kamere Sada kamera ostaje fiksirana na mjestu te se nece ni kretati s likom Kako bi

se krenula kretati mora se dodati nova skripta na taj prazan objekt koji se odsad u pro-

jektu zove Kamera s obzirom na to da zaista i je roditelj glavne kamere Kako bi se u

skripti lakše locirao objekt igraca oznacava ga se u njegovom polju oznaka (engl Tag)

u desnom prozoru Inspector s igrac (engl Player) kao što se može vidjeti na slici 43

zaokruženo plavom bojom

U programskom kodu se želi napraviti varijabla tipa Game Object kako bi se spremilo

igraca kada ga se pronade Unity takoder ima funkciju FindGameObjectWithTag pa

je onda ostatak koda prilicno intuitivan Kada se igrac pronade pomocu njegove oz-

nake Player prilikom svakog osvježavanja poziciji našeg igraca pridružuje se pozicija

kamere kao što je prikazano programskim kodom 42

Programski kod 42 pratiLikacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class pratiLika MonoBehaviour

GameObject igrac

void Start ()

trazi se objekt putem njegove oznake

igrac = GameObjectFindGameObjectWithTag(Player)

15

Slika 43 Oznacavanje lika radi lakšeg pronalaska u skripti

void LateUpdate ()

trenutni objekt mijenja svoju poziciju u skladu s

pozicijom objekta oznacenog oznakom Player

transformposition = igractransformposition

44 Bacanje zraka (engl Ray casting)

Perspektivna kamera u Unityu koristi oblik krnje piramide za dio koji prikazuje u pros-

toru Svaka tocka nekog objekta kojeg kamera prikazuje zapravo odgovara liniji u pros-

toru svijeta te je nama samo jedna tocka duž te linije vidljiva na objektu Sve iza te

tocke na liniji je zamraceno Vanjski rubovi objekta su definirani razilazecim linijama

16

koje odgovaraju kutevima objekta Kada bi se te linije pratile unazad prema kameri

sve bi na kraju konvergirale u jednu tocku U Unityu se ta tocka nalazi tocno na pozi-

ciji kamere i naziva se centrom perspektive Kut naspram linija koje konvergiraju od

gornjeg i donjeg centra ekrana u centru perspektive se zove vidno polje (engl Field Of

View) Sve što pada izvan tih razilazecih linija na rubovima objekta nece biti vidljivo

kameri uz vec prethodno spomenuta ogranicenja ravnina podrezivanja

U igrama je jako korisno imati matematicku reprezentaciju linije koja predstavlja tocku

u pogledu kamere Unity to omogucava u obliku objekta zrake Zraka uvijek odgo-

vara tocki u pogledu pa klasa Kamera (engl Camera) sadrži dvije korisne funkcije

ScreenPointToRay i ViewportPointToRay Razlika izmedu njih je da ScreenPointToRay

ocekuje tocku s koordinatama piksela dok ViewportPointToRay uzima normalizirane

koordinate (od 0 dolje ili lijevo do 1 gore ili desno) Obje funkcije vracaju zraku

koja se sastoji od tocke ishodišta i vektora koji pokazuje smjer linije od tog ishodišta

Zraka izlazi iz ravnine podrezivanja bliže kameri Najcešce se zrake koriste kako bi ih

bacali u scenu Bacanje zraka pošalje imaginarnu liniju uz zraku od njenog ishodišta

dok ne udari u neki sudarac u sceni Tada vraca informaciju o tocki koju je udarila

u objektu RaycastHit To je vrlo korisno kako bi se locirao objekt ovisno o njegovoj

poziciji na zaslonu npr lociranje kursora prikazano programskim kodom 43

Programski kod 43 lociranjeKursoracs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kamera

void Start()

RaycastHit udar

u objekt Ray se sprema pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

ako zraka udara u neki objekt spremi u objektUdaren to

mjesto

if (PhysicsRaycast(zraka out udar))

Transform objektUdaren = udartransform

17

Ponekad je takoder korisno dobiti zraku koja odgovara poziciji na zaslonu te onda

pomicati kameru uz tu zraku Npr želi se dozvoliti igracu da može selektirati objekt

mišem i onda ga povecati dok se objekt nalazi cijelo vrijeme na istoj poziciji na zaslonu

ispod miša prikazano programskim kodom 44 [1]

Programski kod 44 povecavanjeSlikecs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public bool povecavanje

public float brzinaPovecavanja

public Camera kamera

void Update()

ako netko koristi povecavanje slike (engl Zooming)

if (povecavanje)

u objekt Ray sprema se pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(Input

mousePosition)

udaljenost povecavanja ce biti jednaka umnosku

brzine povecavanja vremena i vertikalnog smjera

float udaljenostPovecavanja = brzinaPovecavanja

InputGetAxis(Vertical) TimedeltaTime

pomakni kameru u smjeru kursora misa za udaljenost

povecavanja u koordinatnom sustavu svijeta

kameratransformTranslate(zrakadirection

udaljenostPovecavanja SpaceWorld)

18

5 Kretanje

Pronalazak puta je zapravo pokušaj aplikacije na racunalu ili algoritma da nade naj-

kracu rutu izmedu dvije tocke To je recimo prakticna verzija rješavanja labirinta Ni

danas ne postoji optimalan algoritam koji ce u svakom slucaju u nekom realno krat-

kom vremenu naci najkraci put U ovom poglavlju objasnit ce se koje algoritme Unity

koristi za svoj navigacijski sustav Objašnjavat ce se i neki osnovni koncepti i obrasci

potrebni za ubrzavanje cijele ideje dojavljivanja promjena u sceni Bit ce prikazani i

programski kodovi potrebni za implementiranje kretanja mišem iili tipkovnicom Na

kraju ovog poglavlja želi se imati lika koji ce se slobodno kretati po sceni na mjesto

koje se odredi klikom miša i mogucnost prebacivanja na upravljanje tipkovnicom

51 Navigacijski sustav u Unityu

U Unityu je problem pronalaska puta vec riješen s necim što se zove navigacijska

mreža (engl NavMesh) To je navigacijski sustav koji ima svoje algoritme pronala-

ska puta i puno pojednostavljuje programiranje kretanja lika Sastoji se od cetiri di-

jela NavMesh agent navigacijske mreže (engl NavMesh Agent) izvanmrežna pove-

zanost(engl Off - Mesh Link) i prepreka navigacijske mreže(engl NavMesh Obstacle)

NavMesh je podatkovna struktura koja opisuje površine po kojima se može kretati

u igri i omogucava pronalazak put od jedne lokacije do druge Navigacijski sustav

treba svoje podatke kako bi predstavio prohodna podrucja u sceni Prohodna podru-

cja definiraju se kao mjesta gdje agent može stajati i kretati se Prohodno podrucje se

automatski izgraduje iz geometrije u sceni testirajuci sva podrucja gdje bi agent mo-

gao stajati Onda se te lokacije spajaju s površinom na vrhu geometrije Ta površina se

naziva onda NavMesh te je možemo vidjeti na 51 NavMesh tada sprema tu površinu

kao konveksne poligone te informacije koji su poligoni susjedni Komponenta Nav-

Mesh Agent pomaže pri kreiranju likova koji se medusobno izbjegavaju dok se krecu

prema cilju U Unityu se agenti opisuju kao valjci Koriste NavMesh kako bi se kretali

i znali koje objekte moraju zaobici te kako da se medusobno zaobidu Off-Mesh Link

19

omogucava dodavanje navigacijskih precaca koji se ne mogu predstaviti kao površina

po kojoj se može hodati npr skakanje preko ograde ili otvaranje vrata prije nego što

se ude u neku prostoriju NavMesh Obstacle opisuje prepreke koje se krecu te koje bi

agenti trebali izbjegavati dok hodaju svijetom npr neke bacve koje se kotrljaju prema

igracu Dok se bacva krece agent ce izracunati put oko nje najbolje što može no nakon

što ona naposljetku stane postat ce dio neprohodnog NavMesha te ce se agenti kretati

oko nje [3]

Slika 51 Prikaz navigacijskog sustava u Unityu

52 Pronalazak puta

Dva glavna problema postoje kod pronalaženja puta kako pronaci destinaciju na ni-

vou na kojem se igrac nalazi te kako se onda tamo pomaknuti Pronalaženje destinacije

uzima u obzir cijelu scenu Pomicanje tamo je dinamicnije u obzir uzima samo smjer

kretanja i kako da sprijeci sudaranje s drugim agentima Da bi se pronašao put izmedu

dvije lokacije prvo se moraju oznaciti pocetna i konacna lokacija njihovim najbližim

poligonima Tada se krece tražiti od pocetne lokacije posjecujuci sve susjedne dok se

ne dode do zadane destinacije Onda se prati unatrag vec posjecene poligone kako bi

se našao konacan niz poligona koji vode od pocetka do kraja Algoritam koji Unity

koristi te se cesto koristi za pronalazak puta naziva se A (A zvjezdica) Taj niz po-

ligona koji opisuje put od pocetka do kraja se naziva hodnik Agent ce doci do svoje

20

destinacije tako da se uvijek usmjerava prema sljedecem vidljivom kutu hodnika Ta

logika usmjeravanja uvijek uzima poziciju sljedeceg kuta i ovisno o tome nade željeni

smjer i brzinu potrebnu za dolazak na destinaciju Korištenje brzine po želji progra-

mera bi moglo dovesti do sudara s ostalim agentima Izbjegavanje prepreka takoder

pronalazi svoju novu brzinu koja traži ravnotežu izmedu kretanja prema destinaciji i

sprjecavanja buducih sudara s ostalim agentima i kutevima u navigacijskom sustavu

Nakon usmjeravanja i izbjegavanja prepreka izracuna se konacna brzina Unity ta-

koder uzima u obzir i akceleraciju kako bi simulirao realisticnije kretanje Takoder

treba razumjeti razliku izmedu globalne i lokalne navigacije Globalna navigacija se

koristi za pronalazak hodnika u svijetu Linearna lista poligona koja opisuje taj put je

podatkovna struktura koja se koristi za usmjeravanje te se može lokalno prilagodavati

i mijenjati kako se pozicija agenta mijenja Lokalna navigacija pokušava naci efika-

san nacin kako da se igrac pomakne prema sljedecem kutu bez da se sudari s ostalim

agentima ili objektima koji se krecu [3]

53 Kreiranje navigacijskog sustava

Proces kreiranja NavMesha iz geometrije nivoa se naziva pecenje navigacijske mreže

(engl NavMesh Baking) Skuplja sve terene i mreže objekata koji su oznaceni kao

navigacijski staticko (engl Navigation Static) i onda ih procesira kako bi kreirao navi-

gacijski sustav koji aproksimira prohodne površine nivoa Izgradnja (engl NavMesha)

je vrlo jednostavna Prvo se selektira geometrija koja bi trebala utjecati na navigaciju

tj površine po kojima možemo hodati i prepreke Oznaci se Navigation Static da bi ih

ukljucili u NavMesh Baking proces Prilagode se postavke kako bi odgovarale velicini

agenta - radijus (npr koliko blizu se može doci zidovima) visina (koliko su nisko

prostori koje agent može doseci) maksimalni nagib (koliko su kose rampe po kojima

se agent može uspeti) visina stube(koliko su visoke prepreke na koje agent može za-

koraciti) Onda jednostavno stisnemo ispeci (engl Bake) da izgradimo svoj NavMesh

Izgradeni NavMesh cemo moci vidjeti kao plavu površinu kao na slici 51 te ce se stvo-

riti nova datoteka s nazivom trenutne scene (ako vec ne postoji) i unutra ce se spremiti

kreiran navigacijski sustav [3]

21

54 Programiranje kretanja

Na liku se trenutno nalazi par stvari Animator Capsule Collider i Rigid Body Sada

je cilj isprogramirati mogucnost odredivanja gdje ce se lik kretati klikom miša na to

mjesto Dodaje se nova komponenta na lika NavMesh Agent Ta komponenta za-

pravo vec ima svoj sudarac te se slobodno može obrisati Capsule Collider jer postaje

nepotreban Igranjem s opcijama pomak od baze (engl Base Offset) te pod izbjegava-

nje prepreka (engl Obstacle Avoidance) radijus (engl Radius) i visina (engl Height)

prilagodi se sudarac od (engl NavMesh Agent-a) kako bi se obujmilo njime igraca i

sprijecilo propadanje kroz tlo od prije Sada kada postoji komponenta navigacije mora

se dodati skripta koja ce odrediti kada se lik krece te kada se pokrecu njegove anima-

cije iz Animator-a

Da bi se znalo gdje se miš nalazi mora se takoder dodati nova skriptu na kameru Kako

bi se izracunalo gdje trenutno kursor pokazuje Unity koristi vec prethodno spomenuto

bacanje zraka Da bi se moglo koristiti navigaciju putem klika mišem mora se napisati

skripta za glavnu kameru koja ce omoguciti bacanje zraka Skripta BacanjeZraka

dodaje se na objekt Main Camera koja se dodala pod prazni objekt Kamera Ova

skriptu se takoder koristi za razlikovanje raznih vrsta objekata Naime svaki objekt

kao što ima i Tag ima i sloj (engl Layer) Sloj služi kako bi mogli npr razlikovati

neprijatelje od obicnih objekata ili mjesto na koje želimo doci hodanjem Zato cemo

takoder dodati i jednu enumeraciju koja ce nam zasad služiti samo da razlikujemo je li

mjesto prohodno ili ne te jesmo li kliknuli na neprijatelja Kako bi dodali svoje nove

slojeve za objekte moramo kliknuti na Layer i dodaj sloj (engl Add Layer) kao na slici

52 što nas dovodi do novog prozora prikazanog na slici 53

Programski kod 51 bacanjeZrakacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

sluzi za dodavanje novih slojeva u Unity

public enum Sloj

Prohodno = 8

Neprijatelj = 9

KrajSvijeta = -1

22

Slika 52 Dodavanje novog sloja

public class BacanjeZraka MonoBehaviour

hijerarhija slojeva tj koji ima veci prioritet

public Sloj[] prioritetiSlojeva =

SlojNeprijatelj

SlojProhodno

SlojKrajSvijeta

udaljenost do pozadine je neka izmisljena vrijednost nakon

koje se prestane provjeravati zraka

public float udaljenostDoPozadine = 100f

Camera kamera

RaycastHit _udara

dohvaca varijable ove klase

public RaycastHit udara

get return _udara

Sloj _udaraSloj

23

Slika 53 Prozor za dodavanje novog sloja

public Sloj udaraSloj

get return _udaraSloj

deklariraj novi tip delegata

public delegate void priPromjeniSloja(Sloj noviSloj)

instanciraj skup promatraca

public event priPromjeniSloja promatraciPromjeneSloja

void Start ()

dohvat glavne kamere

kamera = Cameramain

void Update ()

nadi sloj po prioritetu u koji zraka udara

foreach(Sloj sloj in prioritetiSlojeva)

provjeravamo udara li zraka u neki od slojeva

24

var udar = BacanjeZrakaZaSloj(sloj)

if(udarHasValue)

_udara = udarValue

ako se sloj promjenio

if(_udaraSloj = sloj)

spremi novi sloj u varijablu trenutnog sloja

_udaraSloj = sloj

obavijesti promatrace da se sloj promjenio

promatraciPromjeneSloja(sloj)

spremi novi sloj u varijablu trenutnog sloja

ali ne moras obavjestavati promatrace jer je

sloj jednak starom sloju

_udaraSloj = sloj

return

inace vrati da zraka udara u pozadinu i obavijesti

promatrace

_udaradistance = udaljenostDoPozadine

_udaraSloj = SlojKrajSvijeta

promatraciPromjeneSloja(udaraSloj)

RaycastHit BacanjeZrakaZaSloj(Sloj sloj)

kreira se maska za slojeve bit se pomice ulijevo za

onoliko mjesta koliki je redni broj prioriteta sloja

int maska = 1 ltlt (int)sloj

sprema se mjesto pozicije kursora pretvoreno iz tocke u

zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

RaycastHit udar

PhysicsRaycast sprema zraku u varijablu tipa

RaycastHit prima jos i maksimalnu udaljenost za koju

provjerava zraku i masku sloja i potom vraca istinu (

engl True) ili laz (engl False) ako je zraka udarila

u sloj

25

bool udarioJe = PhysicsRaycast(zraka out udar

udaljenostDoPozadine maska)

ako zraka udara u sloj vrati vrijednost udarca

if(udarioJe)

return udar

return null

U programskom kodu 51 se koristi funkcija za primjenu obrasca promatraca pod

nazivom delegat (engl Delegate) Što je obrazac promatraca (engl Observer) To je

oblikovni obrazac koji se u programiranju koristi

bull kad promjena jednog objekta zahtijeva promjene u drugim objektima koji nisu

unaprijed poznati

bull kad objekt treba obavještavati druge objekte

bull uz uvjet da bude što neovisniji o njima

bull kad je potrebno prikazivati razlicite aspekte nekog dinamickog stanja a želimo

izbjeci ciklicku ovisnost izmedu stanja i pogleda

bull kad postoje dva koncepta jedan ovisan o drugome a zgodno ih je razdvojiti

S obzirom na to da mi samo pri promjeni sloja želimo obavještavati pretplacene pro-

matrace uvodenje delegata nam dosta ubrzava kod Obrazac promatraca funkcionira

tako da glavni objekt igra ulogu izdavaca (izvora informacija) u ovom slucaju to je

glavna kamera Ostali ovisni objekti (promatraci) pretplacuju se kod izdavaca te iz-

davaci obavještavaju pretplatnike o promjenama Promatraci prekidaju pretplatu kad

više ne trebaju obavještavanje Funkcija priPromjeniSloja se definira kao delegat i u

ovom slucaju prima sloj Nakon toga se definira dogadaj (engl Event) tipa tog delegata

(priPromjeniSloja) u ovom slucaju naziva promatraciPromjeneSloja i odsad se unutar

subjekta tim nazivom i poziva Kako bi se neki promatrac pretplatio na informacije

koje izdaje kamera dodaje ove dvije linije koda u svoju skriptu

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

Programski kod 52 služi za kretanje korištenjem NavMesha i lijevog klika miša

26

Programski kod 52 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

public float dovoljnoBlizu = 01f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora

[SerializeField] float hodajKreciStaniRadijus = 02f

void Start ()

pronadi igraca koji je tipa agenta navigacijskog sustava

(engl NavMeshAgent)

agent = GetComponentltUnityEngineAINavMeshAgentgt()

pronadi prethodno napisanu klasu BacanjeZraka

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

spremi trenutnu poziciju kursora

trenutnaPozicijaKursora = transformposition

void Update()

ako je igrac dosao na zeljeno mjesto zaustavi animaciju

hodanja

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

ako je stisnut lijevi klik misa

if (InputGetMouseButtonDown(0))

ovisno o sloju primjeni akciju

switch(bacanjeZrakaudaraSloj)

ako se po objektu na koji je igrac kliknuo moze

hodati

27

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 7: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

2 Postavljanje pocetne scene

U ovom poglavlju je predstavljena instalacija razvojne okoline Unity te kreiranje po-

cetnog projekta u kojem ce se do kraja ovog rada izradivati zamišljena igra Upoznaje

se s radom konzole i odlucuje se koji programski jezik ce biti korišten Opisuje se i

objašnjava rad u razlicitim prozorima razvojne okoline te snalaženje u samoj sceni ra-

zvoja igre Nakon kraja ovog poglavlja želi se imati instaliran Unity i pokrenut prazan

projekt

21 Instalacija

Kao što je vec navedeno Unity je besplatan za korištenje za privatne edukacijske te

opcenito bilo kakve nekomercijalne svrhe Razvojni alat se može skinuti i instalirati sa

službene stranice Instalacija je prilicno jednostavna te ima detaljna uputstva koja se

mogu slijediti Verzija korištena tijekom ostatka ovog rada je Unity 56 Za kodiranje

skripti korišten je Microsoft Visual Studio 2017 Naravno može se koristiti i Mono

Develop koji dolazi skupa s instalacijom Unitya

22 Kreiranje prve scene

Nakon instalacije Unitya kreira se novi projekt kao što se vidi na slici 21 Odabere

se ime projekta te mjesto na disku gdje ce se spremiti Nakon kreiranja projekta otvara

se klasicna pocetna scena koja se sastoji od glavne kamere te usmjerenog svijetla koji

su oznaceni brojem 1 na slici 22 Brojem 2 na slici 22 je oznacen prozor projekt

(engl Project) gdje ce se nalaziti sve skripte objekti materijali i sl koje cemo kreirati

kroz izradu projekta Sve te komponente se zapravo spremaju na disku ovisno o tome

gdje je Unity instaliran i gdje je postavljeno spremanje projekata Npr za ovaj projekt

je korišteno DUnity ProjectsAlice Prazni projekt spremamo koristeci postupak

datoteka (engl File) -gt spremi scenu kao (engl Save Scene As) kako bi se kreirala

prva scena u Unityu Odabire se proizvoljno ime te se klikne spremi (engl Save)

2

Slika 21 Kreiranje projekta

23 Razvojna okolina Unity

Na slici 22 može se vidjeti ovaj projekt u nekoj kasnijoj fazi rada Koristi se ova slika

za lakše objašnjavanje dijelova razvojne okoline Unity Razlikuju se dva pogleda

pogled scene i pogled igre koji se vide i na slici 22 pod brojem 3 U pogledu scene

ureduje se scena igre dodaju se objekti skripte te sve ostalo što je potrebno Nakon

prebacivanja u pogled igre može se igrati dosad izradena verziju igre to je ono što ce

igrac zapravo vidjeti Na samom vrhu slike 22 oznaceno brojem 4 vidimo tri gumba

kao na slici 23 igraj (engl Play) pauziraj (engl Pause) i korak (engl Step) Ti

gumbi prebacuju pogled u pogled igre Sve promjene koje se naprave nad objektima

u pogledu igre su privremeni te ce se vratiti na staro kada se izade iz tog pogleda

Pritisak na gumb Play automatski prebacuje na prozor igra (engl Game) iz prozora

scena (engl Scene) ciji se nazivi mogu vidjeti ispod tih gumba

Dalje postoje gumbi oznaceni brojem 5 na slici 22 koji pomažu s kretanjem oko scene

i manipulacijom objekata u sceni koji su prikazani na slici 24 Prvi gumb sa slikom

ruke omogucava pomicanje po sceni dok drugi gumb omogucava pomicanje objekata

po sceni Treci gumb služi za rotaciju objekata cetvrti za skaliranje i peti služi za

korisnicko sucelje

3

Slika 22 Razvojna okolina Unity

Slika 23 Gumbi Pokreni Pauziraj i Korak

24 Konzola

Konzola u Unityu vecinom služi za pomoc pri traženju greški u programskom kodu

Može se vidjeti na slici 22 u donjem dijelu Unitya u obliku kartice pored kartice

Project Ako se ne nalazi tamo mora se dodati odlaskom na prozori (engl Windows)-

gt konzola (engl Console) Pritiskom na nju primjecuje se da je skroz prazna i da

imamo još par kartica ocisti (engl Clear) sruši (engl Collapse) ocisti pri pokretanju

(engl Clear On Play) i pri grešci pauziraj (engl Error Pause) Clear služi za cišce-

nje dosad ispisanih poruka Obicno se oznacava Clear On Play da uvijek ocisti stare

poruke te da svaki put kad se pokrene igra dobiju nove Collapse pomaže ako postoji

puno istih poruka npr je korištena while petlja i ceka se neka promjenu u sceni Nije

potrebno da se ispisuje poruka Cekam cijelo vrijeme dok se ceka nego samo jednom

25 Programski jezik

Unity podržava C i Javascript programske jezike te je kroz projekt korišten samo C

Pretpostavlja se da je citatelj upoznat barem sa sintaksom C-a te osnovama objektno

4

Slika 24 Alati za transformaciju

orijentiranog programiranja Nije potrebno veliko znanje C-a kako bi se kodiralo u

Unityu potrebno je samo razumjeti kako se radi s objektima te poznavati sintaksu C-

a zbog rada s razlicitim vrstama varijabli (za razliku od Python-a gdje nije potrebno

specificirati je li varijabla cijeli broj decimalni broj itd) Unutar prozora oznacenim

brojem 2 na slici 22 stisne se desni klik i odabere kreiraj (engl Create) i C skripta

(engl C Script) da se doda nova skripta Duplim klikom na novo-kreiranu skriptu

otvara se Microsoft Visual Studio ili neka druga razvojna okolina koja podržava C u

kojem se sad može pisati programski kod Programski kod 21 je primjer ispisivanja

jednostavne poruke u konzoli

Programski kod 21 HelloWorld1cs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class HelloWorld MonoBehaviour

koristi se za inicijalizaciju

void Start ()

print(Hello World)

Update se zove svaki okvir (engl Frame)

void Update ()

Sada kada se pritisne na gumb Play sa slike 23 može se vidjeti ispis u konzoli Hello

world Još jedan nacin ispisivanja u konzolu je prikazan programskim kodom 22

Programski kod 22 HelloWorld2cs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

5

public class HelloWorld MonoBehaviour

koristi se za inicijalizaciju

void Start ()

DebugLog(Hello world)

Update se zove svaki okvir (engl Frame)

void Update ()

Ne postoji nikakva bitne razlika izmedu ta dva nacina pa se koristi bilo koji

6

3 Unos glavnog lika u scenu

U ovom poglavlju opisuju se neki pocetni problemi s kojima se susrece pri ubacivanju

modela iz popularnog programa za modeliranje Blender Objašnjavaju se i modeli koji

su ponudeni unutar samog Unitya poput kocke i neke osnovne njihove transformacije

Nakon kraja ovog poglavlja želi se imati svojevrsno tlo i ubaceni glavni lik skupa s

njegovim teksturama i animacijama iz Blender-a koji nece propadati kroz tlo

31 Skaliranje

Jedno od osnovnih stvari o kojima se razmišlja prilikom kreiranja igre je koja ce se

brojcana skala koristiti Unity ima svoje mjerne jedinice koji predstavljaju metre u

njegovom fizickom sustavu Ovisno o tipu igre koja se kreira mora se paziti na skali-

ranje Izraduje li se neka igru u svemiru nece se koristiti naše realne mjerne jedinice

nego ce ih se naravno skalirati U ovom slucaju kreira se RPG (Role-playing game)

igra gdje nam je glavni lik covjek te ce se koristiti normalne Unity mjerne jedinice bez

skaliranja

32 Kreiranje osnovnih objekata

Za pocetak potrebno je kreirati jednostavno tlo Kocka se kreira s objekt igre (engl Ga-

meObject) -gt 3D objekt (engl 3D Object) -gt kocka (engl Cube) te se dobiva rezultat

kao na slici 31 Zasad se kocka skalira po x i z osi sa 100 Tlo je uobicajeno zelene

boje pa mu se dodaje novi materijal Pritisne se u prozor imovina (engl Asset) desnim

klikom miša i odabere se kreiraj (engl Create) -gt materijal (engl Material) kao što se

može vidjeti na slici 32 Klikom na novo-stvoreni materijal desno se pojavljuje novi

prozor Inspektor (engl Inspector) gdje se može odabrati boja Nakon toga samo se

povuce lijevim klikom miša materijal na skaliranu kocku tj tlo S obzirom na to

kako se želi da ta skalirana kocka glumi tlo želi se takoder da se i ostali objekti nalaze

7

Slika 31 Kreiranje tla

na njoj Zato ce se tlo morati pomaknuti po y osi za -05 kako bi se olakšalo daljnje

dodavanje objekata

33 Unos Blender modela u Unity i pocetni problemi

Krece se s ubacivanjem svog lika u igru Lik koji se koristi kroz ostatak ovog rada na-

pravljen je u programu Blender koji služi za 3D modeliranje blend objekt se može

samo povuci mišem u Unity iz datoteke u kojoj se nalazi

1 problem Kada se blend datoteka ubacuje u Unity on nece automatski ubaciti i

teksture koje su korištene u izradi tog modela Najlakši nacin bi bio izrada nove dato-

teku unutar Assets datoteke u Unityu i ubacivanje i blend modela i teksture koja je bila

korištena u izradi u tu novu datoteku Nakon toga klikom na model unutar prozora In-

spector pod Materials odabire se opcija od modelovih materijala (engl From Modelrsquos

Material) kao na slici33 kako bi Unity ucitavao korištene teksture Ponekad na žalost

ni to ne funkcionira pa ce se ovdje objasniti još jedan malo opcenitiji pristup Pri unosu

blend modela Unity kreira novu datoteku i nazove ju materijali (engl Materals) Ako

se dogodi da se korištene teksture na modelu ne vide treba se pogledati u tu datoteku

U njoj ce se nalaziti prazni materijali s istim imenima korištenih tekstura kao npr u

slucaju ovog projekta drvo (engl Wood) Tada se mora odabrati u desnom prozoru

materijala albedo (engl Albedo) kao na slici 34 i u ponudenim Assets naci teksturu

koja je korištena (u ovom slucaju Wood)

8

Slika 32 Kreiranje materijala

2 problem Sada kada je lik pozicioniran u ishodištu (x = 0 y = 0 z = 0) može se

dogoditi da se ne nalazi tocno na tlu koje je kreirano To dakako ovisi o modeliranju

koordinatama koje su korištene i skaliranju pri izradi modela Lik korišten u ovom

radu mora se pomaknuti na koordinatu x = 0 y = 15 z = 0 kako bi stajao tocno na tlu

3 problem Kada bi se igra sad pokrenula pritiskom na gumb Play pri vrhu Unitya

lik bi propao kroz tlo Zašto se to dogada Zbog necega što se zove sudarac (engl Col-

lider) u Unityu koji ce kasnije biti pomnije objašnjen Za sada se samo žele postaviti

neke pocetne stvari kako bi bilo lakše testirati osnovnu interakciju lika i objekata u

prostoru U desnom prozoru Inspector kada je lik oznacen vidi se opcija dodaj kom-

ponentu (engl Add Component) Stisne se na to i upiše sudarac u obliku kapsule

(engl Capsule Collider) kako bi se dodao novi sudarac To je zapravo samo sudarac

9

Slika 33 Unos blend modela u scenu

koji je u obliku kapsule te se igrajuci nekim njegovim osnovnim opcijama može na-

mjestiti vanjski oblik lika Dodaje se još jedna komponenta nad likom Ponovno se

stisne na Add Component te upiše kruto tijelo (engl Rigid Body) što ce takoder biti

naknadno objašnjeno Zasad je bitno razumijevanje da to omogucava liku da se ponaša

kao kruto tijelo u prostoru

4 problem Sada bi kada se igra pokrene trebao postojati lik koji ne propada kroz tlo

Naravno kao najosnovniju mehaniku želi se mogucnost kretanja po tom tlu Skripta

koja se treba napraviti kako bi se lik kretao po tlu nije zapravo komplicirana Sastoji

se samo od toga da se prilikom pritiska na odredeno slovo tipkovnice objekt translatira

po prostoru No ovaj model takoder sadrži i animacije za hodanje te se želi i to ukom-

ponirati Zato ce se takoder sada spomenuti još jedna nova komponenta kontrolor

animacija (engl Animator Controller) Dodaje se i ta komponenta na lika i prebacuje

se na prozor animator (engl Animator) koji se vidi na slici 35

U ovom prozoru postoji par novih opcija Mogu se dodavati nova stanja u kojima

ce se lik naci ovisno o nekim uvjetima koji se zadaju Pocetno stanje je ulazno stanje

(engl Entry State) i iz njega se želi da se lik nade u stanju mirovanja Stisne se desni

klik miša i odabere se novo stanje (engl New State) U ovom projektu je nazvano

Mirovanje Iz mirovanja ovisno o tome kada osoba pritisne neku tipku tipkovnice

želi se da se lik krene kretati Zato treba dodati novo stanje Hodanje Doda se

novo stanje istim postupkom kao i prvo Sada se naravno moraju dodati i usmjereni

prijelazi Stisne se desni klik miša na Mirovanje i odabere dodaj prijelaz (engl Add

10

Slika 34 Traženje tekstura Vašeg blend modela

Slika 35 Animator

Transition) To je sada kreiralo usmjerenu strelicu koja se može povuci prema Ho-

danje Isto to se napravi i u suprotnom smjeru Desni klik miša na Hodanje Add

Transition i povuce se strelica prema Mirovanje Naravno moraju se dodati uvjeti

koji ce odredivati kada ce objekt prijeci iz jednog stanja u drugo U ovom slucaju je

korišten cijeli broj (engl Integer) Ostatak problema kretanja rješavat ce se u poglavlju

4 Bacanje zraka i kretanje po mapi s mišem

11

4 Kamera

U ovom poglavlju se postavlja i bira prava kamera za igru Tijekom izrade igre treba se

takoder razmišljati i iz kojeg kuta ce se imati pogled na nju te hoce li se kamera pomi-

cati s kretanjem lika hoce li se moci rotirati itd Pri kreiranju 3D igre u pogledu scene

primjecuje se da su svi objekti i transformacije u 3D-prostoru No s obzirom na to da je

zaslon monitora igraca 2-dimenzionalan te se ne može prikazati tijela kao takva mora

se moci prikazati sve te objekte u jednoj ravnini i zadržati dojam 3-dimenzionalnosti

To se u Unityu postiže s kamerom Kamera je objekt koja definira pogled i njegov

smjer u prostoru scene Pozicija kamere definira ocište z os definira smjer gledanja

(gledište) te y os definira vrh ekrana Kamera takoder definira velicinu i oblik dijela

koji možemo vidjeti Kamera nam pokazuje ono što ona vidi Kako se ona rotira

translatira itd prikaz scene ce se takoder jednako transformirati Nakon kraja ovog

poglavlja želi se imati kamera koja ce pratiti kretnje lika i imati pogled na njega odoz-

gora

41 Perspektivna i ortografska kamera

Kamerom se zapravo objekte 3D prostora projicira na ravninu u 2D prostor Projek-

cije su matematicki modeli koji govore na koji nacin treba tocke 3D prostora preslikati

u ravninu u tocke 2D prostora Postoji više vrsta projekcija no Unity koristi dvije or-

tografsku projekciju i perspektivnu projekciju Kod ortografskih projekcija kamera je

okomita na ravninu projekcije dok je perspektivna projekcija bliža našem nacinu gle-

danja objekata Možda je najlakše primijetiti razliku koristeci slike Dakle na slici 41

možemo vidjeti blend model koji je modeliran u Blenderu u ortografskoj projekciji te

na slici 42 isti taj model pod istim kutem samo prebacen u perspektivnu projekciju

[6]

Perspektivna projekcija uvodi dvije tocke ocište i gledište Ocište je tocka u ko-

joj se nalazi promatrac Gledište odreduje smjer prema kojem promatrac gleda U

12

Slika 41 Ortografska projekcija blend modela

tocki gledišta stvara se ravnina projekcije koja je okomita na spojnicu ocište-gledište

[6] I perspektivna i ortografska kamera imaju granicu do koje mogu vidjeti od svoje

trenutne pozicije Ona je definirana upravo tom ravninom projekcije Tocka gledišta

pripada toj ravnini i ona tipicno postaje ishodište lokalnog dvodimenzijskog koordi-

natnog sustava koji razapinjemo u ravnini projekcije Ta ravnina se još naziva i daleka

ravnina podrezivanja zato što svi objekti koji se nalaze na vecoj udaljenosti od nje se

odrežu te ih kamera ne prikazuje Takoder postoji i ravnina podrezivanja blizu ka-

meri [1] Dio koji se prikazuje se nalazi izmedu te dvije ravnine

42 Pogled iz prvog lica u pogled iznad glave

U igrama se cesto koristi prebacivanje iz jednog u drugi pogled kamere Kako se

to postiže Koristeci veci broj kamera U ovom slucaju obradit ce se samo kratki

primjer kako se prebacivati iz pogleda prvog lica u pogled iznad glave U unity-u je

zadano da jedna kamera pokriva cijeli ekran te se zato samo pogled jedne kamere može

vidjeti u jednom trenutku Kamera koju vidimo je ona koja ima najvecu vrijednost

za svoje svojstvo dubine[1] Zato se želi napraviti skripta koja ce se prebacivati s

jedne kamere na drugu da bi se dobili drukciji pogledi na scenu koja je prikazana

programskim kodom 41

Programski kod 41 PrimjerViseKameracs

13

Slika 42 Perspektivna projekcija blend modela

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kameraPrvogLica

public Camera kameraIznadGlave

funkcija koja se poziva kada se prebacujemo u pogled iznad

glave

public void prikaziPogledIznadGlave()

kameraPrvogLicaenabled = false gasimo kameru prvog

lica

kameraIznadGlaveenabled = true palimo kameru iznad

glave

funkcija koja se poziva kada se prebacujemo u pogled iz

prvog lica

public void prikaziPogledIzPrvogLica()

kameraPrvogLicaenabled = true palimo kameru prvog

lica

overheadCameraenabled = false gasimo kameru iznad

glave

14

43 Fiksirana kamera

U sceni projekta vec postoji glavna kamera (engl Main Camera) koju Unity automat-

ski dodaje u scenu Kako bi ta kamera pratila lika može se samo povuci u lijevom

prozoru hijerarhije u hijerarhiju lika kako bi postala njegovo dijete Tako ce se postici

da kamera stalno prati njegove transformacije (translaciju rotaciju) prilikom pokreta-

nja igre No kako bi se postiglo da kamera ostane uvijek fiksirana te se samo krece s

njime umjesto da se kamera rotira skupa s likom dodaje se novi prazni objekt sa Game

Object -gt kreiraj prazan (engl Create Empty) Njegova pozicija se postavlja na x =

0 y = 0 z = 0 ako vec nije tamo te se postavlja taj prazan objekt kao roditelj glavne

kamere Sada kamera ostaje fiksirana na mjestu te se nece ni kretati s likom Kako bi

se krenula kretati mora se dodati nova skripta na taj prazan objekt koji se odsad u pro-

jektu zove Kamera s obzirom na to da zaista i je roditelj glavne kamere Kako bi se u

skripti lakše locirao objekt igraca oznacava ga se u njegovom polju oznaka (engl Tag)

u desnom prozoru Inspector s igrac (engl Player) kao što se može vidjeti na slici 43

zaokruženo plavom bojom

U programskom kodu se želi napraviti varijabla tipa Game Object kako bi se spremilo

igraca kada ga se pronade Unity takoder ima funkciju FindGameObjectWithTag pa

je onda ostatak koda prilicno intuitivan Kada se igrac pronade pomocu njegove oz-

nake Player prilikom svakog osvježavanja poziciji našeg igraca pridružuje se pozicija

kamere kao što je prikazano programskim kodom 42

Programski kod 42 pratiLikacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class pratiLika MonoBehaviour

GameObject igrac

void Start ()

trazi se objekt putem njegove oznake

igrac = GameObjectFindGameObjectWithTag(Player)

15

Slika 43 Oznacavanje lika radi lakšeg pronalaska u skripti

void LateUpdate ()

trenutni objekt mijenja svoju poziciju u skladu s

pozicijom objekta oznacenog oznakom Player

transformposition = igractransformposition

44 Bacanje zraka (engl Ray casting)

Perspektivna kamera u Unityu koristi oblik krnje piramide za dio koji prikazuje u pros-

toru Svaka tocka nekog objekta kojeg kamera prikazuje zapravo odgovara liniji u pros-

toru svijeta te je nama samo jedna tocka duž te linije vidljiva na objektu Sve iza te

tocke na liniji je zamraceno Vanjski rubovi objekta su definirani razilazecim linijama

16

koje odgovaraju kutevima objekta Kada bi se te linije pratile unazad prema kameri

sve bi na kraju konvergirale u jednu tocku U Unityu se ta tocka nalazi tocno na pozi-

ciji kamere i naziva se centrom perspektive Kut naspram linija koje konvergiraju od

gornjeg i donjeg centra ekrana u centru perspektive se zove vidno polje (engl Field Of

View) Sve što pada izvan tih razilazecih linija na rubovima objekta nece biti vidljivo

kameri uz vec prethodno spomenuta ogranicenja ravnina podrezivanja

U igrama je jako korisno imati matematicku reprezentaciju linije koja predstavlja tocku

u pogledu kamere Unity to omogucava u obliku objekta zrake Zraka uvijek odgo-

vara tocki u pogledu pa klasa Kamera (engl Camera) sadrži dvije korisne funkcije

ScreenPointToRay i ViewportPointToRay Razlika izmedu njih je da ScreenPointToRay

ocekuje tocku s koordinatama piksela dok ViewportPointToRay uzima normalizirane

koordinate (od 0 dolje ili lijevo do 1 gore ili desno) Obje funkcije vracaju zraku

koja se sastoji od tocke ishodišta i vektora koji pokazuje smjer linije od tog ishodišta

Zraka izlazi iz ravnine podrezivanja bliže kameri Najcešce se zrake koriste kako bi ih

bacali u scenu Bacanje zraka pošalje imaginarnu liniju uz zraku od njenog ishodišta

dok ne udari u neki sudarac u sceni Tada vraca informaciju o tocki koju je udarila

u objektu RaycastHit To je vrlo korisno kako bi se locirao objekt ovisno o njegovoj

poziciji na zaslonu npr lociranje kursora prikazano programskim kodom 43

Programski kod 43 lociranjeKursoracs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kamera

void Start()

RaycastHit udar

u objekt Ray se sprema pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

ako zraka udara u neki objekt spremi u objektUdaren to

mjesto

if (PhysicsRaycast(zraka out udar))

Transform objektUdaren = udartransform

17

Ponekad je takoder korisno dobiti zraku koja odgovara poziciji na zaslonu te onda

pomicati kameru uz tu zraku Npr želi se dozvoliti igracu da može selektirati objekt

mišem i onda ga povecati dok se objekt nalazi cijelo vrijeme na istoj poziciji na zaslonu

ispod miša prikazano programskim kodom 44 [1]

Programski kod 44 povecavanjeSlikecs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public bool povecavanje

public float brzinaPovecavanja

public Camera kamera

void Update()

ako netko koristi povecavanje slike (engl Zooming)

if (povecavanje)

u objekt Ray sprema se pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(Input

mousePosition)

udaljenost povecavanja ce biti jednaka umnosku

brzine povecavanja vremena i vertikalnog smjera

float udaljenostPovecavanja = brzinaPovecavanja

InputGetAxis(Vertical) TimedeltaTime

pomakni kameru u smjeru kursora misa za udaljenost

povecavanja u koordinatnom sustavu svijeta

kameratransformTranslate(zrakadirection

udaljenostPovecavanja SpaceWorld)

18

5 Kretanje

Pronalazak puta je zapravo pokušaj aplikacije na racunalu ili algoritma da nade naj-

kracu rutu izmedu dvije tocke To je recimo prakticna verzija rješavanja labirinta Ni

danas ne postoji optimalan algoritam koji ce u svakom slucaju u nekom realno krat-

kom vremenu naci najkraci put U ovom poglavlju objasnit ce se koje algoritme Unity

koristi za svoj navigacijski sustav Objašnjavat ce se i neki osnovni koncepti i obrasci

potrebni za ubrzavanje cijele ideje dojavljivanja promjena u sceni Bit ce prikazani i

programski kodovi potrebni za implementiranje kretanja mišem iili tipkovnicom Na

kraju ovog poglavlja želi se imati lika koji ce se slobodno kretati po sceni na mjesto

koje se odredi klikom miša i mogucnost prebacivanja na upravljanje tipkovnicom

51 Navigacijski sustav u Unityu

U Unityu je problem pronalaska puta vec riješen s necim što se zove navigacijska

mreža (engl NavMesh) To je navigacijski sustav koji ima svoje algoritme pronala-

ska puta i puno pojednostavljuje programiranje kretanja lika Sastoji se od cetiri di-

jela NavMesh agent navigacijske mreže (engl NavMesh Agent) izvanmrežna pove-

zanost(engl Off - Mesh Link) i prepreka navigacijske mreže(engl NavMesh Obstacle)

NavMesh je podatkovna struktura koja opisuje površine po kojima se može kretati

u igri i omogucava pronalazak put od jedne lokacije do druge Navigacijski sustav

treba svoje podatke kako bi predstavio prohodna podrucja u sceni Prohodna podru-

cja definiraju se kao mjesta gdje agent može stajati i kretati se Prohodno podrucje se

automatski izgraduje iz geometrije u sceni testirajuci sva podrucja gdje bi agent mo-

gao stajati Onda se te lokacije spajaju s površinom na vrhu geometrije Ta površina se

naziva onda NavMesh te je možemo vidjeti na 51 NavMesh tada sprema tu površinu

kao konveksne poligone te informacije koji su poligoni susjedni Komponenta Nav-

Mesh Agent pomaže pri kreiranju likova koji se medusobno izbjegavaju dok se krecu

prema cilju U Unityu se agenti opisuju kao valjci Koriste NavMesh kako bi se kretali

i znali koje objekte moraju zaobici te kako da se medusobno zaobidu Off-Mesh Link

19

omogucava dodavanje navigacijskih precaca koji se ne mogu predstaviti kao površina

po kojoj se može hodati npr skakanje preko ograde ili otvaranje vrata prije nego što

se ude u neku prostoriju NavMesh Obstacle opisuje prepreke koje se krecu te koje bi

agenti trebali izbjegavati dok hodaju svijetom npr neke bacve koje se kotrljaju prema

igracu Dok se bacva krece agent ce izracunati put oko nje najbolje što može no nakon

što ona naposljetku stane postat ce dio neprohodnog NavMesha te ce se agenti kretati

oko nje [3]

Slika 51 Prikaz navigacijskog sustava u Unityu

52 Pronalazak puta

Dva glavna problema postoje kod pronalaženja puta kako pronaci destinaciju na ni-

vou na kojem se igrac nalazi te kako se onda tamo pomaknuti Pronalaženje destinacije

uzima u obzir cijelu scenu Pomicanje tamo je dinamicnije u obzir uzima samo smjer

kretanja i kako da sprijeci sudaranje s drugim agentima Da bi se pronašao put izmedu

dvije lokacije prvo se moraju oznaciti pocetna i konacna lokacija njihovim najbližim

poligonima Tada se krece tražiti od pocetne lokacije posjecujuci sve susjedne dok se

ne dode do zadane destinacije Onda se prati unatrag vec posjecene poligone kako bi

se našao konacan niz poligona koji vode od pocetka do kraja Algoritam koji Unity

koristi te se cesto koristi za pronalazak puta naziva se A (A zvjezdica) Taj niz po-

ligona koji opisuje put od pocetka do kraja se naziva hodnik Agent ce doci do svoje

20

destinacije tako da se uvijek usmjerava prema sljedecem vidljivom kutu hodnika Ta

logika usmjeravanja uvijek uzima poziciju sljedeceg kuta i ovisno o tome nade željeni

smjer i brzinu potrebnu za dolazak na destinaciju Korištenje brzine po želji progra-

mera bi moglo dovesti do sudara s ostalim agentima Izbjegavanje prepreka takoder

pronalazi svoju novu brzinu koja traži ravnotežu izmedu kretanja prema destinaciji i

sprjecavanja buducih sudara s ostalim agentima i kutevima u navigacijskom sustavu

Nakon usmjeravanja i izbjegavanja prepreka izracuna se konacna brzina Unity ta-

koder uzima u obzir i akceleraciju kako bi simulirao realisticnije kretanje Takoder

treba razumjeti razliku izmedu globalne i lokalne navigacije Globalna navigacija se

koristi za pronalazak hodnika u svijetu Linearna lista poligona koja opisuje taj put je

podatkovna struktura koja se koristi za usmjeravanje te se može lokalno prilagodavati

i mijenjati kako se pozicija agenta mijenja Lokalna navigacija pokušava naci efika-

san nacin kako da se igrac pomakne prema sljedecem kutu bez da se sudari s ostalim

agentima ili objektima koji se krecu [3]

53 Kreiranje navigacijskog sustava

Proces kreiranja NavMesha iz geometrije nivoa se naziva pecenje navigacijske mreže

(engl NavMesh Baking) Skuplja sve terene i mreže objekata koji su oznaceni kao

navigacijski staticko (engl Navigation Static) i onda ih procesira kako bi kreirao navi-

gacijski sustav koji aproksimira prohodne površine nivoa Izgradnja (engl NavMesha)

je vrlo jednostavna Prvo se selektira geometrija koja bi trebala utjecati na navigaciju

tj površine po kojima možemo hodati i prepreke Oznaci se Navigation Static da bi ih

ukljucili u NavMesh Baking proces Prilagode se postavke kako bi odgovarale velicini

agenta - radijus (npr koliko blizu se može doci zidovima) visina (koliko su nisko

prostori koje agent može doseci) maksimalni nagib (koliko su kose rampe po kojima

se agent može uspeti) visina stube(koliko su visoke prepreke na koje agent može za-

koraciti) Onda jednostavno stisnemo ispeci (engl Bake) da izgradimo svoj NavMesh

Izgradeni NavMesh cemo moci vidjeti kao plavu površinu kao na slici 51 te ce se stvo-

riti nova datoteka s nazivom trenutne scene (ako vec ne postoji) i unutra ce se spremiti

kreiran navigacijski sustav [3]

21

54 Programiranje kretanja

Na liku se trenutno nalazi par stvari Animator Capsule Collider i Rigid Body Sada

je cilj isprogramirati mogucnost odredivanja gdje ce se lik kretati klikom miša na to

mjesto Dodaje se nova komponenta na lika NavMesh Agent Ta komponenta za-

pravo vec ima svoj sudarac te se slobodno može obrisati Capsule Collider jer postaje

nepotreban Igranjem s opcijama pomak od baze (engl Base Offset) te pod izbjegava-

nje prepreka (engl Obstacle Avoidance) radijus (engl Radius) i visina (engl Height)

prilagodi se sudarac od (engl NavMesh Agent-a) kako bi se obujmilo njime igraca i

sprijecilo propadanje kroz tlo od prije Sada kada postoji komponenta navigacije mora

se dodati skripta koja ce odrediti kada se lik krece te kada se pokrecu njegove anima-

cije iz Animator-a

Da bi se znalo gdje se miš nalazi mora se takoder dodati nova skriptu na kameru Kako

bi se izracunalo gdje trenutno kursor pokazuje Unity koristi vec prethodno spomenuto

bacanje zraka Da bi se moglo koristiti navigaciju putem klika mišem mora se napisati

skripta za glavnu kameru koja ce omoguciti bacanje zraka Skripta BacanjeZraka

dodaje se na objekt Main Camera koja se dodala pod prazni objekt Kamera Ova

skriptu se takoder koristi za razlikovanje raznih vrsta objekata Naime svaki objekt

kao što ima i Tag ima i sloj (engl Layer) Sloj služi kako bi mogli npr razlikovati

neprijatelje od obicnih objekata ili mjesto na koje želimo doci hodanjem Zato cemo

takoder dodati i jednu enumeraciju koja ce nam zasad služiti samo da razlikujemo je li

mjesto prohodno ili ne te jesmo li kliknuli na neprijatelja Kako bi dodali svoje nove

slojeve za objekte moramo kliknuti na Layer i dodaj sloj (engl Add Layer) kao na slici

52 što nas dovodi do novog prozora prikazanog na slici 53

Programski kod 51 bacanjeZrakacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

sluzi za dodavanje novih slojeva u Unity

public enum Sloj

Prohodno = 8

Neprijatelj = 9

KrajSvijeta = -1

22

Slika 52 Dodavanje novog sloja

public class BacanjeZraka MonoBehaviour

hijerarhija slojeva tj koji ima veci prioritet

public Sloj[] prioritetiSlojeva =

SlojNeprijatelj

SlojProhodno

SlojKrajSvijeta

udaljenost do pozadine je neka izmisljena vrijednost nakon

koje se prestane provjeravati zraka

public float udaljenostDoPozadine = 100f

Camera kamera

RaycastHit _udara

dohvaca varijable ove klase

public RaycastHit udara

get return _udara

Sloj _udaraSloj

23

Slika 53 Prozor za dodavanje novog sloja

public Sloj udaraSloj

get return _udaraSloj

deklariraj novi tip delegata

public delegate void priPromjeniSloja(Sloj noviSloj)

instanciraj skup promatraca

public event priPromjeniSloja promatraciPromjeneSloja

void Start ()

dohvat glavne kamere

kamera = Cameramain

void Update ()

nadi sloj po prioritetu u koji zraka udara

foreach(Sloj sloj in prioritetiSlojeva)

provjeravamo udara li zraka u neki od slojeva

24

var udar = BacanjeZrakaZaSloj(sloj)

if(udarHasValue)

_udara = udarValue

ako se sloj promjenio

if(_udaraSloj = sloj)

spremi novi sloj u varijablu trenutnog sloja

_udaraSloj = sloj

obavijesti promatrace da se sloj promjenio

promatraciPromjeneSloja(sloj)

spremi novi sloj u varijablu trenutnog sloja

ali ne moras obavjestavati promatrace jer je

sloj jednak starom sloju

_udaraSloj = sloj

return

inace vrati da zraka udara u pozadinu i obavijesti

promatrace

_udaradistance = udaljenostDoPozadine

_udaraSloj = SlojKrajSvijeta

promatraciPromjeneSloja(udaraSloj)

RaycastHit BacanjeZrakaZaSloj(Sloj sloj)

kreira se maska za slojeve bit se pomice ulijevo za

onoliko mjesta koliki je redni broj prioriteta sloja

int maska = 1 ltlt (int)sloj

sprema se mjesto pozicije kursora pretvoreno iz tocke u

zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

RaycastHit udar

PhysicsRaycast sprema zraku u varijablu tipa

RaycastHit prima jos i maksimalnu udaljenost za koju

provjerava zraku i masku sloja i potom vraca istinu (

engl True) ili laz (engl False) ako je zraka udarila

u sloj

25

bool udarioJe = PhysicsRaycast(zraka out udar

udaljenostDoPozadine maska)

ako zraka udara u sloj vrati vrijednost udarca

if(udarioJe)

return udar

return null

U programskom kodu 51 se koristi funkcija za primjenu obrasca promatraca pod

nazivom delegat (engl Delegate) Što je obrazac promatraca (engl Observer) To je

oblikovni obrazac koji se u programiranju koristi

bull kad promjena jednog objekta zahtijeva promjene u drugim objektima koji nisu

unaprijed poznati

bull kad objekt treba obavještavati druge objekte

bull uz uvjet da bude što neovisniji o njima

bull kad je potrebno prikazivati razlicite aspekte nekog dinamickog stanja a želimo

izbjeci ciklicku ovisnost izmedu stanja i pogleda

bull kad postoje dva koncepta jedan ovisan o drugome a zgodno ih je razdvojiti

S obzirom na to da mi samo pri promjeni sloja želimo obavještavati pretplacene pro-

matrace uvodenje delegata nam dosta ubrzava kod Obrazac promatraca funkcionira

tako da glavni objekt igra ulogu izdavaca (izvora informacija) u ovom slucaju to je

glavna kamera Ostali ovisni objekti (promatraci) pretplacuju se kod izdavaca te iz-

davaci obavještavaju pretplatnike o promjenama Promatraci prekidaju pretplatu kad

više ne trebaju obavještavanje Funkcija priPromjeniSloja se definira kao delegat i u

ovom slucaju prima sloj Nakon toga se definira dogadaj (engl Event) tipa tog delegata

(priPromjeniSloja) u ovom slucaju naziva promatraciPromjeneSloja i odsad se unutar

subjekta tim nazivom i poziva Kako bi se neki promatrac pretplatio na informacije

koje izdaje kamera dodaje ove dvije linije koda u svoju skriptu

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

Programski kod 52 služi za kretanje korištenjem NavMesha i lijevog klika miša

26

Programski kod 52 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

public float dovoljnoBlizu = 01f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora

[SerializeField] float hodajKreciStaniRadijus = 02f

void Start ()

pronadi igraca koji je tipa agenta navigacijskog sustava

(engl NavMeshAgent)

agent = GetComponentltUnityEngineAINavMeshAgentgt()

pronadi prethodno napisanu klasu BacanjeZraka

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

spremi trenutnu poziciju kursora

trenutnaPozicijaKursora = transformposition

void Update()

ako je igrac dosao na zeljeno mjesto zaustavi animaciju

hodanja

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

ako je stisnut lijevi klik misa

if (InputGetMouseButtonDown(0))

ovisno o sloju primjeni akciju

switch(bacanjeZrakaudaraSloj)

ako se po objektu na koji je igrac kliknuo moze

hodati

27

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 8: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

Slika 21 Kreiranje projekta

23 Razvojna okolina Unity

Na slici 22 može se vidjeti ovaj projekt u nekoj kasnijoj fazi rada Koristi se ova slika

za lakše objašnjavanje dijelova razvojne okoline Unity Razlikuju se dva pogleda

pogled scene i pogled igre koji se vide i na slici 22 pod brojem 3 U pogledu scene

ureduje se scena igre dodaju se objekti skripte te sve ostalo što je potrebno Nakon

prebacivanja u pogled igre može se igrati dosad izradena verziju igre to je ono što ce

igrac zapravo vidjeti Na samom vrhu slike 22 oznaceno brojem 4 vidimo tri gumba

kao na slici 23 igraj (engl Play) pauziraj (engl Pause) i korak (engl Step) Ti

gumbi prebacuju pogled u pogled igre Sve promjene koje se naprave nad objektima

u pogledu igre su privremeni te ce se vratiti na staro kada se izade iz tog pogleda

Pritisak na gumb Play automatski prebacuje na prozor igra (engl Game) iz prozora

scena (engl Scene) ciji se nazivi mogu vidjeti ispod tih gumba

Dalje postoje gumbi oznaceni brojem 5 na slici 22 koji pomažu s kretanjem oko scene

i manipulacijom objekata u sceni koji su prikazani na slici 24 Prvi gumb sa slikom

ruke omogucava pomicanje po sceni dok drugi gumb omogucava pomicanje objekata

po sceni Treci gumb služi za rotaciju objekata cetvrti za skaliranje i peti služi za

korisnicko sucelje

3

Slika 22 Razvojna okolina Unity

Slika 23 Gumbi Pokreni Pauziraj i Korak

24 Konzola

Konzola u Unityu vecinom služi za pomoc pri traženju greški u programskom kodu

Može se vidjeti na slici 22 u donjem dijelu Unitya u obliku kartice pored kartice

Project Ako se ne nalazi tamo mora se dodati odlaskom na prozori (engl Windows)-

gt konzola (engl Console) Pritiskom na nju primjecuje se da je skroz prazna i da

imamo još par kartica ocisti (engl Clear) sruši (engl Collapse) ocisti pri pokretanju

(engl Clear On Play) i pri grešci pauziraj (engl Error Pause) Clear služi za cišce-

nje dosad ispisanih poruka Obicno se oznacava Clear On Play da uvijek ocisti stare

poruke te da svaki put kad se pokrene igra dobiju nove Collapse pomaže ako postoji

puno istih poruka npr je korištena while petlja i ceka se neka promjenu u sceni Nije

potrebno da se ispisuje poruka Cekam cijelo vrijeme dok se ceka nego samo jednom

25 Programski jezik

Unity podržava C i Javascript programske jezike te je kroz projekt korišten samo C

Pretpostavlja se da je citatelj upoznat barem sa sintaksom C-a te osnovama objektno

4

Slika 24 Alati za transformaciju

orijentiranog programiranja Nije potrebno veliko znanje C-a kako bi se kodiralo u

Unityu potrebno je samo razumjeti kako se radi s objektima te poznavati sintaksu C-

a zbog rada s razlicitim vrstama varijabli (za razliku od Python-a gdje nije potrebno

specificirati je li varijabla cijeli broj decimalni broj itd) Unutar prozora oznacenim

brojem 2 na slici 22 stisne se desni klik i odabere kreiraj (engl Create) i C skripta

(engl C Script) da se doda nova skripta Duplim klikom na novo-kreiranu skriptu

otvara se Microsoft Visual Studio ili neka druga razvojna okolina koja podržava C u

kojem se sad može pisati programski kod Programski kod 21 je primjer ispisivanja

jednostavne poruke u konzoli

Programski kod 21 HelloWorld1cs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class HelloWorld MonoBehaviour

koristi se za inicijalizaciju

void Start ()

print(Hello World)

Update se zove svaki okvir (engl Frame)

void Update ()

Sada kada se pritisne na gumb Play sa slike 23 može se vidjeti ispis u konzoli Hello

world Još jedan nacin ispisivanja u konzolu je prikazan programskim kodom 22

Programski kod 22 HelloWorld2cs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

5

public class HelloWorld MonoBehaviour

koristi se za inicijalizaciju

void Start ()

DebugLog(Hello world)

Update se zove svaki okvir (engl Frame)

void Update ()

Ne postoji nikakva bitne razlika izmedu ta dva nacina pa se koristi bilo koji

6

3 Unos glavnog lika u scenu

U ovom poglavlju opisuju se neki pocetni problemi s kojima se susrece pri ubacivanju

modela iz popularnog programa za modeliranje Blender Objašnjavaju se i modeli koji

su ponudeni unutar samog Unitya poput kocke i neke osnovne njihove transformacije

Nakon kraja ovog poglavlja želi se imati svojevrsno tlo i ubaceni glavni lik skupa s

njegovim teksturama i animacijama iz Blender-a koji nece propadati kroz tlo

31 Skaliranje

Jedno od osnovnih stvari o kojima se razmišlja prilikom kreiranja igre je koja ce se

brojcana skala koristiti Unity ima svoje mjerne jedinice koji predstavljaju metre u

njegovom fizickom sustavu Ovisno o tipu igre koja se kreira mora se paziti na skali-

ranje Izraduje li se neka igru u svemiru nece se koristiti naše realne mjerne jedinice

nego ce ih se naravno skalirati U ovom slucaju kreira se RPG (Role-playing game)

igra gdje nam je glavni lik covjek te ce se koristiti normalne Unity mjerne jedinice bez

skaliranja

32 Kreiranje osnovnih objekata

Za pocetak potrebno je kreirati jednostavno tlo Kocka se kreira s objekt igre (engl Ga-

meObject) -gt 3D objekt (engl 3D Object) -gt kocka (engl Cube) te se dobiva rezultat

kao na slici 31 Zasad se kocka skalira po x i z osi sa 100 Tlo je uobicajeno zelene

boje pa mu se dodaje novi materijal Pritisne se u prozor imovina (engl Asset) desnim

klikom miša i odabere se kreiraj (engl Create) -gt materijal (engl Material) kao što se

može vidjeti na slici 32 Klikom na novo-stvoreni materijal desno se pojavljuje novi

prozor Inspektor (engl Inspector) gdje se može odabrati boja Nakon toga samo se

povuce lijevim klikom miša materijal na skaliranu kocku tj tlo S obzirom na to

kako se želi da ta skalirana kocka glumi tlo želi se takoder da se i ostali objekti nalaze

7

Slika 31 Kreiranje tla

na njoj Zato ce se tlo morati pomaknuti po y osi za -05 kako bi se olakšalo daljnje

dodavanje objekata

33 Unos Blender modela u Unity i pocetni problemi

Krece se s ubacivanjem svog lika u igru Lik koji se koristi kroz ostatak ovog rada na-

pravljen je u programu Blender koji služi za 3D modeliranje blend objekt se može

samo povuci mišem u Unity iz datoteke u kojoj se nalazi

1 problem Kada se blend datoteka ubacuje u Unity on nece automatski ubaciti i

teksture koje su korištene u izradi tog modela Najlakši nacin bi bio izrada nove dato-

teku unutar Assets datoteke u Unityu i ubacivanje i blend modela i teksture koja je bila

korištena u izradi u tu novu datoteku Nakon toga klikom na model unutar prozora In-

spector pod Materials odabire se opcija od modelovih materijala (engl From Modelrsquos

Material) kao na slici33 kako bi Unity ucitavao korištene teksture Ponekad na žalost

ni to ne funkcionira pa ce se ovdje objasniti još jedan malo opcenitiji pristup Pri unosu

blend modela Unity kreira novu datoteku i nazove ju materijali (engl Materals) Ako

se dogodi da se korištene teksture na modelu ne vide treba se pogledati u tu datoteku

U njoj ce se nalaziti prazni materijali s istim imenima korištenih tekstura kao npr u

slucaju ovog projekta drvo (engl Wood) Tada se mora odabrati u desnom prozoru

materijala albedo (engl Albedo) kao na slici 34 i u ponudenim Assets naci teksturu

koja je korištena (u ovom slucaju Wood)

8

Slika 32 Kreiranje materijala

2 problem Sada kada je lik pozicioniran u ishodištu (x = 0 y = 0 z = 0) može se

dogoditi da se ne nalazi tocno na tlu koje je kreirano To dakako ovisi o modeliranju

koordinatama koje su korištene i skaliranju pri izradi modela Lik korišten u ovom

radu mora se pomaknuti na koordinatu x = 0 y = 15 z = 0 kako bi stajao tocno na tlu

3 problem Kada bi se igra sad pokrenula pritiskom na gumb Play pri vrhu Unitya

lik bi propao kroz tlo Zašto se to dogada Zbog necega što se zove sudarac (engl Col-

lider) u Unityu koji ce kasnije biti pomnije objašnjen Za sada se samo žele postaviti

neke pocetne stvari kako bi bilo lakše testirati osnovnu interakciju lika i objekata u

prostoru U desnom prozoru Inspector kada je lik oznacen vidi se opcija dodaj kom-

ponentu (engl Add Component) Stisne se na to i upiše sudarac u obliku kapsule

(engl Capsule Collider) kako bi se dodao novi sudarac To je zapravo samo sudarac

9

Slika 33 Unos blend modela u scenu

koji je u obliku kapsule te se igrajuci nekim njegovim osnovnim opcijama može na-

mjestiti vanjski oblik lika Dodaje se još jedna komponenta nad likom Ponovno se

stisne na Add Component te upiše kruto tijelo (engl Rigid Body) što ce takoder biti

naknadno objašnjeno Zasad je bitno razumijevanje da to omogucava liku da se ponaša

kao kruto tijelo u prostoru

4 problem Sada bi kada se igra pokrene trebao postojati lik koji ne propada kroz tlo

Naravno kao najosnovniju mehaniku želi se mogucnost kretanja po tom tlu Skripta

koja se treba napraviti kako bi se lik kretao po tlu nije zapravo komplicirana Sastoji

se samo od toga da se prilikom pritiska na odredeno slovo tipkovnice objekt translatira

po prostoru No ovaj model takoder sadrži i animacije za hodanje te se želi i to ukom-

ponirati Zato ce se takoder sada spomenuti još jedna nova komponenta kontrolor

animacija (engl Animator Controller) Dodaje se i ta komponenta na lika i prebacuje

se na prozor animator (engl Animator) koji se vidi na slici 35

U ovom prozoru postoji par novih opcija Mogu se dodavati nova stanja u kojima

ce se lik naci ovisno o nekim uvjetima koji se zadaju Pocetno stanje je ulazno stanje

(engl Entry State) i iz njega se želi da se lik nade u stanju mirovanja Stisne se desni

klik miša i odabere se novo stanje (engl New State) U ovom projektu je nazvano

Mirovanje Iz mirovanja ovisno o tome kada osoba pritisne neku tipku tipkovnice

želi se da se lik krene kretati Zato treba dodati novo stanje Hodanje Doda se

novo stanje istim postupkom kao i prvo Sada se naravno moraju dodati i usmjereni

prijelazi Stisne se desni klik miša na Mirovanje i odabere dodaj prijelaz (engl Add

10

Slika 34 Traženje tekstura Vašeg blend modela

Slika 35 Animator

Transition) To je sada kreiralo usmjerenu strelicu koja se može povuci prema Ho-

danje Isto to se napravi i u suprotnom smjeru Desni klik miša na Hodanje Add

Transition i povuce se strelica prema Mirovanje Naravno moraju se dodati uvjeti

koji ce odredivati kada ce objekt prijeci iz jednog stanja u drugo U ovom slucaju je

korišten cijeli broj (engl Integer) Ostatak problema kretanja rješavat ce se u poglavlju

4 Bacanje zraka i kretanje po mapi s mišem

11

4 Kamera

U ovom poglavlju se postavlja i bira prava kamera za igru Tijekom izrade igre treba se

takoder razmišljati i iz kojeg kuta ce se imati pogled na nju te hoce li se kamera pomi-

cati s kretanjem lika hoce li se moci rotirati itd Pri kreiranju 3D igre u pogledu scene

primjecuje se da su svi objekti i transformacije u 3D-prostoru No s obzirom na to da je

zaslon monitora igraca 2-dimenzionalan te se ne može prikazati tijela kao takva mora

se moci prikazati sve te objekte u jednoj ravnini i zadržati dojam 3-dimenzionalnosti

To se u Unityu postiže s kamerom Kamera je objekt koja definira pogled i njegov

smjer u prostoru scene Pozicija kamere definira ocište z os definira smjer gledanja

(gledište) te y os definira vrh ekrana Kamera takoder definira velicinu i oblik dijela

koji možemo vidjeti Kamera nam pokazuje ono što ona vidi Kako se ona rotira

translatira itd prikaz scene ce se takoder jednako transformirati Nakon kraja ovog

poglavlja želi se imati kamera koja ce pratiti kretnje lika i imati pogled na njega odoz-

gora

41 Perspektivna i ortografska kamera

Kamerom se zapravo objekte 3D prostora projicira na ravninu u 2D prostor Projek-

cije su matematicki modeli koji govore na koji nacin treba tocke 3D prostora preslikati

u ravninu u tocke 2D prostora Postoji više vrsta projekcija no Unity koristi dvije or-

tografsku projekciju i perspektivnu projekciju Kod ortografskih projekcija kamera je

okomita na ravninu projekcije dok je perspektivna projekcija bliža našem nacinu gle-

danja objekata Možda je najlakše primijetiti razliku koristeci slike Dakle na slici 41

možemo vidjeti blend model koji je modeliran u Blenderu u ortografskoj projekciji te

na slici 42 isti taj model pod istim kutem samo prebacen u perspektivnu projekciju

[6]

Perspektivna projekcija uvodi dvije tocke ocište i gledište Ocište je tocka u ko-

joj se nalazi promatrac Gledište odreduje smjer prema kojem promatrac gleda U

12

Slika 41 Ortografska projekcija blend modela

tocki gledišta stvara se ravnina projekcije koja je okomita na spojnicu ocište-gledište

[6] I perspektivna i ortografska kamera imaju granicu do koje mogu vidjeti od svoje

trenutne pozicije Ona je definirana upravo tom ravninom projekcije Tocka gledišta

pripada toj ravnini i ona tipicno postaje ishodište lokalnog dvodimenzijskog koordi-

natnog sustava koji razapinjemo u ravnini projekcije Ta ravnina se još naziva i daleka

ravnina podrezivanja zato što svi objekti koji se nalaze na vecoj udaljenosti od nje se

odrežu te ih kamera ne prikazuje Takoder postoji i ravnina podrezivanja blizu ka-

meri [1] Dio koji se prikazuje se nalazi izmedu te dvije ravnine

42 Pogled iz prvog lica u pogled iznad glave

U igrama se cesto koristi prebacivanje iz jednog u drugi pogled kamere Kako se

to postiže Koristeci veci broj kamera U ovom slucaju obradit ce se samo kratki

primjer kako se prebacivati iz pogleda prvog lica u pogled iznad glave U unity-u je

zadano da jedna kamera pokriva cijeli ekran te se zato samo pogled jedne kamere može

vidjeti u jednom trenutku Kamera koju vidimo je ona koja ima najvecu vrijednost

za svoje svojstvo dubine[1] Zato se želi napraviti skripta koja ce se prebacivati s

jedne kamere na drugu da bi se dobili drukciji pogledi na scenu koja je prikazana

programskim kodom 41

Programski kod 41 PrimjerViseKameracs

13

Slika 42 Perspektivna projekcija blend modela

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kameraPrvogLica

public Camera kameraIznadGlave

funkcija koja se poziva kada se prebacujemo u pogled iznad

glave

public void prikaziPogledIznadGlave()

kameraPrvogLicaenabled = false gasimo kameru prvog

lica

kameraIznadGlaveenabled = true palimo kameru iznad

glave

funkcija koja se poziva kada se prebacujemo u pogled iz

prvog lica

public void prikaziPogledIzPrvogLica()

kameraPrvogLicaenabled = true palimo kameru prvog

lica

overheadCameraenabled = false gasimo kameru iznad

glave

14

43 Fiksirana kamera

U sceni projekta vec postoji glavna kamera (engl Main Camera) koju Unity automat-

ski dodaje u scenu Kako bi ta kamera pratila lika može se samo povuci u lijevom

prozoru hijerarhije u hijerarhiju lika kako bi postala njegovo dijete Tako ce se postici

da kamera stalno prati njegove transformacije (translaciju rotaciju) prilikom pokreta-

nja igre No kako bi se postiglo da kamera ostane uvijek fiksirana te se samo krece s

njime umjesto da se kamera rotira skupa s likom dodaje se novi prazni objekt sa Game

Object -gt kreiraj prazan (engl Create Empty) Njegova pozicija se postavlja na x =

0 y = 0 z = 0 ako vec nije tamo te se postavlja taj prazan objekt kao roditelj glavne

kamere Sada kamera ostaje fiksirana na mjestu te se nece ni kretati s likom Kako bi

se krenula kretati mora se dodati nova skripta na taj prazan objekt koji se odsad u pro-

jektu zove Kamera s obzirom na to da zaista i je roditelj glavne kamere Kako bi se u

skripti lakše locirao objekt igraca oznacava ga se u njegovom polju oznaka (engl Tag)

u desnom prozoru Inspector s igrac (engl Player) kao što se može vidjeti na slici 43

zaokruženo plavom bojom

U programskom kodu se želi napraviti varijabla tipa Game Object kako bi se spremilo

igraca kada ga se pronade Unity takoder ima funkciju FindGameObjectWithTag pa

je onda ostatak koda prilicno intuitivan Kada se igrac pronade pomocu njegove oz-

nake Player prilikom svakog osvježavanja poziciji našeg igraca pridružuje se pozicija

kamere kao što je prikazano programskim kodom 42

Programski kod 42 pratiLikacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class pratiLika MonoBehaviour

GameObject igrac

void Start ()

trazi se objekt putem njegove oznake

igrac = GameObjectFindGameObjectWithTag(Player)

15

Slika 43 Oznacavanje lika radi lakšeg pronalaska u skripti

void LateUpdate ()

trenutni objekt mijenja svoju poziciju u skladu s

pozicijom objekta oznacenog oznakom Player

transformposition = igractransformposition

44 Bacanje zraka (engl Ray casting)

Perspektivna kamera u Unityu koristi oblik krnje piramide za dio koji prikazuje u pros-

toru Svaka tocka nekog objekta kojeg kamera prikazuje zapravo odgovara liniji u pros-

toru svijeta te je nama samo jedna tocka duž te linije vidljiva na objektu Sve iza te

tocke na liniji je zamraceno Vanjski rubovi objekta su definirani razilazecim linijama

16

koje odgovaraju kutevima objekta Kada bi se te linije pratile unazad prema kameri

sve bi na kraju konvergirale u jednu tocku U Unityu se ta tocka nalazi tocno na pozi-

ciji kamere i naziva se centrom perspektive Kut naspram linija koje konvergiraju od

gornjeg i donjeg centra ekrana u centru perspektive se zove vidno polje (engl Field Of

View) Sve što pada izvan tih razilazecih linija na rubovima objekta nece biti vidljivo

kameri uz vec prethodno spomenuta ogranicenja ravnina podrezivanja

U igrama je jako korisno imati matematicku reprezentaciju linije koja predstavlja tocku

u pogledu kamere Unity to omogucava u obliku objekta zrake Zraka uvijek odgo-

vara tocki u pogledu pa klasa Kamera (engl Camera) sadrži dvije korisne funkcije

ScreenPointToRay i ViewportPointToRay Razlika izmedu njih je da ScreenPointToRay

ocekuje tocku s koordinatama piksela dok ViewportPointToRay uzima normalizirane

koordinate (od 0 dolje ili lijevo do 1 gore ili desno) Obje funkcije vracaju zraku

koja se sastoji od tocke ishodišta i vektora koji pokazuje smjer linije od tog ishodišta

Zraka izlazi iz ravnine podrezivanja bliže kameri Najcešce se zrake koriste kako bi ih

bacali u scenu Bacanje zraka pošalje imaginarnu liniju uz zraku od njenog ishodišta

dok ne udari u neki sudarac u sceni Tada vraca informaciju o tocki koju je udarila

u objektu RaycastHit To je vrlo korisno kako bi se locirao objekt ovisno o njegovoj

poziciji na zaslonu npr lociranje kursora prikazano programskim kodom 43

Programski kod 43 lociranjeKursoracs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kamera

void Start()

RaycastHit udar

u objekt Ray se sprema pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

ako zraka udara u neki objekt spremi u objektUdaren to

mjesto

if (PhysicsRaycast(zraka out udar))

Transform objektUdaren = udartransform

17

Ponekad je takoder korisno dobiti zraku koja odgovara poziciji na zaslonu te onda

pomicati kameru uz tu zraku Npr želi se dozvoliti igracu da može selektirati objekt

mišem i onda ga povecati dok se objekt nalazi cijelo vrijeme na istoj poziciji na zaslonu

ispod miša prikazano programskim kodom 44 [1]

Programski kod 44 povecavanjeSlikecs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public bool povecavanje

public float brzinaPovecavanja

public Camera kamera

void Update()

ako netko koristi povecavanje slike (engl Zooming)

if (povecavanje)

u objekt Ray sprema se pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(Input

mousePosition)

udaljenost povecavanja ce biti jednaka umnosku

brzine povecavanja vremena i vertikalnog smjera

float udaljenostPovecavanja = brzinaPovecavanja

InputGetAxis(Vertical) TimedeltaTime

pomakni kameru u smjeru kursora misa za udaljenost

povecavanja u koordinatnom sustavu svijeta

kameratransformTranslate(zrakadirection

udaljenostPovecavanja SpaceWorld)

18

5 Kretanje

Pronalazak puta je zapravo pokušaj aplikacije na racunalu ili algoritma da nade naj-

kracu rutu izmedu dvije tocke To je recimo prakticna verzija rješavanja labirinta Ni

danas ne postoji optimalan algoritam koji ce u svakom slucaju u nekom realno krat-

kom vremenu naci najkraci put U ovom poglavlju objasnit ce se koje algoritme Unity

koristi za svoj navigacijski sustav Objašnjavat ce se i neki osnovni koncepti i obrasci

potrebni za ubrzavanje cijele ideje dojavljivanja promjena u sceni Bit ce prikazani i

programski kodovi potrebni za implementiranje kretanja mišem iili tipkovnicom Na

kraju ovog poglavlja želi se imati lika koji ce se slobodno kretati po sceni na mjesto

koje se odredi klikom miša i mogucnost prebacivanja na upravljanje tipkovnicom

51 Navigacijski sustav u Unityu

U Unityu je problem pronalaska puta vec riješen s necim što se zove navigacijska

mreža (engl NavMesh) To je navigacijski sustav koji ima svoje algoritme pronala-

ska puta i puno pojednostavljuje programiranje kretanja lika Sastoji se od cetiri di-

jela NavMesh agent navigacijske mreže (engl NavMesh Agent) izvanmrežna pove-

zanost(engl Off - Mesh Link) i prepreka navigacijske mreže(engl NavMesh Obstacle)

NavMesh je podatkovna struktura koja opisuje površine po kojima se može kretati

u igri i omogucava pronalazak put od jedne lokacije do druge Navigacijski sustav

treba svoje podatke kako bi predstavio prohodna podrucja u sceni Prohodna podru-

cja definiraju se kao mjesta gdje agent može stajati i kretati se Prohodno podrucje se

automatski izgraduje iz geometrije u sceni testirajuci sva podrucja gdje bi agent mo-

gao stajati Onda se te lokacije spajaju s površinom na vrhu geometrije Ta površina se

naziva onda NavMesh te je možemo vidjeti na 51 NavMesh tada sprema tu površinu

kao konveksne poligone te informacije koji su poligoni susjedni Komponenta Nav-

Mesh Agent pomaže pri kreiranju likova koji se medusobno izbjegavaju dok se krecu

prema cilju U Unityu se agenti opisuju kao valjci Koriste NavMesh kako bi se kretali

i znali koje objekte moraju zaobici te kako da se medusobno zaobidu Off-Mesh Link

19

omogucava dodavanje navigacijskih precaca koji se ne mogu predstaviti kao površina

po kojoj se može hodati npr skakanje preko ograde ili otvaranje vrata prije nego što

se ude u neku prostoriju NavMesh Obstacle opisuje prepreke koje se krecu te koje bi

agenti trebali izbjegavati dok hodaju svijetom npr neke bacve koje se kotrljaju prema

igracu Dok se bacva krece agent ce izracunati put oko nje najbolje što može no nakon

što ona naposljetku stane postat ce dio neprohodnog NavMesha te ce se agenti kretati

oko nje [3]

Slika 51 Prikaz navigacijskog sustava u Unityu

52 Pronalazak puta

Dva glavna problema postoje kod pronalaženja puta kako pronaci destinaciju na ni-

vou na kojem se igrac nalazi te kako se onda tamo pomaknuti Pronalaženje destinacije

uzima u obzir cijelu scenu Pomicanje tamo je dinamicnije u obzir uzima samo smjer

kretanja i kako da sprijeci sudaranje s drugim agentima Da bi se pronašao put izmedu

dvije lokacije prvo se moraju oznaciti pocetna i konacna lokacija njihovim najbližim

poligonima Tada se krece tražiti od pocetne lokacije posjecujuci sve susjedne dok se

ne dode do zadane destinacije Onda se prati unatrag vec posjecene poligone kako bi

se našao konacan niz poligona koji vode od pocetka do kraja Algoritam koji Unity

koristi te se cesto koristi za pronalazak puta naziva se A (A zvjezdica) Taj niz po-

ligona koji opisuje put od pocetka do kraja se naziva hodnik Agent ce doci do svoje

20

destinacije tako da se uvijek usmjerava prema sljedecem vidljivom kutu hodnika Ta

logika usmjeravanja uvijek uzima poziciju sljedeceg kuta i ovisno o tome nade željeni

smjer i brzinu potrebnu za dolazak na destinaciju Korištenje brzine po želji progra-

mera bi moglo dovesti do sudara s ostalim agentima Izbjegavanje prepreka takoder

pronalazi svoju novu brzinu koja traži ravnotežu izmedu kretanja prema destinaciji i

sprjecavanja buducih sudara s ostalim agentima i kutevima u navigacijskom sustavu

Nakon usmjeravanja i izbjegavanja prepreka izracuna se konacna brzina Unity ta-

koder uzima u obzir i akceleraciju kako bi simulirao realisticnije kretanje Takoder

treba razumjeti razliku izmedu globalne i lokalne navigacije Globalna navigacija se

koristi za pronalazak hodnika u svijetu Linearna lista poligona koja opisuje taj put je

podatkovna struktura koja se koristi za usmjeravanje te se može lokalno prilagodavati

i mijenjati kako se pozicija agenta mijenja Lokalna navigacija pokušava naci efika-

san nacin kako da se igrac pomakne prema sljedecem kutu bez da se sudari s ostalim

agentima ili objektima koji se krecu [3]

53 Kreiranje navigacijskog sustava

Proces kreiranja NavMesha iz geometrije nivoa se naziva pecenje navigacijske mreže

(engl NavMesh Baking) Skuplja sve terene i mreže objekata koji su oznaceni kao

navigacijski staticko (engl Navigation Static) i onda ih procesira kako bi kreirao navi-

gacijski sustav koji aproksimira prohodne površine nivoa Izgradnja (engl NavMesha)

je vrlo jednostavna Prvo se selektira geometrija koja bi trebala utjecati na navigaciju

tj površine po kojima možemo hodati i prepreke Oznaci se Navigation Static da bi ih

ukljucili u NavMesh Baking proces Prilagode se postavke kako bi odgovarale velicini

agenta - radijus (npr koliko blizu se može doci zidovima) visina (koliko su nisko

prostori koje agent može doseci) maksimalni nagib (koliko su kose rampe po kojima

se agent može uspeti) visina stube(koliko su visoke prepreke na koje agent može za-

koraciti) Onda jednostavno stisnemo ispeci (engl Bake) da izgradimo svoj NavMesh

Izgradeni NavMesh cemo moci vidjeti kao plavu površinu kao na slici 51 te ce se stvo-

riti nova datoteka s nazivom trenutne scene (ako vec ne postoji) i unutra ce se spremiti

kreiran navigacijski sustav [3]

21

54 Programiranje kretanja

Na liku se trenutno nalazi par stvari Animator Capsule Collider i Rigid Body Sada

je cilj isprogramirati mogucnost odredivanja gdje ce se lik kretati klikom miša na to

mjesto Dodaje se nova komponenta na lika NavMesh Agent Ta komponenta za-

pravo vec ima svoj sudarac te se slobodno može obrisati Capsule Collider jer postaje

nepotreban Igranjem s opcijama pomak od baze (engl Base Offset) te pod izbjegava-

nje prepreka (engl Obstacle Avoidance) radijus (engl Radius) i visina (engl Height)

prilagodi se sudarac od (engl NavMesh Agent-a) kako bi se obujmilo njime igraca i

sprijecilo propadanje kroz tlo od prije Sada kada postoji komponenta navigacije mora

se dodati skripta koja ce odrediti kada se lik krece te kada se pokrecu njegove anima-

cije iz Animator-a

Da bi se znalo gdje se miš nalazi mora se takoder dodati nova skriptu na kameru Kako

bi se izracunalo gdje trenutno kursor pokazuje Unity koristi vec prethodno spomenuto

bacanje zraka Da bi se moglo koristiti navigaciju putem klika mišem mora se napisati

skripta za glavnu kameru koja ce omoguciti bacanje zraka Skripta BacanjeZraka

dodaje se na objekt Main Camera koja se dodala pod prazni objekt Kamera Ova

skriptu se takoder koristi za razlikovanje raznih vrsta objekata Naime svaki objekt

kao što ima i Tag ima i sloj (engl Layer) Sloj služi kako bi mogli npr razlikovati

neprijatelje od obicnih objekata ili mjesto na koje želimo doci hodanjem Zato cemo

takoder dodati i jednu enumeraciju koja ce nam zasad služiti samo da razlikujemo je li

mjesto prohodno ili ne te jesmo li kliknuli na neprijatelja Kako bi dodali svoje nove

slojeve za objekte moramo kliknuti na Layer i dodaj sloj (engl Add Layer) kao na slici

52 što nas dovodi do novog prozora prikazanog na slici 53

Programski kod 51 bacanjeZrakacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

sluzi za dodavanje novih slojeva u Unity

public enum Sloj

Prohodno = 8

Neprijatelj = 9

KrajSvijeta = -1

22

Slika 52 Dodavanje novog sloja

public class BacanjeZraka MonoBehaviour

hijerarhija slojeva tj koji ima veci prioritet

public Sloj[] prioritetiSlojeva =

SlojNeprijatelj

SlojProhodno

SlojKrajSvijeta

udaljenost do pozadine je neka izmisljena vrijednost nakon

koje se prestane provjeravati zraka

public float udaljenostDoPozadine = 100f

Camera kamera

RaycastHit _udara

dohvaca varijable ove klase

public RaycastHit udara

get return _udara

Sloj _udaraSloj

23

Slika 53 Prozor za dodavanje novog sloja

public Sloj udaraSloj

get return _udaraSloj

deklariraj novi tip delegata

public delegate void priPromjeniSloja(Sloj noviSloj)

instanciraj skup promatraca

public event priPromjeniSloja promatraciPromjeneSloja

void Start ()

dohvat glavne kamere

kamera = Cameramain

void Update ()

nadi sloj po prioritetu u koji zraka udara

foreach(Sloj sloj in prioritetiSlojeva)

provjeravamo udara li zraka u neki od slojeva

24

var udar = BacanjeZrakaZaSloj(sloj)

if(udarHasValue)

_udara = udarValue

ako se sloj promjenio

if(_udaraSloj = sloj)

spremi novi sloj u varijablu trenutnog sloja

_udaraSloj = sloj

obavijesti promatrace da se sloj promjenio

promatraciPromjeneSloja(sloj)

spremi novi sloj u varijablu trenutnog sloja

ali ne moras obavjestavati promatrace jer je

sloj jednak starom sloju

_udaraSloj = sloj

return

inace vrati da zraka udara u pozadinu i obavijesti

promatrace

_udaradistance = udaljenostDoPozadine

_udaraSloj = SlojKrajSvijeta

promatraciPromjeneSloja(udaraSloj)

RaycastHit BacanjeZrakaZaSloj(Sloj sloj)

kreira se maska za slojeve bit se pomice ulijevo za

onoliko mjesta koliki je redni broj prioriteta sloja

int maska = 1 ltlt (int)sloj

sprema se mjesto pozicije kursora pretvoreno iz tocke u

zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

RaycastHit udar

PhysicsRaycast sprema zraku u varijablu tipa

RaycastHit prima jos i maksimalnu udaljenost za koju

provjerava zraku i masku sloja i potom vraca istinu (

engl True) ili laz (engl False) ako je zraka udarila

u sloj

25

bool udarioJe = PhysicsRaycast(zraka out udar

udaljenostDoPozadine maska)

ako zraka udara u sloj vrati vrijednost udarca

if(udarioJe)

return udar

return null

U programskom kodu 51 se koristi funkcija za primjenu obrasca promatraca pod

nazivom delegat (engl Delegate) Što je obrazac promatraca (engl Observer) To je

oblikovni obrazac koji se u programiranju koristi

bull kad promjena jednog objekta zahtijeva promjene u drugim objektima koji nisu

unaprijed poznati

bull kad objekt treba obavještavati druge objekte

bull uz uvjet da bude što neovisniji o njima

bull kad je potrebno prikazivati razlicite aspekte nekog dinamickog stanja a želimo

izbjeci ciklicku ovisnost izmedu stanja i pogleda

bull kad postoje dva koncepta jedan ovisan o drugome a zgodno ih je razdvojiti

S obzirom na to da mi samo pri promjeni sloja želimo obavještavati pretplacene pro-

matrace uvodenje delegata nam dosta ubrzava kod Obrazac promatraca funkcionira

tako da glavni objekt igra ulogu izdavaca (izvora informacija) u ovom slucaju to je

glavna kamera Ostali ovisni objekti (promatraci) pretplacuju se kod izdavaca te iz-

davaci obavještavaju pretplatnike o promjenama Promatraci prekidaju pretplatu kad

više ne trebaju obavještavanje Funkcija priPromjeniSloja se definira kao delegat i u

ovom slucaju prima sloj Nakon toga se definira dogadaj (engl Event) tipa tog delegata

(priPromjeniSloja) u ovom slucaju naziva promatraciPromjeneSloja i odsad se unutar

subjekta tim nazivom i poziva Kako bi se neki promatrac pretplatio na informacije

koje izdaje kamera dodaje ove dvije linije koda u svoju skriptu

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

Programski kod 52 služi za kretanje korištenjem NavMesha i lijevog klika miša

26

Programski kod 52 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

public float dovoljnoBlizu = 01f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora

[SerializeField] float hodajKreciStaniRadijus = 02f

void Start ()

pronadi igraca koji je tipa agenta navigacijskog sustava

(engl NavMeshAgent)

agent = GetComponentltUnityEngineAINavMeshAgentgt()

pronadi prethodno napisanu klasu BacanjeZraka

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

spremi trenutnu poziciju kursora

trenutnaPozicijaKursora = transformposition

void Update()

ako je igrac dosao na zeljeno mjesto zaustavi animaciju

hodanja

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

ako je stisnut lijevi klik misa

if (InputGetMouseButtonDown(0))

ovisno o sloju primjeni akciju

switch(bacanjeZrakaudaraSloj)

ako se po objektu na koji je igrac kliknuo moze

hodati

27

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 9: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

Slika 22 Razvojna okolina Unity

Slika 23 Gumbi Pokreni Pauziraj i Korak

24 Konzola

Konzola u Unityu vecinom služi za pomoc pri traženju greški u programskom kodu

Može se vidjeti na slici 22 u donjem dijelu Unitya u obliku kartice pored kartice

Project Ako se ne nalazi tamo mora se dodati odlaskom na prozori (engl Windows)-

gt konzola (engl Console) Pritiskom na nju primjecuje se da je skroz prazna i da

imamo još par kartica ocisti (engl Clear) sruši (engl Collapse) ocisti pri pokretanju

(engl Clear On Play) i pri grešci pauziraj (engl Error Pause) Clear služi za cišce-

nje dosad ispisanih poruka Obicno se oznacava Clear On Play da uvijek ocisti stare

poruke te da svaki put kad se pokrene igra dobiju nove Collapse pomaže ako postoji

puno istih poruka npr je korištena while petlja i ceka se neka promjenu u sceni Nije

potrebno da se ispisuje poruka Cekam cijelo vrijeme dok se ceka nego samo jednom

25 Programski jezik

Unity podržava C i Javascript programske jezike te je kroz projekt korišten samo C

Pretpostavlja se da je citatelj upoznat barem sa sintaksom C-a te osnovama objektno

4

Slika 24 Alati za transformaciju

orijentiranog programiranja Nije potrebno veliko znanje C-a kako bi se kodiralo u

Unityu potrebno je samo razumjeti kako se radi s objektima te poznavati sintaksu C-

a zbog rada s razlicitim vrstama varijabli (za razliku od Python-a gdje nije potrebno

specificirati je li varijabla cijeli broj decimalni broj itd) Unutar prozora oznacenim

brojem 2 na slici 22 stisne se desni klik i odabere kreiraj (engl Create) i C skripta

(engl C Script) da se doda nova skripta Duplim klikom na novo-kreiranu skriptu

otvara se Microsoft Visual Studio ili neka druga razvojna okolina koja podržava C u

kojem se sad može pisati programski kod Programski kod 21 je primjer ispisivanja

jednostavne poruke u konzoli

Programski kod 21 HelloWorld1cs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class HelloWorld MonoBehaviour

koristi se za inicijalizaciju

void Start ()

print(Hello World)

Update se zove svaki okvir (engl Frame)

void Update ()

Sada kada se pritisne na gumb Play sa slike 23 može se vidjeti ispis u konzoli Hello

world Još jedan nacin ispisivanja u konzolu je prikazan programskim kodom 22

Programski kod 22 HelloWorld2cs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

5

public class HelloWorld MonoBehaviour

koristi se za inicijalizaciju

void Start ()

DebugLog(Hello world)

Update se zove svaki okvir (engl Frame)

void Update ()

Ne postoji nikakva bitne razlika izmedu ta dva nacina pa se koristi bilo koji

6

3 Unos glavnog lika u scenu

U ovom poglavlju opisuju se neki pocetni problemi s kojima se susrece pri ubacivanju

modela iz popularnog programa za modeliranje Blender Objašnjavaju se i modeli koji

su ponudeni unutar samog Unitya poput kocke i neke osnovne njihove transformacije

Nakon kraja ovog poglavlja želi se imati svojevrsno tlo i ubaceni glavni lik skupa s

njegovim teksturama i animacijama iz Blender-a koji nece propadati kroz tlo

31 Skaliranje

Jedno od osnovnih stvari o kojima se razmišlja prilikom kreiranja igre je koja ce se

brojcana skala koristiti Unity ima svoje mjerne jedinice koji predstavljaju metre u

njegovom fizickom sustavu Ovisno o tipu igre koja se kreira mora se paziti na skali-

ranje Izraduje li se neka igru u svemiru nece se koristiti naše realne mjerne jedinice

nego ce ih se naravno skalirati U ovom slucaju kreira se RPG (Role-playing game)

igra gdje nam je glavni lik covjek te ce se koristiti normalne Unity mjerne jedinice bez

skaliranja

32 Kreiranje osnovnih objekata

Za pocetak potrebno je kreirati jednostavno tlo Kocka se kreira s objekt igre (engl Ga-

meObject) -gt 3D objekt (engl 3D Object) -gt kocka (engl Cube) te se dobiva rezultat

kao na slici 31 Zasad se kocka skalira po x i z osi sa 100 Tlo je uobicajeno zelene

boje pa mu se dodaje novi materijal Pritisne se u prozor imovina (engl Asset) desnim

klikom miša i odabere se kreiraj (engl Create) -gt materijal (engl Material) kao što se

može vidjeti na slici 32 Klikom na novo-stvoreni materijal desno se pojavljuje novi

prozor Inspektor (engl Inspector) gdje se može odabrati boja Nakon toga samo se

povuce lijevim klikom miša materijal na skaliranu kocku tj tlo S obzirom na to

kako se želi da ta skalirana kocka glumi tlo želi se takoder da se i ostali objekti nalaze

7

Slika 31 Kreiranje tla

na njoj Zato ce se tlo morati pomaknuti po y osi za -05 kako bi se olakšalo daljnje

dodavanje objekata

33 Unos Blender modela u Unity i pocetni problemi

Krece se s ubacivanjem svog lika u igru Lik koji se koristi kroz ostatak ovog rada na-

pravljen je u programu Blender koji služi za 3D modeliranje blend objekt se može

samo povuci mišem u Unity iz datoteke u kojoj se nalazi

1 problem Kada se blend datoteka ubacuje u Unity on nece automatski ubaciti i

teksture koje su korištene u izradi tog modela Najlakši nacin bi bio izrada nove dato-

teku unutar Assets datoteke u Unityu i ubacivanje i blend modela i teksture koja je bila

korištena u izradi u tu novu datoteku Nakon toga klikom na model unutar prozora In-

spector pod Materials odabire se opcija od modelovih materijala (engl From Modelrsquos

Material) kao na slici33 kako bi Unity ucitavao korištene teksture Ponekad na žalost

ni to ne funkcionira pa ce se ovdje objasniti još jedan malo opcenitiji pristup Pri unosu

blend modela Unity kreira novu datoteku i nazove ju materijali (engl Materals) Ako

se dogodi da se korištene teksture na modelu ne vide treba se pogledati u tu datoteku

U njoj ce se nalaziti prazni materijali s istim imenima korištenih tekstura kao npr u

slucaju ovog projekta drvo (engl Wood) Tada se mora odabrati u desnom prozoru

materijala albedo (engl Albedo) kao na slici 34 i u ponudenim Assets naci teksturu

koja je korištena (u ovom slucaju Wood)

8

Slika 32 Kreiranje materijala

2 problem Sada kada je lik pozicioniran u ishodištu (x = 0 y = 0 z = 0) može se

dogoditi da se ne nalazi tocno na tlu koje je kreirano To dakako ovisi o modeliranju

koordinatama koje su korištene i skaliranju pri izradi modela Lik korišten u ovom

radu mora se pomaknuti na koordinatu x = 0 y = 15 z = 0 kako bi stajao tocno na tlu

3 problem Kada bi se igra sad pokrenula pritiskom na gumb Play pri vrhu Unitya

lik bi propao kroz tlo Zašto se to dogada Zbog necega što se zove sudarac (engl Col-

lider) u Unityu koji ce kasnije biti pomnije objašnjen Za sada se samo žele postaviti

neke pocetne stvari kako bi bilo lakše testirati osnovnu interakciju lika i objekata u

prostoru U desnom prozoru Inspector kada je lik oznacen vidi se opcija dodaj kom-

ponentu (engl Add Component) Stisne se na to i upiše sudarac u obliku kapsule

(engl Capsule Collider) kako bi se dodao novi sudarac To je zapravo samo sudarac

9

Slika 33 Unos blend modela u scenu

koji je u obliku kapsule te se igrajuci nekim njegovim osnovnim opcijama može na-

mjestiti vanjski oblik lika Dodaje se još jedna komponenta nad likom Ponovno se

stisne na Add Component te upiše kruto tijelo (engl Rigid Body) što ce takoder biti

naknadno objašnjeno Zasad je bitno razumijevanje da to omogucava liku da se ponaša

kao kruto tijelo u prostoru

4 problem Sada bi kada se igra pokrene trebao postojati lik koji ne propada kroz tlo

Naravno kao najosnovniju mehaniku želi se mogucnost kretanja po tom tlu Skripta

koja se treba napraviti kako bi se lik kretao po tlu nije zapravo komplicirana Sastoji

se samo od toga da se prilikom pritiska na odredeno slovo tipkovnice objekt translatira

po prostoru No ovaj model takoder sadrži i animacije za hodanje te se želi i to ukom-

ponirati Zato ce se takoder sada spomenuti još jedna nova komponenta kontrolor

animacija (engl Animator Controller) Dodaje se i ta komponenta na lika i prebacuje

se na prozor animator (engl Animator) koji se vidi na slici 35

U ovom prozoru postoji par novih opcija Mogu se dodavati nova stanja u kojima

ce se lik naci ovisno o nekim uvjetima koji se zadaju Pocetno stanje je ulazno stanje

(engl Entry State) i iz njega se želi da se lik nade u stanju mirovanja Stisne se desni

klik miša i odabere se novo stanje (engl New State) U ovom projektu je nazvano

Mirovanje Iz mirovanja ovisno o tome kada osoba pritisne neku tipku tipkovnice

želi se da se lik krene kretati Zato treba dodati novo stanje Hodanje Doda se

novo stanje istim postupkom kao i prvo Sada se naravno moraju dodati i usmjereni

prijelazi Stisne se desni klik miša na Mirovanje i odabere dodaj prijelaz (engl Add

10

Slika 34 Traženje tekstura Vašeg blend modela

Slika 35 Animator

Transition) To je sada kreiralo usmjerenu strelicu koja se može povuci prema Ho-

danje Isto to se napravi i u suprotnom smjeru Desni klik miša na Hodanje Add

Transition i povuce se strelica prema Mirovanje Naravno moraju se dodati uvjeti

koji ce odredivati kada ce objekt prijeci iz jednog stanja u drugo U ovom slucaju je

korišten cijeli broj (engl Integer) Ostatak problema kretanja rješavat ce se u poglavlju

4 Bacanje zraka i kretanje po mapi s mišem

11

4 Kamera

U ovom poglavlju se postavlja i bira prava kamera za igru Tijekom izrade igre treba se

takoder razmišljati i iz kojeg kuta ce se imati pogled na nju te hoce li se kamera pomi-

cati s kretanjem lika hoce li se moci rotirati itd Pri kreiranju 3D igre u pogledu scene

primjecuje se da su svi objekti i transformacije u 3D-prostoru No s obzirom na to da je

zaslon monitora igraca 2-dimenzionalan te se ne može prikazati tijela kao takva mora

se moci prikazati sve te objekte u jednoj ravnini i zadržati dojam 3-dimenzionalnosti

To se u Unityu postiže s kamerom Kamera je objekt koja definira pogled i njegov

smjer u prostoru scene Pozicija kamere definira ocište z os definira smjer gledanja

(gledište) te y os definira vrh ekrana Kamera takoder definira velicinu i oblik dijela

koji možemo vidjeti Kamera nam pokazuje ono što ona vidi Kako se ona rotira

translatira itd prikaz scene ce se takoder jednako transformirati Nakon kraja ovog

poglavlja želi se imati kamera koja ce pratiti kretnje lika i imati pogled na njega odoz-

gora

41 Perspektivna i ortografska kamera

Kamerom se zapravo objekte 3D prostora projicira na ravninu u 2D prostor Projek-

cije su matematicki modeli koji govore na koji nacin treba tocke 3D prostora preslikati

u ravninu u tocke 2D prostora Postoji više vrsta projekcija no Unity koristi dvije or-

tografsku projekciju i perspektivnu projekciju Kod ortografskih projekcija kamera je

okomita na ravninu projekcije dok je perspektivna projekcija bliža našem nacinu gle-

danja objekata Možda je najlakše primijetiti razliku koristeci slike Dakle na slici 41

možemo vidjeti blend model koji je modeliran u Blenderu u ortografskoj projekciji te

na slici 42 isti taj model pod istim kutem samo prebacen u perspektivnu projekciju

[6]

Perspektivna projekcija uvodi dvije tocke ocište i gledište Ocište je tocka u ko-

joj se nalazi promatrac Gledište odreduje smjer prema kojem promatrac gleda U

12

Slika 41 Ortografska projekcija blend modela

tocki gledišta stvara se ravnina projekcije koja je okomita na spojnicu ocište-gledište

[6] I perspektivna i ortografska kamera imaju granicu do koje mogu vidjeti od svoje

trenutne pozicije Ona je definirana upravo tom ravninom projekcije Tocka gledišta

pripada toj ravnini i ona tipicno postaje ishodište lokalnog dvodimenzijskog koordi-

natnog sustava koji razapinjemo u ravnini projekcije Ta ravnina se još naziva i daleka

ravnina podrezivanja zato što svi objekti koji se nalaze na vecoj udaljenosti od nje se

odrežu te ih kamera ne prikazuje Takoder postoji i ravnina podrezivanja blizu ka-

meri [1] Dio koji se prikazuje se nalazi izmedu te dvije ravnine

42 Pogled iz prvog lica u pogled iznad glave

U igrama se cesto koristi prebacivanje iz jednog u drugi pogled kamere Kako se

to postiže Koristeci veci broj kamera U ovom slucaju obradit ce se samo kratki

primjer kako se prebacivati iz pogleda prvog lica u pogled iznad glave U unity-u je

zadano da jedna kamera pokriva cijeli ekran te se zato samo pogled jedne kamere može

vidjeti u jednom trenutku Kamera koju vidimo je ona koja ima najvecu vrijednost

za svoje svojstvo dubine[1] Zato se želi napraviti skripta koja ce se prebacivati s

jedne kamere na drugu da bi se dobili drukciji pogledi na scenu koja je prikazana

programskim kodom 41

Programski kod 41 PrimjerViseKameracs

13

Slika 42 Perspektivna projekcija blend modela

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kameraPrvogLica

public Camera kameraIznadGlave

funkcija koja se poziva kada se prebacujemo u pogled iznad

glave

public void prikaziPogledIznadGlave()

kameraPrvogLicaenabled = false gasimo kameru prvog

lica

kameraIznadGlaveenabled = true palimo kameru iznad

glave

funkcija koja se poziva kada se prebacujemo u pogled iz

prvog lica

public void prikaziPogledIzPrvogLica()

kameraPrvogLicaenabled = true palimo kameru prvog

lica

overheadCameraenabled = false gasimo kameru iznad

glave

14

43 Fiksirana kamera

U sceni projekta vec postoji glavna kamera (engl Main Camera) koju Unity automat-

ski dodaje u scenu Kako bi ta kamera pratila lika može se samo povuci u lijevom

prozoru hijerarhije u hijerarhiju lika kako bi postala njegovo dijete Tako ce se postici

da kamera stalno prati njegove transformacije (translaciju rotaciju) prilikom pokreta-

nja igre No kako bi se postiglo da kamera ostane uvijek fiksirana te se samo krece s

njime umjesto da se kamera rotira skupa s likom dodaje se novi prazni objekt sa Game

Object -gt kreiraj prazan (engl Create Empty) Njegova pozicija se postavlja na x =

0 y = 0 z = 0 ako vec nije tamo te se postavlja taj prazan objekt kao roditelj glavne

kamere Sada kamera ostaje fiksirana na mjestu te se nece ni kretati s likom Kako bi

se krenula kretati mora se dodati nova skripta na taj prazan objekt koji se odsad u pro-

jektu zove Kamera s obzirom na to da zaista i je roditelj glavne kamere Kako bi se u

skripti lakše locirao objekt igraca oznacava ga se u njegovom polju oznaka (engl Tag)

u desnom prozoru Inspector s igrac (engl Player) kao što se može vidjeti na slici 43

zaokruženo plavom bojom

U programskom kodu se želi napraviti varijabla tipa Game Object kako bi se spremilo

igraca kada ga se pronade Unity takoder ima funkciju FindGameObjectWithTag pa

je onda ostatak koda prilicno intuitivan Kada se igrac pronade pomocu njegove oz-

nake Player prilikom svakog osvježavanja poziciji našeg igraca pridružuje se pozicija

kamere kao što je prikazano programskim kodom 42

Programski kod 42 pratiLikacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class pratiLika MonoBehaviour

GameObject igrac

void Start ()

trazi se objekt putem njegove oznake

igrac = GameObjectFindGameObjectWithTag(Player)

15

Slika 43 Oznacavanje lika radi lakšeg pronalaska u skripti

void LateUpdate ()

trenutni objekt mijenja svoju poziciju u skladu s

pozicijom objekta oznacenog oznakom Player

transformposition = igractransformposition

44 Bacanje zraka (engl Ray casting)

Perspektivna kamera u Unityu koristi oblik krnje piramide za dio koji prikazuje u pros-

toru Svaka tocka nekog objekta kojeg kamera prikazuje zapravo odgovara liniji u pros-

toru svijeta te je nama samo jedna tocka duž te linije vidljiva na objektu Sve iza te

tocke na liniji je zamraceno Vanjski rubovi objekta su definirani razilazecim linijama

16

koje odgovaraju kutevima objekta Kada bi se te linije pratile unazad prema kameri

sve bi na kraju konvergirale u jednu tocku U Unityu se ta tocka nalazi tocno na pozi-

ciji kamere i naziva se centrom perspektive Kut naspram linija koje konvergiraju od

gornjeg i donjeg centra ekrana u centru perspektive se zove vidno polje (engl Field Of

View) Sve što pada izvan tih razilazecih linija na rubovima objekta nece biti vidljivo

kameri uz vec prethodno spomenuta ogranicenja ravnina podrezivanja

U igrama je jako korisno imati matematicku reprezentaciju linije koja predstavlja tocku

u pogledu kamere Unity to omogucava u obliku objekta zrake Zraka uvijek odgo-

vara tocki u pogledu pa klasa Kamera (engl Camera) sadrži dvije korisne funkcije

ScreenPointToRay i ViewportPointToRay Razlika izmedu njih je da ScreenPointToRay

ocekuje tocku s koordinatama piksela dok ViewportPointToRay uzima normalizirane

koordinate (od 0 dolje ili lijevo do 1 gore ili desno) Obje funkcije vracaju zraku

koja se sastoji od tocke ishodišta i vektora koji pokazuje smjer linije od tog ishodišta

Zraka izlazi iz ravnine podrezivanja bliže kameri Najcešce se zrake koriste kako bi ih

bacali u scenu Bacanje zraka pošalje imaginarnu liniju uz zraku od njenog ishodišta

dok ne udari u neki sudarac u sceni Tada vraca informaciju o tocki koju je udarila

u objektu RaycastHit To je vrlo korisno kako bi se locirao objekt ovisno o njegovoj

poziciji na zaslonu npr lociranje kursora prikazano programskim kodom 43

Programski kod 43 lociranjeKursoracs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kamera

void Start()

RaycastHit udar

u objekt Ray se sprema pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

ako zraka udara u neki objekt spremi u objektUdaren to

mjesto

if (PhysicsRaycast(zraka out udar))

Transform objektUdaren = udartransform

17

Ponekad je takoder korisno dobiti zraku koja odgovara poziciji na zaslonu te onda

pomicati kameru uz tu zraku Npr želi se dozvoliti igracu da može selektirati objekt

mišem i onda ga povecati dok se objekt nalazi cijelo vrijeme na istoj poziciji na zaslonu

ispod miša prikazano programskim kodom 44 [1]

Programski kod 44 povecavanjeSlikecs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public bool povecavanje

public float brzinaPovecavanja

public Camera kamera

void Update()

ako netko koristi povecavanje slike (engl Zooming)

if (povecavanje)

u objekt Ray sprema se pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(Input

mousePosition)

udaljenost povecavanja ce biti jednaka umnosku

brzine povecavanja vremena i vertikalnog smjera

float udaljenostPovecavanja = brzinaPovecavanja

InputGetAxis(Vertical) TimedeltaTime

pomakni kameru u smjeru kursora misa za udaljenost

povecavanja u koordinatnom sustavu svijeta

kameratransformTranslate(zrakadirection

udaljenostPovecavanja SpaceWorld)

18

5 Kretanje

Pronalazak puta je zapravo pokušaj aplikacije na racunalu ili algoritma da nade naj-

kracu rutu izmedu dvije tocke To je recimo prakticna verzija rješavanja labirinta Ni

danas ne postoji optimalan algoritam koji ce u svakom slucaju u nekom realno krat-

kom vremenu naci najkraci put U ovom poglavlju objasnit ce se koje algoritme Unity

koristi za svoj navigacijski sustav Objašnjavat ce se i neki osnovni koncepti i obrasci

potrebni za ubrzavanje cijele ideje dojavljivanja promjena u sceni Bit ce prikazani i

programski kodovi potrebni za implementiranje kretanja mišem iili tipkovnicom Na

kraju ovog poglavlja želi se imati lika koji ce se slobodno kretati po sceni na mjesto

koje se odredi klikom miša i mogucnost prebacivanja na upravljanje tipkovnicom

51 Navigacijski sustav u Unityu

U Unityu je problem pronalaska puta vec riješen s necim što se zove navigacijska

mreža (engl NavMesh) To je navigacijski sustav koji ima svoje algoritme pronala-

ska puta i puno pojednostavljuje programiranje kretanja lika Sastoji se od cetiri di-

jela NavMesh agent navigacijske mreže (engl NavMesh Agent) izvanmrežna pove-

zanost(engl Off - Mesh Link) i prepreka navigacijske mreže(engl NavMesh Obstacle)

NavMesh je podatkovna struktura koja opisuje površine po kojima se može kretati

u igri i omogucava pronalazak put od jedne lokacije do druge Navigacijski sustav

treba svoje podatke kako bi predstavio prohodna podrucja u sceni Prohodna podru-

cja definiraju se kao mjesta gdje agent može stajati i kretati se Prohodno podrucje se

automatski izgraduje iz geometrije u sceni testirajuci sva podrucja gdje bi agent mo-

gao stajati Onda se te lokacije spajaju s površinom na vrhu geometrije Ta površina se

naziva onda NavMesh te je možemo vidjeti na 51 NavMesh tada sprema tu površinu

kao konveksne poligone te informacije koji su poligoni susjedni Komponenta Nav-

Mesh Agent pomaže pri kreiranju likova koji se medusobno izbjegavaju dok se krecu

prema cilju U Unityu se agenti opisuju kao valjci Koriste NavMesh kako bi se kretali

i znali koje objekte moraju zaobici te kako da se medusobno zaobidu Off-Mesh Link

19

omogucava dodavanje navigacijskih precaca koji se ne mogu predstaviti kao površina

po kojoj se može hodati npr skakanje preko ograde ili otvaranje vrata prije nego što

se ude u neku prostoriju NavMesh Obstacle opisuje prepreke koje se krecu te koje bi

agenti trebali izbjegavati dok hodaju svijetom npr neke bacve koje se kotrljaju prema

igracu Dok se bacva krece agent ce izracunati put oko nje najbolje što može no nakon

što ona naposljetku stane postat ce dio neprohodnog NavMesha te ce se agenti kretati

oko nje [3]

Slika 51 Prikaz navigacijskog sustava u Unityu

52 Pronalazak puta

Dva glavna problema postoje kod pronalaženja puta kako pronaci destinaciju na ni-

vou na kojem se igrac nalazi te kako se onda tamo pomaknuti Pronalaženje destinacije

uzima u obzir cijelu scenu Pomicanje tamo je dinamicnije u obzir uzima samo smjer

kretanja i kako da sprijeci sudaranje s drugim agentima Da bi se pronašao put izmedu

dvije lokacije prvo se moraju oznaciti pocetna i konacna lokacija njihovim najbližim

poligonima Tada se krece tražiti od pocetne lokacije posjecujuci sve susjedne dok se

ne dode do zadane destinacije Onda se prati unatrag vec posjecene poligone kako bi

se našao konacan niz poligona koji vode od pocetka do kraja Algoritam koji Unity

koristi te se cesto koristi za pronalazak puta naziva se A (A zvjezdica) Taj niz po-

ligona koji opisuje put od pocetka do kraja se naziva hodnik Agent ce doci do svoje

20

destinacije tako da se uvijek usmjerava prema sljedecem vidljivom kutu hodnika Ta

logika usmjeravanja uvijek uzima poziciju sljedeceg kuta i ovisno o tome nade željeni

smjer i brzinu potrebnu za dolazak na destinaciju Korištenje brzine po želji progra-

mera bi moglo dovesti do sudara s ostalim agentima Izbjegavanje prepreka takoder

pronalazi svoju novu brzinu koja traži ravnotežu izmedu kretanja prema destinaciji i

sprjecavanja buducih sudara s ostalim agentima i kutevima u navigacijskom sustavu

Nakon usmjeravanja i izbjegavanja prepreka izracuna se konacna brzina Unity ta-

koder uzima u obzir i akceleraciju kako bi simulirao realisticnije kretanje Takoder

treba razumjeti razliku izmedu globalne i lokalne navigacije Globalna navigacija se

koristi za pronalazak hodnika u svijetu Linearna lista poligona koja opisuje taj put je

podatkovna struktura koja se koristi za usmjeravanje te se može lokalno prilagodavati

i mijenjati kako se pozicija agenta mijenja Lokalna navigacija pokušava naci efika-

san nacin kako da se igrac pomakne prema sljedecem kutu bez da se sudari s ostalim

agentima ili objektima koji se krecu [3]

53 Kreiranje navigacijskog sustava

Proces kreiranja NavMesha iz geometrije nivoa se naziva pecenje navigacijske mreže

(engl NavMesh Baking) Skuplja sve terene i mreže objekata koji su oznaceni kao

navigacijski staticko (engl Navigation Static) i onda ih procesira kako bi kreirao navi-

gacijski sustav koji aproksimira prohodne površine nivoa Izgradnja (engl NavMesha)

je vrlo jednostavna Prvo se selektira geometrija koja bi trebala utjecati na navigaciju

tj površine po kojima možemo hodati i prepreke Oznaci se Navigation Static da bi ih

ukljucili u NavMesh Baking proces Prilagode se postavke kako bi odgovarale velicini

agenta - radijus (npr koliko blizu se može doci zidovima) visina (koliko su nisko

prostori koje agent može doseci) maksimalni nagib (koliko su kose rampe po kojima

se agent može uspeti) visina stube(koliko su visoke prepreke na koje agent može za-

koraciti) Onda jednostavno stisnemo ispeci (engl Bake) da izgradimo svoj NavMesh

Izgradeni NavMesh cemo moci vidjeti kao plavu površinu kao na slici 51 te ce se stvo-

riti nova datoteka s nazivom trenutne scene (ako vec ne postoji) i unutra ce se spremiti

kreiran navigacijski sustav [3]

21

54 Programiranje kretanja

Na liku se trenutno nalazi par stvari Animator Capsule Collider i Rigid Body Sada

je cilj isprogramirati mogucnost odredivanja gdje ce se lik kretati klikom miša na to

mjesto Dodaje se nova komponenta na lika NavMesh Agent Ta komponenta za-

pravo vec ima svoj sudarac te se slobodno može obrisati Capsule Collider jer postaje

nepotreban Igranjem s opcijama pomak od baze (engl Base Offset) te pod izbjegava-

nje prepreka (engl Obstacle Avoidance) radijus (engl Radius) i visina (engl Height)

prilagodi se sudarac od (engl NavMesh Agent-a) kako bi se obujmilo njime igraca i

sprijecilo propadanje kroz tlo od prije Sada kada postoji komponenta navigacije mora

se dodati skripta koja ce odrediti kada se lik krece te kada se pokrecu njegove anima-

cije iz Animator-a

Da bi se znalo gdje se miš nalazi mora se takoder dodati nova skriptu na kameru Kako

bi se izracunalo gdje trenutno kursor pokazuje Unity koristi vec prethodno spomenuto

bacanje zraka Da bi se moglo koristiti navigaciju putem klika mišem mora se napisati

skripta za glavnu kameru koja ce omoguciti bacanje zraka Skripta BacanjeZraka

dodaje se na objekt Main Camera koja se dodala pod prazni objekt Kamera Ova

skriptu se takoder koristi za razlikovanje raznih vrsta objekata Naime svaki objekt

kao što ima i Tag ima i sloj (engl Layer) Sloj služi kako bi mogli npr razlikovati

neprijatelje od obicnih objekata ili mjesto na koje želimo doci hodanjem Zato cemo

takoder dodati i jednu enumeraciju koja ce nam zasad služiti samo da razlikujemo je li

mjesto prohodno ili ne te jesmo li kliknuli na neprijatelja Kako bi dodali svoje nove

slojeve za objekte moramo kliknuti na Layer i dodaj sloj (engl Add Layer) kao na slici

52 što nas dovodi do novog prozora prikazanog na slici 53

Programski kod 51 bacanjeZrakacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

sluzi za dodavanje novih slojeva u Unity

public enum Sloj

Prohodno = 8

Neprijatelj = 9

KrajSvijeta = -1

22

Slika 52 Dodavanje novog sloja

public class BacanjeZraka MonoBehaviour

hijerarhija slojeva tj koji ima veci prioritet

public Sloj[] prioritetiSlojeva =

SlojNeprijatelj

SlojProhodno

SlojKrajSvijeta

udaljenost do pozadine je neka izmisljena vrijednost nakon

koje se prestane provjeravati zraka

public float udaljenostDoPozadine = 100f

Camera kamera

RaycastHit _udara

dohvaca varijable ove klase

public RaycastHit udara

get return _udara

Sloj _udaraSloj

23

Slika 53 Prozor za dodavanje novog sloja

public Sloj udaraSloj

get return _udaraSloj

deklariraj novi tip delegata

public delegate void priPromjeniSloja(Sloj noviSloj)

instanciraj skup promatraca

public event priPromjeniSloja promatraciPromjeneSloja

void Start ()

dohvat glavne kamere

kamera = Cameramain

void Update ()

nadi sloj po prioritetu u koji zraka udara

foreach(Sloj sloj in prioritetiSlojeva)

provjeravamo udara li zraka u neki od slojeva

24

var udar = BacanjeZrakaZaSloj(sloj)

if(udarHasValue)

_udara = udarValue

ako se sloj promjenio

if(_udaraSloj = sloj)

spremi novi sloj u varijablu trenutnog sloja

_udaraSloj = sloj

obavijesti promatrace da se sloj promjenio

promatraciPromjeneSloja(sloj)

spremi novi sloj u varijablu trenutnog sloja

ali ne moras obavjestavati promatrace jer je

sloj jednak starom sloju

_udaraSloj = sloj

return

inace vrati da zraka udara u pozadinu i obavijesti

promatrace

_udaradistance = udaljenostDoPozadine

_udaraSloj = SlojKrajSvijeta

promatraciPromjeneSloja(udaraSloj)

RaycastHit BacanjeZrakaZaSloj(Sloj sloj)

kreira se maska za slojeve bit se pomice ulijevo za

onoliko mjesta koliki je redni broj prioriteta sloja

int maska = 1 ltlt (int)sloj

sprema se mjesto pozicije kursora pretvoreno iz tocke u

zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

RaycastHit udar

PhysicsRaycast sprema zraku u varijablu tipa

RaycastHit prima jos i maksimalnu udaljenost za koju

provjerava zraku i masku sloja i potom vraca istinu (

engl True) ili laz (engl False) ako je zraka udarila

u sloj

25

bool udarioJe = PhysicsRaycast(zraka out udar

udaljenostDoPozadine maska)

ako zraka udara u sloj vrati vrijednost udarca

if(udarioJe)

return udar

return null

U programskom kodu 51 se koristi funkcija za primjenu obrasca promatraca pod

nazivom delegat (engl Delegate) Što je obrazac promatraca (engl Observer) To je

oblikovni obrazac koji se u programiranju koristi

bull kad promjena jednog objekta zahtijeva promjene u drugim objektima koji nisu

unaprijed poznati

bull kad objekt treba obavještavati druge objekte

bull uz uvjet da bude što neovisniji o njima

bull kad je potrebno prikazivati razlicite aspekte nekog dinamickog stanja a želimo

izbjeci ciklicku ovisnost izmedu stanja i pogleda

bull kad postoje dva koncepta jedan ovisan o drugome a zgodno ih je razdvojiti

S obzirom na to da mi samo pri promjeni sloja želimo obavještavati pretplacene pro-

matrace uvodenje delegata nam dosta ubrzava kod Obrazac promatraca funkcionira

tako da glavni objekt igra ulogu izdavaca (izvora informacija) u ovom slucaju to je

glavna kamera Ostali ovisni objekti (promatraci) pretplacuju se kod izdavaca te iz-

davaci obavještavaju pretplatnike o promjenama Promatraci prekidaju pretplatu kad

više ne trebaju obavještavanje Funkcija priPromjeniSloja se definira kao delegat i u

ovom slucaju prima sloj Nakon toga se definira dogadaj (engl Event) tipa tog delegata

(priPromjeniSloja) u ovom slucaju naziva promatraciPromjeneSloja i odsad se unutar

subjekta tim nazivom i poziva Kako bi se neki promatrac pretplatio na informacije

koje izdaje kamera dodaje ove dvije linije koda u svoju skriptu

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

Programski kod 52 služi za kretanje korištenjem NavMesha i lijevog klika miša

26

Programski kod 52 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

public float dovoljnoBlizu = 01f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora

[SerializeField] float hodajKreciStaniRadijus = 02f

void Start ()

pronadi igraca koji je tipa agenta navigacijskog sustava

(engl NavMeshAgent)

agent = GetComponentltUnityEngineAINavMeshAgentgt()

pronadi prethodno napisanu klasu BacanjeZraka

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

spremi trenutnu poziciju kursora

trenutnaPozicijaKursora = transformposition

void Update()

ako je igrac dosao na zeljeno mjesto zaustavi animaciju

hodanja

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

ako je stisnut lijevi klik misa

if (InputGetMouseButtonDown(0))

ovisno o sloju primjeni akciju

switch(bacanjeZrakaudaraSloj)

ako se po objektu na koji je igrac kliknuo moze

hodati

27

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 10: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

Slika 24 Alati za transformaciju

orijentiranog programiranja Nije potrebno veliko znanje C-a kako bi se kodiralo u

Unityu potrebno je samo razumjeti kako se radi s objektima te poznavati sintaksu C-

a zbog rada s razlicitim vrstama varijabli (za razliku od Python-a gdje nije potrebno

specificirati je li varijabla cijeli broj decimalni broj itd) Unutar prozora oznacenim

brojem 2 na slici 22 stisne se desni klik i odabere kreiraj (engl Create) i C skripta

(engl C Script) da se doda nova skripta Duplim klikom na novo-kreiranu skriptu

otvara se Microsoft Visual Studio ili neka druga razvojna okolina koja podržava C u

kojem se sad može pisati programski kod Programski kod 21 je primjer ispisivanja

jednostavne poruke u konzoli

Programski kod 21 HelloWorld1cs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class HelloWorld MonoBehaviour

koristi se za inicijalizaciju

void Start ()

print(Hello World)

Update se zove svaki okvir (engl Frame)

void Update ()

Sada kada se pritisne na gumb Play sa slike 23 može se vidjeti ispis u konzoli Hello

world Još jedan nacin ispisivanja u konzolu je prikazan programskim kodom 22

Programski kod 22 HelloWorld2cs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

5

public class HelloWorld MonoBehaviour

koristi se za inicijalizaciju

void Start ()

DebugLog(Hello world)

Update se zove svaki okvir (engl Frame)

void Update ()

Ne postoji nikakva bitne razlika izmedu ta dva nacina pa se koristi bilo koji

6

3 Unos glavnog lika u scenu

U ovom poglavlju opisuju se neki pocetni problemi s kojima se susrece pri ubacivanju

modela iz popularnog programa za modeliranje Blender Objašnjavaju se i modeli koji

su ponudeni unutar samog Unitya poput kocke i neke osnovne njihove transformacije

Nakon kraja ovog poglavlja želi se imati svojevrsno tlo i ubaceni glavni lik skupa s

njegovim teksturama i animacijama iz Blender-a koji nece propadati kroz tlo

31 Skaliranje

Jedno od osnovnih stvari o kojima se razmišlja prilikom kreiranja igre je koja ce se

brojcana skala koristiti Unity ima svoje mjerne jedinice koji predstavljaju metre u

njegovom fizickom sustavu Ovisno o tipu igre koja se kreira mora se paziti na skali-

ranje Izraduje li se neka igru u svemiru nece se koristiti naše realne mjerne jedinice

nego ce ih se naravno skalirati U ovom slucaju kreira se RPG (Role-playing game)

igra gdje nam je glavni lik covjek te ce se koristiti normalne Unity mjerne jedinice bez

skaliranja

32 Kreiranje osnovnih objekata

Za pocetak potrebno je kreirati jednostavno tlo Kocka se kreira s objekt igre (engl Ga-

meObject) -gt 3D objekt (engl 3D Object) -gt kocka (engl Cube) te se dobiva rezultat

kao na slici 31 Zasad se kocka skalira po x i z osi sa 100 Tlo je uobicajeno zelene

boje pa mu se dodaje novi materijal Pritisne se u prozor imovina (engl Asset) desnim

klikom miša i odabere se kreiraj (engl Create) -gt materijal (engl Material) kao što se

može vidjeti na slici 32 Klikom na novo-stvoreni materijal desno se pojavljuje novi

prozor Inspektor (engl Inspector) gdje se može odabrati boja Nakon toga samo se

povuce lijevim klikom miša materijal na skaliranu kocku tj tlo S obzirom na to

kako se želi da ta skalirana kocka glumi tlo želi se takoder da se i ostali objekti nalaze

7

Slika 31 Kreiranje tla

na njoj Zato ce se tlo morati pomaknuti po y osi za -05 kako bi se olakšalo daljnje

dodavanje objekata

33 Unos Blender modela u Unity i pocetni problemi

Krece se s ubacivanjem svog lika u igru Lik koji se koristi kroz ostatak ovog rada na-

pravljen je u programu Blender koji služi za 3D modeliranje blend objekt se može

samo povuci mišem u Unity iz datoteke u kojoj se nalazi

1 problem Kada se blend datoteka ubacuje u Unity on nece automatski ubaciti i

teksture koje su korištene u izradi tog modela Najlakši nacin bi bio izrada nove dato-

teku unutar Assets datoteke u Unityu i ubacivanje i blend modela i teksture koja je bila

korištena u izradi u tu novu datoteku Nakon toga klikom na model unutar prozora In-

spector pod Materials odabire se opcija od modelovih materijala (engl From Modelrsquos

Material) kao na slici33 kako bi Unity ucitavao korištene teksture Ponekad na žalost

ni to ne funkcionira pa ce se ovdje objasniti još jedan malo opcenitiji pristup Pri unosu

blend modela Unity kreira novu datoteku i nazove ju materijali (engl Materals) Ako

se dogodi da se korištene teksture na modelu ne vide treba se pogledati u tu datoteku

U njoj ce se nalaziti prazni materijali s istim imenima korištenih tekstura kao npr u

slucaju ovog projekta drvo (engl Wood) Tada se mora odabrati u desnom prozoru

materijala albedo (engl Albedo) kao na slici 34 i u ponudenim Assets naci teksturu

koja je korištena (u ovom slucaju Wood)

8

Slika 32 Kreiranje materijala

2 problem Sada kada je lik pozicioniran u ishodištu (x = 0 y = 0 z = 0) može se

dogoditi da se ne nalazi tocno na tlu koje je kreirano To dakako ovisi o modeliranju

koordinatama koje su korištene i skaliranju pri izradi modela Lik korišten u ovom

radu mora se pomaknuti na koordinatu x = 0 y = 15 z = 0 kako bi stajao tocno na tlu

3 problem Kada bi se igra sad pokrenula pritiskom na gumb Play pri vrhu Unitya

lik bi propao kroz tlo Zašto se to dogada Zbog necega što se zove sudarac (engl Col-

lider) u Unityu koji ce kasnije biti pomnije objašnjen Za sada se samo žele postaviti

neke pocetne stvari kako bi bilo lakše testirati osnovnu interakciju lika i objekata u

prostoru U desnom prozoru Inspector kada je lik oznacen vidi se opcija dodaj kom-

ponentu (engl Add Component) Stisne se na to i upiše sudarac u obliku kapsule

(engl Capsule Collider) kako bi se dodao novi sudarac To je zapravo samo sudarac

9

Slika 33 Unos blend modela u scenu

koji je u obliku kapsule te se igrajuci nekim njegovim osnovnim opcijama može na-

mjestiti vanjski oblik lika Dodaje se još jedna komponenta nad likom Ponovno se

stisne na Add Component te upiše kruto tijelo (engl Rigid Body) što ce takoder biti

naknadno objašnjeno Zasad je bitno razumijevanje da to omogucava liku da se ponaša

kao kruto tijelo u prostoru

4 problem Sada bi kada se igra pokrene trebao postojati lik koji ne propada kroz tlo

Naravno kao najosnovniju mehaniku želi se mogucnost kretanja po tom tlu Skripta

koja se treba napraviti kako bi se lik kretao po tlu nije zapravo komplicirana Sastoji

se samo od toga da se prilikom pritiska na odredeno slovo tipkovnice objekt translatira

po prostoru No ovaj model takoder sadrži i animacije za hodanje te se želi i to ukom-

ponirati Zato ce se takoder sada spomenuti još jedna nova komponenta kontrolor

animacija (engl Animator Controller) Dodaje se i ta komponenta na lika i prebacuje

se na prozor animator (engl Animator) koji se vidi na slici 35

U ovom prozoru postoji par novih opcija Mogu se dodavati nova stanja u kojima

ce se lik naci ovisno o nekim uvjetima koji se zadaju Pocetno stanje je ulazno stanje

(engl Entry State) i iz njega se želi da se lik nade u stanju mirovanja Stisne se desni

klik miša i odabere se novo stanje (engl New State) U ovom projektu je nazvano

Mirovanje Iz mirovanja ovisno o tome kada osoba pritisne neku tipku tipkovnice

želi se da se lik krene kretati Zato treba dodati novo stanje Hodanje Doda se

novo stanje istim postupkom kao i prvo Sada se naravno moraju dodati i usmjereni

prijelazi Stisne se desni klik miša na Mirovanje i odabere dodaj prijelaz (engl Add

10

Slika 34 Traženje tekstura Vašeg blend modela

Slika 35 Animator

Transition) To je sada kreiralo usmjerenu strelicu koja se može povuci prema Ho-

danje Isto to se napravi i u suprotnom smjeru Desni klik miša na Hodanje Add

Transition i povuce se strelica prema Mirovanje Naravno moraju se dodati uvjeti

koji ce odredivati kada ce objekt prijeci iz jednog stanja u drugo U ovom slucaju je

korišten cijeli broj (engl Integer) Ostatak problema kretanja rješavat ce se u poglavlju

4 Bacanje zraka i kretanje po mapi s mišem

11

4 Kamera

U ovom poglavlju se postavlja i bira prava kamera za igru Tijekom izrade igre treba se

takoder razmišljati i iz kojeg kuta ce se imati pogled na nju te hoce li se kamera pomi-

cati s kretanjem lika hoce li se moci rotirati itd Pri kreiranju 3D igre u pogledu scene

primjecuje se da su svi objekti i transformacije u 3D-prostoru No s obzirom na to da je

zaslon monitora igraca 2-dimenzionalan te se ne može prikazati tijela kao takva mora

se moci prikazati sve te objekte u jednoj ravnini i zadržati dojam 3-dimenzionalnosti

To se u Unityu postiže s kamerom Kamera je objekt koja definira pogled i njegov

smjer u prostoru scene Pozicija kamere definira ocište z os definira smjer gledanja

(gledište) te y os definira vrh ekrana Kamera takoder definira velicinu i oblik dijela

koji možemo vidjeti Kamera nam pokazuje ono što ona vidi Kako se ona rotira

translatira itd prikaz scene ce se takoder jednako transformirati Nakon kraja ovog

poglavlja želi se imati kamera koja ce pratiti kretnje lika i imati pogled na njega odoz-

gora

41 Perspektivna i ortografska kamera

Kamerom se zapravo objekte 3D prostora projicira na ravninu u 2D prostor Projek-

cije su matematicki modeli koji govore na koji nacin treba tocke 3D prostora preslikati

u ravninu u tocke 2D prostora Postoji više vrsta projekcija no Unity koristi dvije or-

tografsku projekciju i perspektivnu projekciju Kod ortografskih projekcija kamera je

okomita na ravninu projekcije dok je perspektivna projekcija bliža našem nacinu gle-

danja objekata Možda je najlakše primijetiti razliku koristeci slike Dakle na slici 41

možemo vidjeti blend model koji je modeliran u Blenderu u ortografskoj projekciji te

na slici 42 isti taj model pod istim kutem samo prebacen u perspektivnu projekciju

[6]

Perspektivna projekcija uvodi dvije tocke ocište i gledište Ocište je tocka u ko-

joj se nalazi promatrac Gledište odreduje smjer prema kojem promatrac gleda U

12

Slika 41 Ortografska projekcija blend modela

tocki gledišta stvara se ravnina projekcije koja je okomita na spojnicu ocište-gledište

[6] I perspektivna i ortografska kamera imaju granicu do koje mogu vidjeti od svoje

trenutne pozicije Ona je definirana upravo tom ravninom projekcije Tocka gledišta

pripada toj ravnini i ona tipicno postaje ishodište lokalnog dvodimenzijskog koordi-

natnog sustava koji razapinjemo u ravnini projekcije Ta ravnina se još naziva i daleka

ravnina podrezivanja zato što svi objekti koji se nalaze na vecoj udaljenosti od nje se

odrežu te ih kamera ne prikazuje Takoder postoji i ravnina podrezivanja blizu ka-

meri [1] Dio koji se prikazuje se nalazi izmedu te dvije ravnine

42 Pogled iz prvog lica u pogled iznad glave

U igrama se cesto koristi prebacivanje iz jednog u drugi pogled kamere Kako se

to postiže Koristeci veci broj kamera U ovom slucaju obradit ce se samo kratki

primjer kako se prebacivati iz pogleda prvog lica u pogled iznad glave U unity-u je

zadano da jedna kamera pokriva cijeli ekran te se zato samo pogled jedne kamere može

vidjeti u jednom trenutku Kamera koju vidimo je ona koja ima najvecu vrijednost

za svoje svojstvo dubine[1] Zato se želi napraviti skripta koja ce se prebacivati s

jedne kamere na drugu da bi se dobili drukciji pogledi na scenu koja je prikazana

programskim kodom 41

Programski kod 41 PrimjerViseKameracs

13

Slika 42 Perspektivna projekcija blend modela

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kameraPrvogLica

public Camera kameraIznadGlave

funkcija koja se poziva kada se prebacujemo u pogled iznad

glave

public void prikaziPogledIznadGlave()

kameraPrvogLicaenabled = false gasimo kameru prvog

lica

kameraIznadGlaveenabled = true palimo kameru iznad

glave

funkcija koja se poziva kada se prebacujemo u pogled iz

prvog lica

public void prikaziPogledIzPrvogLica()

kameraPrvogLicaenabled = true palimo kameru prvog

lica

overheadCameraenabled = false gasimo kameru iznad

glave

14

43 Fiksirana kamera

U sceni projekta vec postoji glavna kamera (engl Main Camera) koju Unity automat-

ski dodaje u scenu Kako bi ta kamera pratila lika može se samo povuci u lijevom

prozoru hijerarhije u hijerarhiju lika kako bi postala njegovo dijete Tako ce se postici

da kamera stalno prati njegove transformacije (translaciju rotaciju) prilikom pokreta-

nja igre No kako bi se postiglo da kamera ostane uvijek fiksirana te se samo krece s

njime umjesto da se kamera rotira skupa s likom dodaje se novi prazni objekt sa Game

Object -gt kreiraj prazan (engl Create Empty) Njegova pozicija se postavlja na x =

0 y = 0 z = 0 ako vec nije tamo te se postavlja taj prazan objekt kao roditelj glavne

kamere Sada kamera ostaje fiksirana na mjestu te se nece ni kretati s likom Kako bi

se krenula kretati mora se dodati nova skripta na taj prazan objekt koji se odsad u pro-

jektu zove Kamera s obzirom na to da zaista i je roditelj glavne kamere Kako bi se u

skripti lakše locirao objekt igraca oznacava ga se u njegovom polju oznaka (engl Tag)

u desnom prozoru Inspector s igrac (engl Player) kao što se može vidjeti na slici 43

zaokruženo plavom bojom

U programskom kodu se želi napraviti varijabla tipa Game Object kako bi se spremilo

igraca kada ga se pronade Unity takoder ima funkciju FindGameObjectWithTag pa

je onda ostatak koda prilicno intuitivan Kada se igrac pronade pomocu njegove oz-

nake Player prilikom svakog osvježavanja poziciji našeg igraca pridružuje se pozicija

kamere kao što je prikazano programskim kodom 42

Programski kod 42 pratiLikacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class pratiLika MonoBehaviour

GameObject igrac

void Start ()

trazi se objekt putem njegove oznake

igrac = GameObjectFindGameObjectWithTag(Player)

15

Slika 43 Oznacavanje lika radi lakšeg pronalaska u skripti

void LateUpdate ()

trenutni objekt mijenja svoju poziciju u skladu s

pozicijom objekta oznacenog oznakom Player

transformposition = igractransformposition

44 Bacanje zraka (engl Ray casting)

Perspektivna kamera u Unityu koristi oblik krnje piramide za dio koji prikazuje u pros-

toru Svaka tocka nekog objekta kojeg kamera prikazuje zapravo odgovara liniji u pros-

toru svijeta te je nama samo jedna tocka duž te linije vidljiva na objektu Sve iza te

tocke na liniji je zamraceno Vanjski rubovi objekta su definirani razilazecim linijama

16

koje odgovaraju kutevima objekta Kada bi se te linije pratile unazad prema kameri

sve bi na kraju konvergirale u jednu tocku U Unityu se ta tocka nalazi tocno na pozi-

ciji kamere i naziva se centrom perspektive Kut naspram linija koje konvergiraju od

gornjeg i donjeg centra ekrana u centru perspektive se zove vidno polje (engl Field Of

View) Sve što pada izvan tih razilazecih linija na rubovima objekta nece biti vidljivo

kameri uz vec prethodno spomenuta ogranicenja ravnina podrezivanja

U igrama je jako korisno imati matematicku reprezentaciju linije koja predstavlja tocku

u pogledu kamere Unity to omogucava u obliku objekta zrake Zraka uvijek odgo-

vara tocki u pogledu pa klasa Kamera (engl Camera) sadrži dvije korisne funkcije

ScreenPointToRay i ViewportPointToRay Razlika izmedu njih je da ScreenPointToRay

ocekuje tocku s koordinatama piksela dok ViewportPointToRay uzima normalizirane

koordinate (od 0 dolje ili lijevo do 1 gore ili desno) Obje funkcije vracaju zraku

koja se sastoji od tocke ishodišta i vektora koji pokazuje smjer linije od tog ishodišta

Zraka izlazi iz ravnine podrezivanja bliže kameri Najcešce se zrake koriste kako bi ih

bacali u scenu Bacanje zraka pošalje imaginarnu liniju uz zraku od njenog ishodišta

dok ne udari u neki sudarac u sceni Tada vraca informaciju o tocki koju je udarila

u objektu RaycastHit To je vrlo korisno kako bi se locirao objekt ovisno o njegovoj

poziciji na zaslonu npr lociranje kursora prikazano programskim kodom 43

Programski kod 43 lociranjeKursoracs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kamera

void Start()

RaycastHit udar

u objekt Ray se sprema pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

ako zraka udara u neki objekt spremi u objektUdaren to

mjesto

if (PhysicsRaycast(zraka out udar))

Transform objektUdaren = udartransform

17

Ponekad je takoder korisno dobiti zraku koja odgovara poziciji na zaslonu te onda

pomicati kameru uz tu zraku Npr želi se dozvoliti igracu da može selektirati objekt

mišem i onda ga povecati dok se objekt nalazi cijelo vrijeme na istoj poziciji na zaslonu

ispod miša prikazano programskim kodom 44 [1]

Programski kod 44 povecavanjeSlikecs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public bool povecavanje

public float brzinaPovecavanja

public Camera kamera

void Update()

ako netko koristi povecavanje slike (engl Zooming)

if (povecavanje)

u objekt Ray sprema se pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(Input

mousePosition)

udaljenost povecavanja ce biti jednaka umnosku

brzine povecavanja vremena i vertikalnog smjera

float udaljenostPovecavanja = brzinaPovecavanja

InputGetAxis(Vertical) TimedeltaTime

pomakni kameru u smjeru kursora misa za udaljenost

povecavanja u koordinatnom sustavu svijeta

kameratransformTranslate(zrakadirection

udaljenostPovecavanja SpaceWorld)

18

5 Kretanje

Pronalazak puta je zapravo pokušaj aplikacije na racunalu ili algoritma da nade naj-

kracu rutu izmedu dvije tocke To je recimo prakticna verzija rješavanja labirinta Ni

danas ne postoji optimalan algoritam koji ce u svakom slucaju u nekom realno krat-

kom vremenu naci najkraci put U ovom poglavlju objasnit ce se koje algoritme Unity

koristi za svoj navigacijski sustav Objašnjavat ce se i neki osnovni koncepti i obrasci

potrebni za ubrzavanje cijele ideje dojavljivanja promjena u sceni Bit ce prikazani i

programski kodovi potrebni za implementiranje kretanja mišem iili tipkovnicom Na

kraju ovog poglavlja želi se imati lika koji ce se slobodno kretati po sceni na mjesto

koje se odredi klikom miša i mogucnost prebacivanja na upravljanje tipkovnicom

51 Navigacijski sustav u Unityu

U Unityu je problem pronalaska puta vec riješen s necim što se zove navigacijska

mreža (engl NavMesh) To je navigacijski sustav koji ima svoje algoritme pronala-

ska puta i puno pojednostavljuje programiranje kretanja lika Sastoji se od cetiri di-

jela NavMesh agent navigacijske mreže (engl NavMesh Agent) izvanmrežna pove-

zanost(engl Off - Mesh Link) i prepreka navigacijske mreže(engl NavMesh Obstacle)

NavMesh je podatkovna struktura koja opisuje površine po kojima se može kretati

u igri i omogucava pronalazak put od jedne lokacije do druge Navigacijski sustav

treba svoje podatke kako bi predstavio prohodna podrucja u sceni Prohodna podru-

cja definiraju se kao mjesta gdje agent može stajati i kretati se Prohodno podrucje se

automatski izgraduje iz geometrije u sceni testirajuci sva podrucja gdje bi agent mo-

gao stajati Onda se te lokacije spajaju s površinom na vrhu geometrije Ta površina se

naziva onda NavMesh te je možemo vidjeti na 51 NavMesh tada sprema tu površinu

kao konveksne poligone te informacije koji su poligoni susjedni Komponenta Nav-

Mesh Agent pomaže pri kreiranju likova koji se medusobno izbjegavaju dok se krecu

prema cilju U Unityu se agenti opisuju kao valjci Koriste NavMesh kako bi se kretali

i znali koje objekte moraju zaobici te kako da se medusobno zaobidu Off-Mesh Link

19

omogucava dodavanje navigacijskih precaca koji se ne mogu predstaviti kao površina

po kojoj se može hodati npr skakanje preko ograde ili otvaranje vrata prije nego što

se ude u neku prostoriju NavMesh Obstacle opisuje prepreke koje se krecu te koje bi

agenti trebali izbjegavati dok hodaju svijetom npr neke bacve koje se kotrljaju prema

igracu Dok se bacva krece agent ce izracunati put oko nje najbolje što može no nakon

što ona naposljetku stane postat ce dio neprohodnog NavMesha te ce se agenti kretati

oko nje [3]

Slika 51 Prikaz navigacijskog sustava u Unityu

52 Pronalazak puta

Dva glavna problema postoje kod pronalaženja puta kako pronaci destinaciju na ni-

vou na kojem se igrac nalazi te kako se onda tamo pomaknuti Pronalaženje destinacije

uzima u obzir cijelu scenu Pomicanje tamo je dinamicnije u obzir uzima samo smjer

kretanja i kako da sprijeci sudaranje s drugim agentima Da bi se pronašao put izmedu

dvije lokacije prvo se moraju oznaciti pocetna i konacna lokacija njihovim najbližim

poligonima Tada se krece tražiti od pocetne lokacije posjecujuci sve susjedne dok se

ne dode do zadane destinacije Onda se prati unatrag vec posjecene poligone kako bi

se našao konacan niz poligona koji vode od pocetka do kraja Algoritam koji Unity

koristi te se cesto koristi za pronalazak puta naziva se A (A zvjezdica) Taj niz po-

ligona koji opisuje put od pocetka do kraja se naziva hodnik Agent ce doci do svoje

20

destinacije tako da se uvijek usmjerava prema sljedecem vidljivom kutu hodnika Ta

logika usmjeravanja uvijek uzima poziciju sljedeceg kuta i ovisno o tome nade željeni

smjer i brzinu potrebnu za dolazak na destinaciju Korištenje brzine po želji progra-

mera bi moglo dovesti do sudara s ostalim agentima Izbjegavanje prepreka takoder

pronalazi svoju novu brzinu koja traži ravnotežu izmedu kretanja prema destinaciji i

sprjecavanja buducih sudara s ostalim agentima i kutevima u navigacijskom sustavu

Nakon usmjeravanja i izbjegavanja prepreka izracuna se konacna brzina Unity ta-

koder uzima u obzir i akceleraciju kako bi simulirao realisticnije kretanje Takoder

treba razumjeti razliku izmedu globalne i lokalne navigacije Globalna navigacija se

koristi za pronalazak hodnika u svijetu Linearna lista poligona koja opisuje taj put je

podatkovna struktura koja se koristi za usmjeravanje te se može lokalno prilagodavati

i mijenjati kako se pozicija agenta mijenja Lokalna navigacija pokušava naci efika-

san nacin kako da se igrac pomakne prema sljedecem kutu bez da se sudari s ostalim

agentima ili objektima koji se krecu [3]

53 Kreiranje navigacijskog sustava

Proces kreiranja NavMesha iz geometrije nivoa se naziva pecenje navigacijske mreže

(engl NavMesh Baking) Skuplja sve terene i mreže objekata koji su oznaceni kao

navigacijski staticko (engl Navigation Static) i onda ih procesira kako bi kreirao navi-

gacijski sustav koji aproksimira prohodne površine nivoa Izgradnja (engl NavMesha)

je vrlo jednostavna Prvo se selektira geometrija koja bi trebala utjecati na navigaciju

tj površine po kojima možemo hodati i prepreke Oznaci se Navigation Static da bi ih

ukljucili u NavMesh Baking proces Prilagode se postavke kako bi odgovarale velicini

agenta - radijus (npr koliko blizu se može doci zidovima) visina (koliko su nisko

prostori koje agent može doseci) maksimalni nagib (koliko su kose rampe po kojima

se agent može uspeti) visina stube(koliko su visoke prepreke na koje agent može za-

koraciti) Onda jednostavno stisnemo ispeci (engl Bake) da izgradimo svoj NavMesh

Izgradeni NavMesh cemo moci vidjeti kao plavu površinu kao na slici 51 te ce se stvo-

riti nova datoteka s nazivom trenutne scene (ako vec ne postoji) i unutra ce se spremiti

kreiran navigacijski sustav [3]

21

54 Programiranje kretanja

Na liku se trenutno nalazi par stvari Animator Capsule Collider i Rigid Body Sada

je cilj isprogramirati mogucnost odredivanja gdje ce se lik kretati klikom miša na to

mjesto Dodaje se nova komponenta na lika NavMesh Agent Ta komponenta za-

pravo vec ima svoj sudarac te se slobodno može obrisati Capsule Collider jer postaje

nepotreban Igranjem s opcijama pomak od baze (engl Base Offset) te pod izbjegava-

nje prepreka (engl Obstacle Avoidance) radijus (engl Radius) i visina (engl Height)

prilagodi se sudarac od (engl NavMesh Agent-a) kako bi se obujmilo njime igraca i

sprijecilo propadanje kroz tlo od prije Sada kada postoji komponenta navigacije mora

se dodati skripta koja ce odrediti kada se lik krece te kada se pokrecu njegove anima-

cije iz Animator-a

Da bi se znalo gdje se miš nalazi mora se takoder dodati nova skriptu na kameru Kako

bi se izracunalo gdje trenutno kursor pokazuje Unity koristi vec prethodno spomenuto

bacanje zraka Da bi se moglo koristiti navigaciju putem klika mišem mora se napisati

skripta za glavnu kameru koja ce omoguciti bacanje zraka Skripta BacanjeZraka

dodaje se na objekt Main Camera koja se dodala pod prazni objekt Kamera Ova

skriptu se takoder koristi za razlikovanje raznih vrsta objekata Naime svaki objekt

kao što ima i Tag ima i sloj (engl Layer) Sloj služi kako bi mogli npr razlikovati

neprijatelje od obicnih objekata ili mjesto na koje želimo doci hodanjem Zato cemo

takoder dodati i jednu enumeraciju koja ce nam zasad služiti samo da razlikujemo je li

mjesto prohodno ili ne te jesmo li kliknuli na neprijatelja Kako bi dodali svoje nove

slojeve za objekte moramo kliknuti na Layer i dodaj sloj (engl Add Layer) kao na slici

52 što nas dovodi do novog prozora prikazanog na slici 53

Programski kod 51 bacanjeZrakacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

sluzi za dodavanje novih slojeva u Unity

public enum Sloj

Prohodno = 8

Neprijatelj = 9

KrajSvijeta = -1

22

Slika 52 Dodavanje novog sloja

public class BacanjeZraka MonoBehaviour

hijerarhija slojeva tj koji ima veci prioritet

public Sloj[] prioritetiSlojeva =

SlojNeprijatelj

SlojProhodno

SlojKrajSvijeta

udaljenost do pozadine je neka izmisljena vrijednost nakon

koje se prestane provjeravati zraka

public float udaljenostDoPozadine = 100f

Camera kamera

RaycastHit _udara

dohvaca varijable ove klase

public RaycastHit udara

get return _udara

Sloj _udaraSloj

23

Slika 53 Prozor za dodavanje novog sloja

public Sloj udaraSloj

get return _udaraSloj

deklariraj novi tip delegata

public delegate void priPromjeniSloja(Sloj noviSloj)

instanciraj skup promatraca

public event priPromjeniSloja promatraciPromjeneSloja

void Start ()

dohvat glavne kamere

kamera = Cameramain

void Update ()

nadi sloj po prioritetu u koji zraka udara

foreach(Sloj sloj in prioritetiSlojeva)

provjeravamo udara li zraka u neki od slojeva

24

var udar = BacanjeZrakaZaSloj(sloj)

if(udarHasValue)

_udara = udarValue

ako se sloj promjenio

if(_udaraSloj = sloj)

spremi novi sloj u varijablu trenutnog sloja

_udaraSloj = sloj

obavijesti promatrace da se sloj promjenio

promatraciPromjeneSloja(sloj)

spremi novi sloj u varijablu trenutnog sloja

ali ne moras obavjestavati promatrace jer je

sloj jednak starom sloju

_udaraSloj = sloj

return

inace vrati da zraka udara u pozadinu i obavijesti

promatrace

_udaradistance = udaljenostDoPozadine

_udaraSloj = SlojKrajSvijeta

promatraciPromjeneSloja(udaraSloj)

RaycastHit BacanjeZrakaZaSloj(Sloj sloj)

kreira se maska za slojeve bit se pomice ulijevo za

onoliko mjesta koliki je redni broj prioriteta sloja

int maska = 1 ltlt (int)sloj

sprema se mjesto pozicije kursora pretvoreno iz tocke u

zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

RaycastHit udar

PhysicsRaycast sprema zraku u varijablu tipa

RaycastHit prima jos i maksimalnu udaljenost za koju

provjerava zraku i masku sloja i potom vraca istinu (

engl True) ili laz (engl False) ako je zraka udarila

u sloj

25

bool udarioJe = PhysicsRaycast(zraka out udar

udaljenostDoPozadine maska)

ako zraka udara u sloj vrati vrijednost udarca

if(udarioJe)

return udar

return null

U programskom kodu 51 se koristi funkcija za primjenu obrasca promatraca pod

nazivom delegat (engl Delegate) Što je obrazac promatraca (engl Observer) To je

oblikovni obrazac koji se u programiranju koristi

bull kad promjena jednog objekta zahtijeva promjene u drugim objektima koji nisu

unaprijed poznati

bull kad objekt treba obavještavati druge objekte

bull uz uvjet da bude što neovisniji o njima

bull kad je potrebno prikazivati razlicite aspekte nekog dinamickog stanja a želimo

izbjeci ciklicku ovisnost izmedu stanja i pogleda

bull kad postoje dva koncepta jedan ovisan o drugome a zgodno ih je razdvojiti

S obzirom na to da mi samo pri promjeni sloja želimo obavještavati pretplacene pro-

matrace uvodenje delegata nam dosta ubrzava kod Obrazac promatraca funkcionira

tako da glavni objekt igra ulogu izdavaca (izvora informacija) u ovom slucaju to je

glavna kamera Ostali ovisni objekti (promatraci) pretplacuju se kod izdavaca te iz-

davaci obavještavaju pretplatnike o promjenama Promatraci prekidaju pretplatu kad

više ne trebaju obavještavanje Funkcija priPromjeniSloja se definira kao delegat i u

ovom slucaju prima sloj Nakon toga se definira dogadaj (engl Event) tipa tog delegata

(priPromjeniSloja) u ovom slucaju naziva promatraciPromjeneSloja i odsad se unutar

subjekta tim nazivom i poziva Kako bi se neki promatrac pretplatio na informacije

koje izdaje kamera dodaje ove dvije linije koda u svoju skriptu

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

Programski kod 52 služi za kretanje korištenjem NavMesha i lijevog klika miša

26

Programski kod 52 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

public float dovoljnoBlizu = 01f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora

[SerializeField] float hodajKreciStaniRadijus = 02f

void Start ()

pronadi igraca koji je tipa agenta navigacijskog sustava

(engl NavMeshAgent)

agent = GetComponentltUnityEngineAINavMeshAgentgt()

pronadi prethodno napisanu klasu BacanjeZraka

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

spremi trenutnu poziciju kursora

trenutnaPozicijaKursora = transformposition

void Update()

ako je igrac dosao na zeljeno mjesto zaustavi animaciju

hodanja

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

ako je stisnut lijevi klik misa

if (InputGetMouseButtonDown(0))

ovisno o sloju primjeni akciju

switch(bacanjeZrakaudaraSloj)

ako se po objektu na koji je igrac kliknuo moze

hodati

27

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 11: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

public class HelloWorld MonoBehaviour

koristi se za inicijalizaciju

void Start ()

DebugLog(Hello world)

Update se zove svaki okvir (engl Frame)

void Update ()

Ne postoji nikakva bitne razlika izmedu ta dva nacina pa se koristi bilo koji

6

3 Unos glavnog lika u scenu

U ovom poglavlju opisuju se neki pocetni problemi s kojima se susrece pri ubacivanju

modela iz popularnog programa za modeliranje Blender Objašnjavaju se i modeli koji

su ponudeni unutar samog Unitya poput kocke i neke osnovne njihove transformacije

Nakon kraja ovog poglavlja želi se imati svojevrsno tlo i ubaceni glavni lik skupa s

njegovim teksturama i animacijama iz Blender-a koji nece propadati kroz tlo

31 Skaliranje

Jedno od osnovnih stvari o kojima se razmišlja prilikom kreiranja igre je koja ce se

brojcana skala koristiti Unity ima svoje mjerne jedinice koji predstavljaju metre u

njegovom fizickom sustavu Ovisno o tipu igre koja se kreira mora se paziti na skali-

ranje Izraduje li se neka igru u svemiru nece se koristiti naše realne mjerne jedinice

nego ce ih se naravno skalirati U ovom slucaju kreira se RPG (Role-playing game)

igra gdje nam je glavni lik covjek te ce se koristiti normalne Unity mjerne jedinice bez

skaliranja

32 Kreiranje osnovnih objekata

Za pocetak potrebno je kreirati jednostavno tlo Kocka se kreira s objekt igre (engl Ga-

meObject) -gt 3D objekt (engl 3D Object) -gt kocka (engl Cube) te se dobiva rezultat

kao na slici 31 Zasad se kocka skalira po x i z osi sa 100 Tlo je uobicajeno zelene

boje pa mu se dodaje novi materijal Pritisne se u prozor imovina (engl Asset) desnim

klikom miša i odabere se kreiraj (engl Create) -gt materijal (engl Material) kao što se

može vidjeti na slici 32 Klikom na novo-stvoreni materijal desno se pojavljuje novi

prozor Inspektor (engl Inspector) gdje se može odabrati boja Nakon toga samo se

povuce lijevim klikom miša materijal na skaliranu kocku tj tlo S obzirom na to

kako se želi da ta skalirana kocka glumi tlo želi se takoder da se i ostali objekti nalaze

7

Slika 31 Kreiranje tla

na njoj Zato ce se tlo morati pomaknuti po y osi za -05 kako bi se olakšalo daljnje

dodavanje objekata

33 Unos Blender modela u Unity i pocetni problemi

Krece se s ubacivanjem svog lika u igru Lik koji se koristi kroz ostatak ovog rada na-

pravljen je u programu Blender koji služi za 3D modeliranje blend objekt se može

samo povuci mišem u Unity iz datoteke u kojoj se nalazi

1 problem Kada se blend datoteka ubacuje u Unity on nece automatski ubaciti i

teksture koje su korištene u izradi tog modela Najlakši nacin bi bio izrada nove dato-

teku unutar Assets datoteke u Unityu i ubacivanje i blend modela i teksture koja je bila

korištena u izradi u tu novu datoteku Nakon toga klikom na model unutar prozora In-

spector pod Materials odabire se opcija od modelovih materijala (engl From Modelrsquos

Material) kao na slici33 kako bi Unity ucitavao korištene teksture Ponekad na žalost

ni to ne funkcionira pa ce se ovdje objasniti još jedan malo opcenitiji pristup Pri unosu

blend modela Unity kreira novu datoteku i nazove ju materijali (engl Materals) Ako

se dogodi da se korištene teksture na modelu ne vide treba se pogledati u tu datoteku

U njoj ce se nalaziti prazni materijali s istim imenima korištenih tekstura kao npr u

slucaju ovog projekta drvo (engl Wood) Tada se mora odabrati u desnom prozoru

materijala albedo (engl Albedo) kao na slici 34 i u ponudenim Assets naci teksturu

koja je korištena (u ovom slucaju Wood)

8

Slika 32 Kreiranje materijala

2 problem Sada kada je lik pozicioniran u ishodištu (x = 0 y = 0 z = 0) može se

dogoditi da se ne nalazi tocno na tlu koje je kreirano To dakako ovisi o modeliranju

koordinatama koje su korištene i skaliranju pri izradi modela Lik korišten u ovom

radu mora se pomaknuti na koordinatu x = 0 y = 15 z = 0 kako bi stajao tocno na tlu

3 problem Kada bi se igra sad pokrenula pritiskom na gumb Play pri vrhu Unitya

lik bi propao kroz tlo Zašto se to dogada Zbog necega što se zove sudarac (engl Col-

lider) u Unityu koji ce kasnije biti pomnije objašnjen Za sada se samo žele postaviti

neke pocetne stvari kako bi bilo lakše testirati osnovnu interakciju lika i objekata u

prostoru U desnom prozoru Inspector kada je lik oznacen vidi se opcija dodaj kom-

ponentu (engl Add Component) Stisne se na to i upiše sudarac u obliku kapsule

(engl Capsule Collider) kako bi se dodao novi sudarac To je zapravo samo sudarac

9

Slika 33 Unos blend modela u scenu

koji je u obliku kapsule te se igrajuci nekim njegovim osnovnim opcijama može na-

mjestiti vanjski oblik lika Dodaje se još jedna komponenta nad likom Ponovno se

stisne na Add Component te upiše kruto tijelo (engl Rigid Body) što ce takoder biti

naknadno objašnjeno Zasad je bitno razumijevanje da to omogucava liku da se ponaša

kao kruto tijelo u prostoru

4 problem Sada bi kada se igra pokrene trebao postojati lik koji ne propada kroz tlo

Naravno kao najosnovniju mehaniku želi se mogucnost kretanja po tom tlu Skripta

koja se treba napraviti kako bi se lik kretao po tlu nije zapravo komplicirana Sastoji

se samo od toga da se prilikom pritiska na odredeno slovo tipkovnice objekt translatira

po prostoru No ovaj model takoder sadrži i animacije za hodanje te se želi i to ukom-

ponirati Zato ce se takoder sada spomenuti još jedna nova komponenta kontrolor

animacija (engl Animator Controller) Dodaje se i ta komponenta na lika i prebacuje

se na prozor animator (engl Animator) koji se vidi na slici 35

U ovom prozoru postoji par novih opcija Mogu se dodavati nova stanja u kojima

ce se lik naci ovisno o nekim uvjetima koji se zadaju Pocetno stanje je ulazno stanje

(engl Entry State) i iz njega se želi da se lik nade u stanju mirovanja Stisne se desni

klik miša i odabere se novo stanje (engl New State) U ovom projektu je nazvano

Mirovanje Iz mirovanja ovisno o tome kada osoba pritisne neku tipku tipkovnice

želi se da se lik krene kretati Zato treba dodati novo stanje Hodanje Doda se

novo stanje istim postupkom kao i prvo Sada se naravno moraju dodati i usmjereni

prijelazi Stisne se desni klik miša na Mirovanje i odabere dodaj prijelaz (engl Add

10

Slika 34 Traženje tekstura Vašeg blend modela

Slika 35 Animator

Transition) To je sada kreiralo usmjerenu strelicu koja se može povuci prema Ho-

danje Isto to se napravi i u suprotnom smjeru Desni klik miša na Hodanje Add

Transition i povuce se strelica prema Mirovanje Naravno moraju se dodati uvjeti

koji ce odredivati kada ce objekt prijeci iz jednog stanja u drugo U ovom slucaju je

korišten cijeli broj (engl Integer) Ostatak problema kretanja rješavat ce se u poglavlju

4 Bacanje zraka i kretanje po mapi s mišem

11

4 Kamera

U ovom poglavlju se postavlja i bira prava kamera za igru Tijekom izrade igre treba se

takoder razmišljati i iz kojeg kuta ce se imati pogled na nju te hoce li se kamera pomi-

cati s kretanjem lika hoce li se moci rotirati itd Pri kreiranju 3D igre u pogledu scene

primjecuje se da su svi objekti i transformacije u 3D-prostoru No s obzirom na to da je

zaslon monitora igraca 2-dimenzionalan te se ne može prikazati tijela kao takva mora

se moci prikazati sve te objekte u jednoj ravnini i zadržati dojam 3-dimenzionalnosti

To se u Unityu postiže s kamerom Kamera je objekt koja definira pogled i njegov

smjer u prostoru scene Pozicija kamere definira ocište z os definira smjer gledanja

(gledište) te y os definira vrh ekrana Kamera takoder definira velicinu i oblik dijela

koji možemo vidjeti Kamera nam pokazuje ono što ona vidi Kako se ona rotira

translatira itd prikaz scene ce se takoder jednako transformirati Nakon kraja ovog

poglavlja želi se imati kamera koja ce pratiti kretnje lika i imati pogled na njega odoz-

gora

41 Perspektivna i ortografska kamera

Kamerom se zapravo objekte 3D prostora projicira na ravninu u 2D prostor Projek-

cije su matematicki modeli koji govore na koji nacin treba tocke 3D prostora preslikati

u ravninu u tocke 2D prostora Postoji više vrsta projekcija no Unity koristi dvije or-

tografsku projekciju i perspektivnu projekciju Kod ortografskih projekcija kamera je

okomita na ravninu projekcije dok je perspektivna projekcija bliža našem nacinu gle-

danja objekata Možda je najlakše primijetiti razliku koristeci slike Dakle na slici 41

možemo vidjeti blend model koji je modeliran u Blenderu u ortografskoj projekciji te

na slici 42 isti taj model pod istim kutem samo prebacen u perspektivnu projekciju

[6]

Perspektivna projekcija uvodi dvije tocke ocište i gledište Ocište je tocka u ko-

joj se nalazi promatrac Gledište odreduje smjer prema kojem promatrac gleda U

12

Slika 41 Ortografska projekcija blend modela

tocki gledišta stvara se ravnina projekcije koja je okomita na spojnicu ocište-gledište

[6] I perspektivna i ortografska kamera imaju granicu do koje mogu vidjeti od svoje

trenutne pozicije Ona je definirana upravo tom ravninom projekcije Tocka gledišta

pripada toj ravnini i ona tipicno postaje ishodište lokalnog dvodimenzijskog koordi-

natnog sustava koji razapinjemo u ravnini projekcije Ta ravnina se još naziva i daleka

ravnina podrezivanja zato što svi objekti koji se nalaze na vecoj udaljenosti od nje se

odrežu te ih kamera ne prikazuje Takoder postoji i ravnina podrezivanja blizu ka-

meri [1] Dio koji se prikazuje se nalazi izmedu te dvije ravnine

42 Pogled iz prvog lica u pogled iznad glave

U igrama se cesto koristi prebacivanje iz jednog u drugi pogled kamere Kako se

to postiže Koristeci veci broj kamera U ovom slucaju obradit ce se samo kratki

primjer kako se prebacivati iz pogleda prvog lica u pogled iznad glave U unity-u je

zadano da jedna kamera pokriva cijeli ekran te se zato samo pogled jedne kamere može

vidjeti u jednom trenutku Kamera koju vidimo je ona koja ima najvecu vrijednost

za svoje svojstvo dubine[1] Zato se želi napraviti skripta koja ce se prebacivati s

jedne kamere na drugu da bi se dobili drukciji pogledi na scenu koja je prikazana

programskim kodom 41

Programski kod 41 PrimjerViseKameracs

13

Slika 42 Perspektivna projekcija blend modela

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kameraPrvogLica

public Camera kameraIznadGlave

funkcija koja se poziva kada se prebacujemo u pogled iznad

glave

public void prikaziPogledIznadGlave()

kameraPrvogLicaenabled = false gasimo kameru prvog

lica

kameraIznadGlaveenabled = true palimo kameru iznad

glave

funkcija koja se poziva kada se prebacujemo u pogled iz

prvog lica

public void prikaziPogledIzPrvogLica()

kameraPrvogLicaenabled = true palimo kameru prvog

lica

overheadCameraenabled = false gasimo kameru iznad

glave

14

43 Fiksirana kamera

U sceni projekta vec postoji glavna kamera (engl Main Camera) koju Unity automat-

ski dodaje u scenu Kako bi ta kamera pratila lika može se samo povuci u lijevom

prozoru hijerarhije u hijerarhiju lika kako bi postala njegovo dijete Tako ce se postici

da kamera stalno prati njegove transformacije (translaciju rotaciju) prilikom pokreta-

nja igre No kako bi se postiglo da kamera ostane uvijek fiksirana te se samo krece s

njime umjesto da se kamera rotira skupa s likom dodaje se novi prazni objekt sa Game

Object -gt kreiraj prazan (engl Create Empty) Njegova pozicija se postavlja na x =

0 y = 0 z = 0 ako vec nije tamo te se postavlja taj prazan objekt kao roditelj glavne

kamere Sada kamera ostaje fiksirana na mjestu te se nece ni kretati s likom Kako bi

se krenula kretati mora se dodati nova skripta na taj prazan objekt koji se odsad u pro-

jektu zove Kamera s obzirom na to da zaista i je roditelj glavne kamere Kako bi se u

skripti lakše locirao objekt igraca oznacava ga se u njegovom polju oznaka (engl Tag)

u desnom prozoru Inspector s igrac (engl Player) kao što se može vidjeti na slici 43

zaokruženo plavom bojom

U programskom kodu se želi napraviti varijabla tipa Game Object kako bi se spremilo

igraca kada ga se pronade Unity takoder ima funkciju FindGameObjectWithTag pa

je onda ostatak koda prilicno intuitivan Kada se igrac pronade pomocu njegove oz-

nake Player prilikom svakog osvježavanja poziciji našeg igraca pridružuje se pozicija

kamere kao što je prikazano programskim kodom 42

Programski kod 42 pratiLikacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class pratiLika MonoBehaviour

GameObject igrac

void Start ()

trazi se objekt putem njegove oznake

igrac = GameObjectFindGameObjectWithTag(Player)

15

Slika 43 Oznacavanje lika radi lakšeg pronalaska u skripti

void LateUpdate ()

trenutni objekt mijenja svoju poziciju u skladu s

pozicijom objekta oznacenog oznakom Player

transformposition = igractransformposition

44 Bacanje zraka (engl Ray casting)

Perspektivna kamera u Unityu koristi oblik krnje piramide za dio koji prikazuje u pros-

toru Svaka tocka nekog objekta kojeg kamera prikazuje zapravo odgovara liniji u pros-

toru svijeta te je nama samo jedna tocka duž te linije vidljiva na objektu Sve iza te

tocke na liniji je zamraceno Vanjski rubovi objekta su definirani razilazecim linijama

16

koje odgovaraju kutevima objekta Kada bi se te linije pratile unazad prema kameri

sve bi na kraju konvergirale u jednu tocku U Unityu se ta tocka nalazi tocno na pozi-

ciji kamere i naziva se centrom perspektive Kut naspram linija koje konvergiraju od

gornjeg i donjeg centra ekrana u centru perspektive se zove vidno polje (engl Field Of

View) Sve što pada izvan tih razilazecih linija na rubovima objekta nece biti vidljivo

kameri uz vec prethodno spomenuta ogranicenja ravnina podrezivanja

U igrama je jako korisno imati matematicku reprezentaciju linije koja predstavlja tocku

u pogledu kamere Unity to omogucava u obliku objekta zrake Zraka uvijek odgo-

vara tocki u pogledu pa klasa Kamera (engl Camera) sadrži dvije korisne funkcije

ScreenPointToRay i ViewportPointToRay Razlika izmedu njih je da ScreenPointToRay

ocekuje tocku s koordinatama piksela dok ViewportPointToRay uzima normalizirane

koordinate (od 0 dolje ili lijevo do 1 gore ili desno) Obje funkcije vracaju zraku

koja se sastoji od tocke ishodišta i vektora koji pokazuje smjer linije od tog ishodišta

Zraka izlazi iz ravnine podrezivanja bliže kameri Najcešce se zrake koriste kako bi ih

bacali u scenu Bacanje zraka pošalje imaginarnu liniju uz zraku od njenog ishodišta

dok ne udari u neki sudarac u sceni Tada vraca informaciju o tocki koju je udarila

u objektu RaycastHit To je vrlo korisno kako bi se locirao objekt ovisno o njegovoj

poziciji na zaslonu npr lociranje kursora prikazano programskim kodom 43

Programski kod 43 lociranjeKursoracs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kamera

void Start()

RaycastHit udar

u objekt Ray se sprema pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

ako zraka udara u neki objekt spremi u objektUdaren to

mjesto

if (PhysicsRaycast(zraka out udar))

Transform objektUdaren = udartransform

17

Ponekad je takoder korisno dobiti zraku koja odgovara poziciji na zaslonu te onda

pomicati kameru uz tu zraku Npr želi se dozvoliti igracu da može selektirati objekt

mišem i onda ga povecati dok se objekt nalazi cijelo vrijeme na istoj poziciji na zaslonu

ispod miša prikazano programskim kodom 44 [1]

Programski kod 44 povecavanjeSlikecs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public bool povecavanje

public float brzinaPovecavanja

public Camera kamera

void Update()

ako netko koristi povecavanje slike (engl Zooming)

if (povecavanje)

u objekt Ray sprema se pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(Input

mousePosition)

udaljenost povecavanja ce biti jednaka umnosku

brzine povecavanja vremena i vertikalnog smjera

float udaljenostPovecavanja = brzinaPovecavanja

InputGetAxis(Vertical) TimedeltaTime

pomakni kameru u smjeru kursora misa za udaljenost

povecavanja u koordinatnom sustavu svijeta

kameratransformTranslate(zrakadirection

udaljenostPovecavanja SpaceWorld)

18

5 Kretanje

Pronalazak puta je zapravo pokušaj aplikacije na racunalu ili algoritma da nade naj-

kracu rutu izmedu dvije tocke To je recimo prakticna verzija rješavanja labirinta Ni

danas ne postoji optimalan algoritam koji ce u svakom slucaju u nekom realno krat-

kom vremenu naci najkraci put U ovom poglavlju objasnit ce se koje algoritme Unity

koristi za svoj navigacijski sustav Objašnjavat ce se i neki osnovni koncepti i obrasci

potrebni za ubrzavanje cijele ideje dojavljivanja promjena u sceni Bit ce prikazani i

programski kodovi potrebni za implementiranje kretanja mišem iili tipkovnicom Na

kraju ovog poglavlja želi se imati lika koji ce se slobodno kretati po sceni na mjesto

koje se odredi klikom miša i mogucnost prebacivanja na upravljanje tipkovnicom

51 Navigacijski sustav u Unityu

U Unityu je problem pronalaska puta vec riješen s necim što se zove navigacijska

mreža (engl NavMesh) To je navigacijski sustav koji ima svoje algoritme pronala-

ska puta i puno pojednostavljuje programiranje kretanja lika Sastoji se od cetiri di-

jela NavMesh agent navigacijske mreže (engl NavMesh Agent) izvanmrežna pove-

zanost(engl Off - Mesh Link) i prepreka navigacijske mreže(engl NavMesh Obstacle)

NavMesh je podatkovna struktura koja opisuje površine po kojima se može kretati

u igri i omogucava pronalazak put od jedne lokacije do druge Navigacijski sustav

treba svoje podatke kako bi predstavio prohodna podrucja u sceni Prohodna podru-

cja definiraju se kao mjesta gdje agent može stajati i kretati se Prohodno podrucje se

automatski izgraduje iz geometrije u sceni testirajuci sva podrucja gdje bi agent mo-

gao stajati Onda se te lokacije spajaju s površinom na vrhu geometrije Ta površina se

naziva onda NavMesh te je možemo vidjeti na 51 NavMesh tada sprema tu površinu

kao konveksne poligone te informacije koji su poligoni susjedni Komponenta Nav-

Mesh Agent pomaže pri kreiranju likova koji se medusobno izbjegavaju dok se krecu

prema cilju U Unityu se agenti opisuju kao valjci Koriste NavMesh kako bi se kretali

i znali koje objekte moraju zaobici te kako da se medusobno zaobidu Off-Mesh Link

19

omogucava dodavanje navigacijskih precaca koji se ne mogu predstaviti kao površina

po kojoj se može hodati npr skakanje preko ograde ili otvaranje vrata prije nego što

se ude u neku prostoriju NavMesh Obstacle opisuje prepreke koje se krecu te koje bi

agenti trebali izbjegavati dok hodaju svijetom npr neke bacve koje se kotrljaju prema

igracu Dok se bacva krece agent ce izracunati put oko nje najbolje što može no nakon

što ona naposljetku stane postat ce dio neprohodnog NavMesha te ce se agenti kretati

oko nje [3]

Slika 51 Prikaz navigacijskog sustava u Unityu

52 Pronalazak puta

Dva glavna problema postoje kod pronalaženja puta kako pronaci destinaciju na ni-

vou na kojem se igrac nalazi te kako se onda tamo pomaknuti Pronalaženje destinacije

uzima u obzir cijelu scenu Pomicanje tamo je dinamicnije u obzir uzima samo smjer

kretanja i kako da sprijeci sudaranje s drugim agentima Da bi se pronašao put izmedu

dvije lokacije prvo se moraju oznaciti pocetna i konacna lokacija njihovim najbližim

poligonima Tada se krece tražiti od pocetne lokacije posjecujuci sve susjedne dok se

ne dode do zadane destinacije Onda se prati unatrag vec posjecene poligone kako bi

se našao konacan niz poligona koji vode od pocetka do kraja Algoritam koji Unity

koristi te se cesto koristi za pronalazak puta naziva se A (A zvjezdica) Taj niz po-

ligona koji opisuje put od pocetka do kraja se naziva hodnik Agent ce doci do svoje

20

destinacije tako da se uvijek usmjerava prema sljedecem vidljivom kutu hodnika Ta

logika usmjeravanja uvijek uzima poziciju sljedeceg kuta i ovisno o tome nade željeni

smjer i brzinu potrebnu za dolazak na destinaciju Korištenje brzine po želji progra-

mera bi moglo dovesti do sudara s ostalim agentima Izbjegavanje prepreka takoder

pronalazi svoju novu brzinu koja traži ravnotežu izmedu kretanja prema destinaciji i

sprjecavanja buducih sudara s ostalim agentima i kutevima u navigacijskom sustavu

Nakon usmjeravanja i izbjegavanja prepreka izracuna se konacna brzina Unity ta-

koder uzima u obzir i akceleraciju kako bi simulirao realisticnije kretanje Takoder

treba razumjeti razliku izmedu globalne i lokalne navigacije Globalna navigacija se

koristi za pronalazak hodnika u svijetu Linearna lista poligona koja opisuje taj put je

podatkovna struktura koja se koristi za usmjeravanje te se može lokalno prilagodavati

i mijenjati kako se pozicija agenta mijenja Lokalna navigacija pokušava naci efika-

san nacin kako da se igrac pomakne prema sljedecem kutu bez da se sudari s ostalim

agentima ili objektima koji se krecu [3]

53 Kreiranje navigacijskog sustava

Proces kreiranja NavMesha iz geometrije nivoa se naziva pecenje navigacijske mreže

(engl NavMesh Baking) Skuplja sve terene i mreže objekata koji su oznaceni kao

navigacijski staticko (engl Navigation Static) i onda ih procesira kako bi kreirao navi-

gacijski sustav koji aproksimira prohodne površine nivoa Izgradnja (engl NavMesha)

je vrlo jednostavna Prvo se selektira geometrija koja bi trebala utjecati na navigaciju

tj površine po kojima možemo hodati i prepreke Oznaci se Navigation Static da bi ih

ukljucili u NavMesh Baking proces Prilagode se postavke kako bi odgovarale velicini

agenta - radijus (npr koliko blizu se može doci zidovima) visina (koliko su nisko

prostori koje agent može doseci) maksimalni nagib (koliko su kose rampe po kojima

se agent može uspeti) visina stube(koliko su visoke prepreke na koje agent može za-

koraciti) Onda jednostavno stisnemo ispeci (engl Bake) da izgradimo svoj NavMesh

Izgradeni NavMesh cemo moci vidjeti kao plavu površinu kao na slici 51 te ce se stvo-

riti nova datoteka s nazivom trenutne scene (ako vec ne postoji) i unutra ce se spremiti

kreiran navigacijski sustav [3]

21

54 Programiranje kretanja

Na liku se trenutno nalazi par stvari Animator Capsule Collider i Rigid Body Sada

je cilj isprogramirati mogucnost odredivanja gdje ce se lik kretati klikom miša na to

mjesto Dodaje se nova komponenta na lika NavMesh Agent Ta komponenta za-

pravo vec ima svoj sudarac te se slobodno može obrisati Capsule Collider jer postaje

nepotreban Igranjem s opcijama pomak od baze (engl Base Offset) te pod izbjegava-

nje prepreka (engl Obstacle Avoidance) radijus (engl Radius) i visina (engl Height)

prilagodi se sudarac od (engl NavMesh Agent-a) kako bi se obujmilo njime igraca i

sprijecilo propadanje kroz tlo od prije Sada kada postoji komponenta navigacije mora

se dodati skripta koja ce odrediti kada se lik krece te kada se pokrecu njegove anima-

cije iz Animator-a

Da bi se znalo gdje se miš nalazi mora se takoder dodati nova skriptu na kameru Kako

bi se izracunalo gdje trenutno kursor pokazuje Unity koristi vec prethodno spomenuto

bacanje zraka Da bi se moglo koristiti navigaciju putem klika mišem mora se napisati

skripta za glavnu kameru koja ce omoguciti bacanje zraka Skripta BacanjeZraka

dodaje se na objekt Main Camera koja se dodala pod prazni objekt Kamera Ova

skriptu se takoder koristi za razlikovanje raznih vrsta objekata Naime svaki objekt

kao što ima i Tag ima i sloj (engl Layer) Sloj služi kako bi mogli npr razlikovati

neprijatelje od obicnih objekata ili mjesto na koje želimo doci hodanjem Zato cemo

takoder dodati i jednu enumeraciju koja ce nam zasad služiti samo da razlikujemo je li

mjesto prohodno ili ne te jesmo li kliknuli na neprijatelja Kako bi dodali svoje nove

slojeve za objekte moramo kliknuti na Layer i dodaj sloj (engl Add Layer) kao na slici

52 što nas dovodi do novog prozora prikazanog na slici 53

Programski kod 51 bacanjeZrakacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

sluzi za dodavanje novih slojeva u Unity

public enum Sloj

Prohodno = 8

Neprijatelj = 9

KrajSvijeta = -1

22

Slika 52 Dodavanje novog sloja

public class BacanjeZraka MonoBehaviour

hijerarhija slojeva tj koji ima veci prioritet

public Sloj[] prioritetiSlojeva =

SlojNeprijatelj

SlojProhodno

SlojKrajSvijeta

udaljenost do pozadine je neka izmisljena vrijednost nakon

koje se prestane provjeravati zraka

public float udaljenostDoPozadine = 100f

Camera kamera

RaycastHit _udara

dohvaca varijable ove klase

public RaycastHit udara

get return _udara

Sloj _udaraSloj

23

Slika 53 Prozor za dodavanje novog sloja

public Sloj udaraSloj

get return _udaraSloj

deklariraj novi tip delegata

public delegate void priPromjeniSloja(Sloj noviSloj)

instanciraj skup promatraca

public event priPromjeniSloja promatraciPromjeneSloja

void Start ()

dohvat glavne kamere

kamera = Cameramain

void Update ()

nadi sloj po prioritetu u koji zraka udara

foreach(Sloj sloj in prioritetiSlojeva)

provjeravamo udara li zraka u neki od slojeva

24

var udar = BacanjeZrakaZaSloj(sloj)

if(udarHasValue)

_udara = udarValue

ako se sloj promjenio

if(_udaraSloj = sloj)

spremi novi sloj u varijablu trenutnog sloja

_udaraSloj = sloj

obavijesti promatrace da se sloj promjenio

promatraciPromjeneSloja(sloj)

spremi novi sloj u varijablu trenutnog sloja

ali ne moras obavjestavati promatrace jer je

sloj jednak starom sloju

_udaraSloj = sloj

return

inace vrati da zraka udara u pozadinu i obavijesti

promatrace

_udaradistance = udaljenostDoPozadine

_udaraSloj = SlojKrajSvijeta

promatraciPromjeneSloja(udaraSloj)

RaycastHit BacanjeZrakaZaSloj(Sloj sloj)

kreira se maska za slojeve bit se pomice ulijevo za

onoliko mjesta koliki je redni broj prioriteta sloja

int maska = 1 ltlt (int)sloj

sprema se mjesto pozicije kursora pretvoreno iz tocke u

zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

RaycastHit udar

PhysicsRaycast sprema zraku u varijablu tipa

RaycastHit prima jos i maksimalnu udaljenost za koju

provjerava zraku i masku sloja i potom vraca istinu (

engl True) ili laz (engl False) ako je zraka udarila

u sloj

25

bool udarioJe = PhysicsRaycast(zraka out udar

udaljenostDoPozadine maska)

ako zraka udara u sloj vrati vrijednost udarca

if(udarioJe)

return udar

return null

U programskom kodu 51 se koristi funkcija za primjenu obrasca promatraca pod

nazivom delegat (engl Delegate) Što je obrazac promatraca (engl Observer) To je

oblikovni obrazac koji se u programiranju koristi

bull kad promjena jednog objekta zahtijeva promjene u drugim objektima koji nisu

unaprijed poznati

bull kad objekt treba obavještavati druge objekte

bull uz uvjet da bude što neovisniji o njima

bull kad je potrebno prikazivati razlicite aspekte nekog dinamickog stanja a želimo

izbjeci ciklicku ovisnost izmedu stanja i pogleda

bull kad postoje dva koncepta jedan ovisan o drugome a zgodno ih je razdvojiti

S obzirom na to da mi samo pri promjeni sloja želimo obavještavati pretplacene pro-

matrace uvodenje delegata nam dosta ubrzava kod Obrazac promatraca funkcionira

tako da glavni objekt igra ulogu izdavaca (izvora informacija) u ovom slucaju to je

glavna kamera Ostali ovisni objekti (promatraci) pretplacuju se kod izdavaca te iz-

davaci obavještavaju pretplatnike o promjenama Promatraci prekidaju pretplatu kad

više ne trebaju obavještavanje Funkcija priPromjeniSloja se definira kao delegat i u

ovom slucaju prima sloj Nakon toga se definira dogadaj (engl Event) tipa tog delegata

(priPromjeniSloja) u ovom slucaju naziva promatraciPromjeneSloja i odsad se unutar

subjekta tim nazivom i poziva Kako bi se neki promatrac pretplatio na informacije

koje izdaje kamera dodaje ove dvije linije koda u svoju skriptu

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

Programski kod 52 služi za kretanje korištenjem NavMesha i lijevog klika miša

26

Programski kod 52 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

public float dovoljnoBlizu = 01f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora

[SerializeField] float hodajKreciStaniRadijus = 02f

void Start ()

pronadi igraca koji je tipa agenta navigacijskog sustava

(engl NavMeshAgent)

agent = GetComponentltUnityEngineAINavMeshAgentgt()

pronadi prethodno napisanu klasu BacanjeZraka

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

spremi trenutnu poziciju kursora

trenutnaPozicijaKursora = transformposition

void Update()

ako je igrac dosao na zeljeno mjesto zaustavi animaciju

hodanja

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

ako je stisnut lijevi klik misa

if (InputGetMouseButtonDown(0))

ovisno o sloju primjeni akciju

switch(bacanjeZrakaudaraSloj)

ako se po objektu na koji je igrac kliknuo moze

hodati

27

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 12: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

3 Unos glavnog lika u scenu

U ovom poglavlju opisuju se neki pocetni problemi s kojima se susrece pri ubacivanju

modela iz popularnog programa za modeliranje Blender Objašnjavaju se i modeli koji

su ponudeni unutar samog Unitya poput kocke i neke osnovne njihove transformacije

Nakon kraja ovog poglavlja želi se imati svojevrsno tlo i ubaceni glavni lik skupa s

njegovim teksturama i animacijama iz Blender-a koji nece propadati kroz tlo

31 Skaliranje

Jedno od osnovnih stvari o kojima se razmišlja prilikom kreiranja igre je koja ce se

brojcana skala koristiti Unity ima svoje mjerne jedinice koji predstavljaju metre u

njegovom fizickom sustavu Ovisno o tipu igre koja se kreira mora se paziti na skali-

ranje Izraduje li se neka igru u svemiru nece se koristiti naše realne mjerne jedinice

nego ce ih se naravno skalirati U ovom slucaju kreira se RPG (Role-playing game)

igra gdje nam je glavni lik covjek te ce se koristiti normalne Unity mjerne jedinice bez

skaliranja

32 Kreiranje osnovnih objekata

Za pocetak potrebno je kreirati jednostavno tlo Kocka se kreira s objekt igre (engl Ga-

meObject) -gt 3D objekt (engl 3D Object) -gt kocka (engl Cube) te se dobiva rezultat

kao na slici 31 Zasad se kocka skalira po x i z osi sa 100 Tlo je uobicajeno zelene

boje pa mu se dodaje novi materijal Pritisne se u prozor imovina (engl Asset) desnim

klikom miša i odabere se kreiraj (engl Create) -gt materijal (engl Material) kao što se

može vidjeti na slici 32 Klikom na novo-stvoreni materijal desno se pojavljuje novi

prozor Inspektor (engl Inspector) gdje se može odabrati boja Nakon toga samo se

povuce lijevim klikom miša materijal na skaliranu kocku tj tlo S obzirom na to

kako se želi da ta skalirana kocka glumi tlo želi se takoder da se i ostali objekti nalaze

7

Slika 31 Kreiranje tla

na njoj Zato ce se tlo morati pomaknuti po y osi za -05 kako bi se olakšalo daljnje

dodavanje objekata

33 Unos Blender modela u Unity i pocetni problemi

Krece se s ubacivanjem svog lika u igru Lik koji se koristi kroz ostatak ovog rada na-

pravljen je u programu Blender koji služi za 3D modeliranje blend objekt se može

samo povuci mišem u Unity iz datoteke u kojoj se nalazi

1 problem Kada se blend datoteka ubacuje u Unity on nece automatski ubaciti i

teksture koje su korištene u izradi tog modela Najlakši nacin bi bio izrada nove dato-

teku unutar Assets datoteke u Unityu i ubacivanje i blend modela i teksture koja je bila

korištena u izradi u tu novu datoteku Nakon toga klikom na model unutar prozora In-

spector pod Materials odabire se opcija od modelovih materijala (engl From Modelrsquos

Material) kao na slici33 kako bi Unity ucitavao korištene teksture Ponekad na žalost

ni to ne funkcionira pa ce se ovdje objasniti još jedan malo opcenitiji pristup Pri unosu

blend modela Unity kreira novu datoteku i nazove ju materijali (engl Materals) Ako

se dogodi da se korištene teksture na modelu ne vide treba se pogledati u tu datoteku

U njoj ce se nalaziti prazni materijali s istim imenima korištenih tekstura kao npr u

slucaju ovog projekta drvo (engl Wood) Tada se mora odabrati u desnom prozoru

materijala albedo (engl Albedo) kao na slici 34 i u ponudenim Assets naci teksturu

koja je korištena (u ovom slucaju Wood)

8

Slika 32 Kreiranje materijala

2 problem Sada kada je lik pozicioniran u ishodištu (x = 0 y = 0 z = 0) može se

dogoditi da se ne nalazi tocno na tlu koje je kreirano To dakako ovisi o modeliranju

koordinatama koje su korištene i skaliranju pri izradi modela Lik korišten u ovom

radu mora se pomaknuti na koordinatu x = 0 y = 15 z = 0 kako bi stajao tocno na tlu

3 problem Kada bi se igra sad pokrenula pritiskom na gumb Play pri vrhu Unitya

lik bi propao kroz tlo Zašto se to dogada Zbog necega što se zove sudarac (engl Col-

lider) u Unityu koji ce kasnije biti pomnije objašnjen Za sada se samo žele postaviti

neke pocetne stvari kako bi bilo lakše testirati osnovnu interakciju lika i objekata u

prostoru U desnom prozoru Inspector kada je lik oznacen vidi se opcija dodaj kom-

ponentu (engl Add Component) Stisne se na to i upiše sudarac u obliku kapsule

(engl Capsule Collider) kako bi se dodao novi sudarac To je zapravo samo sudarac

9

Slika 33 Unos blend modela u scenu

koji je u obliku kapsule te se igrajuci nekim njegovim osnovnim opcijama može na-

mjestiti vanjski oblik lika Dodaje se još jedna komponenta nad likom Ponovno se

stisne na Add Component te upiše kruto tijelo (engl Rigid Body) što ce takoder biti

naknadno objašnjeno Zasad je bitno razumijevanje da to omogucava liku da se ponaša

kao kruto tijelo u prostoru

4 problem Sada bi kada se igra pokrene trebao postojati lik koji ne propada kroz tlo

Naravno kao najosnovniju mehaniku želi se mogucnost kretanja po tom tlu Skripta

koja se treba napraviti kako bi se lik kretao po tlu nije zapravo komplicirana Sastoji

se samo od toga da se prilikom pritiska na odredeno slovo tipkovnice objekt translatira

po prostoru No ovaj model takoder sadrži i animacije za hodanje te se želi i to ukom-

ponirati Zato ce se takoder sada spomenuti još jedna nova komponenta kontrolor

animacija (engl Animator Controller) Dodaje se i ta komponenta na lika i prebacuje

se na prozor animator (engl Animator) koji se vidi na slici 35

U ovom prozoru postoji par novih opcija Mogu se dodavati nova stanja u kojima

ce se lik naci ovisno o nekim uvjetima koji se zadaju Pocetno stanje je ulazno stanje

(engl Entry State) i iz njega se želi da se lik nade u stanju mirovanja Stisne se desni

klik miša i odabere se novo stanje (engl New State) U ovom projektu je nazvano

Mirovanje Iz mirovanja ovisno o tome kada osoba pritisne neku tipku tipkovnice

želi se da se lik krene kretati Zato treba dodati novo stanje Hodanje Doda se

novo stanje istim postupkom kao i prvo Sada se naravno moraju dodati i usmjereni

prijelazi Stisne se desni klik miša na Mirovanje i odabere dodaj prijelaz (engl Add

10

Slika 34 Traženje tekstura Vašeg blend modela

Slika 35 Animator

Transition) To je sada kreiralo usmjerenu strelicu koja se može povuci prema Ho-

danje Isto to se napravi i u suprotnom smjeru Desni klik miša na Hodanje Add

Transition i povuce se strelica prema Mirovanje Naravno moraju se dodati uvjeti

koji ce odredivati kada ce objekt prijeci iz jednog stanja u drugo U ovom slucaju je

korišten cijeli broj (engl Integer) Ostatak problema kretanja rješavat ce se u poglavlju

4 Bacanje zraka i kretanje po mapi s mišem

11

4 Kamera

U ovom poglavlju se postavlja i bira prava kamera za igru Tijekom izrade igre treba se

takoder razmišljati i iz kojeg kuta ce se imati pogled na nju te hoce li se kamera pomi-

cati s kretanjem lika hoce li se moci rotirati itd Pri kreiranju 3D igre u pogledu scene

primjecuje se da su svi objekti i transformacije u 3D-prostoru No s obzirom na to da je

zaslon monitora igraca 2-dimenzionalan te se ne može prikazati tijela kao takva mora

se moci prikazati sve te objekte u jednoj ravnini i zadržati dojam 3-dimenzionalnosti

To se u Unityu postiže s kamerom Kamera je objekt koja definira pogled i njegov

smjer u prostoru scene Pozicija kamere definira ocište z os definira smjer gledanja

(gledište) te y os definira vrh ekrana Kamera takoder definira velicinu i oblik dijela

koji možemo vidjeti Kamera nam pokazuje ono što ona vidi Kako se ona rotira

translatira itd prikaz scene ce se takoder jednako transformirati Nakon kraja ovog

poglavlja želi se imati kamera koja ce pratiti kretnje lika i imati pogled na njega odoz-

gora

41 Perspektivna i ortografska kamera

Kamerom se zapravo objekte 3D prostora projicira na ravninu u 2D prostor Projek-

cije su matematicki modeli koji govore na koji nacin treba tocke 3D prostora preslikati

u ravninu u tocke 2D prostora Postoji više vrsta projekcija no Unity koristi dvije or-

tografsku projekciju i perspektivnu projekciju Kod ortografskih projekcija kamera je

okomita na ravninu projekcije dok je perspektivna projekcija bliža našem nacinu gle-

danja objekata Možda je najlakše primijetiti razliku koristeci slike Dakle na slici 41

možemo vidjeti blend model koji je modeliran u Blenderu u ortografskoj projekciji te

na slici 42 isti taj model pod istim kutem samo prebacen u perspektivnu projekciju

[6]

Perspektivna projekcija uvodi dvije tocke ocište i gledište Ocište je tocka u ko-

joj se nalazi promatrac Gledište odreduje smjer prema kojem promatrac gleda U

12

Slika 41 Ortografska projekcija blend modela

tocki gledišta stvara se ravnina projekcije koja je okomita na spojnicu ocište-gledište

[6] I perspektivna i ortografska kamera imaju granicu do koje mogu vidjeti od svoje

trenutne pozicije Ona je definirana upravo tom ravninom projekcije Tocka gledišta

pripada toj ravnini i ona tipicno postaje ishodište lokalnog dvodimenzijskog koordi-

natnog sustava koji razapinjemo u ravnini projekcije Ta ravnina se još naziva i daleka

ravnina podrezivanja zato što svi objekti koji se nalaze na vecoj udaljenosti od nje se

odrežu te ih kamera ne prikazuje Takoder postoji i ravnina podrezivanja blizu ka-

meri [1] Dio koji se prikazuje se nalazi izmedu te dvije ravnine

42 Pogled iz prvog lica u pogled iznad glave

U igrama se cesto koristi prebacivanje iz jednog u drugi pogled kamere Kako se

to postiže Koristeci veci broj kamera U ovom slucaju obradit ce se samo kratki

primjer kako se prebacivati iz pogleda prvog lica u pogled iznad glave U unity-u je

zadano da jedna kamera pokriva cijeli ekran te se zato samo pogled jedne kamere može

vidjeti u jednom trenutku Kamera koju vidimo je ona koja ima najvecu vrijednost

za svoje svojstvo dubine[1] Zato se želi napraviti skripta koja ce se prebacivati s

jedne kamere na drugu da bi se dobili drukciji pogledi na scenu koja je prikazana

programskim kodom 41

Programski kod 41 PrimjerViseKameracs

13

Slika 42 Perspektivna projekcija blend modela

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kameraPrvogLica

public Camera kameraIznadGlave

funkcija koja se poziva kada se prebacujemo u pogled iznad

glave

public void prikaziPogledIznadGlave()

kameraPrvogLicaenabled = false gasimo kameru prvog

lica

kameraIznadGlaveenabled = true palimo kameru iznad

glave

funkcija koja se poziva kada se prebacujemo u pogled iz

prvog lica

public void prikaziPogledIzPrvogLica()

kameraPrvogLicaenabled = true palimo kameru prvog

lica

overheadCameraenabled = false gasimo kameru iznad

glave

14

43 Fiksirana kamera

U sceni projekta vec postoji glavna kamera (engl Main Camera) koju Unity automat-

ski dodaje u scenu Kako bi ta kamera pratila lika može se samo povuci u lijevom

prozoru hijerarhije u hijerarhiju lika kako bi postala njegovo dijete Tako ce se postici

da kamera stalno prati njegove transformacije (translaciju rotaciju) prilikom pokreta-

nja igre No kako bi se postiglo da kamera ostane uvijek fiksirana te se samo krece s

njime umjesto da se kamera rotira skupa s likom dodaje se novi prazni objekt sa Game

Object -gt kreiraj prazan (engl Create Empty) Njegova pozicija se postavlja na x =

0 y = 0 z = 0 ako vec nije tamo te se postavlja taj prazan objekt kao roditelj glavne

kamere Sada kamera ostaje fiksirana na mjestu te se nece ni kretati s likom Kako bi

se krenula kretati mora se dodati nova skripta na taj prazan objekt koji se odsad u pro-

jektu zove Kamera s obzirom na to da zaista i je roditelj glavne kamere Kako bi se u

skripti lakše locirao objekt igraca oznacava ga se u njegovom polju oznaka (engl Tag)

u desnom prozoru Inspector s igrac (engl Player) kao što se može vidjeti na slici 43

zaokruženo plavom bojom

U programskom kodu se želi napraviti varijabla tipa Game Object kako bi se spremilo

igraca kada ga se pronade Unity takoder ima funkciju FindGameObjectWithTag pa

je onda ostatak koda prilicno intuitivan Kada se igrac pronade pomocu njegove oz-

nake Player prilikom svakog osvježavanja poziciji našeg igraca pridružuje se pozicija

kamere kao što je prikazano programskim kodom 42

Programski kod 42 pratiLikacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class pratiLika MonoBehaviour

GameObject igrac

void Start ()

trazi se objekt putem njegove oznake

igrac = GameObjectFindGameObjectWithTag(Player)

15

Slika 43 Oznacavanje lika radi lakšeg pronalaska u skripti

void LateUpdate ()

trenutni objekt mijenja svoju poziciju u skladu s

pozicijom objekta oznacenog oznakom Player

transformposition = igractransformposition

44 Bacanje zraka (engl Ray casting)

Perspektivna kamera u Unityu koristi oblik krnje piramide za dio koji prikazuje u pros-

toru Svaka tocka nekog objekta kojeg kamera prikazuje zapravo odgovara liniji u pros-

toru svijeta te je nama samo jedna tocka duž te linije vidljiva na objektu Sve iza te

tocke na liniji je zamraceno Vanjski rubovi objekta su definirani razilazecim linijama

16

koje odgovaraju kutevima objekta Kada bi se te linije pratile unazad prema kameri

sve bi na kraju konvergirale u jednu tocku U Unityu se ta tocka nalazi tocno na pozi-

ciji kamere i naziva se centrom perspektive Kut naspram linija koje konvergiraju od

gornjeg i donjeg centra ekrana u centru perspektive se zove vidno polje (engl Field Of

View) Sve što pada izvan tih razilazecih linija na rubovima objekta nece biti vidljivo

kameri uz vec prethodno spomenuta ogranicenja ravnina podrezivanja

U igrama je jako korisno imati matematicku reprezentaciju linije koja predstavlja tocku

u pogledu kamere Unity to omogucava u obliku objekta zrake Zraka uvijek odgo-

vara tocki u pogledu pa klasa Kamera (engl Camera) sadrži dvije korisne funkcije

ScreenPointToRay i ViewportPointToRay Razlika izmedu njih je da ScreenPointToRay

ocekuje tocku s koordinatama piksela dok ViewportPointToRay uzima normalizirane

koordinate (od 0 dolje ili lijevo do 1 gore ili desno) Obje funkcije vracaju zraku

koja se sastoji od tocke ishodišta i vektora koji pokazuje smjer linije od tog ishodišta

Zraka izlazi iz ravnine podrezivanja bliže kameri Najcešce se zrake koriste kako bi ih

bacali u scenu Bacanje zraka pošalje imaginarnu liniju uz zraku od njenog ishodišta

dok ne udari u neki sudarac u sceni Tada vraca informaciju o tocki koju je udarila

u objektu RaycastHit To je vrlo korisno kako bi se locirao objekt ovisno o njegovoj

poziciji na zaslonu npr lociranje kursora prikazano programskim kodom 43

Programski kod 43 lociranjeKursoracs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kamera

void Start()

RaycastHit udar

u objekt Ray se sprema pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

ako zraka udara u neki objekt spremi u objektUdaren to

mjesto

if (PhysicsRaycast(zraka out udar))

Transform objektUdaren = udartransform

17

Ponekad je takoder korisno dobiti zraku koja odgovara poziciji na zaslonu te onda

pomicati kameru uz tu zraku Npr želi se dozvoliti igracu da može selektirati objekt

mišem i onda ga povecati dok se objekt nalazi cijelo vrijeme na istoj poziciji na zaslonu

ispod miša prikazano programskim kodom 44 [1]

Programski kod 44 povecavanjeSlikecs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public bool povecavanje

public float brzinaPovecavanja

public Camera kamera

void Update()

ako netko koristi povecavanje slike (engl Zooming)

if (povecavanje)

u objekt Ray sprema se pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(Input

mousePosition)

udaljenost povecavanja ce biti jednaka umnosku

brzine povecavanja vremena i vertikalnog smjera

float udaljenostPovecavanja = brzinaPovecavanja

InputGetAxis(Vertical) TimedeltaTime

pomakni kameru u smjeru kursora misa za udaljenost

povecavanja u koordinatnom sustavu svijeta

kameratransformTranslate(zrakadirection

udaljenostPovecavanja SpaceWorld)

18

5 Kretanje

Pronalazak puta je zapravo pokušaj aplikacije na racunalu ili algoritma da nade naj-

kracu rutu izmedu dvije tocke To je recimo prakticna verzija rješavanja labirinta Ni

danas ne postoji optimalan algoritam koji ce u svakom slucaju u nekom realno krat-

kom vremenu naci najkraci put U ovom poglavlju objasnit ce se koje algoritme Unity

koristi za svoj navigacijski sustav Objašnjavat ce se i neki osnovni koncepti i obrasci

potrebni za ubrzavanje cijele ideje dojavljivanja promjena u sceni Bit ce prikazani i

programski kodovi potrebni za implementiranje kretanja mišem iili tipkovnicom Na

kraju ovog poglavlja želi se imati lika koji ce se slobodno kretati po sceni na mjesto

koje se odredi klikom miša i mogucnost prebacivanja na upravljanje tipkovnicom

51 Navigacijski sustav u Unityu

U Unityu je problem pronalaska puta vec riješen s necim što se zove navigacijska

mreža (engl NavMesh) To je navigacijski sustav koji ima svoje algoritme pronala-

ska puta i puno pojednostavljuje programiranje kretanja lika Sastoji se od cetiri di-

jela NavMesh agent navigacijske mreže (engl NavMesh Agent) izvanmrežna pove-

zanost(engl Off - Mesh Link) i prepreka navigacijske mreže(engl NavMesh Obstacle)

NavMesh je podatkovna struktura koja opisuje površine po kojima se može kretati

u igri i omogucava pronalazak put od jedne lokacije do druge Navigacijski sustav

treba svoje podatke kako bi predstavio prohodna podrucja u sceni Prohodna podru-

cja definiraju se kao mjesta gdje agent može stajati i kretati se Prohodno podrucje se

automatski izgraduje iz geometrije u sceni testirajuci sva podrucja gdje bi agent mo-

gao stajati Onda se te lokacije spajaju s površinom na vrhu geometrije Ta površina se

naziva onda NavMesh te je možemo vidjeti na 51 NavMesh tada sprema tu površinu

kao konveksne poligone te informacije koji su poligoni susjedni Komponenta Nav-

Mesh Agent pomaže pri kreiranju likova koji se medusobno izbjegavaju dok se krecu

prema cilju U Unityu se agenti opisuju kao valjci Koriste NavMesh kako bi se kretali

i znali koje objekte moraju zaobici te kako da se medusobno zaobidu Off-Mesh Link

19

omogucava dodavanje navigacijskih precaca koji se ne mogu predstaviti kao površina

po kojoj se može hodati npr skakanje preko ograde ili otvaranje vrata prije nego što

se ude u neku prostoriju NavMesh Obstacle opisuje prepreke koje se krecu te koje bi

agenti trebali izbjegavati dok hodaju svijetom npr neke bacve koje se kotrljaju prema

igracu Dok se bacva krece agent ce izracunati put oko nje najbolje što može no nakon

što ona naposljetku stane postat ce dio neprohodnog NavMesha te ce se agenti kretati

oko nje [3]

Slika 51 Prikaz navigacijskog sustava u Unityu

52 Pronalazak puta

Dva glavna problema postoje kod pronalaženja puta kako pronaci destinaciju na ni-

vou na kojem se igrac nalazi te kako se onda tamo pomaknuti Pronalaženje destinacije

uzima u obzir cijelu scenu Pomicanje tamo je dinamicnije u obzir uzima samo smjer

kretanja i kako da sprijeci sudaranje s drugim agentima Da bi se pronašao put izmedu

dvije lokacije prvo se moraju oznaciti pocetna i konacna lokacija njihovim najbližim

poligonima Tada se krece tražiti od pocetne lokacije posjecujuci sve susjedne dok se

ne dode do zadane destinacije Onda se prati unatrag vec posjecene poligone kako bi

se našao konacan niz poligona koji vode od pocetka do kraja Algoritam koji Unity

koristi te se cesto koristi za pronalazak puta naziva se A (A zvjezdica) Taj niz po-

ligona koji opisuje put od pocetka do kraja se naziva hodnik Agent ce doci do svoje

20

destinacije tako da se uvijek usmjerava prema sljedecem vidljivom kutu hodnika Ta

logika usmjeravanja uvijek uzima poziciju sljedeceg kuta i ovisno o tome nade željeni

smjer i brzinu potrebnu za dolazak na destinaciju Korištenje brzine po želji progra-

mera bi moglo dovesti do sudara s ostalim agentima Izbjegavanje prepreka takoder

pronalazi svoju novu brzinu koja traži ravnotežu izmedu kretanja prema destinaciji i

sprjecavanja buducih sudara s ostalim agentima i kutevima u navigacijskom sustavu

Nakon usmjeravanja i izbjegavanja prepreka izracuna se konacna brzina Unity ta-

koder uzima u obzir i akceleraciju kako bi simulirao realisticnije kretanje Takoder

treba razumjeti razliku izmedu globalne i lokalne navigacije Globalna navigacija se

koristi za pronalazak hodnika u svijetu Linearna lista poligona koja opisuje taj put je

podatkovna struktura koja se koristi za usmjeravanje te se može lokalno prilagodavati

i mijenjati kako se pozicija agenta mijenja Lokalna navigacija pokušava naci efika-

san nacin kako da se igrac pomakne prema sljedecem kutu bez da se sudari s ostalim

agentima ili objektima koji se krecu [3]

53 Kreiranje navigacijskog sustava

Proces kreiranja NavMesha iz geometrije nivoa se naziva pecenje navigacijske mreže

(engl NavMesh Baking) Skuplja sve terene i mreže objekata koji su oznaceni kao

navigacijski staticko (engl Navigation Static) i onda ih procesira kako bi kreirao navi-

gacijski sustav koji aproksimira prohodne površine nivoa Izgradnja (engl NavMesha)

je vrlo jednostavna Prvo se selektira geometrija koja bi trebala utjecati na navigaciju

tj površine po kojima možemo hodati i prepreke Oznaci se Navigation Static da bi ih

ukljucili u NavMesh Baking proces Prilagode se postavke kako bi odgovarale velicini

agenta - radijus (npr koliko blizu se može doci zidovima) visina (koliko su nisko

prostori koje agent može doseci) maksimalni nagib (koliko su kose rampe po kojima

se agent može uspeti) visina stube(koliko su visoke prepreke na koje agent može za-

koraciti) Onda jednostavno stisnemo ispeci (engl Bake) da izgradimo svoj NavMesh

Izgradeni NavMesh cemo moci vidjeti kao plavu površinu kao na slici 51 te ce se stvo-

riti nova datoteka s nazivom trenutne scene (ako vec ne postoji) i unutra ce se spremiti

kreiran navigacijski sustav [3]

21

54 Programiranje kretanja

Na liku se trenutno nalazi par stvari Animator Capsule Collider i Rigid Body Sada

je cilj isprogramirati mogucnost odredivanja gdje ce se lik kretati klikom miša na to

mjesto Dodaje se nova komponenta na lika NavMesh Agent Ta komponenta za-

pravo vec ima svoj sudarac te se slobodno može obrisati Capsule Collider jer postaje

nepotreban Igranjem s opcijama pomak od baze (engl Base Offset) te pod izbjegava-

nje prepreka (engl Obstacle Avoidance) radijus (engl Radius) i visina (engl Height)

prilagodi se sudarac od (engl NavMesh Agent-a) kako bi se obujmilo njime igraca i

sprijecilo propadanje kroz tlo od prije Sada kada postoji komponenta navigacije mora

se dodati skripta koja ce odrediti kada se lik krece te kada se pokrecu njegove anima-

cije iz Animator-a

Da bi se znalo gdje se miš nalazi mora se takoder dodati nova skriptu na kameru Kako

bi se izracunalo gdje trenutno kursor pokazuje Unity koristi vec prethodno spomenuto

bacanje zraka Da bi se moglo koristiti navigaciju putem klika mišem mora se napisati

skripta za glavnu kameru koja ce omoguciti bacanje zraka Skripta BacanjeZraka

dodaje se na objekt Main Camera koja se dodala pod prazni objekt Kamera Ova

skriptu se takoder koristi za razlikovanje raznih vrsta objekata Naime svaki objekt

kao što ima i Tag ima i sloj (engl Layer) Sloj služi kako bi mogli npr razlikovati

neprijatelje od obicnih objekata ili mjesto na koje želimo doci hodanjem Zato cemo

takoder dodati i jednu enumeraciju koja ce nam zasad služiti samo da razlikujemo je li

mjesto prohodno ili ne te jesmo li kliknuli na neprijatelja Kako bi dodali svoje nove

slojeve za objekte moramo kliknuti na Layer i dodaj sloj (engl Add Layer) kao na slici

52 što nas dovodi do novog prozora prikazanog na slici 53

Programski kod 51 bacanjeZrakacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

sluzi za dodavanje novih slojeva u Unity

public enum Sloj

Prohodno = 8

Neprijatelj = 9

KrajSvijeta = -1

22

Slika 52 Dodavanje novog sloja

public class BacanjeZraka MonoBehaviour

hijerarhija slojeva tj koji ima veci prioritet

public Sloj[] prioritetiSlojeva =

SlojNeprijatelj

SlojProhodno

SlojKrajSvijeta

udaljenost do pozadine je neka izmisljena vrijednost nakon

koje se prestane provjeravati zraka

public float udaljenostDoPozadine = 100f

Camera kamera

RaycastHit _udara

dohvaca varijable ove klase

public RaycastHit udara

get return _udara

Sloj _udaraSloj

23

Slika 53 Prozor za dodavanje novog sloja

public Sloj udaraSloj

get return _udaraSloj

deklariraj novi tip delegata

public delegate void priPromjeniSloja(Sloj noviSloj)

instanciraj skup promatraca

public event priPromjeniSloja promatraciPromjeneSloja

void Start ()

dohvat glavne kamere

kamera = Cameramain

void Update ()

nadi sloj po prioritetu u koji zraka udara

foreach(Sloj sloj in prioritetiSlojeva)

provjeravamo udara li zraka u neki od slojeva

24

var udar = BacanjeZrakaZaSloj(sloj)

if(udarHasValue)

_udara = udarValue

ako se sloj promjenio

if(_udaraSloj = sloj)

spremi novi sloj u varijablu trenutnog sloja

_udaraSloj = sloj

obavijesti promatrace da se sloj promjenio

promatraciPromjeneSloja(sloj)

spremi novi sloj u varijablu trenutnog sloja

ali ne moras obavjestavati promatrace jer je

sloj jednak starom sloju

_udaraSloj = sloj

return

inace vrati da zraka udara u pozadinu i obavijesti

promatrace

_udaradistance = udaljenostDoPozadine

_udaraSloj = SlojKrajSvijeta

promatraciPromjeneSloja(udaraSloj)

RaycastHit BacanjeZrakaZaSloj(Sloj sloj)

kreira se maska za slojeve bit se pomice ulijevo za

onoliko mjesta koliki je redni broj prioriteta sloja

int maska = 1 ltlt (int)sloj

sprema se mjesto pozicije kursora pretvoreno iz tocke u

zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

RaycastHit udar

PhysicsRaycast sprema zraku u varijablu tipa

RaycastHit prima jos i maksimalnu udaljenost za koju

provjerava zraku i masku sloja i potom vraca istinu (

engl True) ili laz (engl False) ako je zraka udarila

u sloj

25

bool udarioJe = PhysicsRaycast(zraka out udar

udaljenostDoPozadine maska)

ako zraka udara u sloj vrati vrijednost udarca

if(udarioJe)

return udar

return null

U programskom kodu 51 se koristi funkcija za primjenu obrasca promatraca pod

nazivom delegat (engl Delegate) Što je obrazac promatraca (engl Observer) To je

oblikovni obrazac koji se u programiranju koristi

bull kad promjena jednog objekta zahtijeva promjene u drugim objektima koji nisu

unaprijed poznati

bull kad objekt treba obavještavati druge objekte

bull uz uvjet da bude što neovisniji o njima

bull kad je potrebno prikazivati razlicite aspekte nekog dinamickog stanja a želimo

izbjeci ciklicku ovisnost izmedu stanja i pogleda

bull kad postoje dva koncepta jedan ovisan o drugome a zgodno ih je razdvojiti

S obzirom na to da mi samo pri promjeni sloja želimo obavještavati pretplacene pro-

matrace uvodenje delegata nam dosta ubrzava kod Obrazac promatraca funkcionira

tako da glavni objekt igra ulogu izdavaca (izvora informacija) u ovom slucaju to je

glavna kamera Ostali ovisni objekti (promatraci) pretplacuju se kod izdavaca te iz-

davaci obavještavaju pretplatnike o promjenama Promatraci prekidaju pretplatu kad

više ne trebaju obavještavanje Funkcija priPromjeniSloja se definira kao delegat i u

ovom slucaju prima sloj Nakon toga se definira dogadaj (engl Event) tipa tog delegata

(priPromjeniSloja) u ovom slucaju naziva promatraciPromjeneSloja i odsad se unutar

subjekta tim nazivom i poziva Kako bi se neki promatrac pretplatio na informacije

koje izdaje kamera dodaje ove dvije linije koda u svoju skriptu

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

Programski kod 52 služi za kretanje korištenjem NavMesha i lijevog klika miša

26

Programski kod 52 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

public float dovoljnoBlizu = 01f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora

[SerializeField] float hodajKreciStaniRadijus = 02f

void Start ()

pronadi igraca koji je tipa agenta navigacijskog sustava

(engl NavMeshAgent)

agent = GetComponentltUnityEngineAINavMeshAgentgt()

pronadi prethodno napisanu klasu BacanjeZraka

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

spremi trenutnu poziciju kursora

trenutnaPozicijaKursora = transformposition

void Update()

ako je igrac dosao na zeljeno mjesto zaustavi animaciju

hodanja

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

ako je stisnut lijevi klik misa

if (InputGetMouseButtonDown(0))

ovisno o sloju primjeni akciju

switch(bacanjeZrakaudaraSloj)

ako se po objektu na koji je igrac kliknuo moze

hodati

27

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 13: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

Slika 31 Kreiranje tla

na njoj Zato ce se tlo morati pomaknuti po y osi za -05 kako bi se olakšalo daljnje

dodavanje objekata

33 Unos Blender modela u Unity i pocetni problemi

Krece se s ubacivanjem svog lika u igru Lik koji se koristi kroz ostatak ovog rada na-

pravljen je u programu Blender koji služi za 3D modeliranje blend objekt se može

samo povuci mišem u Unity iz datoteke u kojoj se nalazi

1 problem Kada se blend datoteka ubacuje u Unity on nece automatski ubaciti i

teksture koje su korištene u izradi tog modela Najlakši nacin bi bio izrada nove dato-

teku unutar Assets datoteke u Unityu i ubacivanje i blend modela i teksture koja je bila

korištena u izradi u tu novu datoteku Nakon toga klikom na model unutar prozora In-

spector pod Materials odabire se opcija od modelovih materijala (engl From Modelrsquos

Material) kao na slici33 kako bi Unity ucitavao korištene teksture Ponekad na žalost

ni to ne funkcionira pa ce se ovdje objasniti još jedan malo opcenitiji pristup Pri unosu

blend modela Unity kreira novu datoteku i nazove ju materijali (engl Materals) Ako

se dogodi da se korištene teksture na modelu ne vide treba se pogledati u tu datoteku

U njoj ce se nalaziti prazni materijali s istim imenima korištenih tekstura kao npr u

slucaju ovog projekta drvo (engl Wood) Tada se mora odabrati u desnom prozoru

materijala albedo (engl Albedo) kao na slici 34 i u ponudenim Assets naci teksturu

koja je korištena (u ovom slucaju Wood)

8

Slika 32 Kreiranje materijala

2 problem Sada kada je lik pozicioniran u ishodištu (x = 0 y = 0 z = 0) može se

dogoditi da se ne nalazi tocno na tlu koje je kreirano To dakako ovisi o modeliranju

koordinatama koje su korištene i skaliranju pri izradi modela Lik korišten u ovom

radu mora se pomaknuti na koordinatu x = 0 y = 15 z = 0 kako bi stajao tocno na tlu

3 problem Kada bi se igra sad pokrenula pritiskom na gumb Play pri vrhu Unitya

lik bi propao kroz tlo Zašto se to dogada Zbog necega što se zove sudarac (engl Col-

lider) u Unityu koji ce kasnije biti pomnije objašnjen Za sada se samo žele postaviti

neke pocetne stvari kako bi bilo lakše testirati osnovnu interakciju lika i objekata u

prostoru U desnom prozoru Inspector kada je lik oznacen vidi se opcija dodaj kom-

ponentu (engl Add Component) Stisne se na to i upiše sudarac u obliku kapsule

(engl Capsule Collider) kako bi se dodao novi sudarac To je zapravo samo sudarac

9

Slika 33 Unos blend modela u scenu

koji je u obliku kapsule te se igrajuci nekim njegovim osnovnim opcijama može na-

mjestiti vanjski oblik lika Dodaje se još jedna komponenta nad likom Ponovno se

stisne na Add Component te upiše kruto tijelo (engl Rigid Body) što ce takoder biti

naknadno objašnjeno Zasad je bitno razumijevanje da to omogucava liku da se ponaša

kao kruto tijelo u prostoru

4 problem Sada bi kada se igra pokrene trebao postojati lik koji ne propada kroz tlo

Naravno kao najosnovniju mehaniku želi se mogucnost kretanja po tom tlu Skripta

koja se treba napraviti kako bi se lik kretao po tlu nije zapravo komplicirana Sastoji

se samo od toga da se prilikom pritiska na odredeno slovo tipkovnice objekt translatira

po prostoru No ovaj model takoder sadrži i animacije za hodanje te se želi i to ukom-

ponirati Zato ce se takoder sada spomenuti još jedna nova komponenta kontrolor

animacija (engl Animator Controller) Dodaje se i ta komponenta na lika i prebacuje

se na prozor animator (engl Animator) koji se vidi na slici 35

U ovom prozoru postoji par novih opcija Mogu se dodavati nova stanja u kojima

ce se lik naci ovisno o nekim uvjetima koji se zadaju Pocetno stanje je ulazno stanje

(engl Entry State) i iz njega se želi da se lik nade u stanju mirovanja Stisne se desni

klik miša i odabere se novo stanje (engl New State) U ovom projektu je nazvano

Mirovanje Iz mirovanja ovisno o tome kada osoba pritisne neku tipku tipkovnice

želi se da se lik krene kretati Zato treba dodati novo stanje Hodanje Doda se

novo stanje istim postupkom kao i prvo Sada se naravno moraju dodati i usmjereni

prijelazi Stisne se desni klik miša na Mirovanje i odabere dodaj prijelaz (engl Add

10

Slika 34 Traženje tekstura Vašeg blend modela

Slika 35 Animator

Transition) To je sada kreiralo usmjerenu strelicu koja se može povuci prema Ho-

danje Isto to se napravi i u suprotnom smjeru Desni klik miša na Hodanje Add

Transition i povuce se strelica prema Mirovanje Naravno moraju se dodati uvjeti

koji ce odredivati kada ce objekt prijeci iz jednog stanja u drugo U ovom slucaju je

korišten cijeli broj (engl Integer) Ostatak problema kretanja rješavat ce se u poglavlju

4 Bacanje zraka i kretanje po mapi s mišem

11

4 Kamera

U ovom poglavlju se postavlja i bira prava kamera za igru Tijekom izrade igre treba se

takoder razmišljati i iz kojeg kuta ce se imati pogled na nju te hoce li se kamera pomi-

cati s kretanjem lika hoce li se moci rotirati itd Pri kreiranju 3D igre u pogledu scene

primjecuje se da su svi objekti i transformacije u 3D-prostoru No s obzirom na to da je

zaslon monitora igraca 2-dimenzionalan te se ne može prikazati tijela kao takva mora

se moci prikazati sve te objekte u jednoj ravnini i zadržati dojam 3-dimenzionalnosti

To se u Unityu postiže s kamerom Kamera je objekt koja definira pogled i njegov

smjer u prostoru scene Pozicija kamere definira ocište z os definira smjer gledanja

(gledište) te y os definira vrh ekrana Kamera takoder definira velicinu i oblik dijela

koji možemo vidjeti Kamera nam pokazuje ono što ona vidi Kako se ona rotira

translatira itd prikaz scene ce se takoder jednako transformirati Nakon kraja ovog

poglavlja želi se imati kamera koja ce pratiti kretnje lika i imati pogled na njega odoz-

gora

41 Perspektivna i ortografska kamera

Kamerom se zapravo objekte 3D prostora projicira na ravninu u 2D prostor Projek-

cije su matematicki modeli koji govore na koji nacin treba tocke 3D prostora preslikati

u ravninu u tocke 2D prostora Postoji više vrsta projekcija no Unity koristi dvije or-

tografsku projekciju i perspektivnu projekciju Kod ortografskih projekcija kamera je

okomita na ravninu projekcije dok je perspektivna projekcija bliža našem nacinu gle-

danja objekata Možda je najlakše primijetiti razliku koristeci slike Dakle na slici 41

možemo vidjeti blend model koji je modeliran u Blenderu u ortografskoj projekciji te

na slici 42 isti taj model pod istim kutem samo prebacen u perspektivnu projekciju

[6]

Perspektivna projekcija uvodi dvije tocke ocište i gledište Ocište je tocka u ko-

joj se nalazi promatrac Gledište odreduje smjer prema kojem promatrac gleda U

12

Slika 41 Ortografska projekcija blend modela

tocki gledišta stvara se ravnina projekcije koja je okomita na spojnicu ocište-gledište

[6] I perspektivna i ortografska kamera imaju granicu do koje mogu vidjeti od svoje

trenutne pozicije Ona je definirana upravo tom ravninom projekcije Tocka gledišta

pripada toj ravnini i ona tipicno postaje ishodište lokalnog dvodimenzijskog koordi-

natnog sustava koji razapinjemo u ravnini projekcije Ta ravnina se još naziva i daleka

ravnina podrezivanja zato što svi objekti koji se nalaze na vecoj udaljenosti od nje se

odrežu te ih kamera ne prikazuje Takoder postoji i ravnina podrezivanja blizu ka-

meri [1] Dio koji se prikazuje se nalazi izmedu te dvije ravnine

42 Pogled iz prvog lica u pogled iznad glave

U igrama se cesto koristi prebacivanje iz jednog u drugi pogled kamere Kako se

to postiže Koristeci veci broj kamera U ovom slucaju obradit ce se samo kratki

primjer kako se prebacivati iz pogleda prvog lica u pogled iznad glave U unity-u je

zadano da jedna kamera pokriva cijeli ekran te se zato samo pogled jedne kamere može

vidjeti u jednom trenutku Kamera koju vidimo je ona koja ima najvecu vrijednost

za svoje svojstvo dubine[1] Zato se želi napraviti skripta koja ce se prebacivati s

jedne kamere na drugu da bi se dobili drukciji pogledi na scenu koja je prikazana

programskim kodom 41

Programski kod 41 PrimjerViseKameracs

13

Slika 42 Perspektivna projekcija blend modela

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kameraPrvogLica

public Camera kameraIznadGlave

funkcija koja se poziva kada se prebacujemo u pogled iznad

glave

public void prikaziPogledIznadGlave()

kameraPrvogLicaenabled = false gasimo kameru prvog

lica

kameraIznadGlaveenabled = true palimo kameru iznad

glave

funkcija koja se poziva kada se prebacujemo u pogled iz

prvog lica

public void prikaziPogledIzPrvogLica()

kameraPrvogLicaenabled = true palimo kameru prvog

lica

overheadCameraenabled = false gasimo kameru iznad

glave

14

43 Fiksirana kamera

U sceni projekta vec postoji glavna kamera (engl Main Camera) koju Unity automat-

ski dodaje u scenu Kako bi ta kamera pratila lika može se samo povuci u lijevom

prozoru hijerarhije u hijerarhiju lika kako bi postala njegovo dijete Tako ce se postici

da kamera stalno prati njegove transformacije (translaciju rotaciju) prilikom pokreta-

nja igre No kako bi se postiglo da kamera ostane uvijek fiksirana te se samo krece s

njime umjesto da se kamera rotira skupa s likom dodaje se novi prazni objekt sa Game

Object -gt kreiraj prazan (engl Create Empty) Njegova pozicija se postavlja na x =

0 y = 0 z = 0 ako vec nije tamo te se postavlja taj prazan objekt kao roditelj glavne

kamere Sada kamera ostaje fiksirana na mjestu te se nece ni kretati s likom Kako bi

se krenula kretati mora se dodati nova skripta na taj prazan objekt koji se odsad u pro-

jektu zove Kamera s obzirom na to da zaista i je roditelj glavne kamere Kako bi se u

skripti lakše locirao objekt igraca oznacava ga se u njegovom polju oznaka (engl Tag)

u desnom prozoru Inspector s igrac (engl Player) kao što se može vidjeti na slici 43

zaokruženo plavom bojom

U programskom kodu se želi napraviti varijabla tipa Game Object kako bi se spremilo

igraca kada ga se pronade Unity takoder ima funkciju FindGameObjectWithTag pa

je onda ostatak koda prilicno intuitivan Kada se igrac pronade pomocu njegove oz-

nake Player prilikom svakog osvježavanja poziciji našeg igraca pridružuje se pozicija

kamere kao što je prikazano programskim kodom 42

Programski kod 42 pratiLikacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class pratiLika MonoBehaviour

GameObject igrac

void Start ()

trazi se objekt putem njegove oznake

igrac = GameObjectFindGameObjectWithTag(Player)

15

Slika 43 Oznacavanje lika radi lakšeg pronalaska u skripti

void LateUpdate ()

trenutni objekt mijenja svoju poziciju u skladu s

pozicijom objekta oznacenog oznakom Player

transformposition = igractransformposition

44 Bacanje zraka (engl Ray casting)

Perspektivna kamera u Unityu koristi oblik krnje piramide za dio koji prikazuje u pros-

toru Svaka tocka nekog objekta kojeg kamera prikazuje zapravo odgovara liniji u pros-

toru svijeta te je nama samo jedna tocka duž te linije vidljiva na objektu Sve iza te

tocke na liniji je zamraceno Vanjski rubovi objekta su definirani razilazecim linijama

16

koje odgovaraju kutevima objekta Kada bi se te linije pratile unazad prema kameri

sve bi na kraju konvergirale u jednu tocku U Unityu se ta tocka nalazi tocno na pozi-

ciji kamere i naziva se centrom perspektive Kut naspram linija koje konvergiraju od

gornjeg i donjeg centra ekrana u centru perspektive se zove vidno polje (engl Field Of

View) Sve što pada izvan tih razilazecih linija na rubovima objekta nece biti vidljivo

kameri uz vec prethodno spomenuta ogranicenja ravnina podrezivanja

U igrama je jako korisno imati matematicku reprezentaciju linije koja predstavlja tocku

u pogledu kamere Unity to omogucava u obliku objekta zrake Zraka uvijek odgo-

vara tocki u pogledu pa klasa Kamera (engl Camera) sadrži dvije korisne funkcije

ScreenPointToRay i ViewportPointToRay Razlika izmedu njih je da ScreenPointToRay

ocekuje tocku s koordinatama piksela dok ViewportPointToRay uzima normalizirane

koordinate (od 0 dolje ili lijevo do 1 gore ili desno) Obje funkcije vracaju zraku

koja se sastoji od tocke ishodišta i vektora koji pokazuje smjer linije od tog ishodišta

Zraka izlazi iz ravnine podrezivanja bliže kameri Najcešce se zrake koriste kako bi ih

bacali u scenu Bacanje zraka pošalje imaginarnu liniju uz zraku od njenog ishodišta

dok ne udari u neki sudarac u sceni Tada vraca informaciju o tocki koju je udarila

u objektu RaycastHit To je vrlo korisno kako bi se locirao objekt ovisno o njegovoj

poziciji na zaslonu npr lociranje kursora prikazano programskim kodom 43

Programski kod 43 lociranjeKursoracs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kamera

void Start()

RaycastHit udar

u objekt Ray se sprema pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

ako zraka udara u neki objekt spremi u objektUdaren to

mjesto

if (PhysicsRaycast(zraka out udar))

Transform objektUdaren = udartransform

17

Ponekad je takoder korisno dobiti zraku koja odgovara poziciji na zaslonu te onda

pomicati kameru uz tu zraku Npr želi se dozvoliti igracu da može selektirati objekt

mišem i onda ga povecati dok se objekt nalazi cijelo vrijeme na istoj poziciji na zaslonu

ispod miša prikazano programskim kodom 44 [1]

Programski kod 44 povecavanjeSlikecs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public bool povecavanje

public float brzinaPovecavanja

public Camera kamera

void Update()

ako netko koristi povecavanje slike (engl Zooming)

if (povecavanje)

u objekt Ray sprema se pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(Input

mousePosition)

udaljenost povecavanja ce biti jednaka umnosku

brzine povecavanja vremena i vertikalnog smjera

float udaljenostPovecavanja = brzinaPovecavanja

InputGetAxis(Vertical) TimedeltaTime

pomakni kameru u smjeru kursora misa za udaljenost

povecavanja u koordinatnom sustavu svijeta

kameratransformTranslate(zrakadirection

udaljenostPovecavanja SpaceWorld)

18

5 Kretanje

Pronalazak puta je zapravo pokušaj aplikacije na racunalu ili algoritma da nade naj-

kracu rutu izmedu dvije tocke To je recimo prakticna verzija rješavanja labirinta Ni

danas ne postoji optimalan algoritam koji ce u svakom slucaju u nekom realno krat-

kom vremenu naci najkraci put U ovom poglavlju objasnit ce se koje algoritme Unity

koristi za svoj navigacijski sustav Objašnjavat ce se i neki osnovni koncepti i obrasci

potrebni za ubrzavanje cijele ideje dojavljivanja promjena u sceni Bit ce prikazani i

programski kodovi potrebni za implementiranje kretanja mišem iili tipkovnicom Na

kraju ovog poglavlja želi se imati lika koji ce se slobodno kretati po sceni na mjesto

koje se odredi klikom miša i mogucnost prebacivanja na upravljanje tipkovnicom

51 Navigacijski sustav u Unityu

U Unityu je problem pronalaska puta vec riješen s necim što se zove navigacijska

mreža (engl NavMesh) To je navigacijski sustav koji ima svoje algoritme pronala-

ska puta i puno pojednostavljuje programiranje kretanja lika Sastoji se od cetiri di-

jela NavMesh agent navigacijske mreže (engl NavMesh Agent) izvanmrežna pove-

zanost(engl Off - Mesh Link) i prepreka navigacijske mreže(engl NavMesh Obstacle)

NavMesh je podatkovna struktura koja opisuje površine po kojima se može kretati

u igri i omogucava pronalazak put od jedne lokacije do druge Navigacijski sustav

treba svoje podatke kako bi predstavio prohodna podrucja u sceni Prohodna podru-

cja definiraju se kao mjesta gdje agent može stajati i kretati se Prohodno podrucje se

automatski izgraduje iz geometrije u sceni testirajuci sva podrucja gdje bi agent mo-

gao stajati Onda se te lokacije spajaju s površinom na vrhu geometrije Ta površina se

naziva onda NavMesh te je možemo vidjeti na 51 NavMesh tada sprema tu površinu

kao konveksne poligone te informacije koji su poligoni susjedni Komponenta Nav-

Mesh Agent pomaže pri kreiranju likova koji se medusobno izbjegavaju dok se krecu

prema cilju U Unityu se agenti opisuju kao valjci Koriste NavMesh kako bi se kretali

i znali koje objekte moraju zaobici te kako da se medusobno zaobidu Off-Mesh Link

19

omogucava dodavanje navigacijskih precaca koji se ne mogu predstaviti kao površina

po kojoj se može hodati npr skakanje preko ograde ili otvaranje vrata prije nego što

se ude u neku prostoriju NavMesh Obstacle opisuje prepreke koje se krecu te koje bi

agenti trebali izbjegavati dok hodaju svijetom npr neke bacve koje se kotrljaju prema

igracu Dok se bacva krece agent ce izracunati put oko nje najbolje što može no nakon

što ona naposljetku stane postat ce dio neprohodnog NavMesha te ce se agenti kretati

oko nje [3]

Slika 51 Prikaz navigacijskog sustava u Unityu

52 Pronalazak puta

Dva glavna problema postoje kod pronalaženja puta kako pronaci destinaciju na ni-

vou na kojem se igrac nalazi te kako se onda tamo pomaknuti Pronalaženje destinacije

uzima u obzir cijelu scenu Pomicanje tamo je dinamicnije u obzir uzima samo smjer

kretanja i kako da sprijeci sudaranje s drugim agentima Da bi se pronašao put izmedu

dvije lokacije prvo se moraju oznaciti pocetna i konacna lokacija njihovim najbližim

poligonima Tada se krece tražiti od pocetne lokacije posjecujuci sve susjedne dok se

ne dode do zadane destinacije Onda se prati unatrag vec posjecene poligone kako bi

se našao konacan niz poligona koji vode od pocetka do kraja Algoritam koji Unity

koristi te se cesto koristi za pronalazak puta naziva se A (A zvjezdica) Taj niz po-

ligona koji opisuje put od pocetka do kraja se naziva hodnik Agent ce doci do svoje

20

destinacije tako da se uvijek usmjerava prema sljedecem vidljivom kutu hodnika Ta

logika usmjeravanja uvijek uzima poziciju sljedeceg kuta i ovisno o tome nade željeni

smjer i brzinu potrebnu za dolazak na destinaciju Korištenje brzine po želji progra-

mera bi moglo dovesti do sudara s ostalim agentima Izbjegavanje prepreka takoder

pronalazi svoju novu brzinu koja traži ravnotežu izmedu kretanja prema destinaciji i

sprjecavanja buducih sudara s ostalim agentima i kutevima u navigacijskom sustavu

Nakon usmjeravanja i izbjegavanja prepreka izracuna se konacna brzina Unity ta-

koder uzima u obzir i akceleraciju kako bi simulirao realisticnije kretanje Takoder

treba razumjeti razliku izmedu globalne i lokalne navigacije Globalna navigacija se

koristi za pronalazak hodnika u svijetu Linearna lista poligona koja opisuje taj put je

podatkovna struktura koja se koristi za usmjeravanje te se može lokalno prilagodavati

i mijenjati kako se pozicija agenta mijenja Lokalna navigacija pokušava naci efika-

san nacin kako da se igrac pomakne prema sljedecem kutu bez da se sudari s ostalim

agentima ili objektima koji se krecu [3]

53 Kreiranje navigacijskog sustava

Proces kreiranja NavMesha iz geometrije nivoa se naziva pecenje navigacijske mreže

(engl NavMesh Baking) Skuplja sve terene i mreže objekata koji su oznaceni kao

navigacijski staticko (engl Navigation Static) i onda ih procesira kako bi kreirao navi-

gacijski sustav koji aproksimira prohodne površine nivoa Izgradnja (engl NavMesha)

je vrlo jednostavna Prvo se selektira geometrija koja bi trebala utjecati na navigaciju

tj površine po kojima možemo hodati i prepreke Oznaci se Navigation Static da bi ih

ukljucili u NavMesh Baking proces Prilagode se postavke kako bi odgovarale velicini

agenta - radijus (npr koliko blizu se može doci zidovima) visina (koliko su nisko

prostori koje agent može doseci) maksimalni nagib (koliko su kose rampe po kojima

se agent može uspeti) visina stube(koliko su visoke prepreke na koje agent može za-

koraciti) Onda jednostavno stisnemo ispeci (engl Bake) da izgradimo svoj NavMesh

Izgradeni NavMesh cemo moci vidjeti kao plavu površinu kao na slici 51 te ce se stvo-

riti nova datoteka s nazivom trenutne scene (ako vec ne postoji) i unutra ce se spremiti

kreiran navigacijski sustav [3]

21

54 Programiranje kretanja

Na liku se trenutno nalazi par stvari Animator Capsule Collider i Rigid Body Sada

je cilj isprogramirati mogucnost odredivanja gdje ce se lik kretati klikom miša na to

mjesto Dodaje se nova komponenta na lika NavMesh Agent Ta komponenta za-

pravo vec ima svoj sudarac te se slobodno može obrisati Capsule Collider jer postaje

nepotreban Igranjem s opcijama pomak od baze (engl Base Offset) te pod izbjegava-

nje prepreka (engl Obstacle Avoidance) radijus (engl Radius) i visina (engl Height)

prilagodi se sudarac od (engl NavMesh Agent-a) kako bi se obujmilo njime igraca i

sprijecilo propadanje kroz tlo od prije Sada kada postoji komponenta navigacije mora

se dodati skripta koja ce odrediti kada se lik krece te kada se pokrecu njegove anima-

cije iz Animator-a

Da bi se znalo gdje se miš nalazi mora se takoder dodati nova skriptu na kameru Kako

bi se izracunalo gdje trenutno kursor pokazuje Unity koristi vec prethodno spomenuto

bacanje zraka Da bi se moglo koristiti navigaciju putem klika mišem mora se napisati

skripta za glavnu kameru koja ce omoguciti bacanje zraka Skripta BacanjeZraka

dodaje se na objekt Main Camera koja se dodala pod prazni objekt Kamera Ova

skriptu se takoder koristi za razlikovanje raznih vrsta objekata Naime svaki objekt

kao što ima i Tag ima i sloj (engl Layer) Sloj služi kako bi mogli npr razlikovati

neprijatelje od obicnih objekata ili mjesto na koje želimo doci hodanjem Zato cemo

takoder dodati i jednu enumeraciju koja ce nam zasad služiti samo da razlikujemo je li

mjesto prohodno ili ne te jesmo li kliknuli na neprijatelja Kako bi dodali svoje nove

slojeve za objekte moramo kliknuti na Layer i dodaj sloj (engl Add Layer) kao na slici

52 što nas dovodi do novog prozora prikazanog na slici 53

Programski kod 51 bacanjeZrakacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

sluzi za dodavanje novih slojeva u Unity

public enum Sloj

Prohodno = 8

Neprijatelj = 9

KrajSvijeta = -1

22

Slika 52 Dodavanje novog sloja

public class BacanjeZraka MonoBehaviour

hijerarhija slojeva tj koji ima veci prioritet

public Sloj[] prioritetiSlojeva =

SlojNeprijatelj

SlojProhodno

SlojKrajSvijeta

udaljenost do pozadine je neka izmisljena vrijednost nakon

koje se prestane provjeravati zraka

public float udaljenostDoPozadine = 100f

Camera kamera

RaycastHit _udara

dohvaca varijable ove klase

public RaycastHit udara

get return _udara

Sloj _udaraSloj

23

Slika 53 Prozor za dodavanje novog sloja

public Sloj udaraSloj

get return _udaraSloj

deklariraj novi tip delegata

public delegate void priPromjeniSloja(Sloj noviSloj)

instanciraj skup promatraca

public event priPromjeniSloja promatraciPromjeneSloja

void Start ()

dohvat glavne kamere

kamera = Cameramain

void Update ()

nadi sloj po prioritetu u koji zraka udara

foreach(Sloj sloj in prioritetiSlojeva)

provjeravamo udara li zraka u neki od slojeva

24

var udar = BacanjeZrakaZaSloj(sloj)

if(udarHasValue)

_udara = udarValue

ako se sloj promjenio

if(_udaraSloj = sloj)

spremi novi sloj u varijablu trenutnog sloja

_udaraSloj = sloj

obavijesti promatrace da se sloj promjenio

promatraciPromjeneSloja(sloj)

spremi novi sloj u varijablu trenutnog sloja

ali ne moras obavjestavati promatrace jer je

sloj jednak starom sloju

_udaraSloj = sloj

return

inace vrati da zraka udara u pozadinu i obavijesti

promatrace

_udaradistance = udaljenostDoPozadine

_udaraSloj = SlojKrajSvijeta

promatraciPromjeneSloja(udaraSloj)

RaycastHit BacanjeZrakaZaSloj(Sloj sloj)

kreira se maska za slojeve bit se pomice ulijevo za

onoliko mjesta koliki je redni broj prioriteta sloja

int maska = 1 ltlt (int)sloj

sprema se mjesto pozicije kursora pretvoreno iz tocke u

zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

RaycastHit udar

PhysicsRaycast sprema zraku u varijablu tipa

RaycastHit prima jos i maksimalnu udaljenost za koju

provjerava zraku i masku sloja i potom vraca istinu (

engl True) ili laz (engl False) ako je zraka udarila

u sloj

25

bool udarioJe = PhysicsRaycast(zraka out udar

udaljenostDoPozadine maska)

ako zraka udara u sloj vrati vrijednost udarca

if(udarioJe)

return udar

return null

U programskom kodu 51 se koristi funkcija za primjenu obrasca promatraca pod

nazivom delegat (engl Delegate) Što je obrazac promatraca (engl Observer) To je

oblikovni obrazac koji se u programiranju koristi

bull kad promjena jednog objekta zahtijeva promjene u drugim objektima koji nisu

unaprijed poznati

bull kad objekt treba obavještavati druge objekte

bull uz uvjet da bude što neovisniji o njima

bull kad je potrebno prikazivati razlicite aspekte nekog dinamickog stanja a želimo

izbjeci ciklicku ovisnost izmedu stanja i pogleda

bull kad postoje dva koncepta jedan ovisan o drugome a zgodno ih je razdvojiti

S obzirom na to da mi samo pri promjeni sloja želimo obavještavati pretplacene pro-

matrace uvodenje delegata nam dosta ubrzava kod Obrazac promatraca funkcionira

tako da glavni objekt igra ulogu izdavaca (izvora informacija) u ovom slucaju to je

glavna kamera Ostali ovisni objekti (promatraci) pretplacuju se kod izdavaca te iz-

davaci obavještavaju pretplatnike o promjenama Promatraci prekidaju pretplatu kad

više ne trebaju obavještavanje Funkcija priPromjeniSloja se definira kao delegat i u

ovom slucaju prima sloj Nakon toga se definira dogadaj (engl Event) tipa tog delegata

(priPromjeniSloja) u ovom slucaju naziva promatraciPromjeneSloja i odsad se unutar

subjekta tim nazivom i poziva Kako bi se neki promatrac pretplatio na informacije

koje izdaje kamera dodaje ove dvije linije koda u svoju skriptu

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

Programski kod 52 služi za kretanje korištenjem NavMesha i lijevog klika miša

26

Programski kod 52 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

public float dovoljnoBlizu = 01f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora

[SerializeField] float hodajKreciStaniRadijus = 02f

void Start ()

pronadi igraca koji je tipa agenta navigacijskog sustava

(engl NavMeshAgent)

agent = GetComponentltUnityEngineAINavMeshAgentgt()

pronadi prethodno napisanu klasu BacanjeZraka

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

spremi trenutnu poziciju kursora

trenutnaPozicijaKursora = transformposition

void Update()

ako je igrac dosao na zeljeno mjesto zaustavi animaciju

hodanja

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

ako je stisnut lijevi klik misa

if (InputGetMouseButtonDown(0))

ovisno o sloju primjeni akciju

switch(bacanjeZrakaudaraSloj)

ako se po objektu na koji je igrac kliknuo moze

hodati

27

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 14: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

Slika 32 Kreiranje materijala

2 problem Sada kada je lik pozicioniran u ishodištu (x = 0 y = 0 z = 0) može se

dogoditi da se ne nalazi tocno na tlu koje je kreirano To dakako ovisi o modeliranju

koordinatama koje su korištene i skaliranju pri izradi modela Lik korišten u ovom

radu mora se pomaknuti na koordinatu x = 0 y = 15 z = 0 kako bi stajao tocno na tlu

3 problem Kada bi se igra sad pokrenula pritiskom na gumb Play pri vrhu Unitya

lik bi propao kroz tlo Zašto se to dogada Zbog necega što se zove sudarac (engl Col-

lider) u Unityu koji ce kasnije biti pomnije objašnjen Za sada se samo žele postaviti

neke pocetne stvari kako bi bilo lakše testirati osnovnu interakciju lika i objekata u

prostoru U desnom prozoru Inspector kada je lik oznacen vidi se opcija dodaj kom-

ponentu (engl Add Component) Stisne se na to i upiše sudarac u obliku kapsule

(engl Capsule Collider) kako bi se dodao novi sudarac To je zapravo samo sudarac

9

Slika 33 Unos blend modela u scenu

koji je u obliku kapsule te se igrajuci nekim njegovim osnovnim opcijama može na-

mjestiti vanjski oblik lika Dodaje se još jedna komponenta nad likom Ponovno se

stisne na Add Component te upiše kruto tijelo (engl Rigid Body) što ce takoder biti

naknadno objašnjeno Zasad je bitno razumijevanje da to omogucava liku da se ponaša

kao kruto tijelo u prostoru

4 problem Sada bi kada se igra pokrene trebao postojati lik koji ne propada kroz tlo

Naravno kao najosnovniju mehaniku želi se mogucnost kretanja po tom tlu Skripta

koja se treba napraviti kako bi se lik kretao po tlu nije zapravo komplicirana Sastoji

se samo od toga da se prilikom pritiska na odredeno slovo tipkovnice objekt translatira

po prostoru No ovaj model takoder sadrži i animacije za hodanje te se želi i to ukom-

ponirati Zato ce se takoder sada spomenuti još jedna nova komponenta kontrolor

animacija (engl Animator Controller) Dodaje se i ta komponenta na lika i prebacuje

se na prozor animator (engl Animator) koji se vidi na slici 35

U ovom prozoru postoji par novih opcija Mogu se dodavati nova stanja u kojima

ce se lik naci ovisno o nekim uvjetima koji se zadaju Pocetno stanje je ulazno stanje

(engl Entry State) i iz njega se želi da se lik nade u stanju mirovanja Stisne se desni

klik miša i odabere se novo stanje (engl New State) U ovom projektu je nazvano

Mirovanje Iz mirovanja ovisno o tome kada osoba pritisne neku tipku tipkovnice

želi se da se lik krene kretati Zato treba dodati novo stanje Hodanje Doda se

novo stanje istim postupkom kao i prvo Sada se naravno moraju dodati i usmjereni

prijelazi Stisne se desni klik miša na Mirovanje i odabere dodaj prijelaz (engl Add

10

Slika 34 Traženje tekstura Vašeg blend modela

Slika 35 Animator

Transition) To je sada kreiralo usmjerenu strelicu koja se može povuci prema Ho-

danje Isto to se napravi i u suprotnom smjeru Desni klik miša na Hodanje Add

Transition i povuce se strelica prema Mirovanje Naravno moraju se dodati uvjeti

koji ce odredivati kada ce objekt prijeci iz jednog stanja u drugo U ovom slucaju je

korišten cijeli broj (engl Integer) Ostatak problema kretanja rješavat ce se u poglavlju

4 Bacanje zraka i kretanje po mapi s mišem

11

4 Kamera

U ovom poglavlju se postavlja i bira prava kamera za igru Tijekom izrade igre treba se

takoder razmišljati i iz kojeg kuta ce se imati pogled na nju te hoce li se kamera pomi-

cati s kretanjem lika hoce li se moci rotirati itd Pri kreiranju 3D igre u pogledu scene

primjecuje se da su svi objekti i transformacije u 3D-prostoru No s obzirom na to da je

zaslon monitora igraca 2-dimenzionalan te se ne može prikazati tijela kao takva mora

se moci prikazati sve te objekte u jednoj ravnini i zadržati dojam 3-dimenzionalnosti

To se u Unityu postiže s kamerom Kamera je objekt koja definira pogled i njegov

smjer u prostoru scene Pozicija kamere definira ocište z os definira smjer gledanja

(gledište) te y os definira vrh ekrana Kamera takoder definira velicinu i oblik dijela

koji možemo vidjeti Kamera nam pokazuje ono što ona vidi Kako se ona rotira

translatira itd prikaz scene ce se takoder jednako transformirati Nakon kraja ovog

poglavlja želi se imati kamera koja ce pratiti kretnje lika i imati pogled na njega odoz-

gora

41 Perspektivna i ortografska kamera

Kamerom se zapravo objekte 3D prostora projicira na ravninu u 2D prostor Projek-

cije su matematicki modeli koji govore na koji nacin treba tocke 3D prostora preslikati

u ravninu u tocke 2D prostora Postoji više vrsta projekcija no Unity koristi dvije or-

tografsku projekciju i perspektivnu projekciju Kod ortografskih projekcija kamera je

okomita na ravninu projekcije dok je perspektivna projekcija bliža našem nacinu gle-

danja objekata Možda je najlakše primijetiti razliku koristeci slike Dakle na slici 41

možemo vidjeti blend model koji je modeliran u Blenderu u ortografskoj projekciji te

na slici 42 isti taj model pod istim kutem samo prebacen u perspektivnu projekciju

[6]

Perspektivna projekcija uvodi dvije tocke ocište i gledište Ocište je tocka u ko-

joj se nalazi promatrac Gledište odreduje smjer prema kojem promatrac gleda U

12

Slika 41 Ortografska projekcija blend modela

tocki gledišta stvara se ravnina projekcije koja je okomita na spojnicu ocište-gledište

[6] I perspektivna i ortografska kamera imaju granicu do koje mogu vidjeti od svoje

trenutne pozicije Ona je definirana upravo tom ravninom projekcije Tocka gledišta

pripada toj ravnini i ona tipicno postaje ishodište lokalnog dvodimenzijskog koordi-

natnog sustava koji razapinjemo u ravnini projekcije Ta ravnina se još naziva i daleka

ravnina podrezivanja zato što svi objekti koji se nalaze na vecoj udaljenosti od nje se

odrežu te ih kamera ne prikazuje Takoder postoji i ravnina podrezivanja blizu ka-

meri [1] Dio koji se prikazuje se nalazi izmedu te dvije ravnine

42 Pogled iz prvog lica u pogled iznad glave

U igrama se cesto koristi prebacivanje iz jednog u drugi pogled kamere Kako se

to postiže Koristeci veci broj kamera U ovom slucaju obradit ce se samo kratki

primjer kako se prebacivati iz pogleda prvog lica u pogled iznad glave U unity-u je

zadano da jedna kamera pokriva cijeli ekran te se zato samo pogled jedne kamere može

vidjeti u jednom trenutku Kamera koju vidimo je ona koja ima najvecu vrijednost

za svoje svojstvo dubine[1] Zato se želi napraviti skripta koja ce se prebacivati s

jedne kamere na drugu da bi se dobili drukciji pogledi na scenu koja je prikazana

programskim kodom 41

Programski kod 41 PrimjerViseKameracs

13

Slika 42 Perspektivna projekcija blend modela

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kameraPrvogLica

public Camera kameraIznadGlave

funkcija koja se poziva kada se prebacujemo u pogled iznad

glave

public void prikaziPogledIznadGlave()

kameraPrvogLicaenabled = false gasimo kameru prvog

lica

kameraIznadGlaveenabled = true palimo kameru iznad

glave

funkcija koja se poziva kada se prebacujemo u pogled iz

prvog lica

public void prikaziPogledIzPrvogLica()

kameraPrvogLicaenabled = true palimo kameru prvog

lica

overheadCameraenabled = false gasimo kameru iznad

glave

14

43 Fiksirana kamera

U sceni projekta vec postoji glavna kamera (engl Main Camera) koju Unity automat-

ski dodaje u scenu Kako bi ta kamera pratila lika može se samo povuci u lijevom

prozoru hijerarhije u hijerarhiju lika kako bi postala njegovo dijete Tako ce se postici

da kamera stalno prati njegove transformacije (translaciju rotaciju) prilikom pokreta-

nja igre No kako bi se postiglo da kamera ostane uvijek fiksirana te se samo krece s

njime umjesto da se kamera rotira skupa s likom dodaje se novi prazni objekt sa Game

Object -gt kreiraj prazan (engl Create Empty) Njegova pozicija se postavlja na x =

0 y = 0 z = 0 ako vec nije tamo te se postavlja taj prazan objekt kao roditelj glavne

kamere Sada kamera ostaje fiksirana na mjestu te se nece ni kretati s likom Kako bi

se krenula kretati mora se dodati nova skripta na taj prazan objekt koji se odsad u pro-

jektu zove Kamera s obzirom na to da zaista i je roditelj glavne kamere Kako bi se u

skripti lakše locirao objekt igraca oznacava ga se u njegovom polju oznaka (engl Tag)

u desnom prozoru Inspector s igrac (engl Player) kao što se može vidjeti na slici 43

zaokruženo plavom bojom

U programskom kodu se želi napraviti varijabla tipa Game Object kako bi se spremilo

igraca kada ga se pronade Unity takoder ima funkciju FindGameObjectWithTag pa

je onda ostatak koda prilicno intuitivan Kada se igrac pronade pomocu njegove oz-

nake Player prilikom svakog osvježavanja poziciji našeg igraca pridružuje se pozicija

kamere kao što je prikazano programskim kodom 42

Programski kod 42 pratiLikacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class pratiLika MonoBehaviour

GameObject igrac

void Start ()

trazi se objekt putem njegove oznake

igrac = GameObjectFindGameObjectWithTag(Player)

15

Slika 43 Oznacavanje lika radi lakšeg pronalaska u skripti

void LateUpdate ()

trenutni objekt mijenja svoju poziciju u skladu s

pozicijom objekta oznacenog oznakom Player

transformposition = igractransformposition

44 Bacanje zraka (engl Ray casting)

Perspektivna kamera u Unityu koristi oblik krnje piramide za dio koji prikazuje u pros-

toru Svaka tocka nekog objekta kojeg kamera prikazuje zapravo odgovara liniji u pros-

toru svijeta te je nama samo jedna tocka duž te linije vidljiva na objektu Sve iza te

tocke na liniji je zamraceno Vanjski rubovi objekta su definirani razilazecim linijama

16

koje odgovaraju kutevima objekta Kada bi se te linije pratile unazad prema kameri

sve bi na kraju konvergirale u jednu tocku U Unityu se ta tocka nalazi tocno na pozi-

ciji kamere i naziva se centrom perspektive Kut naspram linija koje konvergiraju od

gornjeg i donjeg centra ekrana u centru perspektive se zove vidno polje (engl Field Of

View) Sve što pada izvan tih razilazecih linija na rubovima objekta nece biti vidljivo

kameri uz vec prethodno spomenuta ogranicenja ravnina podrezivanja

U igrama je jako korisno imati matematicku reprezentaciju linije koja predstavlja tocku

u pogledu kamere Unity to omogucava u obliku objekta zrake Zraka uvijek odgo-

vara tocki u pogledu pa klasa Kamera (engl Camera) sadrži dvije korisne funkcije

ScreenPointToRay i ViewportPointToRay Razlika izmedu njih je da ScreenPointToRay

ocekuje tocku s koordinatama piksela dok ViewportPointToRay uzima normalizirane

koordinate (od 0 dolje ili lijevo do 1 gore ili desno) Obje funkcije vracaju zraku

koja se sastoji od tocke ishodišta i vektora koji pokazuje smjer linije od tog ishodišta

Zraka izlazi iz ravnine podrezivanja bliže kameri Najcešce se zrake koriste kako bi ih

bacali u scenu Bacanje zraka pošalje imaginarnu liniju uz zraku od njenog ishodišta

dok ne udari u neki sudarac u sceni Tada vraca informaciju o tocki koju je udarila

u objektu RaycastHit To je vrlo korisno kako bi se locirao objekt ovisno o njegovoj

poziciji na zaslonu npr lociranje kursora prikazano programskim kodom 43

Programski kod 43 lociranjeKursoracs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kamera

void Start()

RaycastHit udar

u objekt Ray se sprema pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

ako zraka udara u neki objekt spremi u objektUdaren to

mjesto

if (PhysicsRaycast(zraka out udar))

Transform objektUdaren = udartransform

17

Ponekad je takoder korisno dobiti zraku koja odgovara poziciji na zaslonu te onda

pomicati kameru uz tu zraku Npr želi se dozvoliti igracu da može selektirati objekt

mišem i onda ga povecati dok se objekt nalazi cijelo vrijeme na istoj poziciji na zaslonu

ispod miša prikazano programskim kodom 44 [1]

Programski kod 44 povecavanjeSlikecs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public bool povecavanje

public float brzinaPovecavanja

public Camera kamera

void Update()

ako netko koristi povecavanje slike (engl Zooming)

if (povecavanje)

u objekt Ray sprema se pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(Input

mousePosition)

udaljenost povecavanja ce biti jednaka umnosku

brzine povecavanja vremena i vertikalnog smjera

float udaljenostPovecavanja = brzinaPovecavanja

InputGetAxis(Vertical) TimedeltaTime

pomakni kameru u smjeru kursora misa za udaljenost

povecavanja u koordinatnom sustavu svijeta

kameratransformTranslate(zrakadirection

udaljenostPovecavanja SpaceWorld)

18

5 Kretanje

Pronalazak puta je zapravo pokušaj aplikacije na racunalu ili algoritma da nade naj-

kracu rutu izmedu dvije tocke To je recimo prakticna verzija rješavanja labirinta Ni

danas ne postoji optimalan algoritam koji ce u svakom slucaju u nekom realno krat-

kom vremenu naci najkraci put U ovom poglavlju objasnit ce se koje algoritme Unity

koristi za svoj navigacijski sustav Objašnjavat ce se i neki osnovni koncepti i obrasci

potrebni za ubrzavanje cijele ideje dojavljivanja promjena u sceni Bit ce prikazani i

programski kodovi potrebni za implementiranje kretanja mišem iili tipkovnicom Na

kraju ovog poglavlja želi se imati lika koji ce se slobodno kretati po sceni na mjesto

koje se odredi klikom miša i mogucnost prebacivanja na upravljanje tipkovnicom

51 Navigacijski sustav u Unityu

U Unityu je problem pronalaska puta vec riješen s necim što se zove navigacijska

mreža (engl NavMesh) To je navigacijski sustav koji ima svoje algoritme pronala-

ska puta i puno pojednostavljuje programiranje kretanja lika Sastoji se od cetiri di-

jela NavMesh agent navigacijske mreže (engl NavMesh Agent) izvanmrežna pove-

zanost(engl Off - Mesh Link) i prepreka navigacijske mreže(engl NavMesh Obstacle)

NavMesh je podatkovna struktura koja opisuje površine po kojima se može kretati

u igri i omogucava pronalazak put od jedne lokacije do druge Navigacijski sustav

treba svoje podatke kako bi predstavio prohodna podrucja u sceni Prohodna podru-

cja definiraju se kao mjesta gdje agent može stajati i kretati se Prohodno podrucje se

automatski izgraduje iz geometrije u sceni testirajuci sva podrucja gdje bi agent mo-

gao stajati Onda se te lokacije spajaju s površinom na vrhu geometrije Ta površina se

naziva onda NavMesh te je možemo vidjeti na 51 NavMesh tada sprema tu površinu

kao konveksne poligone te informacije koji su poligoni susjedni Komponenta Nav-

Mesh Agent pomaže pri kreiranju likova koji se medusobno izbjegavaju dok se krecu

prema cilju U Unityu se agenti opisuju kao valjci Koriste NavMesh kako bi se kretali

i znali koje objekte moraju zaobici te kako da se medusobno zaobidu Off-Mesh Link

19

omogucava dodavanje navigacijskih precaca koji se ne mogu predstaviti kao površina

po kojoj se može hodati npr skakanje preko ograde ili otvaranje vrata prije nego što

se ude u neku prostoriju NavMesh Obstacle opisuje prepreke koje se krecu te koje bi

agenti trebali izbjegavati dok hodaju svijetom npr neke bacve koje se kotrljaju prema

igracu Dok se bacva krece agent ce izracunati put oko nje najbolje što može no nakon

što ona naposljetku stane postat ce dio neprohodnog NavMesha te ce se agenti kretati

oko nje [3]

Slika 51 Prikaz navigacijskog sustava u Unityu

52 Pronalazak puta

Dva glavna problema postoje kod pronalaženja puta kako pronaci destinaciju na ni-

vou na kojem se igrac nalazi te kako se onda tamo pomaknuti Pronalaženje destinacije

uzima u obzir cijelu scenu Pomicanje tamo je dinamicnije u obzir uzima samo smjer

kretanja i kako da sprijeci sudaranje s drugim agentima Da bi se pronašao put izmedu

dvije lokacije prvo se moraju oznaciti pocetna i konacna lokacija njihovim najbližim

poligonima Tada se krece tražiti od pocetne lokacije posjecujuci sve susjedne dok se

ne dode do zadane destinacije Onda se prati unatrag vec posjecene poligone kako bi

se našao konacan niz poligona koji vode od pocetka do kraja Algoritam koji Unity

koristi te se cesto koristi za pronalazak puta naziva se A (A zvjezdica) Taj niz po-

ligona koji opisuje put od pocetka do kraja se naziva hodnik Agent ce doci do svoje

20

destinacije tako da se uvijek usmjerava prema sljedecem vidljivom kutu hodnika Ta

logika usmjeravanja uvijek uzima poziciju sljedeceg kuta i ovisno o tome nade željeni

smjer i brzinu potrebnu za dolazak na destinaciju Korištenje brzine po želji progra-

mera bi moglo dovesti do sudara s ostalim agentima Izbjegavanje prepreka takoder

pronalazi svoju novu brzinu koja traži ravnotežu izmedu kretanja prema destinaciji i

sprjecavanja buducih sudara s ostalim agentima i kutevima u navigacijskom sustavu

Nakon usmjeravanja i izbjegavanja prepreka izracuna se konacna brzina Unity ta-

koder uzima u obzir i akceleraciju kako bi simulirao realisticnije kretanje Takoder

treba razumjeti razliku izmedu globalne i lokalne navigacije Globalna navigacija se

koristi za pronalazak hodnika u svijetu Linearna lista poligona koja opisuje taj put je

podatkovna struktura koja se koristi za usmjeravanje te se može lokalno prilagodavati

i mijenjati kako se pozicija agenta mijenja Lokalna navigacija pokušava naci efika-

san nacin kako da se igrac pomakne prema sljedecem kutu bez da se sudari s ostalim

agentima ili objektima koji se krecu [3]

53 Kreiranje navigacijskog sustava

Proces kreiranja NavMesha iz geometrije nivoa se naziva pecenje navigacijske mreže

(engl NavMesh Baking) Skuplja sve terene i mreže objekata koji su oznaceni kao

navigacijski staticko (engl Navigation Static) i onda ih procesira kako bi kreirao navi-

gacijski sustav koji aproksimira prohodne površine nivoa Izgradnja (engl NavMesha)

je vrlo jednostavna Prvo se selektira geometrija koja bi trebala utjecati na navigaciju

tj površine po kojima možemo hodati i prepreke Oznaci se Navigation Static da bi ih

ukljucili u NavMesh Baking proces Prilagode se postavke kako bi odgovarale velicini

agenta - radijus (npr koliko blizu se može doci zidovima) visina (koliko su nisko

prostori koje agent može doseci) maksimalni nagib (koliko su kose rampe po kojima

se agent može uspeti) visina stube(koliko su visoke prepreke na koje agent može za-

koraciti) Onda jednostavno stisnemo ispeci (engl Bake) da izgradimo svoj NavMesh

Izgradeni NavMesh cemo moci vidjeti kao plavu površinu kao na slici 51 te ce se stvo-

riti nova datoteka s nazivom trenutne scene (ako vec ne postoji) i unutra ce se spremiti

kreiran navigacijski sustav [3]

21

54 Programiranje kretanja

Na liku se trenutno nalazi par stvari Animator Capsule Collider i Rigid Body Sada

je cilj isprogramirati mogucnost odredivanja gdje ce se lik kretati klikom miša na to

mjesto Dodaje se nova komponenta na lika NavMesh Agent Ta komponenta za-

pravo vec ima svoj sudarac te se slobodno može obrisati Capsule Collider jer postaje

nepotreban Igranjem s opcijama pomak od baze (engl Base Offset) te pod izbjegava-

nje prepreka (engl Obstacle Avoidance) radijus (engl Radius) i visina (engl Height)

prilagodi se sudarac od (engl NavMesh Agent-a) kako bi se obujmilo njime igraca i

sprijecilo propadanje kroz tlo od prije Sada kada postoji komponenta navigacije mora

se dodati skripta koja ce odrediti kada se lik krece te kada se pokrecu njegove anima-

cije iz Animator-a

Da bi se znalo gdje se miš nalazi mora se takoder dodati nova skriptu na kameru Kako

bi se izracunalo gdje trenutno kursor pokazuje Unity koristi vec prethodno spomenuto

bacanje zraka Da bi se moglo koristiti navigaciju putem klika mišem mora se napisati

skripta za glavnu kameru koja ce omoguciti bacanje zraka Skripta BacanjeZraka

dodaje se na objekt Main Camera koja se dodala pod prazni objekt Kamera Ova

skriptu se takoder koristi za razlikovanje raznih vrsta objekata Naime svaki objekt

kao što ima i Tag ima i sloj (engl Layer) Sloj služi kako bi mogli npr razlikovati

neprijatelje od obicnih objekata ili mjesto na koje želimo doci hodanjem Zato cemo

takoder dodati i jednu enumeraciju koja ce nam zasad služiti samo da razlikujemo je li

mjesto prohodno ili ne te jesmo li kliknuli na neprijatelja Kako bi dodali svoje nove

slojeve za objekte moramo kliknuti na Layer i dodaj sloj (engl Add Layer) kao na slici

52 što nas dovodi do novog prozora prikazanog na slici 53

Programski kod 51 bacanjeZrakacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

sluzi za dodavanje novih slojeva u Unity

public enum Sloj

Prohodno = 8

Neprijatelj = 9

KrajSvijeta = -1

22

Slika 52 Dodavanje novog sloja

public class BacanjeZraka MonoBehaviour

hijerarhija slojeva tj koji ima veci prioritet

public Sloj[] prioritetiSlojeva =

SlojNeprijatelj

SlojProhodno

SlojKrajSvijeta

udaljenost do pozadine je neka izmisljena vrijednost nakon

koje se prestane provjeravati zraka

public float udaljenostDoPozadine = 100f

Camera kamera

RaycastHit _udara

dohvaca varijable ove klase

public RaycastHit udara

get return _udara

Sloj _udaraSloj

23

Slika 53 Prozor za dodavanje novog sloja

public Sloj udaraSloj

get return _udaraSloj

deklariraj novi tip delegata

public delegate void priPromjeniSloja(Sloj noviSloj)

instanciraj skup promatraca

public event priPromjeniSloja promatraciPromjeneSloja

void Start ()

dohvat glavne kamere

kamera = Cameramain

void Update ()

nadi sloj po prioritetu u koji zraka udara

foreach(Sloj sloj in prioritetiSlojeva)

provjeravamo udara li zraka u neki od slojeva

24

var udar = BacanjeZrakaZaSloj(sloj)

if(udarHasValue)

_udara = udarValue

ako se sloj promjenio

if(_udaraSloj = sloj)

spremi novi sloj u varijablu trenutnog sloja

_udaraSloj = sloj

obavijesti promatrace da se sloj promjenio

promatraciPromjeneSloja(sloj)

spremi novi sloj u varijablu trenutnog sloja

ali ne moras obavjestavati promatrace jer je

sloj jednak starom sloju

_udaraSloj = sloj

return

inace vrati da zraka udara u pozadinu i obavijesti

promatrace

_udaradistance = udaljenostDoPozadine

_udaraSloj = SlojKrajSvijeta

promatraciPromjeneSloja(udaraSloj)

RaycastHit BacanjeZrakaZaSloj(Sloj sloj)

kreira se maska za slojeve bit se pomice ulijevo za

onoliko mjesta koliki je redni broj prioriteta sloja

int maska = 1 ltlt (int)sloj

sprema se mjesto pozicije kursora pretvoreno iz tocke u

zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

RaycastHit udar

PhysicsRaycast sprema zraku u varijablu tipa

RaycastHit prima jos i maksimalnu udaljenost za koju

provjerava zraku i masku sloja i potom vraca istinu (

engl True) ili laz (engl False) ako je zraka udarila

u sloj

25

bool udarioJe = PhysicsRaycast(zraka out udar

udaljenostDoPozadine maska)

ako zraka udara u sloj vrati vrijednost udarca

if(udarioJe)

return udar

return null

U programskom kodu 51 se koristi funkcija za primjenu obrasca promatraca pod

nazivom delegat (engl Delegate) Što je obrazac promatraca (engl Observer) To je

oblikovni obrazac koji se u programiranju koristi

bull kad promjena jednog objekta zahtijeva promjene u drugim objektima koji nisu

unaprijed poznati

bull kad objekt treba obavještavati druge objekte

bull uz uvjet da bude što neovisniji o njima

bull kad je potrebno prikazivati razlicite aspekte nekog dinamickog stanja a želimo

izbjeci ciklicku ovisnost izmedu stanja i pogleda

bull kad postoje dva koncepta jedan ovisan o drugome a zgodno ih je razdvojiti

S obzirom na to da mi samo pri promjeni sloja želimo obavještavati pretplacene pro-

matrace uvodenje delegata nam dosta ubrzava kod Obrazac promatraca funkcionira

tako da glavni objekt igra ulogu izdavaca (izvora informacija) u ovom slucaju to je

glavna kamera Ostali ovisni objekti (promatraci) pretplacuju se kod izdavaca te iz-

davaci obavještavaju pretplatnike o promjenama Promatraci prekidaju pretplatu kad

više ne trebaju obavještavanje Funkcija priPromjeniSloja se definira kao delegat i u

ovom slucaju prima sloj Nakon toga se definira dogadaj (engl Event) tipa tog delegata

(priPromjeniSloja) u ovom slucaju naziva promatraciPromjeneSloja i odsad se unutar

subjekta tim nazivom i poziva Kako bi se neki promatrac pretplatio na informacije

koje izdaje kamera dodaje ove dvije linije koda u svoju skriptu

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

Programski kod 52 služi za kretanje korištenjem NavMesha i lijevog klika miša

26

Programski kod 52 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

public float dovoljnoBlizu = 01f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora

[SerializeField] float hodajKreciStaniRadijus = 02f

void Start ()

pronadi igraca koji je tipa agenta navigacijskog sustava

(engl NavMeshAgent)

agent = GetComponentltUnityEngineAINavMeshAgentgt()

pronadi prethodno napisanu klasu BacanjeZraka

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

spremi trenutnu poziciju kursora

trenutnaPozicijaKursora = transformposition

void Update()

ako je igrac dosao na zeljeno mjesto zaustavi animaciju

hodanja

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

ako je stisnut lijevi klik misa

if (InputGetMouseButtonDown(0))

ovisno o sloju primjeni akciju

switch(bacanjeZrakaudaraSloj)

ako se po objektu na koji je igrac kliknuo moze

hodati

27

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 15: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

Slika 33 Unos blend modela u scenu

koji je u obliku kapsule te se igrajuci nekim njegovim osnovnim opcijama može na-

mjestiti vanjski oblik lika Dodaje se još jedna komponenta nad likom Ponovno se

stisne na Add Component te upiše kruto tijelo (engl Rigid Body) što ce takoder biti

naknadno objašnjeno Zasad je bitno razumijevanje da to omogucava liku da se ponaša

kao kruto tijelo u prostoru

4 problem Sada bi kada se igra pokrene trebao postojati lik koji ne propada kroz tlo

Naravno kao najosnovniju mehaniku želi se mogucnost kretanja po tom tlu Skripta

koja se treba napraviti kako bi se lik kretao po tlu nije zapravo komplicirana Sastoji

se samo od toga da se prilikom pritiska na odredeno slovo tipkovnice objekt translatira

po prostoru No ovaj model takoder sadrži i animacije za hodanje te se želi i to ukom-

ponirati Zato ce se takoder sada spomenuti još jedna nova komponenta kontrolor

animacija (engl Animator Controller) Dodaje se i ta komponenta na lika i prebacuje

se na prozor animator (engl Animator) koji se vidi na slici 35

U ovom prozoru postoji par novih opcija Mogu se dodavati nova stanja u kojima

ce se lik naci ovisno o nekim uvjetima koji se zadaju Pocetno stanje je ulazno stanje

(engl Entry State) i iz njega se želi da se lik nade u stanju mirovanja Stisne se desni

klik miša i odabere se novo stanje (engl New State) U ovom projektu je nazvano

Mirovanje Iz mirovanja ovisno o tome kada osoba pritisne neku tipku tipkovnice

želi se da se lik krene kretati Zato treba dodati novo stanje Hodanje Doda se

novo stanje istim postupkom kao i prvo Sada se naravno moraju dodati i usmjereni

prijelazi Stisne se desni klik miša na Mirovanje i odabere dodaj prijelaz (engl Add

10

Slika 34 Traženje tekstura Vašeg blend modela

Slika 35 Animator

Transition) To je sada kreiralo usmjerenu strelicu koja se može povuci prema Ho-

danje Isto to se napravi i u suprotnom smjeru Desni klik miša na Hodanje Add

Transition i povuce se strelica prema Mirovanje Naravno moraju se dodati uvjeti

koji ce odredivati kada ce objekt prijeci iz jednog stanja u drugo U ovom slucaju je

korišten cijeli broj (engl Integer) Ostatak problema kretanja rješavat ce se u poglavlju

4 Bacanje zraka i kretanje po mapi s mišem

11

4 Kamera

U ovom poglavlju se postavlja i bira prava kamera za igru Tijekom izrade igre treba se

takoder razmišljati i iz kojeg kuta ce se imati pogled na nju te hoce li se kamera pomi-

cati s kretanjem lika hoce li se moci rotirati itd Pri kreiranju 3D igre u pogledu scene

primjecuje se da su svi objekti i transformacije u 3D-prostoru No s obzirom na to da je

zaslon monitora igraca 2-dimenzionalan te se ne može prikazati tijela kao takva mora

se moci prikazati sve te objekte u jednoj ravnini i zadržati dojam 3-dimenzionalnosti

To se u Unityu postiže s kamerom Kamera je objekt koja definira pogled i njegov

smjer u prostoru scene Pozicija kamere definira ocište z os definira smjer gledanja

(gledište) te y os definira vrh ekrana Kamera takoder definira velicinu i oblik dijela

koji možemo vidjeti Kamera nam pokazuje ono što ona vidi Kako se ona rotira

translatira itd prikaz scene ce se takoder jednako transformirati Nakon kraja ovog

poglavlja želi se imati kamera koja ce pratiti kretnje lika i imati pogled na njega odoz-

gora

41 Perspektivna i ortografska kamera

Kamerom se zapravo objekte 3D prostora projicira na ravninu u 2D prostor Projek-

cije su matematicki modeli koji govore na koji nacin treba tocke 3D prostora preslikati

u ravninu u tocke 2D prostora Postoji više vrsta projekcija no Unity koristi dvije or-

tografsku projekciju i perspektivnu projekciju Kod ortografskih projekcija kamera je

okomita na ravninu projekcije dok je perspektivna projekcija bliža našem nacinu gle-

danja objekata Možda je najlakše primijetiti razliku koristeci slike Dakle na slici 41

možemo vidjeti blend model koji je modeliran u Blenderu u ortografskoj projekciji te

na slici 42 isti taj model pod istim kutem samo prebacen u perspektivnu projekciju

[6]

Perspektivna projekcija uvodi dvije tocke ocište i gledište Ocište je tocka u ko-

joj se nalazi promatrac Gledište odreduje smjer prema kojem promatrac gleda U

12

Slika 41 Ortografska projekcija blend modela

tocki gledišta stvara se ravnina projekcije koja je okomita na spojnicu ocište-gledište

[6] I perspektivna i ortografska kamera imaju granicu do koje mogu vidjeti od svoje

trenutne pozicije Ona je definirana upravo tom ravninom projekcije Tocka gledišta

pripada toj ravnini i ona tipicno postaje ishodište lokalnog dvodimenzijskog koordi-

natnog sustava koji razapinjemo u ravnini projekcije Ta ravnina se još naziva i daleka

ravnina podrezivanja zato što svi objekti koji se nalaze na vecoj udaljenosti od nje se

odrežu te ih kamera ne prikazuje Takoder postoji i ravnina podrezivanja blizu ka-

meri [1] Dio koji se prikazuje se nalazi izmedu te dvije ravnine

42 Pogled iz prvog lica u pogled iznad glave

U igrama se cesto koristi prebacivanje iz jednog u drugi pogled kamere Kako se

to postiže Koristeci veci broj kamera U ovom slucaju obradit ce se samo kratki

primjer kako se prebacivati iz pogleda prvog lica u pogled iznad glave U unity-u je

zadano da jedna kamera pokriva cijeli ekran te se zato samo pogled jedne kamere može

vidjeti u jednom trenutku Kamera koju vidimo je ona koja ima najvecu vrijednost

za svoje svojstvo dubine[1] Zato se želi napraviti skripta koja ce se prebacivati s

jedne kamere na drugu da bi se dobili drukciji pogledi na scenu koja je prikazana

programskim kodom 41

Programski kod 41 PrimjerViseKameracs

13

Slika 42 Perspektivna projekcija blend modela

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kameraPrvogLica

public Camera kameraIznadGlave

funkcija koja se poziva kada se prebacujemo u pogled iznad

glave

public void prikaziPogledIznadGlave()

kameraPrvogLicaenabled = false gasimo kameru prvog

lica

kameraIznadGlaveenabled = true palimo kameru iznad

glave

funkcija koja se poziva kada se prebacujemo u pogled iz

prvog lica

public void prikaziPogledIzPrvogLica()

kameraPrvogLicaenabled = true palimo kameru prvog

lica

overheadCameraenabled = false gasimo kameru iznad

glave

14

43 Fiksirana kamera

U sceni projekta vec postoji glavna kamera (engl Main Camera) koju Unity automat-

ski dodaje u scenu Kako bi ta kamera pratila lika može se samo povuci u lijevom

prozoru hijerarhije u hijerarhiju lika kako bi postala njegovo dijete Tako ce se postici

da kamera stalno prati njegove transformacije (translaciju rotaciju) prilikom pokreta-

nja igre No kako bi se postiglo da kamera ostane uvijek fiksirana te se samo krece s

njime umjesto da se kamera rotira skupa s likom dodaje se novi prazni objekt sa Game

Object -gt kreiraj prazan (engl Create Empty) Njegova pozicija se postavlja na x =

0 y = 0 z = 0 ako vec nije tamo te se postavlja taj prazan objekt kao roditelj glavne

kamere Sada kamera ostaje fiksirana na mjestu te se nece ni kretati s likom Kako bi

se krenula kretati mora se dodati nova skripta na taj prazan objekt koji se odsad u pro-

jektu zove Kamera s obzirom na to da zaista i je roditelj glavne kamere Kako bi se u

skripti lakše locirao objekt igraca oznacava ga se u njegovom polju oznaka (engl Tag)

u desnom prozoru Inspector s igrac (engl Player) kao što se može vidjeti na slici 43

zaokruženo plavom bojom

U programskom kodu se želi napraviti varijabla tipa Game Object kako bi se spremilo

igraca kada ga se pronade Unity takoder ima funkciju FindGameObjectWithTag pa

je onda ostatak koda prilicno intuitivan Kada se igrac pronade pomocu njegove oz-

nake Player prilikom svakog osvježavanja poziciji našeg igraca pridružuje se pozicija

kamere kao što je prikazano programskim kodom 42

Programski kod 42 pratiLikacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class pratiLika MonoBehaviour

GameObject igrac

void Start ()

trazi se objekt putem njegove oznake

igrac = GameObjectFindGameObjectWithTag(Player)

15

Slika 43 Oznacavanje lika radi lakšeg pronalaska u skripti

void LateUpdate ()

trenutni objekt mijenja svoju poziciju u skladu s

pozicijom objekta oznacenog oznakom Player

transformposition = igractransformposition

44 Bacanje zraka (engl Ray casting)

Perspektivna kamera u Unityu koristi oblik krnje piramide za dio koji prikazuje u pros-

toru Svaka tocka nekog objekta kojeg kamera prikazuje zapravo odgovara liniji u pros-

toru svijeta te je nama samo jedna tocka duž te linije vidljiva na objektu Sve iza te

tocke na liniji je zamraceno Vanjski rubovi objekta su definirani razilazecim linijama

16

koje odgovaraju kutevima objekta Kada bi se te linije pratile unazad prema kameri

sve bi na kraju konvergirale u jednu tocku U Unityu se ta tocka nalazi tocno na pozi-

ciji kamere i naziva se centrom perspektive Kut naspram linija koje konvergiraju od

gornjeg i donjeg centra ekrana u centru perspektive se zove vidno polje (engl Field Of

View) Sve što pada izvan tih razilazecih linija na rubovima objekta nece biti vidljivo

kameri uz vec prethodno spomenuta ogranicenja ravnina podrezivanja

U igrama je jako korisno imati matematicku reprezentaciju linije koja predstavlja tocku

u pogledu kamere Unity to omogucava u obliku objekta zrake Zraka uvijek odgo-

vara tocki u pogledu pa klasa Kamera (engl Camera) sadrži dvije korisne funkcije

ScreenPointToRay i ViewportPointToRay Razlika izmedu njih je da ScreenPointToRay

ocekuje tocku s koordinatama piksela dok ViewportPointToRay uzima normalizirane

koordinate (od 0 dolje ili lijevo do 1 gore ili desno) Obje funkcije vracaju zraku

koja se sastoji od tocke ishodišta i vektora koji pokazuje smjer linije od tog ishodišta

Zraka izlazi iz ravnine podrezivanja bliže kameri Najcešce se zrake koriste kako bi ih

bacali u scenu Bacanje zraka pošalje imaginarnu liniju uz zraku od njenog ishodišta

dok ne udari u neki sudarac u sceni Tada vraca informaciju o tocki koju je udarila

u objektu RaycastHit To je vrlo korisno kako bi se locirao objekt ovisno o njegovoj

poziciji na zaslonu npr lociranje kursora prikazano programskim kodom 43

Programski kod 43 lociranjeKursoracs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kamera

void Start()

RaycastHit udar

u objekt Ray se sprema pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

ako zraka udara u neki objekt spremi u objektUdaren to

mjesto

if (PhysicsRaycast(zraka out udar))

Transform objektUdaren = udartransform

17

Ponekad je takoder korisno dobiti zraku koja odgovara poziciji na zaslonu te onda

pomicati kameru uz tu zraku Npr želi se dozvoliti igracu da može selektirati objekt

mišem i onda ga povecati dok se objekt nalazi cijelo vrijeme na istoj poziciji na zaslonu

ispod miša prikazano programskim kodom 44 [1]

Programski kod 44 povecavanjeSlikecs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public bool povecavanje

public float brzinaPovecavanja

public Camera kamera

void Update()

ako netko koristi povecavanje slike (engl Zooming)

if (povecavanje)

u objekt Ray sprema se pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(Input

mousePosition)

udaljenost povecavanja ce biti jednaka umnosku

brzine povecavanja vremena i vertikalnog smjera

float udaljenostPovecavanja = brzinaPovecavanja

InputGetAxis(Vertical) TimedeltaTime

pomakni kameru u smjeru kursora misa za udaljenost

povecavanja u koordinatnom sustavu svijeta

kameratransformTranslate(zrakadirection

udaljenostPovecavanja SpaceWorld)

18

5 Kretanje

Pronalazak puta je zapravo pokušaj aplikacije na racunalu ili algoritma da nade naj-

kracu rutu izmedu dvije tocke To je recimo prakticna verzija rješavanja labirinta Ni

danas ne postoji optimalan algoritam koji ce u svakom slucaju u nekom realno krat-

kom vremenu naci najkraci put U ovom poglavlju objasnit ce se koje algoritme Unity

koristi za svoj navigacijski sustav Objašnjavat ce se i neki osnovni koncepti i obrasci

potrebni za ubrzavanje cijele ideje dojavljivanja promjena u sceni Bit ce prikazani i

programski kodovi potrebni za implementiranje kretanja mišem iili tipkovnicom Na

kraju ovog poglavlja želi se imati lika koji ce se slobodno kretati po sceni na mjesto

koje se odredi klikom miša i mogucnost prebacivanja na upravljanje tipkovnicom

51 Navigacijski sustav u Unityu

U Unityu je problem pronalaska puta vec riješen s necim što se zove navigacijska

mreža (engl NavMesh) To je navigacijski sustav koji ima svoje algoritme pronala-

ska puta i puno pojednostavljuje programiranje kretanja lika Sastoji se od cetiri di-

jela NavMesh agent navigacijske mreže (engl NavMesh Agent) izvanmrežna pove-

zanost(engl Off - Mesh Link) i prepreka navigacijske mreže(engl NavMesh Obstacle)

NavMesh je podatkovna struktura koja opisuje površine po kojima se može kretati

u igri i omogucava pronalazak put od jedne lokacije do druge Navigacijski sustav

treba svoje podatke kako bi predstavio prohodna podrucja u sceni Prohodna podru-

cja definiraju se kao mjesta gdje agent može stajati i kretati se Prohodno podrucje se

automatski izgraduje iz geometrije u sceni testirajuci sva podrucja gdje bi agent mo-

gao stajati Onda se te lokacije spajaju s površinom na vrhu geometrije Ta površina se

naziva onda NavMesh te je možemo vidjeti na 51 NavMesh tada sprema tu površinu

kao konveksne poligone te informacije koji su poligoni susjedni Komponenta Nav-

Mesh Agent pomaže pri kreiranju likova koji se medusobno izbjegavaju dok se krecu

prema cilju U Unityu se agenti opisuju kao valjci Koriste NavMesh kako bi se kretali

i znali koje objekte moraju zaobici te kako da se medusobno zaobidu Off-Mesh Link

19

omogucava dodavanje navigacijskih precaca koji se ne mogu predstaviti kao površina

po kojoj se može hodati npr skakanje preko ograde ili otvaranje vrata prije nego što

se ude u neku prostoriju NavMesh Obstacle opisuje prepreke koje se krecu te koje bi

agenti trebali izbjegavati dok hodaju svijetom npr neke bacve koje se kotrljaju prema

igracu Dok se bacva krece agent ce izracunati put oko nje najbolje što može no nakon

što ona naposljetku stane postat ce dio neprohodnog NavMesha te ce se agenti kretati

oko nje [3]

Slika 51 Prikaz navigacijskog sustava u Unityu

52 Pronalazak puta

Dva glavna problema postoje kod pronalaženja puta kako pronaci destinaciju na ni-

vou na kojem se igrac nalazi te kako se onda tamo pomaknuti Pronalaženje destinacije

uzima u obzir cijelu scenu Pomicanje tamo je dinamicnije u obzir uzima samo smjer

kretanja i kako da sprijeci sudaranje s drugim agentima Da bi se pronašao put izmedu

dvije lokacije prvo se moraju oznaciti pocetna i konacna lokacija njihovim najbližim

poligonima Tada se krece tražiti od pocetne lokacije posjecujuci sve susjedne dok se

ne dode do zadane destinacije Onda se prati unatrag vec posjecene poligone kako bi

se našao konacan niz poligona koji vode od pocetka do kraja Algoritam koji Unity

koristi te se cesto koristi za pronalazak puta naziva se A (A zvjezdica) Taj niz po-

ligona koji opisuje put od pocetka do kraja se naziva hodnik Agent ce doci do svoje

20

destinacije tako da se uvijek usmjerava prema sljedecem vidljivom kutu hodnika Ta

logika usmjeravanja uvijek uzima poziciju sljedeceg kuta i ovisno o tome nade željeni

smjer i brzinu potrebnu za dolazak na destinaciju Korištenje brzine po želji progra-

mera bi moglo dovesti do sudara s ostalim agentima Izbjegavanje prepreka takoder

pronalazi svoju novu brzinu koja traži ravnotežu izmedu kretanja prema destinaciji i

sprjecavanja buducih sudara s ostalim agentima i kutevima u navigacijskom sustavu

Nakon usmjeravanja i izbjegavanja prepreka izracuna se konacna brzina Unity ta-

koder uzima u obzir i akceleraciju kako bi simulirao realisticnije kretanje Takoder

treba razumjeti razliku izmedu globalne i lokalne navigacije Globalna navigacija se

koristi za pronalazak hodnika u svijetu Linearna lista poligona koja opisuje taj put je

podatkovna struktura koja se koristi za usmjeravanje te se može lokalno prilagodavati

i mijenjati kako se pozicija agenta mijenja Lokalna navigacija pokušava naci efika-

san nacin kako da se igrac pomakne prema sljedecem kutu bez da se sudari s ostalim

agentima ili objektima koji se krecu [3]

53 Kreiranje navigacijskog sustava

Proces kreiranja NavMesha iz geometrije nivoa se naziva pecenje navigacijske mreže

(engl NavMesh Baking) Skuplja sve terene i mreže objekata koji su oznaceni kao

navigacijski staticko (engl Navigation Static) i onda ih procesira kako bi kreirao navi-

gacijski sustav koji aproksimira prohodne površine nivoa Izgradnja (engl NavMesha)

je vrlo jednostavna Prvo se selektira geometrija koja bi trebala utjecati na navigaciju

tj površine po kojima možemo hodati i prepreke Oznaci se Navigation Static da bi ih

ukljucili u NavMesh Baking proces Prilagode se postavke kako bi odgovarale velicini

agenta - radijus (npr koliko blizu se može doci zidovima) visina (koliko su nisko

prostori koje agent može doseci) maksimalni nagib (koliko su kose rampe po kojima

se agent može uspeti) visina stube(koliko su visoke prepreke na koje agent može za-

koraciti) Onda jednostavno stisnemo ispeci (engl Bake) da izgradimo svoj NavMesh

Izgradeni NavMesh cemo moci vidjeti kao plavu površinu kao na slici 51 te ce se stvo-

riti nova datoteka s nazivom trenutne scene (ako vec ne postoji) i unutra ce se spremiti

kreiran navigacijski sustav [3]

21

54 Programiranje kretanja

Na liku se trenutno nalazi par stvari Animator Capsule Collider i Rigid Body Sada

je cilj isprogramirati mogucnost odredivanja gdje ce se lik kretati klikom miša na to

mjesto Dodaje se nova komponenta na lika NavMesh Agent Ta komponenta za-

pravo vec ima svoj sudarac te se slobodno može obrisati Capsule Collider jer postaje

nepotreban Igranjem s opcijama pomak od baze (engl Base Offset) te pod izbjegava-

nje prepreka (engl Obstacle Avoidance) radijus (engl Radius) i visina (engl Height)

prilagodi se sudarac od (engl NavMesh Agent-a) kako bi se obujmilo njime igraca i

sprijecilo propadanje kroz tlo od prije Sada kada postoji komponenta navigacije mora

se dodati skripta koja ce odrediti kada se lik krece te kada se pokrecu njegove anima-

cije iz Animator-a

Da bi se znalo gdje se miš nalazi mora se takoder dodati nova skriptu na kameru Kako

bi se izracunalo gdje trenutno kursor pokazuje Unity koristi vec prethodno spomenuto

bacanje zraka Da bi se moglo koristiti navigaciju putem klika mišem mora se napisati

skripta za glavnu kameru koja ce omoguciti bacanje zraka Skripta BacanjeZraka

dodaje se na objekt Main Camera koja se dodala pod prazni objekt Kamera Ova

skriptu se takoder koristi za razlikovanje raznih vrsta objekata Naime svaki objekt

kao što ima i Tag ima i sloj (engl Layer) Sloj služi kako bi mogli npr razlikovati

neprijatelje od obicnih objekata ili mjesto na koje želimo doci hodanjem Zato cemo

takoder dodati i jednu enumeraciju koja ce nam zasad služiti samo da razlikujemo je li

mjesto prohodno ili ne te jesmo li kliknuli na neprijatelja Kako bi dodali svoje nove

slojeve za objekte moramo kliknuti na Layer i dodaj sloj (engl Add Layer) kao na slici

52 što nas dovodi do novog prozora prikazanog na slici 53

Programski kod 51 bacanjeZrakacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

sluzi za dodavanje novih slojeva u Unity

public enum Sloj

Prohodno = 8

Neprijatelj = 9

KrajSvijeta = -1

22

Slika 52 Dodavanje novog sloja

public class BacanjeZraka MonoBehaviour

hijerarhija slojeva tj koji ima veci prioritet

public Sloj[] prioritetiSlojeva =

SlojNeprijatelj

SlojProhodno

SlojKrajSvijeta

udaljenost do pozadine je neka izmisljena vrijednost nakon

koje se prestane provjeravati zraka

public float udaljenostDoPozadine = 100f

Camera kamera

RaycastHit _udara

dohvaca varijable ove klase

public RaycastHit udara

get return _udara

Sloj _udaraSloj

23

Slika 53 Prozor za dodavanje novog sloja

public Sloj udaraSloj

get return _udaraSloj

deklariraj novi tip delegata

public delegate void priPromjeniSloja(Sloj noviSloj)

instanciraj skup promatraca

public event priPromjeniSloja promatraciPromjeneSloja

void Start ()

dohvat glavne kamere

kamera = Cameramain

void Update ()

nadi sloj po prioritetu u koji zraka udara

foreach(Sloj sloj in prioritetiSlojeva)

provjeravamo udara li zraka u neki od slojeva

24

var udar = BacanjeZrakaZaSloj(sloj)

if(udarHasValue)

_udara = udarValue

ako se sloj promjenio

if(_udaraSloj = sloj)

spremi novi sloj u varijablu trenutnog sloja

_udaraSloj = sloj

obavijesti promatrace da se sloj promjenio

promatraciPromjeneSloja(sloj)

spremi novi sloj u varijablu trenutnog sloja

ali ne moras obavjestavati promatrace jer je

sloj jednak starom sloju

_udaraSloj = sloj

return

inace vrati da zraka udara u pozadinu i obavijesti

promatrace

_udaradistance = udaljenostDoPozadine

_udaraSloj = SlojKrajSvijeta

promatraciPromjeneSloja(udaraSloj)

RaycastHit BacanjeZrakaZaSloj(Sloj sloj)

kreira se maska za slojeve bit se pomice ulijevo za

onoliko mjesta koliki je redni broj prioriteta sloja

int maska = 1 ltlt (int)sloj

sprema se mjesto pozicije kursora pretvoreno iz tocke u

zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

RaycastHit udar

PhysicsRaycast sprema zraku u varijablu tipa

RaycastHit prima jos i maksimalnu udaljenost za koju

provjerava zraku i masku sloja i potom vraca istinu (

engl True) ili laz (engl False) ako je zraka udarila

u sloj

25

bool udarioJe = PhysicsRaycast(zraka out udar

udaljenostDoPozadine maska)

ako zraka udara u sloj vrati vrijednost udarca

if(udarioJe)

return udar

return null

U programskom kodu 51 se koristi funkcija za primjenu obrasca promatraca pod

nazivom delegat (engl Delegate) Što je obrazac promatraca (engl Observer) To je

oblikovni obrazac koji se u programiranju koristi

bull kad promjena jednog objekta zahtijeva promjene u drugim objektima koji nisu

unaprijed poznati

bull kad objekt treba obavještavati druge objekte

bull uz uvjet da bude što neovisniji o njima

bull kad je potrebno prikazivati razlicite aspekte nekog dinamickog stanja a želimo

izbjeci ciklicku ovisnost izmedu stanja i pogleda

bull kad postoje dva koncepta jedan ovisan o drugome a zgodno ih je razdvojiti

S obzirom na to da mi samo pri promjeni sloja želimo obavještavati pretplacene pro-

matrace uvodenje delegata nam dosta ubrzava kod Obrazac promatraca funkcionira

tako da glavni objekt igra ulogu izdavaca (izvora informacija) u ovom slucaju to je

glavna kamera Ostali ovisni objekti (promatraci) pretplacuju se kod izdavaca te iz-

davaci obavještavaju pretplatnike o promjenama Promatraci prekidaju pretplatu kad

više ne trebaju obavještavanje Funkcija priPromjeniSloja se definira kao delegat i u

ovom slucaju prima sloj Nakon toga se definira dogadaj (engl Event) tipa tog delegata

(priPromjeniSloja) u ovom slucaju naziva promatraciPromjeneSloja i odsad se unutar

subjekta tim nazivom i poziva Kako bi se neki promatrac pretplatio na informacije

koje izdaje kamera dodaje ove dvije linije koda u svoju skriptu

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

Programski kod 52 služi za kretanje korištenjem NavMesha i lijevog klika miša

26

Programski kod 52 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

public float dovoljnoBlizu = 01f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora

[SerializeField] float hodajKreciStaniRadijus = 02f

void Start ()

pronadi igraca koji je tipa agenta navigacijskog sustava

(engl NavMeshAgent)

agent = GetComponentltUnityEngineAINavMeshAgentgt()

pronadi prethodno napisanu klasu BacanjeZraka

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

spremi trenutnu poziciju kursora

trenutnaPozicijaKursora = transformposition

void Update()

ako je igrac dosao na zeljeno mjesto zaustavi animaciju

hodanja

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

ako je stisnut lijevi klik misa

if (InputGetMouseButtonDown(0))

ovisno o sloju primjeni akciju

switch(bacanjeZrakaudaraSloj)

ako se po objektu na koji je igrac kliknuo moze

hodati

27

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 16: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

Slika 34 Traženje tekstura Vašeg blend modela

Slika 35 Animator

Transition) To je sada kreiralo usmjerenu strelicu koja se može povuci prema Ho-

danje Isto to se napravi i u suprotnom smjeru Desni klik miša na Hodanje Add

Transition i povuce se strelica prema Mirovanje Naravno moraju se dodati uvjeti

koji ce odredivati kada ce objekt prijeci iz jednog stanja u drugo U ovom slucaju je

korišten cijeli broj (engl Integer) Ostatak problema kretanja rješavat ce se u poglavlju

4 Bacanje zraka i kretanje po mapi s mišem

11

4 Kamera

U ovom poglavlju se postavlja i bira prava kamera za igru Tijekom izrade igre treba se

takoder razmišljati i iz kojeg kuta ce se imati pogled na nju te hoce li se kamera pomi-

cati s kretanjem lika hoce li se moci rotirati itd Pri kreiranju 3D igre u pogledu scene

primjecuje se da su svi objekti i transformacije u 3D-prostoru No s obzirom na to da je

zaslon monitora igraca 2-dimenzionalan te se ne može prikazati tijela kao takva mora

se moci prikazati sve te objekte u jednoj ravnini i zadržati dojam 3-dimenzionalnosti

To se u Unityu postiže s kamerom Kamera je objekt koja definira pogled i njegov

smjer u prostoru scene Pozicija kamere definira ocište z os definira smjer gledanja

(gledište) te y os definira vrh ekrana Kamera takoder definira velicinu i oblik dijela

koji možemo vidjeti Kamera nam pokazuje ono što ona vidi Kako se ona rotira

translatira itd prikaz scene ce se takoder jednako transformirati Nakon kraja ovog

poglavlja želi se imati kamera koja ce pratiti kretnje lika i imati pogled na njega odoz-

gora

41 Perspektivna i ortografska kamera

Kamerom se zapravo objekte 3D prostora projicira na ravninu u 2D prostor Projek-

cije su matematicki modeli koji govore na koji nacin treba tocke 3D prostora preslikati

u ravninu u tocke 2D prostora Postoji više vrsta projekcija no Unity koristi dvije or-

tografsku projekciju i perspektivnu projekciju Kod ortografskih projekcija kamera je

okomita na ravninu projekcije dok je perspektivna projekcija bliža našem nacinu gle-

danja objekata Možda je najlakše primijetiti razliku koristeci slike Dakle na slici 41

možemo vidjeti blend model koji je modeliran u Blenderu u ortografskoj projekciji te

na slici 42 isti taj model pod istim kutem samo prebacen u perspektivnu projekciju

[6]

Perspektivna projekcija uvodi dvije tocke ocište i gledište Ocište je tocka u ko-

joj se nalazi promatrac Gledište odreduje smjer prema kojem promatrac gleda U

12

Slika 41 Ortografska projekcija blend modela

tocki gledišta stvara se ravnina projekcije koja je okomita na spojnicu ocište-gledište

[6] I perspektivna i ortografska kamera imaju granicu do koje mogu vidjeti od svoje

trenutne pozicije Ona je definirana upravo tom ravninom projekcije Tocka gledišta

pripada toj ravnini i ona tipicno postaje ishodište lokalnog dvodimenzijskog koordi-

natnog sustava koji razapinjemo u ravnini projekcije Ta ravnina se još naziva i daleka

ravnina podrezivanja zato što svi objekti koji se nalaze na vecoj udaljenosti od nje se

odrežu te ih kamera ne prikazuje Takoder postoji i ravnina podrezivanja blizu ka-

meri [1] Dio koji se prikazuje se nalazi izmedu te dvije ravnine

42 Pogled iz prvog lica u pogled iznad glave

U igrama se cesto koristi prebacivanje iz jednog u drugi pogled kamere Kako se

to postiže Koristeci veci broj kamera U ovom slucaju obradit ce se samo kratki

primjer kako se prebacivati iz pogleda prvog lica u pogled iznad glave U unity-u je

zadano da jedna kamera pokriva cijeli ekran te se zato samo pogled jedne kamere može

vidjeti u jednom trenutku Kamera koju vidimo je ona koja ima najvecu vrijednost

za svoje svojstvo dubine[1] Zato se želi napraviti skripta koja ce se prebacivati s

jedne kamere na drugu da bi se dobili drukciji pogledi na scenu koja je prikazana

programskim kodom 41

Programski kod 41 PrimjerViseKameracs

13

Slika 42 Perspektivna projekcija blend modela

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kameraPrvogLica

public Camera kameraIznadGlave

funkcija koja se poziva kada se prebacujemo u pogled iznad

glave

public void prikaziPogledIznadGlave()

kameraPrvogLicaenabled = false gasimo kameru prvog

lica

kameraIznadGlaveenabled = true palimo kameru iznad

glave

funkcija koja se poziva kada se prebacujemo u pogled iz

prvog lica

public void prikaziPogledIzPrvogLica()

kameraPrvogLicaenabled = true palimo kameru prvog

lica

overheadCameraenabled = false gasimo kameru iznad

glave

14

43 Fiksirana kamera

U sceni projekta vec postoji glavna kamera (engl Main Camera) koju Unity automat-

ski dodaje u scenu Kako bi ta kamera pratila lika može se samo povuci u lijevom

prozoru hijerarhije u hijerarhiju lika kako bi postala njegovo dijete Tako ce se postici

da kamera stalno prati njegove transformacije (translaciju rotaciju) prilikom pokreta-

nja igre No kako bi se postiglo da kamera ostane uvijek fiksirana te se samo krece s

njime umjesto da se kamera rotira skupa s likom dodaje se novi prazni objekt sa Game

Object -gt kreiraj prazan (engl Create Empty) Njegova pozicija se postavlja na x =

0 y = 0 z = 0 ako vec nije tamo te se postavlja taj prazan objekt kao roditelj glavne

kamere Sada kamera ostaje fiksirana na mjestu te se nece ni kretati s likom Kako bi

se krenula kretati mora se dodati nova skripta na taj prazan objekt koji se odsad u pro-

jektu zove Kamera s obzirom na to da zaista i je roditelj glavne kamere Kako bi se u

skripti lakše locirao objekt igraca oznacava ga se u njegovom polju oznaka (engl Tag)

u desnom prozoru Inspector s igrac (engl Player) kao što se može vidjeti na slici 43

zaokruženo plavom bojom

U programskom kodu se želi napraviti varijabla tipa Game Object kako bi se spremilo

igraca kada ga se pronade Unity takoder ima funkciju FindGameObjectWithTag pa

je onda ostatak koda prilicno intuitivan Kada se igrac pronade pomocu njegove oz-

nake Player prilikom svakog osvježavanja poziciji našeg igraca pridružuje se pozicija

kamere kao što je prikazano programskim kodom 42

Programski kod 42 pratiLikacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class pratiLika MonoBehaviour

GameObject igrac

void Start ()

trazi se objekt putem njegove oznake

igrac = GameObjectFindGameObjectWithTag(Player)

15

Slika 43 Oznacavanje lika radi lakšeg pronalaska u skripti

void LateUpdate ()

trenutni objekt mijenja svoju poziciju u skladu s

pozicijom objekta oznacenog oznakom Player

transformposition = igractransformposition

44 Bacanje zraka (engl Ray casting)

Perspektivna kamera u Unityu koristi oblik krnje piramide za dio koji prikazuje u pros-

toru Svaka tocka nekog objekta kojeg kamera prikazuje zapravo odgovara liniji u pros-

toru svijeta te je nama samo jedna tocka duž te linije vidljiva na objektu Sve iza te

tocke na liniji je zamraceno Vanjski rubovi objekta su definirani razilazecim linijama

16

koje odgovaraju kutevima objekta Kada bi se te linije pratile unazad prema kameri

sve bi na kraju konvergirale u jednu tocku U Unityu se ta tocka nalazi tocno na pozi-

ciji kamere i naziva se centrom perspektive Kut naspram linija koje konvergiraju od

gornjeg i donjeg centra ekrana u centru perspektive se zove vidno polje (engl Field Of

View) Sve što pada izvan tih razilazecih linija na rubovima objekta nece biti vidljivo

kameri uz vec prethodno spomenuta ogranicenja ravnina podrezivanja

U igrama je jako korisno imati matematicku reprezentaciju linije koja predstavlja tocku

u pogledu kamere Unity to omogucava u obliku objekta zrake Zraka uvijek odgo-

vara tocki u pogledu pa klasa Kamera (engl Camera) sadrži dvije korisne funkcije

ScreenPointToRay i ViewportPointToRay Razlika izmedu njih je da ScreenPointToRay

ocekuje tocku s koordinatama piksela dok ViewportPointToRay uzima normalizirane

koordinate (od 0 dolje ili lijevo do 1 gore ili desno) Obje funkcije vracaju zraku

koja se sastoji od tocke ishodišta i vektora koji pokazuje smjer linije od tog ishodišta

Zraka izlazi iz ravnine podrezivanja bliže kameri Najcešce se zrake koriste kako bi ih

bacali u scenu Bacanje zraka pošalje imaginarnu liniju uz zraku od njenog ishodišta

dok ne udari u neki sudarac u sceni Tada vraca informaciju o tocki koju je udarila

u objektu RaycastHit To je vrlo korisno kako bi se locirao objekt ovisno o njegovoj

poziciji na zaslonu npr lociranje kursora prikazano programskim kodom 43

Programski kod 43 lociranjeKursoracs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kamera

void Start()

RaycastHit udar

u objekt Ray se sprema pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

ako zraka udara u neki objekt spremi u objektUdaren to

mjesto

if (PhysicsRaycast(zraka out udar))

Transform objektUdaren = udartransform

17

Ponekad je takoder korisno dobiti zraku koja odgovara poziciji na zaslonu te onda

pomicati kameru uz tu zraku Npr želi se dozvoliti igracu da može selektirati objekt

mišem i onda ga povecati dok se objekt nalazi cijelo vrijeme na istoj poziciji na zaslonu

ispod miša prikazano programskim kodom 44 [1]

Programski kod 44 povecavanjeSlikecs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public bool povecavanje

public float brzinaPovecavanja

public Camera kamera

void Update()

ako netko koristi povecavanje slike (engl Zooming)

if (povecavanje)

u objekt Ray sprema se pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(Input

mousePosition)

udaljenost povecavanja ce biti jednaka umnosku

brzine povecavanja vremena i vertikalnog smjera

float udaljenostPovecavanja = brzinaPovecavanja

InputGetAxis(Vertical) TimedeltaTime

pomakni kameru u smjeru kursora misa za udaljenost

povecavanja u koordinatnom sustavu svijeta

kameratransformTranslate(zrakadirection

udaljenostPovecavanja SpaceWorld)

18

5 Kretanje

Pronalazak puta je zapravo pokušaj aplikacije na racunalu ili algoritma da nade naj-

kracu rutu izmedu dvije tocke To je recimo prakticna verzija rješavanja labirinta Ni

danas ne postoji optimalan algoritam koji ce u svakom slucaju u nekom realno krat-

kom vremenu naci najkraci put U ovom poglavlju objasnit ce se koje algoritme Unity

koristi za svoj navigacijski sustav Objašnjavat ce se i neki osnovni koncepti i obrasci

potrebni za ubrzavanje cijele ideje dojavljivanja promjena u sceni Bit ce prikazani i

programski kodovi potrebni za implementiranje kretanja mišem iili tipkovnicom Na

kraju ovog poglavlja želi se imati lika koji ce se slobodno kretati po sceni na mjesto

koje se odredi klikom miša i mogucnost prebacivanja na upravljanje tipkovnicom

51 Navigacijski sustav u Unityu

U Unityu je problem pronalaska puta vec riješen s necim što se zove navigacijska

mreža (engl NavMesh) To je navigacijski sustav koji ima svoje algoritme pronala-

ska puta i puno pojednostavljuje programiranje kretanja lika Sastoji se od cetiri di-

jela NavMesh agent navigacijske mreže (engl NavMesh Agent) izvanmrežna pove-

zanost(engl Off - Mesh Link) i prepreka navigacijske mreže(engl NavMesh Obstacle)

NavMesh je podatkovna struktura koja opisuje površine po kojima se može kretati

u igri i omogucava pronalazak put od jedne lokacije do druge Navigacijski sustav

treba svoje podatke kako bi predstavio prohodna podrucja u sceni Prohodna podru-

cja definiraju se kao mjesta gdje agent može stajati i kretati se Prohodno podrucje se

automatski izgraduje iz geometrije u sceni testirajuci sva podrucja gdje bi agent mo-

gao stajati Onda se te lokacije spajaju s površinom na vrhu geometrije Ta površina se

naziva onda NavMesh te je možemo vidjeti na 51 NavMesh tada sprema tu površinu

kao konveksne poligone te informacije koji su poligoni susjedni Komponenta Nav-

Mesh Agent pomaže pri kreiranju likova koji se medusobno izbjegavaju dok se krecu

prema cilju U Unityu se agenti opisuju kao valjci Koriste NavMesh kako bi se kretali

i znali koje objekte moraju zaobici te kako da se medusobno zaobidu Off-Mesh Link

19

omogucava dodavanje navigacijskih precaca koji se ne mogu predstaviti kao površina

po kojoj se može hodati npr skakanje preko ograde ili otvaranje vrata prije nego što

se ude u neku prostoriju NavMesh Obstacle opisuje prepreke koje se krecu te koje bi

agenti trebali izbjegavati dok hodaju svijetom npr neke bacve koje se kotrljaju prema

igracu Dok se bacva krece agent ce izracunati put oko nje najbolje što može no nakon

što ona naposljetku stane postat ce dio neprohodnog NavMesha te ce se agenti kretati

oko nje [3]

Slika 51 Prikaz navigacijskog sustava u Unityu

52 Pronalazak puta

Dva glavna problema postoje kod pronalaženja puta kako pronaci destinaciju na ni-

vou na kojem se igrac nalazi te kako se onda tamo pomaknuti Pronalaženje destinacije

uzima u obzir cijelu scenu Pomicanje tamo je dinamicnije u obzir uzima samo smjer

kretanja i kako da sprijeci sudaranje s drugim agentima Da bi se pronašao put izmedu

dvije lokacije prvo se moraju oznaciti pocetna i konacna lokacija njihovim najbližim

poligonima Tada se krece tražiti od pocetne lokacije posjecujuci sve susjedne dok se

ne dode do zadane destinacije Onda se prati unatrag vec posjecene poligone kako bi

se našao konacan niz poligona koji vode od pocetka do kraja Algoritam koji Unity

koristi te se cesto koristi za pronalazak puta naziva se A (A zvjezdica) Taj niz po-

ligona koji opisuje put od pocetka do kraja se naziva hodnik Agent ce doci do svoje

20

destinacije tako da se uvijek usmjerava prema sljedecem vidljivom kutu hodnika Ta

logika usmjeravanja uvijek uzima poziciju sljedeceg kuta i ovisno o tome nade željeni

smjer i brzinu potrebnu za dolazak na destinaciju Korištenje brzine po želji progra-

mera bi moglo dovesti do sudara s ostalim agentima Izbjegavanje prepreka takoder

pronalazi svoju novu brzinu koja traži ravnotežu izmedu kretanja prema destinaciji i

sprjecavanja buducih sudara s ostalim agentima i kutevima u navigacijskom sustavu

Nakon usmjeravanja i izbjegavanja prepreka izracuna se konacna brzina Unity ta-

koder uzima u obzir i akceleraciju kako bi simulirao realisticnije kretanje Takoder

treba razumjeti razliku izmedu globalne i lokalne navigacije Globalna navigacija se

koristi za pronalazak hodnika u svijetu Linearna lista poligona koja opisuje taj put je

podatkovna struktura koja se koristi za usmjeravanje te se može lokalno prilagodavati

i mijenjati kako se pozicija agenta mijenja Lokalna navigacija pokušava naci efika-

san nacin kako da se igrac pomakne prema sljedecem kutu bez da se sudari s ostalim

agentima ili objektima koji se krecu [3]

53 Kreiranje navigacijskog sustava

Proces kreiranja NavMesha iz geometrije nivoa se naziva pecenje navigacijske mreže

(engl NavMesh Baking) Skuplja sve terene i mreže objekata koji su oznaceni kao

navigacijski staticko (engl Navigation Static) i onda ih procesira kako bi kreirao navi-

gacijski sustav koji aproksimira prohodne površine nivoa Izgradnja (engl NavMesha)

je vrlo jednostavna Prvo se selektira geometrija koja bi trebala utjecati na navigaciju

tj površine po kojima možemo hodati i prepreke Oznaci se Navigation Static da bi ih

ukljucili u NavMesh Baking proces Prilagode se postavke kako bi odgovarale velicini

agenta - radijus (npr koliko blizu se može doci zidovima) visina (koliko su nisko

prostori koje agent može doseci) maksimalni nagib (koliko su kose rampe po kojima

se agent može uspeti) visina stube(koliko su visoke prepreke na koje agent može za-

koraciti) Onda jednostavno stisnemo ispeci (engl Bake) da izgradimo svoj NavMesh

Izgradeni NavMesh cemo moci vidjeti kao plavu površinu kao na slici 51 te ce se stvo-

riti nova datoteka s nazivom trenutne scene (ako vec ne postoji) i unutra ce se spremiti

kreiran navigacijski sustav [3]

21

54 Programiranje kretanja

Na liku se trenutno nalazi par stvari Animator Capsule Collider i Rigid Body Sada

je cilj isprogramirati mogucnost odredivanja gdje ce se lik kretati klikom miša na to

mjesto Dodaje se nova komponenta na lika NavMesh Agent Ta komponenta za-

pravo vec ima svoj sudarac te se slobodno može obrisati Capsule Collider jer postaje

nepotreban Igranjem s opcijama pomak od baze (engl Base Offset) te pod izbjegava-

nje prepreka (engl Obstacle Avoidance) radijus (engl Radius) i visina (engl Height)

prilagodi se sudarac od (engl NavMesh Agent-a) kako bi se obujmilo njime igraca i

sprijecilo propadanje kroz tlo od prije Sada kada postoji komponenta navigacije mora

se dodati skripta koja ce odrediti kada se lik krece te kada se pokrecu njegove anima-

cije iz Animator-a

Da bi se znalo gdje se miš nalazi mora se takoder dodati nova skriptu na kameru Kako

bi se izracunalo gdje trenutno kursor pokazuje Unity koristi vec prethodno spomenuto

bacanje zraka Da bi se moglo koristiti navigaciju putem klika mišem mora se napisati

skripta za glavnu kameru koja ce omoguciti bacanje zraka Skripta BacanjeZraka

dodaje se na objekt Main Camera koja se dodala pod prazni objekt Kamera Ova

skriptu se takoder koristi za razlikovanje raznih vrsta objekata Naime svaki objekt

kao što ima i Tag ima i sloj (engl Layer) Sloj služi kako bi mogli npr razlikovati

neprijatelje od obicnih objekata ili mjesto na koje želimo doci hodanjem Zato cemo

takoder dodati i jednu enumeraciju koja ce nam zasad služiti samo da razlikujemo je li

mjesto prohodno ili ne te jesmo li kliknuli na neprijatelja Kako bi dodali svoje nove

slojeve za objekte moramo kliknuti na Layer i dodaj sloj (engl Add Layer) kao na slici

52 što nas dovodi do novog prozora prikazanog na slici 53

Programski kod 51 bacanjeZrakacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

sluzi za dodavanje novih slojeva u Unity

public enum Sloj

Prohodno = 8

Neprijatelj = 9

KrajSvijeta = -1

22

Slika 52 Dodavanje novog sloja

public class BacanjeZraka MonoBehaviour

hijerarhija slojeva tj koji ima veci prioritet

public Sloj[] prioritetiSlojeva =

SlojNeprijatelj

SlojProhodno

SlojKrajSvijeta

udaljenost do pozadine je neka izmisljena vrijednost nakon

koje se prestane provjeravati zraka

public float udaljenostDoPozadine = 100f

Camera kamera

RaycastHit _udara

dohvaca varijable ove klase

public RaycastHit udara

get return _udara

Sloj _udaraSloj

23

Slika 53 Prozor za dodavanje novog sloja

public Sloj udaraSloj

get return _udaraSloj

deklariraj novi tip delegata

public delegate void priPromjeniSloja(Sloj noviSloj)

instanciraj skup promatraca

public event priPromjeniSloja promatraciPromjeneSloja

void Start ()

dohvat glavne kamere

kamera = Cameramain

void Update ()

nadi sloj po prioritetu u koji zraka udara

foreach(Sloj sloj in prioritetiSlojeva)

provjeravamo udara li zraka u neki od slojeva

24

var udar = BacanjeZrakaZaSloj(sloj)

if(udarHasValue)

_udara = udarValue

ako se sloj promjenio

if(_udaraSloj = sloj)

spremi novi sloj u varijablu trenutnog sloja

_udaraSloj = sloj

obavijesti promatrace da se sloj promjenio

promatraciPromjeneSloja(sloj)

spremi novi sloj u varijablu trenutnog sloja

ali ne moras obavjestavati promatrace jer je

sloj jednak starom sloju

_udaraSloj = sloj

return

inace vrati da zraka udara u pozadinu i obavijesti

promatrace

_udaradistance = udaljenostDoPozadine

_udaraSloj = SlojKrajSvijeta

promatraciPromjeneSloja(udaraSloj)

RaycastHit BacanjeZrakaZaSloj(Sloj sloj)

kreira se maska za slojeve bit se pomice ulijevo za

onoliko mjesta koliki je redni broj prioriteta sloja

int maska = 1 ltlt (int)sloj

sprema se mjesto pozicije kursora pretvoreno iz tocke u

zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

RaycastHit udar

PhysicsRaycast sprema zraku u varijablu tipa

RaycastHit prima jos i maksimalnu udaljenost za koju

provjerava zraku i masku sloja i potom vraca istinu (

engl True) ili laz (engl False) ako je zraka udarila

u sloj

25

bool udarioJe = PhysicsRaycast(zraka out udar

udaljenostDoPozadine maska)

ako zraka udara u sloj vrati vrijednost udarca

if(udarioJe)

return udar

return null

U programskom kodu 51 se koristi funkcija za primjenu obrasca promatraca pod

nazivom delegat (engl Delegate) Što je obrazac promatraca (engl Observer) To je

oblikovni obrazac koji se u programiranju koristi

bull kad promjena jednog objekta zahtijeva promjene u drugim objektima koji nisu

unaprijed poznati

bull kad objekt treba obavještavati druge objekte

bull uz uvjet da bude što neovisniji o njima

bull kad je potrebno prikazivati razlicite aspekte nekog dinamickog stanja a želimo

izbjeci ciklicku ovisnost izmedu stanja i pogleda

bull kad postoje dva koncepta jedan ovisan o drugome a zgodno ih je razdvojiti

S obzirom na to da mi samo pri promjeni sloja želimo obavještavati pretplacene pro-

matrace uvodenje delegata nam dosta ubrzava kod Obrazac promatraca funkcionira

tako da glavni objekt igra ulogu izdavaca (izvora informacija) u ovom slucaju to je

glavna kamera Ostali ovisni objekti (promatraci) pretplacuju se kod izdavaca te iz-

davaci obavještavaju pretplatnike o promjenama Promatraci prekidaju pretplatu kad

više ne trebaju obavještavanje Funkcija priPromjeniSloja se definira kao delegat i u

ovom slucaju prima sloj Nakon toga se definira dogadaj (engl Event) tipa tog delegata

(priPromjeniSloja) u ovom slucaju naziva promatraciPromjeneSloja i odsad se unutar

subjekta tim nazivom i poziva Kako bi se neki promatrac pretplatio na informacije

koje izdaje kamera dodaje ove dvije linije koda u svoju skriptu

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

Programski kod 52 služi za kretanje korištenjem NavMesha i lijevog klika miša

26

Programski kod 52 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

public float dovoljnoBlizu = 01f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora

[SerializeField] float hodajKreciStaniRadijus = 02f

void Start ()

pronadi igraca koji je tipa agenta navigacijskog sustava

(engl NavMeshAgent)

agent = GetComponentltUnityEngineAINavMeshAgentgt()

pronadi prethodno napisanu klasu BacanjeZraka

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

spremi trenutnu poziciju kursora

trenutnaPozicijaKursora = transformposition

void Update()

ako je igrac dosao na zeljeno mjesto zaustavi animaciju

hodanja

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

ako je stisnut lijevi klik misa

if (InputGetMouseButtonDown(0))

ovisno o sloju primjeni akciju

switch(bacanjeZrakaudaraSloj)

ako se po objektu na koji je igrac kliknuo moze

hodati

27

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 17: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

4 Kamera

U ovom poglavlju se postavlja i bira prava kamera za igru Tijekom izrade igre treba se

takoder razmišljati i iz kojeg kuta ce se imati pogled na nju te hoce li se kamera pomi-

cati s kretanjem lika hoce li se moci rotirati itd Pri kreiranju 3D igre u pogledu scene

primjecuje se da su svi objekti i transformacije u 3D-prostoru No s obzirom na to da je

zaslon monitora igraca 2-dimenzionalan te se ne može prikazati tijela kao takva mora

se moci prikazati sve te objekte u jednoj ravnini i zadržati dojam 3-dimenzionalnosti

To se u Unityu postiže s kamerom Kamera je objekt koja definira pogled i njegov

smjer u prostoru scene Pozicija kamere definira ocište z os definira smjer gledanja

(gledište) te y os definira vrh ekrana Kamera takoder definira velicinu i oblik dijela

koji možemo vidjeti Kamera nam pokazuje ono što ona vidi Kako se ona rotira

translatira itd prikaz scene ce se takoder jednako transformirati Nakon kraja ovog

poglavlja želi se imati kamera koja ce pratiti kretnje lika i imati pogled na njega odoz-

gora

41 Perspektivna i ortografska kamera

Kamerom se zapravo objekte 3D prostora projicira na ravninu u 2D prostor Projek-

cije su matematicki modeli koji govore na koji nacin treba tocke 3D prostora preslikati

u ravninu u tocke 2D prostora Postoji više vrsta projekcija no Unity koristi dvije or-

tografsku projekciju i perspektivnu projekciju Kod ortografskih projekcija kamera je

okomita na ravninu projekcije dok je perspektivna projekcija bliža našem nacinu gle-

danja objekata Možda je najlakše primijetiti razliku koristeci slike Dakle na slici 41

možemo vidjeti blend model koji je modeliran u Blenderu u ortografskoj projekciji te

na slici 42 isti taj model pod istim kutem samo prebacen u perspektivnu projekciju

[6]

Perspektivna projekcija uvodi dvije tocke ocište i gledište Ocište je tocka u ko-

joj se nalazi promatrac Gledište odreduje smjer prema kojem promatrac gleda U

12

Slika 41 Ortografska projekcija blend modela

tocki gledišta stvara se ravnina projekcije koja je okomita na spojnicu ocište-gledište

[6] I perspektivna i ortografska kamera imaju granicu do koje mogu vidjeti od svoje

trenutne pozicije Ona je definirana upravo tom ravninom projekcije Tocka gledišta

pripada toj ravnini i ona tipicno postaje ishodište lokalnog dvodimenzijskog koordi-

natnog sustava koji razapinjemo u ravnini projekcije Ta ravnina se još naziva i daleka

ravnina podrezivanja zato što svi objekti koji se nalaze na vecoj udaljenosti od nje se

odrežu te ih kamera ne prikazuje Takoder postoji i ravnina podrezivanja blizu ka-

meri [1] Dio koji se prikazuje se nalazi izmedu te dvije ravnine

42 Pogled iz prvog lica u pogled iznad glave

U igrama se cesto koristi prebacivanje iz jednog u drugi pogled kamere Kako se

to postiže Koristeci veci broj kamera U ovom slucaju obradit ce se samo kratki

primjer kako se prebacivati iz pogleda prvog lica u pogled iznad glave U unity-u je

zadano da jedna kamera pokriva cijeli ekran te se zato samo pogled jedne kamere može

vidjeti u jednom trenutku Kamera koju vidimo je ona koja ima najvecu vrijednost

za svoje svojstvo dubine[1] Zato se želi napraviti skripta koja ce se prebacivati s

jedne kamere na drugu da bi se dobili drukciji pogledi na scenu koja je prikazana

programskim kodom 41

Programski kod 41 PrimjerViseKameracs

13

Slika 42 Perspektivna projekcija blend modela

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kameraPrvogLica

public Camera kameraIznadGlave

funkcija koja se poziva kada se prebacujemo u pogled iznad

glave

public void prikaziPogledIznadGlave()

kameraPrvogLicaenabled = false gasimo kameru prvog

lica

kameraIznadGlaveenabled = true palimo kameru iznad

glave

funkcija koja se poziva kada se prebacujemo u pogled iz

prvog lica

public void prikaziPogledIzPrvogLica()

kameraPrvogLicaenabled = true palimo kameru prvog

lica

overheadCameraenabled = false gasimo kameru iznad

glave

14

43 Fiksirana kamera

U sceni projekta vec postoji glavna kamera (engl Main Camera) koju Unity automat-

ski dodaje u scenu Kako bi ta kamera pratila lika može se samo povuci u lijevom

prozoru hijerarhije u hijerarhiju lika kako bi postala njegovo dijete Tako ce se postici

da kamera stalno prati njegove transformacije (translaciju rotaciju) prilikom pokreta-

nja igre No kako bi se postiglo da kamera ostane uvijek fiksirana te se samo krece s

njime umjesto da se kamera rotira skupa s likom dodaje se novi prazni objekt sa Game

Object -gt kreiraj prazan (engl Create Empty) Njegova pozicija se postavlja na x =

0 y = 0 z = 0 ako vec nije tamo te se postavlja taj prazan objekt kao roditelj glavne

kamere Sada kamera ostaje fiksirana na mjestu te se nece ni kretati s likom Kako bi

se krenula kretati mora se dodati nova skripta na taj prazan objekt koji se odsad u pro-

jektu zove Kamera s obzirom na to da zaista i je roditelj glavne kamere Kako bi se u

skripti lakše locirao objekt igraca oznacava ga se u njegovom polju oznaka (engl Tag)

u desnom prozoru Inspector s igrac (engl Player) kao što se može vidjeti na slici 43

zaokruženo plavom bojom

U programskom kodu se želi napraviti varijabla tipa Game Object kako bi se spremilo

igraca kada ga se pronade Unity takoder ima funkciju FindGameObjectWithTag pa

je onda ostatak koda prilicno intuitivan Kada se igrac pronade pomocu njegove oz-

nake Player prilikom svakog osvježavanja poziciji našeg igraca pridružuje se pozicija

kamere kao što je prikazano programskim kodom 42

Programski kod 42 pratiLikacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class pratiLika MonoBehaviour

GameObject igrac

void Start ()

trazi se objekt putem njegove oznake

igrac = GameObjectFindGameObjectWithTag(Player)

15

Slika 43 Oznacavanje lika radi lakšeg pronalaska u skripti

void LateUpdate ()

trenutni objekt mijenja svoju poziciju u skladu s

pozicijom objekta oznacenog oznakom Player

transformposition = igractransformposition

44 Bacanje zraka (engl Ray casting)

Perspektivna kamera u Unityu koristi oblik krnje piramide za dio koji prikazuje u pros-

toru Svaka tocka nekog objekta kojeg kamera prikazuje zapravo odgovara liniji u pros-

toru svijeta te je nama samo jedna tocka duž te linije vidljiva na objektu Sve iza te

tocke na liniji je zamraceno Vanjski rubovi objekta su definirani razilazecim linijama

16

koje odgovaraju kutevima objekta Kada bi se te linije pratile unazad prema kameri

sve bi na kraju konvergirale u jednu tocku U Unityu se ta tocka nalazi tocno na pozi-

ciji kamere i naziva se centrom perspektive Kut naspram linija koje konvergiraju od

gornjeg i donjeg centra ekrana u centru perspektive se zove vidno polje (engl Field Of

View) Sve što pada izvan tih razilazecih linija na rubovima objekta nece biti vidljivo

kameri uz vec prethodno spomenuta ogranicenja ravnina podrezivanja

U igrama je jako korisno imati matematicku reprezentaciju linije koja predstavlja tocku

u pogledu kamere Unity to omogucava u obliku objekta zrake Zraka uvijek odgo-

vara tocki u pogledu pa klasa Kamera (engl Camera) sadrži dvije korisne funkcije

ScreenPointToRay i ViewportPointToRay Razlika izmedu njih je da ScreenPointToRay

ocekuje tocku s koordinatama piksela dok ViewportPointToRay uzima normalizirane

koordinate (od 0 dolje ili lijevo do 1 gore ili desno) Obje funkcije vracaju zraku

koja se sastoji od tocke ishodišta i vektora koji pokazuje smjer linije od tog ishodišta

Zraka izlazi iz ravnine podrezivanja bliže kameri Najcešce se zrake koriste kako bi ih

bacali u scenu Bacanje zraka pošalje imaginarnu liniju uz zraku od njenog ishodišta

dok ne udari u neki sudarac u sceni Tada vraca informaciju o tocki koju je udarila

u objektu RaycastHit To je vrlo korisno kako bi se locirao objekt ovisno o njegovoj

poziciji na zaslonu npr lociranje kursora prikazano programskim kodom 43

Programski kod 43 lociranjeKursoracs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kamera

void Start()

RaycastHit udar

u objekt Ray se sprema pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

ako zraka udara u neki objekt spremi u objektUdaren to

mjesto

if (PhysicsRaycast(zraka out udar))

Transform objektUdaren = udartransform

17

Ponekad je takoder korisno dobiti zraku koja odgovara poziciji na zaslonu te onda

pomicati kameru uz tu zraku Npr želi se dozvoliti igracu da može selektirati objekt

mišem i onda ga povecati dok se objekt nalazi cijelo vrijeme na istoj poziciji na zaslonu

ispod miša prikazano programskim kodom 44 [1]

Programski kod 44 povecavanjeSlikecs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public bool povecavanje

public float brzinaPovecavanja

public Camera kamera

void Update()

ako netko koristi povecavanje slike (engl Zooming)

if (povecavanje)

u objekt Ray sprema se pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(Input

mousePosition)

udaljenost povecavanja ce biti jednaka umnosku

brzine povecavanja vremena i vertikalnog smjera

float udaljenostPovecavanja = brzinaPovecavanja

InputGetAxis(Vertical) TimedeltaTime

pomakni kameru u smjeru kursora misa za udaljenost

povecavanja u koordinatnom sustavu svijeta

kameratransformTranslate(zrakadirection

udaljenostPovecavanja SpaceWorld)

18

5 Kretanje

Pronalazak puta je zapravo pokušaj aplikacije na racunalu ili algoritma da nade naj-

kracu rutu izmedu dvije tocke To je recimo prakticna verzija rješavanja labirinta Ni

danas ne postoji optimalan algoritam koji ce u svakom slucaju u nekom realno krat-

kom vremenu naci najkraci put U ovom poglavlju objasnit ce se koje algoritme Unity

koristi za svoj navigacijski sustav Objašnjavat ce se i neki osnovni koncepti i obrasci

potrebni za ubrzavanje cijele ideje dojavljivanja promjena u sceni Bit ce prikazani i

programski kodovi potrebni za implementiranje kretanja mišem iili tipkovnicom Na

kraju ovog poglavlja želi se imati lika koji ce se slobodno kretati po sceni na mjesto

koje se odredi klikom miša i mogucnost prebacivanja na upravljanje tipkovnicom

51 Navigacijski sustav u Unityu

U Unityu je problem pronalaska puta vec riješen s necim što se zove navigacijska

mreža (engl NavMesh) To je navigacijski sustav koji ima svoje algoritme pronala-

ska puta i puno pojednostavljuje programiranje kretanja lika Sastoji se od cetiri di-

jela NavMesh agent navigacijske mreže (engl NavMesh Agent) izvanmrežna pove-

zanost(engl Off - Mesh Link) i prepreka navigacijske mreže(engl NavMesh Obstacle)

NavMesh je podatkovna struktura koja opisuje površine po kojima se može kretati

u igri i omogucava pronalazak put od jedne lokacije do druge Navigacijski sustav

treba svoje podatke kako bi predstavio prohodna podrucja u sceni Prohodna podru-

cja definiraju se kao mjesta gdje agent može stajati i kretati se Prohodno podrucje se

automatski izgraduje iz geometrije u sceni testirajuci sva podrucja gdje bi agent mo-

gao stajati Onda se te lokacije spajaju s površinom na vrhu geometrije Ta površina se

naziva onda NavMesh te je možemo vidjeti na 51 NavMesh tada sprema tu površinu

kao konveksne poligone te informacije koji su poligoni susjedni Komponenta Nav-

Mesh Agent pomaže pri kreiranju likova koji se medusobno izbjegavaju dok se krecu

prema cilju U Unityu se agenti opisuju kao valjci Koriste NavMesh kako bi se kretali

i znali koje objekte moraju zaobici te kako da se medusobno zaobidu Off-Mesh Link

19

omogucava dodavanje navigacijskih precaca koji se ne mogu predstaviti kao površina

po kojoj se može hodati npr skakanje preko ograde ili otvaranje vrata prije nego što

se ude u neku prostoriju NavMesh Obstacle opisuje prepreke koje se krecu te koje bi

agenti trebali izbjegavati dok hodaju svijetom npr neke bacve koje se kotrljaju prema

igracu Dok se bacva krece agent ce izracunati put oko nje najbolje što može no nakon

što ona naposljetku stane postat ce dio neprohodnog NavMesha te ce se agenti kretati

oko nje [3]

Slika 51 Prikaz navigacijskog sustava u Unityu

52 Pronalazak puta

Dva glavna problema postoje kod pronalaženja puta kako pronaci destinaciju na ni-

vou na kojem se igrac nalazi te kako se onda tamo pomaknuti Pronalaženje destinacije

uzima u obzir cijelu scenu Pomicanje tamo je dinamicnije u obzir uzima samo smjer

kretanja i kako da sprijeci sudaranje s drugim agentima Da bi se pronašao put izmedu

dvije lokacije prvo se moraju oznaciti pocetna i konacna lokacija njihovim najbližim

poligonima Tada se krece tražiti od pocetne lokacije posjecujuci sve susjedne dok se

ne dode do zadane destinacije Onda se prati unatrag vec posjecene poligone kako bi

se našao konacan niz poligona koji vode od pocetka do kraja Algoritam koji Unity

koristi te se cesto koristi za pronalazak puta naziva se A (A zvjezdica) Taj niz po-

ligona koji opisuje put od pocetka do kraja se naziva hodnik Agent ce doci do svoje

20

destinacije tako da se uvijek usmjerava prema sljedecem vidljivom kutu hodnika Ta

logika usmjeravanja uvijek uzima poziciju sljedeceg kuta i ovisno o tome nade željeni

smjer i brzinu potrebnu za dolazak na destinaciju Korištenje brzine po želji progra-

mera bi moglo dovesti do sudara s ostalim agentima Izbjegavanje prepreka takoder

pronalazi svoju novu brzinu koja traži ravnotežu izmedu kretanja prema destinaciji i

sprjecavanja buducih sudara s ostalim agentima i kutevima u navigacijskom sustavu

Nakon usmjeravanja i izbjegavanja prepreka izracuna se konacna brzina Unity ta-

koder uzima u obzir i akceleraciju kako bi simulirao realisticnije kretanje Takoder

treba razumjeti razliku izmedu globalne i lokalne navigacije Globalna navigacija se

koristi za pronalazak hodnika u svijetu Linearna lista poligona koja opisuje taj put je

podatkovna struktura koja se koristi za usmjeravanje te se može lokalno prilagodavati

i mijenjati kako se pozicija agenta mijenja Lokalna navigacija pokušava naci efika-

san nacin kako da se igrac pomakne prema sljedecem kutu bez da se sudari s ostalim

agentima ili objektima koji se krecu [3]

53 Kreiranje navigacijskog sustava

Proces kreiranja NavMesha iz geometrije nivoa se naziva pecenje navigacijske mreže

(engl NavMesh Baking) Skuplja sve terene i mreže objekata koji su oznaceni kao

navigacijski staticko (engl Navigation Static) i onda ih procesira kako bi kreirao navi-

gacijski sustav koji aproksimira prohodne površine nivoa Izgradnja (engl NavMesha)

je vrlo jednostavna Prvo se selektira geometrija koja bi trebala utjecati na navigaciju

tj površine po kojima možemo hodati i prepreke Oznaci se Navigation Static da bi ih

ukljucili u NavMesh Baking proces Prilagode se postavke kako bi odgovarale velicini

agenta - radijus (npr koliko blizu se može doci zidovima) visina (koliko su nisko

prostori koje agent može doseci) maksimalni nagib (koliko su kose rampe po kojima

se agent može uspeti) visina stube(koliko su visoke prepreke na koje agent može za-

koraciti) Onda jednostavno stisnemo ispeci (engl Bake) da izgradimo svoj NavMesh

Izgradeni NavMesh cemo moci vidjeti kao plavu površinu kao na slici 51 te ce se stvo-

riti nova datoteka s nazivom trenutne scene (ako vec ne postoji) i unutra ce se spremiti

kreiran navigacijski sustav [3]

21

54 Programiranje kretanja

Na liku se trenutno nalazi par stvari Animator Capsule Collider i Rigid Body Sada

je cilj isprogramirati mogucnost odredivanja gdje ce se lik kretati klikom miša na to

mjesto Dodaje se nova komponenta na lika NavMesh Agent Ta komponenta za-

pravo vec ima svoj sudarac te se slobodno može obrisati Capsule Collider jer postaje

nepotreban Igranjem s opcijama pomak od baze (engl Base Offset) te pod izbjegava-

nje prepreka (engl Obstacle Avoidance) radijus (engl Radius) i visina (engl Height)

prilagodi se sudarac od (engl NavMesh Agent-a) kako bi se obujmilo njime igraca i

sprijecilo propadanje kroz tlo od prije Sada kada postoji komponenta navigacije mora

se dodati skripta koja ce odrediti kada se lik krece te kada se pokrecu njegove anima-

cije iz Animator-a

Da bi se znalo gdje se miš nalazi mora se takoder dodati nova skriptu na kameru Kako

bi se izracunalo gdje trenutno kursor pokazuje Unity koristi vec prethodno spomenuto

bacanje zraka Da bi se moglo koristiti navigaciju putem klika mišem mora se napisati

skripta za glavnu kameru koja ce omoguciti bacanje zraka Skripta BacanjeZraka

dodaje se na objekt Main Camera koja se dodala pod prazni objekt Kamera Ova

skriptu se takoder koristi za razlikovanje raznih vrsta objekata Naime svaki objekt

kao što ima i Tag ima i sloj (engl Layer) Sloj služi kako bi mogli npr razlikovati

neprijatelje od obicnih objekata ili mjesto na koje želimo doci hodanjem Zato cemo

takoder dodati i jednu enumeraciju koja ce nam zasad služiti samo da razlikujemo je li

mjesto prohodno ili ne te jesmo li kliknuli na neprijatelja Kako bi dodali svoje nove

slojeve za objekte moramo kliknuti na Layer i dodaj sloj (engl Add Layer) kao na slici

52 što nas dovodi do novog prozora prikazanog na slici 53

Programski kod 51 bacanjeZrakacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

sluzi za dodavanje novih slojeva u Unity

public enum Sloj

Prohodno = 8

Neprijatelj = 9

KrajSvijeta = -1

22

Slika 52 Dodavanje novog sloja

public class BacanjeZraka MonoBehaviour

hijerarhija slojeva tj koji ima veci prioritet

public Sloj[] prioritetiSlojeva =

SlojNeprijatelj

SlojProhodno

SlojKrajSvijeta

udaljenost do pozadine je neka izmisljena vrijednost nakon

koje se prestane provjeravati zraka

public float udaljenostDoPozadine = 100f

Camera kamera

RaycastHit _udara

dohvaca varijable ove klase

public RaycastHit udara

get return _udara

Sloj _udaraSloj

23

Slika 53 Prozor za dodavanje novog sloja

public Sloj udaraSloj

get return _udaraSloj

deklariraj novi tip delegata

public delegate void priPromjeniSloja(Sloj noviSloj)

instanciraj skup promatraca

public event priPromjeniSloja promatraciPromjeneSloja

void Start ()

dohvat glavne kamere

kamera = Cameramain

void Update ()

nadi sloj po prioritetu u koji zraka udara

foreach(Sloj sloj in prioritetiSlojeva)

provjeravamo udara li zraka u neki od slojeva

24

var udar = BacanjeZrakaZaSloj(sloj)

if(udarHasValue)

_udara = udarValue

ako se sloj promjenio

if(_udaraSloj = sloj)

spremi novi sloj u varijablu trenutnog sloja

_udaraSloj = sloj

obavijesti promatrace da se sloj promjenio

promatraciPromjeneSloja(sloj)

spremi novi sloj u varijablu trenutnog sloja

ali ne moras obavjestavati promatrace jer je

sloj jednak starom sloju

_udaraSloj = sloj

return

inace vrati da zraka udara u pozadinu i obavijesti

promatrace

_udaradistance = udaljenostDoPozadine

_udaraSloj = SlojKrajSvijeta

promatraciPromjeneSloja(udaraSloj)

RaycastHit BacanjeZrakaZaSloj(Sloj sloj)

kreira se maska za slojeve bit se pomice ulijevo za

onoliko mjesta koliki je redni broj prioriteta sloja

int maska = 1 ltlt (int)sloj

sprema se mjesto pozicije kursora pretvoreno iz tocke u

zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

RaycastHit udar

PhysicsRaycast sprema zraku u varijablu tipa

RaycastHit prima jos i maksimalnu udaljenost za koju

provjerava zraku i masku sloja i potom vraca istinu (

engl True) ili laz (engl False) ako je zraka udarila

u sloj

25

bool udarioJe = PhysicsRaycast(zraka out udar

udaljenostDoPozadine maska)

ako zraka udara u sloj vrati vrijednost udarca

if(udarioJe)

return udar

return null

U programskom kodu 51 se koristi funkcija za primjenu obrasca promatraca pod

nazivom delegat (engl Delegate) Što je obrazac promatraca (engl Observer) To je

oblikovni obrazac koji se u programiranju koristi

bull kad promjena jednog objekta zahtijeva promjene u drugim objektima koji nisu

unaprijed poznati

bull kad objekt treba obavještavati druge objekte

bull uz uvjet da bude što neovisniji o njima

bull kad je potrebno prikazivati razlicite aspekte nekog dinamickog stanja a želimo

izbjeci ciklicku ovisnost izmedu stanja i pogleda

bull kad postoje dva koncepta jedan ovisan o drugome a zgodno ih je razdvojiti

S obzirom na to da mi samo pri promjeni sloja želimo obavještavati pretplacene pro-

matrace uvodenje delegata nam dosta ubrzava kod Obrazac promatraca funkcionira

tako da glavni objekt igra ulogu izdavaca (izvora informacija) u ovom slucaju to je

glavna kamera Ostali ovisni objekti (promatraci) pretplacuju se kod izdavaca te iz-

davaci obavještavaju pretplatnike o promjenama Promatraci prekidaju pretplatu kad

više ne trebaju obavještavanje Funkcija priPromjeniSloja se definira kao delegat i u

ovom slucaju prima sloj Nakon toga se definira dogadaj (engl Event) tipa tog delegata

(priPromjeniSloja) u ovom slucaju naziva promatraciPromjeneSloja i odsad se unutar

subjekta tim nazivom i poziva Kako bi se neki promatrac pretplatio na informacije

koje izdaje kamera dodaje ove dvije linije koda u svoju skriptu

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

Programski kod 52 služi za kretanje korištenjem NavMesha i lijevog klika miša

26

Programski kod 52 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

public float dovoljnoBlizu = 01f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora

[SerializeField] float hodajKreciStaniRadijus = 02f

void Start ()

pronadi igraca koji je tipa agenta navigacijskog sustava

(engl NavMeshAgent)

agent = GetComponentltUnityEngineAINavMeshAgentgt()

pronadi prethodno napisanu klasu BacanjeZraka

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

spremi trenutnu poziciju kursora

trenutnaPozicijaKursora = transformposition

void Update()

ako je igrac dosao na zeljeno mjesto zaustavi animaciju

hodanja

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

ako je stisnut lijevi klik misa

if (InputGetMouseButtonDown(0))

ovisno o sloju primjeni akciju

switch(bacanjeZrakaudaraSloj)

ako se po objektu na koji je igrac kliknuo moze

hodati

27

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 18: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

Slika 41 Ortografska projekcija blend modela

tocki gledišta stvara se ravnina projekcije koja je okomita na spojnicu ocište-gledište

[6] I perspektivna i ortografska kamera imaju granicu do koje mogu vidjeti od svoje

trenutne pozicije Ona je definirana upravo tom ravninom projekcije Tocka gledišta

pripada toj ravnini i ona tipicno postaje ishodište lokalnog dvodimenzijskog koordi-

natnog sustava koji razapinjemo u ravnini projekcije Ta ravnina se još naziva i daleka

ravnina podrezivanja zato što svi objekti koji se nalaze na vecoj udaljenosti od nje se

odrežu te ih kamera ne prikazuje Takoder postoji i ravnina podrezivanja blizu ka-

meri [1] Dio koji se prikazuje se nalazi izmedu te dvije ravnine

42 Pogled iz prvog lica u pogled iznad glave

U igrama se cesto koristi prebacivanje iz jednog u drugi pogled kamere Kako se

to postiže Koristeci veci broj kamera U ovom slucaju obradit ce se samo kratki

primjer kako se prebacivati iz pogleda prvog lica u pogled iznad glave U unity-u je

zadano da jedna kamera pokriva cijeli ekran te se zato samo pogled jedne kamere može

vidjeti u jednom trenutku Kamera koju vidimo je ona koja ima najvecu vrijednost

za svoje svojstvo dubine[1] Zato se želi napraviti skripta koja ce se prebacivati s

jedne kamere na drugu da bi se dobili drukciji pogledi na scenu koja je prikazana

programskim kodom 41

Programski kod 41 PrimjerViseKameracs

13

Slika 42 Perspektivna projekcija blend modela

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kameraPrvogLica

public Camera kameraIznadGlave

funkcija koja se poziva kada se prebacujemo u pogled iznad

glave

public void prikaziPogledIznadGlave()

kameraPrvogLicaenabled = false gasimo kameru prvog

lica

kameraIznadGlaveenabled = true palimo kameru iznad

glave

funkcija koja se poziva kada se prebacujemo u pogled iz

prvog lica

public void prikaziPogledIzPrvogLica()

kameraPrvogLicaenabled = true palimo kameru prvog

lica

overheadCameraenabled = false gasimo kameru iznad

glave

14

43 Fiksirana kamera

U sceni projekta vec postoji glavna kamera (engl Main Camera) koju Unity automat-

ski dodaje u scenu Kako bi ta kamera pratila lika može se samo povuci u lijevom

prozoru hijerarhije u hijerarhiju lika kako bi postala njegovo dijete Tako ce se postici

da kamera stalno prati njegove transformacije (translaciju rotaciju) prilikom pokreta-

nja igre No kako bi se postiglo da kamera ostane uvijek fiksirana te se samo krece s

njime umjesto da se kamera rotira skupa s likom dodaje se novi prazni objekt sa Game

Object -gt kreiraj prazan (engl Create Empty) Njegova pozicija se postavlja na x =

0 y = 0 z = 0 ako vec nije tamo te se postavlja taj prazan objekt kao roditelj glavne

kamere Sada kamera ostaje fiksirana na mjestu te se nece ni kretati s likom Kako bi

se krenula kretati mora se dodati nova skripta na taj prazan objekt koji se odsad u pro-

jektu zove Kamera s obzirom na to da zaista i je roditelj glavne kamere Kako bi se u

skripti lakše locirao objekt igraca oznacava ga se u njegovom polju oznaka (engl Tag)

u desnom prozoru Inspector s igrac (engl Player) kao što se može vidjeti na slici 43

zaokruženo plavom bojom

U programskom kodu se želi napraviti varijabla tipa Game Object kako bi se spremilo

igraca kada ga se pronade Unity takoder ima funkciju FindGameObjectWithTag pa

je onda ostatak koda prilicno intuitivan Kada se igrac pronade pomocu njegove oz-

nake Player prilikom svakog osvježavanja poziciji našeg igraca pridružuje se pozicija

kamere kao što je prikazano programskim kodom 42

Programski kod 42 pratiLikacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class pratiLika MonoBehaviour

GameObject igrac

void Start ()

trazi se objekt putem njegove oznake

igrac = GameObjectFindGameObjectWithTag(Player)

15

Slika 43 Oznacavanje lika radi lakšeg pronalaska u skripti

void LateUpdate ()

trenutni objekt mijenja svoju poziciju u skladu s

pozicijom objekta oznacenog oznakom Player

transformposition = igractransformposition

44 Bacanje zraka (engl Ray casting)

Perspektivna kamera u Unityu koristi oblik krnje piramide za dio koji prikazuje u pros-

toru Svaka tocka nekog objekta kojeg kamera prikazuje zapravo odgovara liniji u pros-

toru svijeta te je nama samo jedna tocka duž te linije vidljiva na objektu Sve iza te

tocke na liniji je zamraceno Vanjski rubovi objekta su definirani razilazecim linijama

16

koje odgovaraju kutevima objekta Kada bi se te linije pratile unazad prema kameri

sve bi na kraju konvergirale u jednu tocku U Unityu se ta tocka nalazi tocno na pozi-

ciji kamere i naziva se centrom perspektive Kut naspram linija koje konvergiraju od

gornjeg i donjeg centra ekrana u centru perspektive se zove vidno polje (engl Field Of

View) Sve što pada izvan tih razilazecih linija na rubovima objekta nece biti vidljivo

kameri uz vec prethodno spomenuta ogranicenja ravnina podrezivanja

U igrama je jako korisno imati matematicku reprezentaciju linije koja predstavlja tocku

u pogledu kamere Unity to omogucava u obliku objekta zrake Zraka uvijek odgo-

vara tocki u pogledu pa klasa Kamera (engl Camera) sadrži dvije korisne funkcije

ScreenPointToRay i ViewportPointToRay Razlika izmedu njih je da ScreenPointToRay

ocekuje tocku s koordinatama piksela dok ViewportPointToRay uzima normalizirane

koordinate (od 0 dolje ili lijevo do 1 gore ili desno) Obje funkcije vracaju zraku

koja se sastoji od tocke ishodišta i vektora koji pokazuje smjer linije od tog ishodišta

Zraka izlazi iz ravnine podrezivanja bliže kameri Najcešce se zrake koriste kako bi ih

bacali u scenu Bacanje zraka pošalje imaginarnu liniju uz zraku od njenog ishodišta

dok ne udari u neki sudarac u sceni Tada vraca informaciju o tocki koju je udarila

u objektu RaycastHit To je vrlo korisno kako bi se locirao objekt ovisno o njegovoj

poziciji na zaslonu npr lociranje kursora prikazano programskim kodom 43

Programski kod 43 lociranjeKursoracs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kamera

void Start()

RaycastHit udar

u objekt Ray se sprema pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

ako zraka udara u neki objekt spremi u objektUdaren to

mjesto

if (PhysicsRaycast(zraka out udar))

Transform objektUdaren = udartransform

17

Ponekad je takoder korisno dobiti zraku koja odgovara poziciji na zaslonu te onda

pomicati kameru uz tu zraku Npr želi se dozvoliti igracu da može selektirati objekt

mišem i onda ga povecati dok se objekt nalazi cijelo vrijeme na istoj poziciji na zaslonu

ispod miša prikazano programskim kodom 44 [1]

Programski kod 44 povecavanjeSlikecs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public bool povecavanje

public float brzinaPovecavanja

public Camera kamera

void Update()

ako netko koristi povecavanje slike (engl Zooming)

if (povecavanje)

u objekt Ray sprema se pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(Input

mousePosition)

udaljenost povecavanja ce biti jednaka umnosku

brzine povecavanja vremena i vertikalnog smjera

float udaljenostPovecavanja = brzinaPovecavanja

InputGetAxis(Vertical) TimedeltaTime

pomakni kameru u smjeru kursora misa za udaljenost

povecavanja u koordinatnom sustavu svijeta

kameratransformTranslate(zrakadirection

udaljenostPovecavanja SpaceWorld)

18

5 Kretanje

Pronalazak puta je zapravo pokušaj aplikacije na racunalu ili algoritma da nade naj-

kracu rutu izmedu dvije tocke To je recimo prakticna verzija rješavanja labirinta Ni

danas ne postoji optimalan algoritam koji ce u svakom slucaju u nekom realno krat-

kom vremenu naci najkraci put U ovom poglavlju objasnit ce se koje algoritme Unity

koristi za svoj navigacijski sustav Objašnjavat ce se i neki osnovni koncepti i obrasci

potrebni za ubrzavanje cijele ideje dojavljivanja promjena u sceni Bit ce prikazani i

programski kodovi potrebni za implementiranje kretanja mišem iili tipkovnicom Na

kraju ovog poglavlja želi se imati lika koji ce se slobodno kretati po sceni na mjesto

koje se odredi klikom miša i mogucnost prebacivanja na upravljanje tipkovnicom

51 Navigacijski sustav u Unityu

U Unityu je problem pronalaska puta vec riješen s necim što se zove navigacijska

mreža (engl NavMesh) To je navigacijski sustav koji ima svoje algoritme pronala-

ska puta i puno pojednostavljuje programiranje kretanja lika Sastoji se od cetiri di-

jela NavMesh agent navigacijske mreže (engl NavMesh Agent) izvanmrežna pove-

zanost(engl Off - Mesh Link) i prepreka navigacijske mreže(engl NavMesh Obstacle)

NavMesh je podatkovna struktura koja opisuje površine po kojima se može kretati

u igri i omogucava pronalazak put od jedne lokacije do druge Navigacijski sustav

treba svoje podatke kako bi predstavio prohodna podrucja u sceni Prohodna podru-

cja definiraju se kao mjesta gdje agent može stajati i kretati se Prohodno podrucje se

automatski izgraduje iz geometrije u sceni testirajuci sva podrucja gdje bi agent mo-

gao stajati Onda se te lokacije spajaju s površinom na vrhu geometrije Ta površina se

naziva onda NavMesh te je možemo vidjeti na 51 NavMesh tada sprema tu površinu

kao konveksne poligone te informacije koji su poligoni susjedni Komponenta Nav-

Mesh Agent pomaže pri kreiranju likova koji se medusobno izbjegavaju dok se krecu

prema cilju U Unityu se agenti opisuju kao valjci Koriste NavMesh kako bi se kretali

i znali koje objekte moraju zaobici te kako da se medusobno zaobidu Off-Mesh Link

19

omogucava dodavanje navigacijskih precaca koji se ne mogu predstaviti kao površina

po kojoj se može hodati npr skakanje preko ograde ili otvaranje vrata prije nego što

se ude u neku prostoriju NavMesh Obstacle opisuje prepreke koje se krecu te koje bi

agenti trebali izbjegavati dok hodaju svijetom npr neke bacve koje se kotrljaju prema

igracu Dok se bacva krece agent ce izracunati put oko nje najbolje što može no nakon

što ona naposljetku stane postat ce dio neprohodnog NavMesha te ce se agenti kretati

oko nje [3]

Slika 51 Prikaz navigacijskog sustava u Unityu

52 Pronalazak puta

Dva glavna problema postoje kod pronalaženja puta kako pronaci destinaciju na ni-

vou na kojem se igrac nalazi te kako se onda tamo pomaknuti Pronalaženje destinacije

uzima u obzir cijelu scenu Pomicanje tamo je dinamicnije u obzir uzima samo smjer

kretanja i kako da sprijeci sudaranje s drugim agentima Da bi se pronašao put izmedu

dvije lokacije prvo se moraju oznaciti pocetna i konacna lokacija njihovim najbližim

poligonima Tada se krece tražiti od pocetne lokacije posjecujuci sve susjedne dok se

ne dode do zadane destinacije Onda se prati unatrag vec posjecene poligone kako bi

se našao konacan niz poligona koji vode od pocetka do kraja Algoritam koji Unity

koristi te se cesto koristi za pronalazak puta naziva se A (A zvjezdica) Taj niz po-

ligona koji opisuje put od pocetka do kraja se naziva hodnik Agent ce doci do svoje

20

destinacije tako da se uvijek usmjerava prema sljedecem vidljivom kutu hodnika Ta

logika usmjeravanja uvijek uzima poziciju sljedeceg kuta i ovisno o tome nade željeni

smjer i brzinu potrebnu za dolazak na destinaciju Korištenje brzine po želji progra-

mera bi moglo dovesti do sudara s ostalim agentima Izbjegavanje prepreka takoder

pronalazi svoju novu brzinu koja traži ravnotežu izmedu kretanja prema destinaciji i

sprjecavanja buducih sudara s ostalim agentima i kutevima u navigacijskom sustavu

Nakon usmjeravanja i izbjegavanja prepreka izracuna se konacna brzina Unity ta-

koder uzima u obzir i akceleraciju kako bi simulirao realisticnije kretanje Takoder

treba razumjeti razliku izmedu globalne i lokalne navigacije Globalna navigacija se

koristi za pronalazak hodnika u svijetu Linearna lista poligona koja opisuje taj put je

podatkovna struktura koja se koristi za usmjeravanje te se može lokalno prilagodavati

i mijenjati kako se pozicija agenta mijenja Lokalna navigacija pokušava naci efika-

san nacin kako da se igrac pomakne prema sljedecem kutu bez da se sudari s ostalim

agentima ili objektima koji se krecu [3]

53 Kreiranje navigacijskog sustava

Proces kreiranja NavMesha iz geometrije nivoa se naziva pecenje navigacijske mreže

(engl NavMesh Baking) Skuplja sve terene i mreže objekata koji su oznaceni kao

navigacijski staticko (engl Navigation Static) i onda ih procesira kako bi kreirao navi-

gacijski sustav koji aproksimira prohodne površine nivoa Izgradnja (engl NavMesha)

je vrlo jednostavna Prvo se selektira geometrija koja bi trebala utjecati na navigaciju

tj površine po kojima možemo hodati i prepreke Oznaci se Navigation Static da bi ih

ukljucili u NavMesh Baking proces Prilagode se postavke kako bi odgovarale velicini

agenta - radijus (npr koliko blizu se može doci zidovima) visina (koliko su nisko

prostori koje agent može doseci) maksimalni nagib (koliko su kose rampe po kojima

se agent može uspeti) visina stube(koliko su visoke prepreke na koje agent može za-

koraciti) Onda jednostavno stisnemo ispeci (engl Bake) da izgradimo svoj NavMesh

Izgradeni NavMesh cemo moci vidjeti kao plavu površinu kao na slici 51 te ce se stvo-

riti nova datoteka s nazivom trenutne scene (ako vec ne postoji) i unutra ce se spremiti

kreiran navigacijski sustav [3]

21

54 Programiranje kretanja

Na liku se trenutno nalazi par stvari Animator Capsule Collider i Rigid Body Sada

je cilj isprogramirati mogucnost odredivanja gdje ce se lik kretati klikom miša na to

mjesto Dodaje se nova komponenta na lika NavMesh Agent Ta komponenta za-

pravo vec ima svoj sudarac te se slobodno može obrisati Capsule Collider jer postaje

nepotreban Igranjem s opcijama pomak od baze (engl Base Offset) te pod izbjegava-

nje prepreka (engl Obstacle Avoidance) radijus (engl Radius) i visina (engl Height)

prilagodi se sudarac od (engl NavMesh Agent-a) kako bi se obujmilo njime igraca i

sprijecilo propadanje kroz tlo od prije Sada kada postoji komponenta navigacije mora

se dodati skripta koja ce odrediti kada se lik krece te kada se pokrecu njegove anima-

cije iz Animator-a

Da bi se znalo gdje se miš nalazi mora se takoder dodati nova skriptu na kameru Kako

bi se izracunalo gdje trenutno kursor pokazuje Unity koristi vec prethodno spomenuto

bacanje zraka Da bi se moglo koristiti navigaciju putem klika mišem mora se napisati

skripta za glavnu kameru koja ce omoguciti bacanje zraka Skripta BacanjeZraka

dodaje se na objekt Main Camera koja se dodala pod prazni objekt Kamera Ova

skriptu se takoder koristi za razlikovanje raznih vrsta objekata Naime svaki objekt

kao što ima i Tag ima i sloj (engl Layer) Sloj služi kako bi mogli npr razlikovati

neprijatelje od obicnih objekata ili mjesto na koje želimo doci hodanjem Zato cemo

takoder dodati i jednu enumeraciju koja ce nam zasad služiti samo da razlikujemo je li

mjesto prohodno ili ne te jesmo li kliknuli na neprijatelja Kako bi dodali svoje nove

slojeve za objekte moramo kliknuti na Layer i dodaj sloj (engl Add Layer) kao na slici

52 što nas dovodi do novog prozora prikazanog na slici 53

Programski kod 51 bacanjeZrakacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

sluzi za dodavanje novih slojeva u Unity

public enum Sloj

Prohodno = 8

Neprijatelj = 9

KrajSvijeta = -1

22

Slika 52 Dodavanje novog sloja

public class BacanjeZraka MonoBehaviour

hijerarhija slojeva tj koji ima veci prioritet

public Sloj[] prioritetiSlojeva =

SlojNeprijatelj

SlojProhodno

SlojKrajSvijeta

udaljenost do pozadine je neka izmisljena vrijednost nakon

koje se prestane provjeravati zraka

public float udaljenostDoPozadine = 100f

Camera kamera

RaycastHit _udara

dohvaca varijable ove klase

public RaycastHit udara

get return _udara

Sloj _udaraSloj

23

Slika 53 Prozor za dodavanje novog sloja

public Sloj udaraSloj

get return _udaraSloj

deklariraj novi tip delegata

public delegate void priPromjeniSloja(Sloj noviSloj)

instanciraj skup promatraca

public event priPromjeniSloja promatraciPromjeneSloja

void Start ()

dohvat glavne kamere

kamera = Cameramain

void Update ()

nadi sloj po prioritetu u koji zraka udara

foreach(Sloj sloj in prioritetiSlojeva)

provjeravamo udara li zraka u neki od slojeva

24

var udar = BacanjeZrakaZaSloj(sloj)

if(udarHasValue)

_udara = udarValue

ako se sloj promjenio

if(_udaraSloj = sloj)

spremi novi sloj u varijablu trenutnog sloja

_udaraSloj = sloj

obavijesti promatrace da se sloj promjenio

promatraciPromjeneSloja(sloj)

spremi novi sloj u varijablu trenutnog sloja

ali ne moras obavjestavati promatrace jer je

sloj jednak starom sloju

_udaraSloj = sloj

return

inace vrati da zraka udara u pozadinu i obavijesti

promatrace

_udaradistance = udaljenostDoPozadine

_udaraSloj = SlojKrajSvijeta

promatraciPromjeneSloja(udaraSloj)

RaycastHit BacanjeZrakaZaSloj(Sloj sloj)

kreira se maska za slojeve bit se pomice ulijevo za

onoliko mjesta koliki je redni broj prioriteta sloja

int maska = 1 ltlt (int)sloj

sprema se mjesto pozicije kursora pretvoreno iz tocke u

zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

RaycastHit udar

PhysicsRaycast sprema zraku u varijablu tipa

RaycastHit prima jos i maksimalnu udaljenost za koju

provjerava zraku i masku sloja i potom vraca istinu (

engl True) ili laz (engl False) ako je zraka udarila

u sloj

25

bool udarioJe = PhysicsRaycast(zraka out udar

udaljenostDoPozadine maska)

ako zraka udara u sloj vrati vrijednost udarca

if(udarioJe)

return udar

return null

U programskom kodu 51 se koristi funkcija za primjenu obrasca promatraca pod

nazivom delegat (engl Delegate) Što je obrazac promatraca (engl Observer) To je

oblikovni obrazac koji se u programiranju koristi

bull kad promjena jednog objekta zahtijeva promjene u drugim objektima koji nisu

unaprijed poznati

bull kad objekt treba obavještavati druge objekte

bull uz uvjet da bude što neovisniji o njima

bull kad je potrebno prikazivati razlicite aspekte nekog dinamickog stanja a želimo

izbjeci ciklicku ovisnost izmedu stanja i pogleda

bull kad postoje dva koncepta jedan ovisan o drugome a zgodno ih je razdvojiti

S obzirom na to da mi samo pri promjeni sloja želimo obavještavati pretplacene pro-

matrace uvodenje delegata nam dosta ubrzava kod Obrazac promatraca funkcionira

tako da glavni objekt igra ulogu izdavaca (izvora informacija) u ovom slucaju to je

glavna kamera Ostali ovisni objekti (promatraci) pretplacuju se kod izdavaca te iz-

davaci obavještavaju pretplatnike o promjenama Promatraci prekidaju pretplatu kad

više ne trebaju obavještavanje Funkcija priPromjeniSloja se definira kao delegat i u

ovom slucaju prima sloj Nakon toga se definira dogadaj (engl Event) tipa tog delegata

(priPromjeniSloja) u ovom slucaju naziva promatraciPromjeneSloja i odsad se unutar

subjekta tim nazivom i poziva Kako bi se neki promatrac pretplatio na informacije

koje izdaje kamera dodaje ove dvije linije koda u svoju skriptu

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

Programski kod 52 služi za kretanje korištenjem NavMesha i lijevog klika miša

26

Programski kod 52 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

public float dovoljnoBlizu = 01f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora

[SerializeField] float hodajKreciStaniRadijus = 02f

void Start ()

pronadi igraca koji je tipa agenta navigacijskog sustava

(engl NavMeshAgent)

agent = GetComponentltUnityEngineAINavMeshAgentgt()

pronadi prethodno napisanu klasu BacanjeZraka

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

spremi trenutnu poziciju kursora

trenutnaPozicijaKursora = transformposition

void Update()

ako je igrac dosao na zeljeno mjesto zaustavi animaciju

hodanja

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

ako je stisnut lijevi klik misa

if (InputGetMouseButtonDown(0))

ovisno o sloju primjeni akciju

switch(bacanjeZrakaudaraSloj)

ako se po objektu na koji je igrac kliknuo moze

hodati

27

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 19: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

Slika 42 Perspektivna projekcija blend modela

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kameraPrvogLica

public Camera kameraIznadGlave

funkcija koja se poziva kada se prebacujemo u pogled iznad

glave

public void prikaziPogledIznadGlave()

kameraPrvogLicaenabled = false gasimo kameru prvog

lica

kameraIznadGlaveenabled = true palimo kameru iznad

glave

funkcija koja se poziva kada se prebacujemo u pogled iz

prvog lica

public void prikaziPogledIzPrvogLica()

kameraPrvogLicaenabled = true palimo kameru prvog

lica

overheadCameraenabled = false gasimo kameru iznad

glave

14

43 Fiksirana kamera

U sceni projekta vec postoji glavna kamera (engl Main Camera) koju Unity automat-

ski dodaje u scenu Kako bi ta kamera pratila lika može se samo povuci u lijevom

prozoru hijerarhije u hijerarhiju lika kako bi postala njegovo dijete Tako ce se postici

da kamera stalno prati njegove transformacije (translaciju rotaciju) prilikom pokreta-

nja igre No kako bi se postiglo da kamera ostane uvijek fiksirana te se samo krece s

njime umjesto da se kamera rotira skupa s likom dodaje se novi prazni objekt sa Game

Object -gt kreiraj prazan (engl Create Empty) Njegova pozicija se postavlja na x =

0 y = 0 z = 0 ako vec nije tamo te se postavlja taj prazan objekt kao roditelj glavne

kamere Sada kamera ostaje fiksirana na mjestu te se nece ni kretati s likom Kako bi

se krenula kretati mora se dodati nova skripta na taj prazan objekt koji se odsad u pro-

jektu zove Kamera s obzirom na to da zaista i je roditelj glavne kamere Kako bi se u

skripti lakše locirao objekt igraca oznacava ga se u njegovom polju oznaka (engl Tag)

u desnom prozoru Inspector s igrac (engl Player) kao što se može vidjeti na slici 43

zaokruženo plavom bojom

U programskom kodu se želi napraviti varijabla tipa Game Object kako bi se spremilo

igraca kada ga se pronade Unity takoder ima funkciju FindGameObjectWithTag pa

je onda ostatak koda prilicno intuitivan Kada se igrac pronade pomocu njegove oz-

nake Player prilikom svakog osvježavanja poziciji našeg igraca pridružuje se pozicija

kamere kao što je prikazano programskim kodom 42

Programski kod 42 pratiLikacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class pratiLika MonoBehaviour

GameObject igrac

void Start ()

trazi se objekt putem njegove oznake

igrac = GameObjectFindGameObjectWithTag(Player)

15

Slika 43 Oznacavanje lika radi lakšeg pronalaska u skripti

void LateUpdate ()

trenutni objekt mijenja svoju poziciju u skladu s

pozicijom objekta oznacenog oznakom Player

transformposition = igractransformposition

44 Bacanje zraka (engl Ray casting)

Perspektivna kamera u Unityu koristi oblik krnje piramide za dio koji prikazuje u pros-

toru Svaka tocka nekog objekta kojeg kamera prikazuje zapravo odgovara liniji u pros-

toru svijeta te je nama samo jedna tocka duž te linije vidljiva na objektu Sve iza te

tocke na liniji je zamraceno Vanjski rubovi objekta su definirani razilazecim linijama

16

koje odgovaraju kutevima objekta Kada bi se te linije pratile unazad prema kameri

sve bi na kraju konvergirale u jednu tocku U Unityu se ta tocka nalazi tocno na pozi-

ciji kamere i naziva se centrom perspektive Kut naspram linija koje konvergiraju od

gornjeg i donjeg centra ekrana u centru perspektive se zove vidno polje (engl Field Of

View) Sve što pada izvan tih razilazecih linija na rubovima objekta nece biti vidljivo

kameri uz vec prethodno spomenuta ogranicenja ravnina podrezivanja

U igrama je jako korisno imati matematicku reprezentaciju linije koja predstavlja tocku

u pogledu kamere Unity to omogucava u obliku objekta zrake Zraka uvijek odgo-

vara tocki u pogledu pa klasa Kamera (engl Camera) sadrži dvije korisne funkcije

ScreenPointToRay i ViewportPointToRay Razlika izmedu njih je da ScreenPointToRay

ocekuje tocku s koordinatama piksela dok ViewportPointToRay uzima normalizirane

koordinate (od 0 dolje ili lijevo do 1 gore ili desno) Obje funkcije vracaju zraku

koja se sastoji od tocke ishodišta i vektora koji pokazuje smjer linije od tog ishodišta

Zraka izlazi iz ravnine podrezivanja bliže kameri Najcešce se zrake koriste kako bi ih

bacali u scenu Bacanje zraka pošalje imaginarnu liniju uz zraku od njenog ishodišta

dok ne udari u neki sudarac u sceni Tada vraca informaciju o tocki koju je udarila

u objektu RaycastHit To je vrlo korisno kako bi se locirao objekt ovisno o njegovoj

poziciji na zaslonu npr lociranje kursora prikazano programskim kodom 43

Programski kod 43 lociranjeKursoracs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kamera

void Start()

RaycastHit udar

u objekt Ray se sprema pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

ako zraka udara u neki objekt spremi u objektUdaren to

mjesto

if (PhysicsRaycast(zraka out udar))

Transform objektUdaren = udartransform

17

Ponekad je takoder korisno dobiti zraku koja odgovara poziciji na zaslonu te onda

pomicati kameru uz tu zraku Npr želi se dozvoliti igracu da može selektirati objekt

mišem i onda ga povecati dok se objekt nalazi cijelo vrijeme na istoj poziciji na zaslonu

ispod miša prikazano programskim kodom 44 [1]

Programski kod 44 povecavanjeSlikecs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public bool povecavanje

public float brzinaPovecavanja

public Camera kamera

void Update()

ako netko koristi povecavanje slike (engl Zooming)

if (povecavanje)

u objekt Ray sprema se pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(Input

mousePosition)

udaljenost povecavanja ce biti jednaka umnosku

brzine povecavanja vremena i vertikalnog smjera

float udaljenostPovecavanja = brzinaPovecavanja

InputGetAxis(Vertical) TimedeltaTime

pomakni kameru u smjeru kursora misa za udaljenost

povecavanja u koordinatnom sustavu svijeta

kameratransformTranslate(zrakadirection

udaljenostPovecavanja SpaceWorld)

18

5 Kretanje

Pronalazak puta je zapravo pokušaj aplikacije na racunalu ili algoritma da nade naj-

kracu rutu izmedu dvije tocke To je recimo prakticna verzija rješavanja labirinta Ni

danas ne postoji optimalan algoritam koji ce u svakom slucaju u nekom realno krat-

kom vremenu naci najkraci put U ovom poglavlju objasnit ce se koje algoritme Unity

koristi za svoj navigacijski sustav Objašnjavat ce se i neki osnovni koncepti i obrasci

potrebni za ubrzavanje cijele ideje dojavljivanja promjena u sceni Bit ce prikazani i

programski kodovi potrebni za implementiranje kretanja mišem iili tipkovnicom Na

kraju ovog poglavlja želi se imati lika koji ce se slobodno kretati po sceni na mjesto

koje se odredi klikom miša i mogucnost prebacivanja na upravljanje tipkovnicom

51 Navigacijski sustav u Unityu

U Unityu je problem pronalaska puta vec riješen s necim što se zove navigacijska

mreža (engl NavMesh) To je navigacijski sustav koji ima svoje algoritme pronala-

ska puta i puno pojednostavljuje programiranje kretanja lika Sastoji se od cetiri di-

jela NavMesh agent navigacijske mreže (engl NavMesh Agent) izvanmrežna pove-

zanost(engl Off - Mesh Link) i prepreka navigacijske mreže(engl NavMesh Obstacle)

NavMesh je podatkovna struktura koja opisuje površine po kojima se može kretati

u igri i omogucava pronalazak put od jedne lokacije do druge Navigacijski sustav

treba svoje podatke kako bi predstavio prohodna podrucja u sceni Prohodna podru-

cja definiraju se kao mjesta gdje agent može stajati i kretati se Prohodno podrucje se

automatski izgraduje iz geometrije u sceni testirajuci sva podrucja gdje bi agent mo-

gao stajati Onda se te lokacije spajaju s površinom na vrhu geometrije Ta površina se

naziva onda NavMesh te je možemo vidjeti na 51 NavMesh tada sprema tu površinu

kao konveksne poligone te informacije koji su poligoni susjedni Komponenta Nav-

Mesh Agent pomaže pri kreiranju likova koji se medusobno izbjegavaju dok se krecu

prema cilju U Unityu se agenti opisuju kao valjci Koriste NavMesh kako bi se kretali

i znali koje objekte moraju zaobici te kako da se medusobno zaobidu Off-Mesh Link

19

omogucava dodavanje navigacijskih precaca koji se ne mogu predstaviti kao površina

po kojoj se može hodati npr skakanje preko ograde ili otvaranje vrata prije nego što

se ude u neku prostoriju NavMesh Obstacle opisuje prepreke koje se krecu te koje bi

agenti trebali izbjegavati dok hodaju svijetom npr neke bacve koje se kotrljaju prema

igracu Dok se bacva krece agent ce izracunati put oko nje najbolje što može no nakon

što ona naposljetku stane postat ce dio neprohodnog NavMesha te ce se agenti kretati

oko nje [3]

Slika 51 Prikaz navigacijskog sustava u Unityu

52 Pronalazak puta

Dva glavna problema postoje kod pronalaženja puta kako pronaci destinaciju na ni-

vou na kojem se igrac nalazi te kako se onda tamo pomaknuti Pronalaženje destinacije

uzima u obzir cijelu scenu Pomicanje tamo je dinamicnije u obzir uzima samo smjer

kretanja i kako da sprijeci sudaranje s drugim agentima Da bi se pronašao put izmedu

dvije lokacije prvo se moraju oznaciti pocetna i konacna lokacija njihovim najbližim

poligonima Tada se krece tražiti od pocetne lokacije posjecujuci sve susjedne dok se

ne dode do zadane destinacije Onda se prati unatrag vec posjecene poligone kako bi

se našao konacan niz poligona koji vode od pocetka do kraja Algoritam koji Unity

koristi te se cesto koristi za pronalazak puta naziva se A (A zvjezdica) Taj niz po-

ligona koji opisuje put od pocetka do kraja se naziva hodnik Agent ce doci do svoje

20

destinacije tako da se uvijek usmjerava prema sljedecem vidljivom kutu hodnika Ta

logika usmjeravanja uvijek uzima poziciju sljedeceg kuta i ovisno o tome nade željeni

smjer i brzinu potrebnu za dolazak na destinaciju Korištenje brzine po želji progra-

mera bi moglo dovesti do sudara s ostalim agentima Izbjegavanje prepreka takoder

pronalazi svoju novu brzinu koja traži ravnotežu izmedu kretanja prema destinaciji i

sprjecavanja buducih sudara s ostalim agentima i kutevima u navigacijskom sustavu

Nakon usmjeravanja i izbjegavanja prepreka izracuna se konacna brzina Unity ta-

koder uzima u obzir i akceleraciju kako bi simulirao realisticnije kretanje Takoder

treba razumjeti razliku izmedu globalne i lokalne navigacije Globalna navigacija se

koristi za pronalazak hodnika u svijetu Linearna lista poligona koja opisuje taj put je

podatkovna struktura koja se koristi za usmjeravanje te se može lokalno prilagodavati

i mijenjati kako se pozicija agenta mijenja Lokalna navigacija pokušava naci efika-

san nacin kako da se igrac pomakne prema sljedecem kutu bez da se sudari s ostalim

agentima ili objektima koji se krecu [3]

53 Kreiranje navigacijskog sustava

Proces kreiranja NavMesha iz geometrije nivoa se naziva pecenje navigacijske mreže

(engl NavMesh Baking) Skuplja sve terene i mreže objekata koji su oznaceni kao

navigacijski staticko (engl Navigation Static) i onda ih procesira kako bi kreirao navi-

gacijski sustav koji aproksimira prohodne površine nivoa Izgradnja (engl NavMesha)

je vrlo jednostavna Prvo se selektira geometrija koja bi trebala utjecati na navigaciju

tj površine po kojima možemo hodati i prepreke Oznaci se Navigation Static da bi ih

ukljucili u NavMesh Baking proces Prilagode se postavke kako bi odgovarale velicini

agenta - radijus (npr koliko blizu se može doci zidovima) visina (koliko su nisko

prostori koje agent može doseci) maksimalni nagib (koliko su kose rampe po kojima

se agent može uspeti) visina stube(koliko su visoke prepreke na koje agent može za-

koraciti) Onda jednostavno stisnemo ispeci (engl Bake) da izgradimo svoj NavMesh

Izgradeni NavMesh cemo moci vidjeti kao plavu površinu kao na slici 51 te ce se stvo-

riti nova datoteka s nazivom trenutne scene (ako vec ne postoji) i unutra ce se spremiti

kreiran navigacijski sustav [3]

21

54 Programiranje kretanja

Na liku se trenutno nalazi par stvari Animator Capsule Collider i Rigid Body Sada

je cilj isprogramirati mogucnost odredivanja gdje ce se lik kretati klikom miša na to

mjesto Dodaje se nova komponenta na lika NavMesh Agent Ta komponenta za-

pravo vec ima svoj sudarac te se slobodno može obrisati Capsule Collider jer postaje

nepotreban Igranjem s opcijama pomak od baze (engl Base Offset) te pod izbjegava-

nje prepreka (engl Obstacle Avoidance) radijus (engl Radius) i visina (engl Height)

prilagodi se sudarac od (engl NavMesh Agent-a) kako bi se obujmilo njime igraca i

sprijecilo propadanje kroz tlo od prije Sada kada postoji komponenta navigacije mora

se dodati skripta koja ce odrediti kada se lik krece te kada se pokrecu njegove anima-

cije iz Animator-a

Da bi se znalo gdje se miš nalazi mora se takoder dodati nova skriptu na kameru Kako

bi se izracunalo gdje trenutno kursor pokazuje Unity koristi vec prethodno spomenuto

bacanje zraka Da bi se moglo koristiti navigaciju putem klika mišem mora se napisati

skripta za glavnu kameru koja ce omoguciti bacanje zraka Skripta BacanjeZraka

dodaje se na objekt Main Camera koja se dodala pod prazni objekt Kamera Ova

skriptu se takoder koristi za razlikovanje raznih vrsta objekata Naime svaki objekt

kao što ima i Tag ima i sloj (engl Layer) Sloj služi kako bi mogli npr razlikovati

neprijatelje od obicnih objekata ili mjesto na koje želimo doci hodanjem Zato cemo

takoder dodati i jednu enumeraciju koja ce nam zasad služiti samo da razlikujemo je li

mjesto prohodno ili ne te jesmo li kliknuli na neprijatelja Kako bi dodali svoje nove

slojeve za objekte moramo kliknuti na Layer i dodaj sloj (engl Add Layer) kao na slici

52 što nas dovodi do novog prozora prikazanog na slici 53

Programski kod 51 bacanjeZrakacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

sluzi za dodavanje novih slojeva u Unity

public enum Sloj

Prohodno = 8

Neprijatelj = 9

KrajSvijeta = -1

22

Slika 52 Dodavanje novog sloja

public class BacanjeZraka MonoBehaviour

hijerarhija slojeva tj koji ima veci prioritet

public Sloj[] prioritetiSlojeva =

SlojNeprijatelj

SlojProhodno

SlojKrajSvijeta

udaljenost do pozadine je neka izmisljena vrijednost nakon

koje se prestane provjeravati zraka

public float udaljenostDoPozadine = 100f

Camera kamera

RaycastHit _udara

dohvaca varijable ove klase

public RaycastHit udara

get return _udara

Sloj _udaraSloj

23

Slika 53 Prozor za dodavanje novog sloja

public Sloj udaraSloj

get return _udaraSloj

deklariraj novi tip delegata

public delegate void priPromjeniSloja(Sloj noviSloj)

instanciraj skup promatraca

public event priPromjeniSloja promatraciPromjeneSloja

void Start ()

dohvat glavne kamere

kamera = Cameramain

void Update ()

nadi sloj po prioritetu u koji zraka udara

foreach(Sloj sloj in prioritetiSlojeva)

provjeravamo udara li zraka u neki od slojeva

24

var udar = BacanjeZrakaZaSloj(sloj)

if(udarHasValue)

_udara = udarValue

ako se sloj promjenio

if(_udaraSloj = sloj)

spremi novi sloj u varijablu trenutnog sloja

_udaraSloj = sloj

obavijesti promatrace da se sloj promjenio

promatraciPromjeneSloja(sloj)

spremi novi sloj u varijablu trenutnog sloja

ali ne moras obavjestavati promatrace jer je

sloj jednak starom sloju

_udaraSloj = sloj

return

inace vrati da zraka udara u pozadinu i obavijesti

promatrace

_udaradistance = udaljenostDoPozadine

_udaraSloj = SlojKrajSvijeta

promatraciPromjeneSloja(udaraSloj)

RaycastHit BacanjeZrakaZaSloj(Sloj sloj)

kreira se maska za slojeve bit se pomice ulijevo za

onoliko mjesta koliki je redni broj prioriteta sloja

int maska = 1 ltlt (int)sloj

sprema se mjesto pozicije kursora pretvoreno iz tocke u

zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

RaycastHit udar

PhysicsRaycast sprema zraku u varijablu tipa

RaycastHit prima jos i maksimalnu udaljenost za koju

provjerava zraku i masku sloja i potom vraca istinu (

engl True) ili laz (engl False) ako je zraka udarila

u sloj

25

bool udarioJe = PhysicsRaycast(zraka out udar

udaljenostDoPozadine maska)

ako zraka udara u sloj vrati vrijednost udarca

if(udarioJe)

return udar

return null

U programskom kodu 51 se koristi funkcija za primjenu obrasca promatraca pod

nazivom delegat (engl Delegate) Što je obrazac promatraca (engl Observer) To je

oblikovni obrazac koji se u programiranju koristi

bull kad promjena jednog objekta zahtijeva promjene u drugim objektima koji nisu

unaprijed poznati

bull kad objekt treba obavještavati druge objekte

bull uz uvjet da bude što neovisniji o njima

bull kad je potrebno prikazivati razlicite aspekte nekog dinamickog stanja a želimo

izbjeci ciklicku ovisnost izmedu stanja i pogleda

bull kad postoje dva koncepta jedan ovisan o drugome a zgodno ih je razdvojiti

S obzirom na to da mi samo pri promjeni sloja želimo obavještavati pretplacene pro-

matrace uvodenje delegata nam dosta ubrzava kod Obrazac promatraca funkcionira

tako da glavni objekt igra ulogu izdavaca (izvora informacija) u ovom slucaju to je

glavna kamera Ostali ovisni objekti (promatraci) pretplacuju se kod izdavaca te iz-

davaci obavještavaju pretplatnike o promjenama Promatraci prekidaju pretplatu kad

više ne trebaju obavještavanje Funkcija priPromjeniSloja se definira kao delegat i u

ovom slucaju prima sloj Nakon toga se definira dogadaj (engl Event) tipa tog delegata

(priPromjeniSloja) u ovom slucaju naziva promatraciPromjeneSloja i odsad se unutar

subjekta tim nazivom i poziva Kako bi se neki promatrac pretplatio na informacije

koje izdaje kamera dodaje ove dvije linije koda u svoju skriptu

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

Programski kod 52 služi za kretanje korištenjem NavMesha i lijevog klika miša

26

Programski kod 52 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

public float dovoljnoBlizu = 01f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora

[SerializeField] float hodajKreciStaniRadijus = 02f

void Start ()

pronadi igraca koji je tipa agenta navigacijskog sustava

(engl NavMeshAgent)

agent = GetComponentltUnityEngineAINavMeshAgentgt()

pronadi prethodno napisanu klasu BacanjeZraka

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

spremi trenutnu poziciju kursora

trenutnaPozicijaKursora = transformposition

void Update()

ako je igrac dosao na zeljeno mjesto zaustavi animaciju

hodanja

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

ako je stisnut lijevi klik misa

if (InputGetMouseButtonDown(0))

ovisno o sloju primjeni akciju

switch(bacanjeZrakaudaraSloj)

ako se po objektu na koji je igrac kliknuo moze

hodati

27

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 20: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

43 Fiksirana kamera

U sceni projekta vec postoji glavna kamera (engl Main Camera) koju Unity automat-

ski dodaje u scenu Kako bi ta kamera pratila lika može se samo povuci u lijevom

prozoru hijerarhije u hijerarhiju lika kako bi postala njegovo dijete Tako ce se postici

da kamera stalno prati njegove transformacije (translaciju rotaciju) prilikom pokreta-

nja igre No kako bi se postiglo da kamera ostane uvijek fiksirana te se samo krece s

njime umjesto da se kamera rotira skupa s likom dodaje se novi prazni objekt sa Game

Object -gt kreiraj prazan (engl Create Empty) Njegova pozicija se postavlja na x =

0 y = 0 z = 0 ako vec nije tamo te se postavlja taj prazan objekt kao roditelj glavne

kamere Sada kamera ostaje fiksirana na mjestu te se nece ni kretati s likom Kako bi

se krenula kretati mora se dodati nova skripta na taj prazan objekt koji se odsad u pro-

jektu zove Kamera s obzirom na to da zaista i je roditelj glavne kamere Kako bi se u

skripti lakše locirao objekt igraca oznacava ga se u njegovom polju oznaka (engl Tag)

u desnom prozoru Inspector s igrac (engl Player) kao što se može vidjeti na slici 43

zaokruženo plavom bojom

U programskom kodu se želi napraviti varijabla tipa Game Object kako bi se spremilo

igraca kada ga se pronade Unity takoder ima funkciju FindGameObjectWithTag pa

je onda ostatak koda prilicno intuitivan Kada se igrac pronade pomocu njegove oz-

nake Player prilikom svakog osvježavanja poziciji našeg igraca pridružuje se pozicija

kamere kao što je prikazano programskim kodom 42

Programski kod 42 pratiLikacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class pratiLika MonoBehaviour

GameObject igrac

void Start ()

trazi se objekt putem njegove oznake

igrac = GameObjectFindGameObjectWithTag(Player)

15

Slika 43 Oznacavanje lika radi lakšeg pronalaska u skripti

void LateUpdate ()

trenutni objekt mijenja svoju poziciju u skladu s

pozicijom objekta oznacenog oznakom Player

transformposition = igractransformposition

44 Bacanje zraka (engl Ray casting)

Perspektivna kamera u Unityu koristi oblik krnje piramide za dio koji prikazuje u pros-

toru Svaka tocka nekog objekta kojeg kamera prikazuje zapravo odgovara liniji u pros-

toru svijeta te je nama samo jedna tocka duž te linije vidljiva na objektu Sve iza te

tocke na liniji je zamraceno Vanjski rubovi objekta su definirani razilazecim linijama

16

koje odgovaraju kutevima objekta Kada bi se te linije pratile unazad prema kameri

sve bi na kraju konvergirale u jednu tocku U Unityu se ta tocka nalazi tocno na pozi-

ciji kamere i naziva se centrom perspektive Kut naspram linija koje konvergiraju od

gornjeg i donjeg centra ekrana u centru perspektive se zove vidno polje (engl Field Of

View) Sve što pada izvan tih razilazecih linija na rubovima objekta nece biti vidljivo

kameri uz vec prethodno spomenuta ogranicenja ravnina podrezivanja

U igrama je jako korisno imati matematicku reprezentaciju linije koja predstavlja tocku

u pogledu kamere Unity to omogucava u obliku objekta zrake Zraka uvijek odgo-

vara tocki u pogledu pa klasa Kamera (engl Camera) sadrži dvije korisne funkcije

ScreenPointToRay i ViewportPointToRay Razlika izmedu njih je da ScreenPointToRay

ocekuje tocku s koordinatama piksela dok ViewportPointToRay uzima normalizirane

koordinate (od 0 dolje ili lijevo do 1 gore ili desno) Obje funkcije vracaju zraku

koja se sastoji od tocke ishodišta i vektora koji pokazuje smjer linije od tog ishodišta

Zraka izlazi iz ravnine podrezivanja bliže kameri Najcešce se zrake koriste kako bi ih

bacali u scenu Bacanje zraka pošalje imaginarnu liniju uz zraku od njenog ishodišta

dok ne udari u neki sudarac u sceni Tada vraca informaciju o tocki koju je udarila

u objektu RaycastHit To je vrlo korisno kako bi se locirao objekt ovisno o njegovoj

poziciji na zaslonu npr lociranje kursora prikazano programskim kodom 43

Programski kod 43 lociranjeKursoracs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kamera

void Start()

RaycastHit udar

u objekt Ray se sprema pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

ako zraka udara u neki objekt spremi u objektUdaren to

mjesto

if (PhysicsRaycast(zraka out udar))

Transform objektUdaren = udartransform

17

Ponekad je takoder korisno dobiti zraku koja odgovara poziciji na zaslonu te onda

pomicati kameru uz tu zraku Npr želi se dozvoliti igracu da može selektirati objekt

mišem i onda ga povecati dok se objekt nalazi cijelo vrijeme na istoj poziciji na zaslonu

ispod miša prikazano programskim kodom 44 [1]

Programski kod 44 povecavanjeSlikecs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public bool povecavanje

public float brzinaPovecavanja

public Camera kamera

void Update()

ako netko koristi povecavanje slike (engl Zooming)

if (povecavanje)

u objekt Ray sprema se pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(Input

mousePosition)

udaljenost povecavanja ce biti jednaka umnosku

brzine povecavanja vremena i vertikalnog smjera

float udaljenostPovecavanja = brzinaPovecavanja

InputGetAxis(Vertical) TimedeltaTime

pomakni kameru u smjeru kursora misa za udaljenost

povecavanja u koordinatnom sustavu svijeta

kameratransformTranslate(zrakadirection

udaljenostPovecavanja SpaceWorld)

18

5 Kretanje

Pronalazak puta je zapravo pokušaj aplikacije na racunalu ili algoritma da nade naj-

kracu rutu izmedu dvije tocke To je recimo prakticna verzija rješavanja labirinta Ni

danas ne postoji optimalan algoritam koji ce u svakom slucaju u nekom realno krat-

kom vremenu naci najkraci put U ovom poglavlju objasnit ce se koje algoritme Unity

koristi za svoj navigacijski sustav Objašnjavat ce se i neki osnovni koncepti i obrasci

potrebni za ubrzavanje cijele ideje dojavljivanja promjena u sceni Bit ce prikazani i

programski kodovi potrebni za implementiranje kretanja mišem iili tipkovnicom Na

kraju ovog poglavlja želi se imati lika koji ce se slobodno kretati po sceni na mjesto

koje se odredi klikom miša i mogucnost prebacivanja na upravljanje tipkovnicom

51 Navigacijski sustav u Unityu

U Unityu je problem pronalaska puta vec riješen s necim što se zove navigacijska

mreža (engl NavMesh) To je navigacijski sustav koji ima svoje algoritme pronala-

ska puta i puno pojednostavljuje programiranje kretanja lika Sastoji se od cetiri di-

jela NavMesh agent navigacijske mreže (engl NavMesh Agent) izvanmrežna pove-

zanost(engl Off - Mesh Link) i prepreka navigacijske mreže(engl NavMesh Obstacle)

NavMesh je podatkovna struktura koja opisuje površine po kojima se može kretati

u igri i omogucava pronalazak put od jedne lokacije do druge Navigacijski sustav

treba svoje podatke kako bi predstavio prohodna podrucja u sceni Prohodna podru-

cja definiraju se kao mjesta gdje agent može stajati i kretati se Prohodno podrucje se

automatski izgraduje iz geometrije u sceni testirajuci sva podrucja gdje bi agent mo-

gao stajati Onda se te lokacije spajaju s površinom na vrhu geometrije Ta površina se

naziva onda NavMesh te je možemo vidjeti na 51 NavMesh tada sprema tu površinu

kao konveksne poligone te informacije koji su poligoni susjedni Komponenta Nav-

Mesh Agent pomaže pri kreiranju likova koji se medusobno izbjegavaju dok se krecu

prema cilju U Unityu se agenti opisuju kao valjci Koriste NavMesh kako bi se kretali

i znali koje objekte moraju zaobici te kako da se medusobno zaobidu Off-Mesh Link

19

omogucava dodavanje navigacijskih precaca koji se ne mogu predstaviti kao površina

po kojoj se može hodati npr skakanje preko ograde ili otvaranje vrata prije nego što

se ude u neku prostoriju NavMesh Obstacle opisuje prepreke koje se krecu te koje bi

agenti trebali izbjegavati dok hodaju svijetom npr neke bacve koje se kotrljaju prema

igracu Dok se bacva krece agent ce izracunati put oko nje najbolje što može no nakon

što ona naposljetku stane postat ce dio neprohodnog NavMesha te ce se agenti kretati

oko nje [3]

Slika 51 Prikaz navigacijskog sustava u Unityu

52 Pronalazak puta

Dva glavna problema postoje kod pronalaženja puta kako pronaci destinaciju na ni-

vou na kojem se igrac nalazi te kako se onda tamo pomaknuti Pronalaženje destinacije

uzima u obzir cijelu scenu Pomicanje tamo je dinamicnije u obzir uzima samo smjer

kretanja i kako da sprijeci sudaranje s drugim agentima Da bi se pronašao put izmedu

dvije lokacije prvo se moraju oznaciti pocetna i konacna lokacija njihovim najbližim

poligonima Tada se krece tražiti od pocetne lokacije posjecujuci sve susjedne dok se

ne dode do zadane destinacije Onda se prati unatrag vec posjecene poligone kako bi

se našao konacan niz poligona koji vode od pocetka do kraja Algoritam koji Unity

koristi te se cesto koristi za pronalazak puta naziva se A (A zvjezdica) Taj niz po-

ligona koji opisuje put od pocetka do kraja se naziva hodnik Agent ce doci do svoje

20

destinacije tako da se uvijek usmjerava prema sljedecem vidljivom kutu hodnika Ta

logika usmjeravanja uvijek uzima poziciju sljedeceg kuta i ovisno o tome nade željeni

smjer i brzinu potrebnu za dolazak na destinaciju Korištenje brzine po želji progra-

mera bi moglo dovesti do sudara s ostalim agentima Izbjegavanje prepreka takoder

pronalazi svoju novu brzinu koja traži ravnotežu izmedu kretanja prema destinaciji i

sprjecavanja buducih sudara s ostalim agentima i kutevima u navigacijskom sustavu

Nakon usmjeravanja i izbjegavanja prepreka izracuna se konacna brzina Unity ta-

koder uzima u obzir i akceleraciju kako bi simulirao realisticnije kretanje Takoder

treba razumjeti razliku izmedu globalne i lokalne navigacije Globalna navigacija se

koristi za pronalazak hodnika u svijetu Linearna lista poligona koja opisuje taj put je

podatkovna struktura koja se koristi za usmjeravanje te se može lokalno prilagodavati

i mijenjati kako se pozicija agenta mijenja Lokalna navigacija pokušava naci efika-

san nacin kako da se igrac pomakne prema sljedecem kutu bez da se sudari s ostalim

agentima ili objektima koji se krecu [3]

53 Kreiranje navigacijskog sustava

Proces kreiranja NavMesha iz geometrije nivoa se naziva pecenje navigacijske mreže

(engl NavMesh Baking) Skuplja sve terene i mreže objekata koji su oznaceni kao

navigacijski staticko (engl Navigation Static) i onda ih procesira kako bi kreirao navi-

gacijski sustav koji aproksimira prohodne površine nivoa Izgradnja (engl NavMesha)

je vrlo jednostavna Prvo se selektira geometrija koja bi trebala utjecati na navigaciju

tj površine po kojima možemo hodati i prepreke Oznaci se Navigation Static da bi ih

ukljucili u NavMesh Baking proces Prilagode se postavke kako bi odgovarale velicini

agenta - radijus (npr koliko blizu se može doci zidovima) visina (koliko su nisko

prostori koje agent može doseci) maksimalni nagib (koliko su kose rampe po kojima

se agent može uspeti) visina stube(koliko su visoke prepreke na koje agent može za-

koraciti) Onda jednostavno stisnemo ispeci (engl Bake) da izgradimo svoj NavMesh

Izgradeni NavMesh cemo moci vidjeti kao plavu površinu kao na slici 51 te ce se stvo-

riti nova datoteka s nazivom trenutne scene (ako vec ne postoji) i unutra ce se spremiti

kreiran navigacijski sustav [3]

21

54 Programiranje kretanja

Na liku se trenutno nalazi par stvari Animator Capsule Collider i Rigid Body Sada

je cilj isprogramirati mogucnost odredivanja gdje ce se lik kretati klikom miša na to

mjesto Dodaje se nova komponenta na lika NavMesh Agent Ta komponenta za-

pravo vec ima svoj sudarac te se slobodno može obrisati Capsule Collider jer postaje

nepotreban Igranjem s opcijama pomak od baze (engl Base Offset) te pod izbjegava-

nje prepreka (engl Obstacle Avoidance) radijus (engl Radius) i visina (engl Height)

prilagodi se sudarac od (engl NavMesh Agent-a) kako bi se obujmilo njime igraca i

sprijecilo propadanje kroz tlo od prije Sada kada postoji komponenta navigacije mora

se dodati skripta koja ce odrediti kada se lik krece te kada se pokrecu njegove anima-

cije iz Animator-a

Da bi se znalo gdje se miš nalazi mora se takoder dodati nova skriptu na kameru Kako

bi se izracunalo gdje trenutno kursor pokazuje Unity koristi vec prethodno spomenuto

bacanje zraka Da bi se moglo koristiti navigaciju putem klika mišem mora se napisati

skripta za glavnu kameru koja ce omoguciti bacanje zraka Skripta BacanjeZraka

dodaje se na objekt Main Camera koja se dodala pod prazni objekt Kamera Ova

skriptu se takoder koristi za razlikovanje raznih vrsta objekata Naime svaki objekt

kao što ima i Tag ima i sloj (engl Layer) Sloj služi kako bi mogli npr razlikovati

neprijatelje od obicnih objekata ili mjesto na koje želimo doci hodanjem Zato cemo

takoder dodati i jednu enumeraciju koja ce nam zasad služiti samo da razlikujemo je li

mjesto prohodno ili ne te jesmo li kliknuli na neprijatelja Kako bi dodali svoje nove

slojeve za objekte moramo kliknuti na Layer i dodaj sloj (engl Add Layer) kao na slici

52 što nas dovodi do novog prozora prikazanog na slici 53

Programski kod 51 bacanjeZrakacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

sluzi za dodavanje novih slojeva u Unity

public enum Sloj

Prohodno = 8

Neprijatelj = 9

KrajSvijeta = -1

22

Slika 52 Dodavanje novog sloja

public class BacanjeZraka MonoBehaviour

hijerarhija slojeva tj koji ima veci prioritet

public Sloj[] prioritetiSlojeva =

SlojNeprijatelj

SlojProhodno

SlojKrajSvijeta

udaljenost do pozadine je neka izmisljena vrijednost nakon

koje se prestane provjeravati zraka

public float udaljenostDoPozadine = 100f

Camera kamera

RaycastHit _udara

dohvaca varijable ove klase

public RaycastHit udara

get return _udara

Sloj _udaraSloj

23

Slika 53 Prozor za dodavanje novog sloja

public Sloj udaraSloj

get return _udaraSloj

deklariraj novi tip delegata

public delegate void priPromjeniSloja(Sloj noviSloj)

instanciraj skup promatraca

public event priPromjeniSloja promatraciPromjeneSloja

void Start ()

dohvat glavne kamere

kamera = Cameramain

void Update ()

nadi sloj po prioritetu u koji zraka udara

foreach(Sloj sloj in prioritetiSlojeva)

provjeravamo udara li zraka u neki od slojeva

24

var udar = BacanjeZrakaZaSloj(sloj)

if(udarHasValue)

_udara = udarValue

ako se sloj promjenio

if(_udaraSloj = sloj)

spremi novi sloj u varijablu trenutnog sloja

_udaraSloj = sloj

obavijesti promatrace da se sloj promjenio

promatraciPromjeneSloja(sloj)

spremi novi sloj u varijablu trenutnog sloja

ali ne moras obavjestavati promatrace jer je

sloj jednak starom sloju

_udaraSloj = sloj

return

inace vrati da zraka udara u pozadinu i obavijesti

promatrace

_udaradistance = udaljenostDoPozadine

_udaraSloj = SlojKrajSvijeta

promatraciPromjeneSloja(udaraSloj)

RaycastHit BacanjeZrakaZaSloj(Sloj sloj)

kreira se maska za slojeve bit se pomice ulijevo za

onoliko mjesta koliki je redni broj prioriteta sloja

int maska = 1 ltlt (int)sloj

sprema se mjesto pozicije kursora pretvoreno iz tocke u

zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

RaycastHit udar

PhysicsRaycast sprema zraku u varijablu tipa

RaycastHit prima jos i maksimalnu udaljenost za koju

provjerava zraku i masku sloja i potom vraca istinu (

engl True) ili laz (engl False) ako je zraka udarila

u sloj

25

bool udarioJe = PhysicsRaycast(zraka out udar

udaljenostDoPozadine maska)

ako zraka udara u sloj vrati vrijednost udarca

if(udarioJe)

return udar

return null

U programskom kodu 51 se koristi funkcija za primjenu obrasca promatraca pod

nazivom delegat (engl Delegate) Što je obrazac promatraca (engl Observer) To je

oblikovni obrazac koji se u programiranju koristi

bull kad promjena jednog objekta zahtijeva promjene u drugim objektima koji nisu

unaprijed poznati

bull kad objekt treba obavještavati druge objekte

bull uz uvjet da bude što neovisniji o njima

bull kad je potrebno prikazivati razlicite aspekte nekog dinamickog stanja a želimo

izbjeci ciklicku ovisnost izmedu stanja i pogleda

bull kad postoje dva koncepta jedan ovisan o drugome a zgodno ih je razdvojiti

S obzirom na to da mi samo pri promjeni sloja želimo obavještavati pretplacene pro-

matrace uvodenje delegata nam dosta ubrzava kod Obrazac promatraca funkcionira

tako da glavni objekt igra ulogu izdavaca (izvora informacija) u ovom slucaju to je

glavna kamera Ostali ovisni objekti (promatraci) pretplacuju se kod izdavaca te iz-

davaci obavještavaju pretplatnike o promjenama Promatraci prekidaju pretplatu kad

više ne trebaju obavještavanje Funkcija priPromjeniSloja se definira kao delegat i u

ovom slucaju prima sloj Nakon toga se definira dogadaj (engl Event) tipa tog delegata

(priPromjeniSloja) u ovom slucaju naziva promatraciPromjeneSloja i odsad se unutar

subjekta tim nazivom i poziva Kako bi se neki promatrac pretplatio na informacije

koje izdaje kamera dodaje ove dvije linije koda u svoju skriptu

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

Programski kod 52 služi za kretanje korištenjem NavMesha i lijevog klika miša

26

Programski kod 52 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

public float dovoljnoBlizu = 01f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora

[SerializeField] float hodajKreciStaniRadijus = 02f

void Start ()

pronadi igraca koji je tipa agenta navigacijskog sustava

(engl NavMeshAgent)

agent = GetComponentltUnityEngineAINavMeshAgentgt()

pronadi prethodno napisanu klasu BacanjeZraka

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

spremi trenutnu poziciju kursora

trenutnaPozicijaKursora = transformposition

void Update()

ako je igrac dosao na zeljeno mjesto zaustavi animaciju

hodanja

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

ako je stisnut lijevi klik misa

if (InputGetMouseButtonDown(0))

ovisno o sloju primjeni akciju

switch(bacanjeZrakaudaraSloj)

ako se po objektu na koji je igrac kliknuo moze

hodati

27

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 21: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

Slika 43 Oznacavanje lika radi lakšeg pronalaska u skripti

void LateUpdate ()

trenutni objekt mijenja svoju poziciju u skladu s

pozicijom objekta oznacenog oznakom Player

transformposition = igractransformposition

44 Bacanje zraka (engl Ray casting)

Perspektivna kamera u Unityu koristi oblik krnje piramide za dio koji prikazuje u pros-

toru Svaka tocka nekog objekta kojeg kamera prikazuje zapravo odgovara liniji u pros-

toru svijeta te je nama samo jedna tocka duž te linije vidljiva na objektu Sve iza te

tocke na liniji je zamraceno Vanjski rubovi objekta su definirani razilazecim linijama

16

koje odgovaraju kutevima objekta Kada bi se te linije pratile unazad prema kameri

sve bi na kraju konvergirale u jednu tocku U Unityu se ta tocka nalazi tocno na pozi-

ciji kamere i naziva se centrom perspektive Kut naspram linija koje konvergiraju od

gornjeg i donjeg centra ekrana u centru perspektive se zove vidno polje (engl Field Of

View) Sve što pada izvan tih razilazecih linija na rubovima objekta nece biti vidljivo

kameri uz vec prethodno spomenuta ogranicenja ravnina podrezivanja

U igrama je jako korisno imati matematicku reprezentaciju linije koja predstavlja tocku

u pogledu kamere Unity to omogucava u obliku objekta zrake Zraka uvijek odgo-

vara tocki u pogledu pa klasa Kamera (engl Camera) sadrži dvije korisne funkcije

ScreenPointToRay i ViewportPointToRay Razlika izmedu njih je da ScreenPointToRay

ocekuje tocku s koordinatama piksela dok ViewportPointToRay uzima normalizirane

koordinate (od 0 dolje ili lijevo do 1 gore ili desno) Obje funkcije vracaju zraku

koja se sastoji od tocke ishodišta i vektora koji pokazuje smjer linije od tog ishodišta

Zraka izlazi iz ravnine podrezivanja bliže kameri Najcešce se zrake koriste kako bi ih

bacali u scenu Bacanje zraka pošalje imaginarnu liniju uz zraku od njenog ishodišta

dok ne udari u neki sudarac u sceni Tada vraca informaciju o tocki koju je udarila

u objektu RaycastHit To je vrlo korisno kako bi se locirao objekt ovisno o njegovoj

poziciji na zaslonu npr lociranje kursora prikazano programskim kodom 43

Programski kod 43 lociranjeKursoracs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kamera

void Start()

RaycastHit udar

u objekt Ray se sprema pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

ako zraka udara u neki objekt spremi u objektUdaren to

mjesto

if (PhysicsRaycast(zraka out udar))

Transform objektUdaren = udartransform

17

Ponekad je takoder korisno dobiti zraku koja odgovara poziciji na zaslonu te onda

pomicati kameru uz tu zraku Npr želi se dozvoliti igracu da može selektirati objekt

mišem i onda ga povecati dok se objekt nalazi cijelo vrijeme na istoj poziciji na zaslonu

ispod miša prikazano programskim kodom 44 [1]

Programski kod 44 povecavanjeSlikecs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public bool povecavanje

public float brzinaPovecavanja

public Camera kamera

void Update()

ako netko koristi povecavanje slike (engl Zooming)

if (povecavanje)

u objekt Ray sprema se pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(Input

mousePosition)

udaljenost povecavanja ce biti jednaka umnosku

brzine povecavanja vremena i vertikalnog smjera

float udaljenostPovecavanja = brzinaPovecavanja

InputGetAxis(Vertical) TimedeltaTime

pomakni kameru u smjeru kursora misa za udaljenost

povecavanja u koordinatnom sustavu svijeta

kameratransformTranslate(zrakadirection

udaljenostPovecavanja SpaceWorld)

18

5 Kretanje

Pronalazak puta je zapravo pokušaj aplikacije na racunalu ili algoritma da nade naj-

kracu rutu izmedu dvije tocke To je recimo prakticna verzija rješavanja labirinta Ni

danas ne postoji optimalan algoritam koji ce u svakom slucaju u nekom realno krat-

kom vremenu naci najkraci put U ovom poglavlju objasnit ce se koje algoritme Unity

koristi za svoj navigacijski sustav Objašnjavat ce se i neki osnovni koncepti i obrasci

potrebni za ubrzavanje cijele ideje dojavljivanja promjena u sceni Bit ce prikazani i

programski kodovi potrebni za implementiranje kretanja mišem iili tipkovnicom Na

kraju ovog poglavlja želi se imati lika koji ce se slobodno kretati po sceni na mjesto

koje se odredi klikom miša i mogucnost prebacivanja na upravljanje tipkovnicom

51 Navigacijski sustav u Unityu

U Unityu je problem pronalaska puta vec riješen s necim što se zove navigacijska

mreža (engl NavMesh) To je navigacijski sustav koji ima svoje algoritme pronala-

ska puta i puno pojednostavljuje programiranje kretanja lika Sastoji se od cetiri di-

jela NavMesh agent navigacijske mreže (engl NavMesh Agent) izvanmrežna pove-

zanost(engl Off - Mesh Link) i prepreka navigacijske mreže(engl NavMesh Obstacle)

NavMesh je podatkovna struktura koja opisuje površine po kojima se može kretati

u igri i omogucava pronalazak put od jedne lokacije do druge Navigacijski sustav

treba svoje podatke kako bi predstavio prohodna podrucja u sceni Prohodna podru-

cja definiraju se kao mjesta gdje agent može stajati i kretati se Prohodno podrucje se

automatski izgraduje iz geometrije u sceni testirajuci sva podrucja gdje bi agent mo-

gao stajati Onda se te lokacije spajaju s površinom na vrhu geometrije Ta površina se

naziva onda NavMesh te je možemo vidjeti na 51 NavMesh tada sprema tu površinu

kao konveksne poligone te informacije koji su poligoni susjedni Komponenta Nav-

Mesh Agent pomaže pri kreiranju likova koji se medusobno izbjegavaju dok se krecu

prema cilju U Unityu se agenti opisuju kao valjci Koriste NavMesh kako bi se kretali

i znali koje objekte moraju zaobici te kako da se medusobno zaobidu Off-Mesh Link

19

omogucava dodavanje navigacijskih precaca koji se ne mogu predstaviti kao površina

po kojoj se može hodati npr skakanje preko ograde ili otvaranje vrata prije nego što

se ude u neku prostoriju NavMesh Obstacle opisuje prepreke koje se krecu te koje bi

agenti trebali izbjegavati dok hodaju svijetom npr neke bacve koje se kotrljaju prema

igracu Dok se bacva krece agent ce izracunati put oko nje najbolje što može no nakon

što ona naposljetku stane postat ce dio neprohodnog NavMesha te ce se agenti kretati

oko nje [3]

Slika 51 Prikaz navigacijskog sustava u Unityu

52 Pronalazak puta

Dva glavna problema postoje kod pronalaženja puta kako pronaci destinaciju na ni-

vou na kojem se igrac nalazi te kako se onda tamo pomaknuti Pronalaženje destinacije

uzima u obzir cijelu scenu Pomicanje tamo je dinamicnije u obzir uzima samo smjer

kretanja i kako da sprijeci sudaranje s drugim agentima Da bi se pronašao put izmedu

dvije lokacije prvo se moraju oznaciti pocetna i konacna lokacija njihovim najbližim

poligonima Tada se krece tražiti od pocetne lokacije posjecujuci sve susjedne dok se

ne dode do zadane destinacije Onda se prati unatrag vec posjecene poligone kako bi

se našao konacan niz poligona koji vode od pocetka do kraja Algoritam koji Unity

koristi te se cesto koristi za pronalazak puta naziva se A (A zvjezdica) Taj niz po-

ligona koji opisuje put od pocetka do kraja se naziva hodnik Agent ce doci do svoje

20

destinacije tako da se uvijek usmjerava prema sljedecem vidljivom kutu hodnika Ta

logika usmjeravanja uvijek uzima poziciju sljedeceg kuta i ovisno o tome nade željeni

smjer i brzinu potrebnu za dolazak na destinaciju Korištenje brzine po želji progra-

mera bi moglo dovesti do sudara s ostalim agentima Izbjegavanje prepreka takoder

pronalazi svoju novu brzinu koja traži ravnotežu izmedu kretanja prema destinaciji i

sprjecavanja buducih sudara s ostalim agentima i kutevima u navigacijskom sustavu

Nakon usmjeravanja i izbjegavanja prepreka izracuna se konacna brzina Unity ta-

koder uzima u obzir i akceleraciju kako bi simulirao realisticnije kretanje Takoder

treba razumjeti razliku izmedu globalne i lokalne navigacije Globalna navigacija se

koristi za pronalazak hodnika u svijetu Linearna lista poligona koja opisuje taj put je

podatkovna struktura koja se koristi za usmjeravanje te se može lokalno prilagodavati

i mijenjati kako se pozicija agenta mijenja Lokalna navigacija pokušava naci efika-

san nacin kako da se igrac pomakne prema sljedecem kutu bez da se sudari s ostalim

agentima ili objektima koji se krecu [3]

53 Kreiranje navigacijskog sustava

Proces kreiranja NavMesha iz geometrije nivoa se naziva pecenje navigacijske mreže

(engl NavMesh Baking) Skuplja sve terene i mreže objekata koji su oznaceni kao

navigacijski staticko (engl Navigation Static) i onda ih procesira kako bi kreirao navi-

gacijski sustav koji aproksimira prohodne površine nivoa Izgradnja (engl NavMesha)

je vrlo jednostavna Prvo se selektira geometrija koja bi trebala utjecati na navigaciju

tj površine po kojima možemo hodati i prepreke Oznaci se Navigation Static da bi ih

ukljucili u NavMesh Baking proces Prilagode se postavke kako bi odgovarale velicini

agenta - radijus (npr koliko blizu se može doci zidovima) visina (koliko su nisko

prostori koje agent može doseci) maksimalni nagib (koliko su kose rampe po kojima

se agent može uspeti) visina stube(koliko su visoke prepreke na koje agent može za-

koraciti) Onda jednostavno stisnemo ispeci (engl Bake) da izgradimo svoj NavMesh

Izgradeni NavMesh cemo moci vidjeti kao plavu površinu kao na slici 51 te ce se stvo-

riti nova datoteka s nazivom trenutne scene (ako vec ne postoji) i unutra ce se spremiti

kreiran navigacijski sustav [3]

21

54 Programiranje kretanja

Na liku se trenutno nalazi par stvari Animator Capsule Collider i Rigid Body Sada

je cilj isprogramirati mogucnost odredivanja gdje ce se lik kretati klikom miša na to

mjesto Dodaje se nova komponenta na lika NavMesh Agent Ta komponenta za-

pravo vec ima svoj sudarac te se slobodno može obrisati Capsule Collider jer postaje

nepotreban Igranjem s opcijama pomak od baze (engl Base Offset) te pod izbjegava-

nje prepreka (engl Obstacle Avoidance) radijus (engl Radius) i visina (engl Height)

prilagodi se sudarac od (engl NavMesh Agent-a) kako bi se obujmilo njime igraca i

sprijecilo propadanje kroz tlo od prije Sada kada postoji komponenta navigacije mora

se dodati skripta koja ce odrediti kada se lik krece te kada se pokrecu njegove anima-

cije iz Animator-a

Da bi se znalo gdje se miš nalazi mora se takoder dodati nova skriptu na kameru Kako

bi se izracunalo gdje trenutno kursor pokazuje Unity koristi vec prethodno spomenuto

bacanje zraka Da bi se moglo koristiti navigaciju putem klika mišem mora se napisati

skripta za glavnu kameru koja ce omoguciti bacanje zraka Skripta BacanjeZraka

dodaje se na objekt Main Camera koja se dodala pod prazni objekt Kamera Ova

skriptu se takoder koristi za razlikovanje raznih vrsta objekata Naime svaki objekt

kao što ima i Tag ima i sloj (engl Layer) Sloj služi kako bi mogli npr razlikovati

neprijatelje od obicnih objekata ili mjesto na koje želimo doci hodanjem Zato cemo

takoder dodati i jednu enumeraciju koja ce nam zasad služiti samo da razlikujemo je li

mjesto prohodno ili ne te jesmo li kliknuli na neprijatelja Kako bi dodali svoje nove

slojeve za objekte moramo kliknuti na Layer i dodaj sloj (engl Add Layer) kao na slici

52 što nas dovodi do novog prozora prikazanog na slici 53

Programski kod 51 bacanjeZrakacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

sluzi za dodavanje novih slojeva u Unity

public enum Sloj

Prohodno = 8

Neprijatelj = 9

KrajSvijeta = -1

22

Slika 52 Dodavanje novog sloja

public class BacanjeZraka MonoBehaviour

hijerarhija slojeva tj koji ima veci prioritet

public Sloj[] prioritetiSlojeva =

SlojNeprijatelj

SlojProhodno

SlojKrajSvijeta

udaljenost do pozadine je neka izmisljena vrijednost nakon

koje se prestane provjeravati zraka

public float udaljenostDoPozadine = 100f

Camera kamera

RaycastHit _udara

dohvaca varijable ove klase

public RaycastHit udara

get return _udara

Sloj _udaraSloj

23

Slika 53 Prozor za dodavanje novog sloja

public Sloj udaraSloj

get return _udaraSloj

deklariraj novi tip delegata

public delegate void priPromjeniSloja(Sloj noviSloj)

instanciraj skup promatraca

public event priPromjeniSloja promatraciPromjeneSloja

void Start ()

dohvat glavne kamere

kamera = Cameramain

void Update ()

nadi sloj po prioritetu u koji zraka udara

foreach(Sloj sloj in prioritetiSlojeva)

provjeravamo udara li zraka u neki od slojeva

24

var udar = BacanjeZrakaZaSloj(sloj)

if(udarHasValue)

_udara = udarValue

ako se sloj promjenio

if(_udaraSloj = sloj)

spremi novi sloj u varijablu trenutnog sloja

_udaraSloj = sloj

obavijesti promatrace da se sloj promjenio

promatraciPromjeneSloja(sloj)

spremi novi sloj u varijablu trenutnog sloja

ali ne moras obavjestavati promatrace jer je

sloj jednak starom sloju

_udaraSloj = sloj

return

inace vrati da zraka udara u pozadinu i obavijesti

promatrace

_udaradistance = udaljenostDoPozadine

_udaraSloj = SlojKrajSvijeta

promatraciPromjeneSloja(udaraSloj)

RaycastHit BacanjeZrakaZaSloj(Sloj sloj)

kreira se maska za slojeve bit se pomice ulijevo za

onoliko mjesta koliki je redni broj prioriteta sloja

int maska = 1 ltlt (int)sloj

sprema se mjesto pozicije kursora pretvoreno iz tocke u

zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

RaycastHit udar

PhysicsRaycast sprema zraku u varijablu tipa

RaycastHit prima jos i maksimalnu udaljenost za koju

provjerava zraku i masku sloja i potom vraca istinu (

engl True) ili laz (engl False) ako je zraka udarila

u sloj

25

bool udarioJe = PhysicsRaycast(zraka out udar

udaljenostDoPozadine maska)

ako zraka udara u sloj vrati vrijednost udarca

if(udarioJe)

return udar

return null

U programskom kodu 51 se koristi funkcija za primjenu obrasca promatraca pod

nazivom delegat (engl Delegate) Što je obrazac promatraca (engl Observer) To je

oblikovni obrazac koji se u programiranju koristi

bull kad promjena jednog objekta zahtijeva promjene u drugim objektima koji nisu

unaprijed poznati

bull kad objekt treba obavještavati druge objekte

bull uz uvjet da bude što neovisniji o njima

bull kad je potrebno prikazivati razlicite aspekte nekog dinamickog stanja a želimo

izbjeci ciklicku ovisnost izmedu stanja i pogleda

bull kad postoje dva koncepta jedan ovisan o drugome a zgodno ih je razdvojiti

S obzirom na to da mi samo pri promjeni sloja želimo obavještavati pretplacene pro-

matrace uvodenje delegata nam dosta ubrzava kod Obrazac promatraca funkcionira

tako da glavni objekt igra ulogu izdavaca (izvora informacija) u ovom slucaju to je

glavna kamera Ostali ovisni objekti (promatraci) pretplacuju se kod izdavaca te iz-

davaci obavještavaju pretplatnike o promjenama Promatraci prekidaju pretplatu kad

više ne trebaju obavještavanje Funkcija priPromjeniSloja se definira kao delegat i u

ovom slucaju prima sloj Nakon toga se definira dogadaj (engl Event) tipa tog delegata

(priPromjeniSloja) u ovom slucaju naziva promatraciPromjeneSloja i odsad se unutar

subjekta tim nazivom i poziva Kako bi se neki promatrac pretplatio na informacije

koje izdaje kamera dodaje ove dvije linije koda u svoju skriptu

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

Programski kod 52 služi za kretanje korištenjem NavMesha i lijevog klika miša

26

Programski kod 52 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

public float dovoljnoBlizu = 01f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora

[SerializeField] float hodajKreciStaniRadijus = 02f

void Start ()

pronadi igraca koji je tipa agenta navigacijskog sustava

(engl NavMeshAgent)

agent = GetComponentltUnityEngineAINavMeshAgentgt()

pronadi prethodno napisanu klasu BacanjeZraka

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

spremi trenutnu poziciju kursora

trenutnaPozicijaKursora = transformposition

void Update()

ako je igrac dosao na zeljeno mjesto zaustavi animaciju

hodanja

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

ako je stisnut lijevi klik misa

if (InputGetMouseButtonDown(0))

ovisno o sloju primjeni akciju

switch(bacanjeZrakaudaraSloj)

ako se po objektu na koji je igrac kliknuo moze

hodati

27

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 22: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

koje odgovaraju kutevima objekta Kada bi se te linije pratile unazad prema kameri

sve bi na kraju konvergirale u jednu tocku U Unityu se ta tocka nalazi tocno na pozi-

ciji kamere i naziva se centrom perspektive Kut naspram linija koje konvergiraju od

gornjeg i donjeg centra ekrana u centru perspektive se zove vidno polje (engl Field Of

View) Sve što pada izvan tih razilazecih linija na rubovima objekta nece biti vidljivo

kameri uz vec prethodno spomenuta ogranicenja ravnina podrezivanja

U igrama je jako korisno imati matematicku reprezentaciju linije koja predstavlja tocku

u pogledu kamere Unity to omogucava u obliku objekta zrake Zraka uvijek odgo-

vara tocki u pogledu pa klasa Kamera (engl Camera) sadrži dvije korisne funkcije

ScreenPointToRay i ViewportPointToRay Razlika izmedu njih je da ScreenPointToRay

ocekuje tocku s koordinatama piksela dok ViewportPointToRay uzima normalizirane

koordinate (od 0 dolje ili lijevo do 1 gore ili desno) Obje funkcije vracaju zraku

koja se sastoji od tocke ishodišta i vektora koji pokazuje smjer linije od tog ishodišta

Zraka izlazi iz ravnine podrezivanja bliže kameri Najcešce se zrake koriste kako bi ih

bacali u scenu Bacanje zraka pošalje imaginarnu liniju uz zraku od njenog ishodišta

dok ne udari u neki sudarac u sceni Tada vraca informaciju o tocki koju je udarila

u objektu RaycastHit To je vrlo korisno kako bi se locirao objekt ovisno o njegovoj

poziciji na zaslonu npr lociranje kursora prikazano programskim kodom 43

Programski kod 43 lociranjeKursoracs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public Camera kamera

void Start()

RaycastHit udar

u objekt Ray se sprema pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

ako zraka udara u neki objekt spremi u objektUdaren to

mjesto

if (PhysicsRaycast(zraka out udar))

Transform objektUdaren = udartransform

17

Ponekad je takoder korisno dobiti zraku koja odgovara poziciji na zaslonu te onda

pomicati kameru uz tu zraku Npr želi se dozvoliti igracu da može selektirati objekt

mišem i onda ga povecati dok se objekt nalazi cijelo vrijeme na istoj poziciji na zaslonu

ispod miša prikazano programskim kodom 44 [1]

Programski kod 44 povecavanjeSlikecs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public bool povecavanje

public float brzinaPovecavanja

public Camera kamera

void Update()

ako netko koristi povecavanje slike (engl Zooming)

if (povecavanje)

u objekt Ray sprema se pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(Input

mousePosition)

udaljenost povecavanja ce biti jednaka umnosku

brzine povecavanja vremena i vertikalnog smjera

float udaljenostPovecavanja = brzinaPovecavanja

InputGetAxis(Vertical) TimedeltaTime

pomakni kameru u smjeru kursora misa za udaljenost

povecavanja u koordinatnom sustavu svijeta

kameratransformTranslate(zrakadirection

udaljenostPovecavanja SpaceWorld)

18

5 Kretanje

Pronalazak puta je zapravo pokušaj aplikacije na racunalu ili algoritma da nade naj-

kracu rutu izmedu dvije tocke To je recimo prakticna verzija rješavanja labirinta Ni

danas ne postoji optimalan algoritam koji ce u svakom slucaju u nekom realno krat-

kom vremenu naci najkraci put U ovom poglavlju objasnit ce se koje algoritme Unity

koristi za svoj navigacijski sustav Objašnjavat ce se i neki osnovni koncepti i obrasci

potrebni za ubrzavanje cijele ideje dojavljivanja promjena u sceni Bit ce prikazani i

programski kodovi potrebni za implementiranje kretanja mišem iili tipkovnicom Na

kraju ovog poglavlja želi se imati lika koji ce se slobodno kretati po sceni na mjesto

koje se odredi klikom miša i mogucnost prebacivanja na upravljanje tipkovnicom

51 Navigacijski sustav u Unityu

U Unityu je problem pronalaska puta vec riješen s necim što se zove navigacijska

mreža (engl NavMesh) To je navigacijski sustav koji ima svoje algoritme pronala-

ska puta i puno pojednostavljuje programiranje kretanja lika Sastoji se od cetiri di-

jela NavMesh agent navigacijske mreže (engl NavMesh Agent) izvanmrežna pove-

zanost(engl Off - Mesh Link) i prepreka navigacijske mreže(engl NavMesh Obstacle)

NavMesh je podatkovna struktura koja opisuje površine po kojima se može kretati

u igri i omogucava pronalazak put od jedne lokacije do druge Navigacijski sustav

treba svoje podatke kako bi predstavio prohodna podrucja u sceni Prohodna podru-

cja definiraju se kao mjesta gdje agent može stajati i kretati se Prohodno podrucje se

automatski izgraduje iz geometrije u sceni testirajuci sva podrucja gdje bi agent mo-

gao stajati Onda se te lokacije spajaju s površinom na vrhu geometrije Ta površina se

naziva onda NavMesh te je možemo vidjeti na 51 NavMesh tada sprema tu površinu

kao konveksne poligone te informacije koji su poligoni susjedni Komponenta Nav-

Mesh Agent pomaže pri kreiranju likova koji se medusobno izbjegavaju dok se krecu

prema cilju U Unityu se agenti opisuju kao valjci Koriste NavMesh kako bi se kretali

i znali koje objekte moraju zaobici te kako da se medusobno zaobidu Off-Mesh Link

19

omogucava dodavanje navigacijskih precaca koji se ne mogu predstaviti kao površina

po kojoj se može hodati npr skakanje preko ograde ili otvaranje vrata prije nego što

se ude u neku prostoriju NavMesh Obstacle opisuje prepreke koje se krecu te koje bi

agenti trebali izbjegavati dok hodaju svijetom npr neke bacve koje se kotrljaju prema

igracu Dok se bacva krece agent ce izracunati put oko nje najbolje što može no nakon

što ona naposljetku stane postat ce dio neprohodnog NavMesha te ce se agenti kretati

oko nje [3]

Slika 51 Prikaz navigacijskog sustava u Unityu

52 Pronalazak puta

Dva glavna problema postoje kod pronalaženja puta kako pronaci destinaciju na ni-

vou na kojem se igrac nalazi te kako se onda tamo pomaknuti Pronalaženje destinacije

uzima u obzir cijelu scenu Pomicanje tamo je dinamicnije u obzir uzima samo smjer

kretanja i kako da sprijeci sudaranje s drugim agentima Da bi se pronašao put izmedu

dvije lokacije prvo se moraju oznaciti pocetna i konacna lokacija njihovim najbližim

poligonima Tada se krece tražiti od pocetne lokacije posjecujuci sve susjedne dok se

ne dode do zadane destinacije Onda se prati unatrag vec posjecene poligone kako bi

se našao konacan niz poligona koji vode od pocetka do kraja Algoritam koji Unity

koristi te se cesto koristi za pronalazak puta naziva se A (A zvjezdica) Taj niz po-

ligona koji opisuje put od pocetka do kraja se naziva hodnik Agent ce doci do svoje

20

destinacije tako da se uvijek usmjerava prema sljedecem vidljivom kutu hodnika Ta

logika usmjeravanja uvijek uzima poziciju sljedeceg kuta i ovisno o tome nade željeni

smjer i brzinu potrebnu za dolazak na destinaciju Korištenje brzine po želji progra-

mera bi moglo dovesti do sudara s ostalim agentima Izbjegavanje prepreka takoder

pronalazi svoju novu brzinu koja traži ravnotežu izmedu kretanja prema destinaciji i

sprjecavanja buducih sudara s ostalim agentima i kutevima u navigacijskom sustavu

Nakon usmjeravanja i izbjegavanja prepreka izracuna se konacna brzina Unity ta-

koder uzima u obzir i akceleraciju kako bi simulirao realisticnije kretanje Takoder

treba razumjeti razliku izmedu globalne i lokalne navigacije Globalna navigacija se

koristi za pronalazak hodnika u svijetu Linearna lista poligona koja opisuje taj put je

podatkovna struktura koja se koristi za usmjeravanje te se može lokalno prilagodavati

i mijenjati kako se pozicija agenta mijenja Lokalna navigacija pokušava naci efika-

san nacin kako da se igrac pomakne prema sljedecem kutu bez da se sudari s ostalim

agentima ili objektima koji se krecu [3]

53 Kreiranje navigacijskog sustava

Proces kreiranja NavMesha iz geometrije nivoa se naziva pecenje navigacijske mreže

(engl NavMesh Baking) Skuplja sve terene i mreže objekata koji su oznaceni kao

navigacijski staticko (engl Navigation Static) i onda ih procesira kako bi kreirao navi-

gacijski sustav koji aproksimira prohodne površine nivoa Izgradnja (engl NavMesha)

je vrlo jednostavna Prvo se selektira geometrija koja bi trebala utjecati na navigaciju

tj površine po kojima možemo hodati i prepreke Oznaci se Navigation Static da bi ih

ukljucili u NavMesh Baking proces Prilagode se postavke kako bi odgovarale velicini

agenta - radijus (npr koliko blizu se može doci zidovima) visina (koliko su nisko

prostori koje agent može doseci) maksimalni nagib (koliko su kose rampe po kojima

se agent može uspeti) visina stube(koliko su visoke prepreke na koje agent može za-

koraciti) Onda jednostavno stisnemo ispeci (engl Bake) da izgradimo svoj NavMesh

Izgradeni NavMesh cemo moci vidjeti kao plavu površinu kao na slici 51 te ce se stvo-

riti nova datoteka s nazivom trenutne scene (ako vec ne postoji) i unutra ce se spremiti

kreiran navigacijski sustav [3]

21

54 Programiranje kretanja

Na liku se trenutno nalazi par stvari Animator Capsule Collider i Rigid Body Sada

je cilj isprogramirati mogucnost odredivanja gdje ce se lik kretati klikom miša na to

mjesto Dodaje se nova komponenta na lika NavMesh Agent Ta komponenta za-

pravo vec ima svoj sudarac te se slobodno može obrisati Capsule Collider jer postaje

nepotreban Igranjem s opcijama pomak od baze (engl Base Offset) te pod izbjegava-

nje prepreka (engl Obstacle Avoidance) radijus (engl Radius) i visina (engl Height)

prilagodi se sudarac od (engl NavMesh Agent-a) kako bi se obujmilo njime igraca i

sprijecilo propadanje kroz tlo od prije Sada kada postoji komponenta navigacije mora

se dodati skripta koja ce odrediti kada se lik krece te kada se pokrecu njegove anima-

cije iz Animator-a

Da bi se znalo gdje se miš nalazi mora se takoder dodati nova skriptu na kameru Kako

bi se izracunalo gdje trenutno kursor pokazuje Unity koristi vec prethodno spomenuto

bacanje zraka Da bi se moglo koristiti navigaciju putem klika mišem mora se napisati

skripta za glavnu kameru koja ce omoguciti bacanje zraka Skripta BacanjeZraka

dodaje se na objekt Main Camera koja se dodala pod prazni objekt Kamera Ova

skriptu se takoder koristi za razlikovanje raznih vrsta objekata Naime svaki objekt

kao što ima i Tag ima i sloj (engl Layer) Sloj služi kako bi mogli npr razlikovati

neprijatelje od obicnih objekata ili mjesto na koje želimo doci hodanjem Zato cemo

takoder dodati i jednu enumeraciju koja ce nam zasad služiti samo da razlikujemo je li

mjesto prohodno ili ne te jesmo li kliknuli na neprijatelja Kako bi dodali svoje nove

slojeve za objekte moramo kliknuti na Layer i dodaj sloj (engl Add Layer) kao na slici

52 što nas dovodi do novog prozora prikazanog na slici 53

Programski kod 51 bacanjeZrakacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

sluzi za dodavanje novih slojeva u Unity

public enum Sloj

Prohodno = 8

Neprijatelj = 9

KrajSvijeta = -1

22

Slika 52 Dodavanje novog sloja

public class BacanjeZraka MonoBehaviour

hijerarhija slojeva tj koji ima veci prioritet

public Sloj[] prioritetiSlojeva =

SlojNeprijatelj

SlojProhodno

SlojKrajSvijeta

udaljenost do pozadine je neka izmisljena vrijednost nakon

koje se prestane provjeravati zraka

public float udaljenostDoPozadine = 100f

Camera kamera

RaycastHit _udara

dohvaca varijable ove klase

public RaycastHit udara

get return _udara

Sloj _udaraSloj

23

Slika 53 Prozor za dodavanje novog sloja

public Sloj udaraSloj

get return _udaraSloj

deklariraj novi tip delegata

public delegate void priPromjeniSloja(Sloj noviSloj)

instanciraj skup promatraca

public event priPromjeniSloja promatraciPromjeneSloja

void Start ()

dohvat glavne kamere

kamera = Cameramain

void Update ()

nadi sloj po prioritetu u koji zraka udara

foreach(Sloj sloj in prioritetiSlojeva)

provjeravamo udara li zraka u neki od slojeva

24

var udar = BacanjeZrakaZaSloj(sloj)

if(udarHasValue)

_udara = udarValue

ako se sloj promjenio

if(_udaraSloj = sloj)

spremi novi sloj u varijablu trenutnog sloja

_udaraSloj = sloj

obavijesti promatrace da se sloj promjenio

promatraciPromjeneSloja(sloj)

spremi novi sloj u varijablu trenutnog sloja

ali ne moras obavjestavati promatrace jer je

sloj jednak starom sloju

_udaraSloj = sloj

return

inace vrati da zraka udara u pozadinu i obavijesti

promatrace

_udaradistance = udaljenostDoPozadine

_udaraSloj = SlojKrajSvijeta

promatraciPromjeneSloja(udaraSloj)

RaycastHit BacanjeZrakaZaSloj(Sloj sloj)

kreira se maska za slojeve bit se pomice ulijevo za

onoliko mjesta koliki je redni broj prioriteta sloja

int maska = 1 ltlt (int)sloj

sprema se mjesto pozicije kursora pretvoreno iz tocke u

zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

RaycastHit udar

PhysicsRaycast sprema zraku u varijablu tipa

RaycastHit prima jos i maksimalnu udaljenost za koju

provjerava zraku i masku sloja i potom vraca istinu (

engl True) ili laz (engl False) ako je zraka udarila

u sloj

25

bool udarioJe = PhysicsRaycast(zraka out udar

udaljenostDoPozadine maska)

ako zraka udara u sloj vrati vrijednost udarca

if(udarioJe)

return udar

return null

U programskom kodu 51 se koristi funkcija za primjenu obrasca promatraca pod

nazivom delegat (engl Delegate) Što je obrazac promatraca (engl Observer) To je

oblikovni obrazac koji se u programiranju koristi

bull kad promjena jednog objekta zahtijeva promjene u drugim objektima koji nisu

unaprijed poznati

bull kad objekt treba obavještavati druge objekte

bull uz uvjet da bude što neovisniji o njima

bull kad je potrebno prikazivati razlicite aspekte nekog dinamickog stanja a želimo

izbjeci ciklicku ovisnost izmedu stanja i pogleda

bull kad postoje dva koncepta jedan ovisan o drugome a zgodno ih je razdvojiti

S obzirom na to da mi samo pri promjeni sloja želimo obavještavati pretplacene pro-

matrace uvodenje delegata nam dosta ubrzava kod Obrazac promatraca funkcionira

tako da glavni objekt igra ulogu izdavaca (izvora informacija) u ovom slucaju to je

glavna kamera Ostali ovisni objekti (promatraci) pretplacuju se kod izdavaca te iz-

davaci obavještavaju pretplatnike o promjenama Promatraci prekidaju pretplatu kad

više ne trebaju obavještavanje Funkcija priPromjeniSloja se definira kao delegat i u

ovom slucaju prima sloj Nakon toga se definira dogadaj (engl Event) tipa tog delegata

(priPromjeniSloja) u ovom slucaju naziva promatraciPromjeneSloja i odsad se unutar

subjekta tim nazivom i poziva Kako bi se neki promatrac pretplatio na informacije

koje izdaje kamera dodaje ove dvije linije koda u svoju skriptu

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

Programski kod 52 služi za kretanje korištenjem NavMesha i lijevog klika miša

26

Programski kod 52 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

public float dovoljnoBlizu = 01f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora

[SerializeField] float hodajKreciStaniRadijus = 02f

void Start ()

pronadi igraca koji je tipa agenta navigacijskog sustava

(engl NavMeshAgent)

agent = GetComponentltUnityEngineAINavMeshAgentgt()

pronadi prethodno napisanu klasu BacanjeZraka

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

spremi trenutnu poziciju kursora

trenutnaPozicijaKursora = transformposition

void Update()

ako je igrac dosao na zeljeno mjesto zaustavi animaciju

hodanja

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

ako je stisnut lijevi klik misa

if (InputGetMouseButtonDown(0))

ovisno o sloju primjeni akciju

switch(bacanjeZrakaudaraSloj)

ako se po objektu na koji je igrac kliknuo moze

hodati

27

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 23: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

Ponekad je takoder korisno dobiti zraku koja odgovara poziciji na zaslonu te onda

pomicati kameru uz tu zraku Npr želi se dozvoliti igracu da može selektirati objekt

mišem i onda ga povecati dok se objekt nalazi cijelo vrijeme na istoj poziciji na zaslonu

ispod miša prikazano programskim kodom 44 [1]

Programski kod 44 povecavanjeSlikecs

using UnityEngine

using SystemCollections

public class Primjer MonoBehaviour

public bool povecavanje

public float brzinaPovecavanja

public Camera kamera

void Update()

ako netko koristi povecavanje slike (engl Zooming)

if (povecavanje)

u objekt Ray sprema se pozicija misa na ekranu

pretvorena u zraku

Ray zraka = kameraScreenPointToRay(Input

mousePosition)

udaljenost povecavanja ce biti jednaka umnosku

brzine povecavanja vremena i vertikalnog smjera

float udaljenostPovecavanja = brzinaPovecavanja

InputGetAxis(Vertical) TimedeltaTime

pomakni kameru u smjeru kursora misa za udaljenost

povecavanja u koordinatnom sustavu svijeta

kameratransformTranslate(zrakadirection

udaljenostPovecavanja SpaceWorld)

18

5 Kretanje

Pronalazak puta je zapravo pokušaj aplikacije na racunalu ili algoritma da nade naj-

kracu rutu izmedu dvije tocke To je recimo prakticna verzija rješavanja labirinta Ni

danas ne postoji optimalan algoritam koji ce u svakom slucaju u nekom realno krat-

kom vremenu naci najkraci put U ovom poglavlju objasnit ce se koje algoritme Unity

koristi za svoj navigacijski sustav Objašnjavat ce se i neki osnovni koncepti i obrasci

potrebni za ubrzavanje cijele ideje dojavljivanja promjena u sceni Bit ce prikazani i

programski kodovi potrebni za implementiranje kretanja mišem iili tipkovnicom Na

kraju ovog poglavlja želi se imati lika koji ce se slobodno kretati po sceni na mjesto

koje se odredi klikom miša i mogucnost prebacivanja na upravljanje tipkovnicom

51 Navigacijski sustav u Unityu

U Unityu je problem pronalaska puta vec riješen s necim što se zove navigacijska

mreža (engl NavMesh) To je navigacijski sustav koji ima svoje algoritme pronala-

ska puta i puno pojednostavljuje programiranje kretanja lika Sastoji se od cetiri di-

jela NavMesh agent navigacijske mreže (engl NavMesh Agent) izvanmrežna pove-

zanost(engl Off - Mesh Link) i prepreka navigacijske mreže(engl NavMesh Obstacle)

NavMesh je podatkovna struktura koja opisuje površine po kojima se može kretati

u igri i omogucava pronalazak put od jedne lokacije do druge Navigacijski sustav

treba svoje podatke kako bi predstavio prohodna podrucja u sceni Prohodna podru-

cja definiraju se kao mjesta gdje agent može stajati i kretati se Prohodno podrucje se

automatski izgraduje iz geometrije u sceni testirajuci sva podrucja gdje bi agent mo-

gao stajati Onda se te lokacije spajaju s površinom na vrhu geometrije Ta površina se

naziva onda NavMesh te je možemo vidjeti na 51 NavMesh tada sprema tu površinu

kao konveksne poligone te informacije koji su poligoni susjedni Komponenta Nav-

Mesh Agent pomaže pri kreiranju likova koji se medusobno izbjegavaju dok se krecu

prema cilju U Unityu se agenti opisuju kao valjci Koriste NavMesh kako bi se kretali

i znali koje objekte moraju zaobici te kako da se medusobno zaobidu Off-Mesh Link

19

omogucava dodavanje navigacijskih precaca koji se ne mogu predstaviti kao površina

po kojoj se može hodati npr skakanje preko ograde ili otvaranje vrata prije nego što

se ude u neku prostoriju NavMesh Obstacle opisuje prepreke koje se krecu te koje bi

agenti trebali izbjegavati dok hodaju svijetom npr neke bacve koje se kotrljaju prema

igracu Dok se bacva krece agent ce izracunati put oko nje najbolje što može no nakon

što ona naposljetku stane postat ce dio neprohodnog NavMesha te ce se agenti kretati

oko nje [3]

Slika 51 Prikaz navigacijskog sustava u Unityu

52 Pronalazak puta

Dva glavna problema postoje kod pronalaženja puta kako pronaci destinaciju na ni-

vou na kojem se igrac nalazi te kako se onda tamo pomaknuti Pronalaženje destinacije

uzima u obzir cijelu scenu Pomicanje tamo je dinamicnije u obzir uzima samo smjer

kretanja i kako da sprijeci sudaranje s drugim agentima Da bi se pronašao put izmedu

dvije lokacije prvo se moraju oznaciti pocetna i konacna lokacija njihovim najbližim

poligonima Tada se krece tražiti od pocetne lokacije posjecujuci sve susjedne dok se

ne dode do zadane destinacije Onda se prati unatrag vec posjecene poligone kako bi

se našao konacan niz poligona koji vode od pocetka do kraja Algoritam koji Unity

koristi te se cesto koristi za pronalazak puta naziva se A (A zvjezdica) Taj niz po-

ligona koji opisuje put od pocetka do kraja se naziva hodnik Agent ce doci do svoje

20

destinacije tako da se uvijek usmjerava prema sljedecem vidljivom kutu hodnika Ta

logika usmjeravanja uvijek uzima poziciju sljedeceg kuta i ovisno o tome nade željeni

smjer i brzinu potrebnu za dolazak na destinaciju Korištenje brzine po želji progra-

mera bi moglo dovesti do sudara s ostalim agentima Izbjegavanje prepreka takoder

pronalazi svoju novu brzinu koja traži ravnotežu izmedu kretanja prema destinaciji i

sprjecavanja buducih sudara s ostalim agentima i kutevima u navigacijskom sustavu

Nakon usmjeravanja i izbjegavanja prepreka izracuna se konacna brzina Unity ta-

koder uzima u obzir i akceleraciju kako bi simulirao realisticnije kretanje Takoder

treba razumjeti razliku izmedu globalne i lokalne navigacije Globalna navigacija se

koristi za pronalazak hodnika u svijetu Linearna lista poligona koja opisuje taj put je

podatkovna struktura koja se koristi za usmjeravanje te se može lokalno prilagodavati

i mijenjati kako se pozicija agenta mijenja Lokalna navigacija pokušava naci efika-

san nacin kako da se igrac pomakne prema sljedecem kutu bez da se sudari s ostalim

agentima ili objektima koji se krecu [3]

53 Kreiranje navigacijskog sustava

Proces kreiranja NavMesha iz geometrije nivoa se naziva pecenje navigacijske mreže

(engl NavMesh Baking) Skuplja sve terene i mreže objekata koji su oznaceni kao

navigacijski staticko (engl Navigation Static) i onda ih procesira kako bi kreirao navi-

gacijski sustav koji aproksimira prohodne površine nivoa Izgradnja (engl NavMesha)

je vrlo jednostavna Prvo se selektira geometrija koja bi trebala utjecati na navigaciju

tj površine po kojima možemo hodati i prepreke Oznaci se Navigation Static da bi ih

ukljucili u NavMesh Baking proces Prilagode se postavke kako bi odgovarale velicini

agenta - radijus (npr koliko blizu se može doci zidovima) visina (koliko su nisko

prostori koje agent može doseci) maksimalni nagib (koliko su kose rampe po kojima

se agent može uspeti) visina stube(koliko su visoke prepreke na koje agent može za-

koraciti) Onda jednostavno stisnemo ispeci (engl Bake) da izgradimo svoj NavMesh

Izgradeni NavMesh cemo moci vidjeti kao plavu površinu kao na slici 51 te ce se stvo-

riti nova datoteka s nazivom trenutne scene (ako vec ne postoji) i unutra ce se spremiti

kreiran navigacijski sustav [3]

21

54 Programiranje kretanja

Na liku se trenutno nalazi par stvari Animator Capsule Collider i Rigid Body Sada

je cilj isprogramirati mogucnost odredivanja gdje ce se lik kretati klikom miša na to

mjesto Dodaje se nova komponenta na lika NavMesh Agent Ta komponenta za-

pravo vec ima svoj sudarac te se slobodno može obrisati Capsule Collider jer postaje

nepotreban Igranjem s opcijama pomak od baze (engl Base Offset) te pod izbjegava-

nje prepreka (engl Obstacle Avoidance) radijus (engl Radius) i visina (engl Height)

prilagodi se sudarac od (engl NavMesh Agent-a) kako bi se obujmilo njime igraca i

sprijecilo propadanje kroz tlo od prije Sada kada postoji komponenta navigacije mora

se dodati skripta koja ce odrediti kada se lik krece te kada se pokrecu njegove anima-

cije iz Animator-a

Da bi se znalo gdje se miš nalazi mora se takoder dodati nova skriptu na kameru Kako

bi se izracunalo gdje trenutno kursor pokazuje Unity koristi vec prethodno spomenuto

bacanje zraka Da bi se moglo koristiti navigaciju putem klika mišem mora se napisati

skripta za glavnu kameru koja ce omoguciti bacanje zraka Skripta BacanjeZraka

dodaje se na objekt Main Camera koja se dodala pod prazni objekt Kamera Ova

skriptu se takoder koristi za razlikovanje raznih vrsta objekata Naime svaki objekt

kao što ima i Tag ima i sloj (engl Layer) Sloj služi kako bi mogli npr razlikovati

neprijatelje od obicnih objekata ili mjesto na koje želimo doci hodanjem Zato cemo

takoder dodati i jednu enumeraciju koja ce nam zasad služiti samo da razlikujemo je li

mjesto prohodno ili ne te jesmo li kliknuli na neprijatelja Kako bi dodali svoje nove

slojeve za objekte moramo kliknuti na Layer i dodaj sloj (engl Add Layer) kao na slici

52 što nas dovodi do novog prozora prikazanog na slici 53

Programski kod 51 bacanjeZrakacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

sluzi za dodavanje novih slojeva u Unity

public enum Sloj

Prohodno = 8

Neprijatelj = 9

KrajSvijeta = -1

22

Slika 52 Dodavanje novog sloja

public class BacanjeZraka MonoBehaviour

hijerarhija slojeva tj koji ima veci prioritet

public Sloj[] prioritetiSlojeva =

SlojNeprijatelj

SlojProhodno

SlojKrajSvijeta

udaljenost do pozadine je neka izmisljena vrijednost nakon

koje se prestane provjeravati zraka

public float udaljenostDoPozadine = 100f

Camera kamera

RaycastHit _udara

dohvaca varijable ove klase

public RaycastHit udara

get return _udara

Sloj _udaraSloj

23

Slika 53 Prozor za dodavanje novog sloja

public Sloj udaraSloj

get return _udaraSloj

deklariraj novi tip delegata

public delegate void priPromjeniSloja(Sloj noviSloj)

instanciraj skup promatraca

public event priPromjeniSloja promatraciPromjeneSloja

void Start ()

dohvat glavne kamere

kamera = Cameramain

void Update ()

nadi sloj po prioritetu u koji zraka udara

foreach(Sloj sloj in prioritetiSlojeva)

provjeravamo udara li zraka u neki od slojeva

24

var udar = BacanjeZrakaZaSloj(sloj)

if(udarHasValue)

_udara = udarValue

ako se sloj promjenio

if(_udaraSloj = sloj)

spremi novi sloj u varijablu trenutnog sloja

_udaraSloj = sloj

obavijesti promatrace da se sloj promjenio

promatraciPromjeneSloja(sloj)

spremi novi sloj u varijablu trenutnog sloja

ali ne moras obavjestavati promatrace jer je

sloj jednak starom sloju

_udaraSloj = sloj

return

inace vrati da zraka udara u pozadinu i obavijesti

promatrace

_udaradistance = udaljenostDoPozadine

_udaraSloj = SlojKrajSvijeta

promatraciPromjeneSloja(udaraSloj)

RaycastHit BacanjeZrakaZaSloj(Sloj sloj)

kreira se maska za slojeve bit se pomice ulijevo za

onoliko mjesta koliki je redni broj prioriteta sloja

int maska = 1 ltlt (int)sloj

sprema se mjesto pozicije kursora pretvoreno iz tocke u

zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

RaycastHit udar

PhysicsRaycast sprema zraku u varijablu tipa

RaycastHit prima jos i maksimalnu udaljenost za koju

provjerava zraku i masku sloja i potom vraca istinu (

engl True) ili laz (engl False) ako je zraka udarila

u sloj

25

bool udarioJe = PhysicsRaycast(zraka out udar

udaljenostDoPozadine maska)

ako zraka udara u sloj vrati vrijednost udarca

if(udarioJe)

return udar

return null

U programskom kodu 51 se koristi funkcija za primjenu obrasca promatraca pod

nazivom delegat (engl Delegate) Što je obrazac promatraca (engl Observer) To je

oblikovni obrazac koji se u programiranju koristi

bull kad promjena jednog objekta zahtijeva promjene u drugim objektima koji nisu

unaprijed poznati

bull kad objekt treba obavještavati druge objekte

bull uz uvjet da bude što neovisniji o njima

bull kad je potrebno prikazivati razlicite aspekte nekog dinamickog stanja a želimo

izbjeci ciklicku ovisnost izmedu stanja i pogleda

bull kad postoje dva koncepta jedan ovisan o drugome a zgodno ih je razdvojiti

S obzirom na to da mi samo pri promjeni sloja želimo obavještavati pretplacene pro-

matrace uvodenje delegata nam dosta ubrzava kod Obrazac promatraca funkcionira

tako da glavni objekt igra ulogu izdavaca (izvora informacija) u ovom slucaju to je

glavna kamera Ostali ovisni objekti (promatraci) pretplacuju se kod izdavaca te iz-

davaci obavještavaju pretplatnike o promjenama Promatraci prekidaju pretplatu kad

više ne trebaju obavještavanje Funkcija priPromjeniSloja se definira kao delegat i u

ovom slucaju prima sloj Nakon toga se definira dogadaj (engl Event) tipa tog delegata

(priPromjeniSloja) u ovom slucaju naziva promatraciPromjeneSloja i odsad se unutar

subjekta tim nazivom i poziva Kako bi se neki promatrac pretplatio na informacije

koje izdaje kamera dodaje ove dvije linije koda u svoju skriptu

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

Programski kod 52 služi za kretanje korištenjem NavMesha i lijevog klika miša

26

Programski kod 52 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

public float dovoljnoBlizu = 01f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora

[SerializeField] float hodajKreciStaniRadijus = 02f

void Start ()

pronadi igraca koji je tipa agenta navigacijskog sustava

(engl NavMeshAgent)

agent = GetComponentltUnityEngineAINavMeshAgentgt()

pronadi prethodno napisanu klasu BacanjeZraka

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

spremi trenutnu poziciju kursora

trenutnaPozicijaKursora = transformposition

void Update()

ako je igrac dosao na zeljeno mjesto zaustavi animaciju

hodanja

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

ako je stisnut lijevi klik misa

if (InputGetMouseButtonDown(0))

ovisno o sloju primjeni akciju

switch(bacanjeZrakaudaraSloj)

ako se po objektu na koji je igrac kliknuo moze

hodati

27

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 24: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

5 Kretanje

Pronalazak puta je zapravo pokušaj aplikacije na racunalu ili algoritma da nade naj-

kracu rutu izmedu dvije tocke To je recimo prakticna verzija rješavanja labirinta Ni

danas ne postoji optimalan algoritam koji ce u svakom slucaju u nekom realno krat-

kom vremenu naci najkraci put U ovom poglavlju objasnit ce se koje algoritme Unity

koristi za svoj navigacijski sustav Objašnjavat ce se i neki osnovni koncepti i obrasci

potrebni za ubrzavanje cijele ideje dojavljivanja promjena u sceni Bit ce prikazani i

programski kodovi potrebni za implementiranje kretanja mišem iili tipkovnicom Na

kraju ovog poglavlja želi se imati lika koji ce se slobodno kretati po sceni na mjesto

koje se odredi klikom miša i mogucnost prebacivanja na upravljanje tipkovnicom

51 Navigacijski sustav u Unityu

U Unityu je problem pronalaska puta vec riješen s necim što se zove navigacijska

mreža (engl NavMesh) To je navigacijski sustav koji ima svoje algoritme pronala-

ska puta i puno pojednostavljuje programiranje kretanja lika Sastoji se od cetiri di-

jela NavMesh agent navigacijske mreže (engl NavMesh Agent) izvanmrežna pove-

zanost(engl Off - Mesh Link) i prepreka navigacijske mreže(engl NavMesh Obstacle)

NavMesh je podatkovna struktura koja opisuje površine po kojima se može kretati

u igri i omogucava pronalazak put od jedne lokacije do druge Navigacijski sustav

treba svoje podatke kako bi predstavio prohodna podrucja u sceni Prohodna podru-

cja definiraju se kao mjesta gdje agent može stajati i kretati se Prohodno podrucje se

automatski izgraduje iz geometrije u sceni testirajuci sva podrucja gdje bi agent mo-

gao stajati Onda se te lokacije spajaju s površinom na vrhu geometrije Ta površina se

naziva onda NavMesh te je možemo vidjeti na 51 NavMesh tada sprema tu površinu

kao konveksne poligone te informacije koji su poligoni susjedni Komponenta Nav-

Mesh Agent pomaže pri kreiranju likova koji se medusobno izbjegavaju dok se krecu

prema cilju U Unityu se agenti opisuju kao valjci Koriste NavMesh kako bi se kretali

i znali koje objekte moraju zaobici te kako da se medusobno zaobidu Off-Mesh Link

19

omogucava dodavanje navigacijskih precaca koji se ne mogu predstaviti kao površina

po kojoj se može hodati npr skakanje preko ograde ili otvaranje vrata prije nego što

se ude u neku prostoriju NavMesh Obstacle opisuje prepreke koje se krecu te koje bi

agenti trebali izbjegavati dok hodaju svijetom npr neke bacve koje se kotrljaju prema

igracu Dok se bacva krece agent ce izracunati put oko nje najbolje što može no nakon

što ona naposljetku stane postat ce dio neprohodnog NavMesha te ce se agenti kretati

oko nje [3]

Slika 51 Prikaz navigacijskog sustava u Unityu

52 Pronalazak puta

Dva glavna problema postoje kod pronalaženja puta kako pronaci destinaciju na ni-

vou na kojem se igrac nalazi te kako se onda tamo pomaknuti Pronalaženje destinacije

uzima u obzir cijelu scenu Pomicanje tamo je dinamicnije u obzir uzima samo smjer

kretanja i kako da sprijeci sudaranje s drugim agentima Da bi se pronašao put izmedu

dvije lokacije prvo se moraju oznaciti pocetna i konacna lokacija njihovim najbližim

poligonima Tada se krece tražiti od pocetne lokacije posjecujuci sve susjedne dok se

ne dode do zadane destinacije Onda se prati unatrag vec posjecene poligone kako bi

se našao konacan niz poligona koji vode od pocetka do kraja Algoritam koji Unity

koristi te se cesto koristi za pronalazak puta naziva se A (A zvjezdica) Taj niz po-

ligona koji opisuje put od pocetka do kraja se naziva hodnik Agent ce doci do svoje

20

destinacije tako da se uvijek usmjerava prema sljedecem vidljivom kutu hodnika Ta

logika usmjeravanja uvijek uzima poziciju sljedeceg kuta i ovisno o tome nade željeni

smjer i brzinu potrebnu za dolazak na destinaciju Korištenje brzine po želji progra-

mera bi moglo dovesti do sudara s ostalim agentima Izbjegavanje prepreka takoder

pronalazi svoju novu brzinu koja traži ravnotežu izmedu kretanja prema destinaciji i

sprjecavanja buducih sudara s ostalim agentima i kutevima u navigacijskom sustavu

Nakon usmjeravanja i izbjegavanja prepreka izracuna se konacna brzina Unity ta-

koder uzima u obzir i akceleraciju kako bi simulirao realisticnije kretanje Takoder

treba razumjeti razliku izmedu globalne i lokalne navigacije Globalna navigacija se

koristi za pronalazak hodnika u svijetu Linearna lista poligona koja opisuje taj put je

podatkovna struktura koja se koristi za usmjeravanje te se može lokalno prilagodavati

i mijenjati kako se pozicija agenta mijenja Lokalna navigacija pokušava naci efika-

san nacin kako da se igrac pomakne prema sljedecem kutu bez da se sudari s ostalim

agentima ili objektima koji se krecu [3]

53 Kreiranje navigacijskog sustava

Proces kreiranja NavMesha iz geometrije nivoa se naziva pecenje navigacijske mreže

(engl NavMesh Baking) Skuplja sve terene i mreže objekata koji su oznaceni kao

navigacijski staticko (engl Navigation Static) i onda ih procesira kako bi kreirao navi-

gacijski sustav koji aproksimira prohodne površine nivoa Izgradnja (engl NavMesha)

je vrlo jednostavna Prvo se selektira geometrija koja bi trebala utjecati na navigaciju

tj površine po kojima možemo hodati i prepreke Oznaci se Navigation Static da bi ih

ukljucili u NavMesh Baking proces Prilagode se postavke kako bi odgovarale velicini

agenta - radijus (npr koliko blizu se može doci zidovima) visina (koliko su nisko

prostori koje agent može doseci) maksimalni nagib (koliko su kose rampe po kojima

se agent može uspeti) visina stube(koliko su visoke prepreke na koje agent može za-

koraciti) Onda jednostavno stisnemo ispeci (engl Bake) da izgradimo svoj NavMesh

Izgradeni NavMesh cemo moci vidjeti kao plavu površinu kao na slici 51 te ce se stvo-

riti nova datoteka s nazivom trenutne scene (ako vec ne postoji) i unutra ce se spremiti

kreiran navigacijski sustav [3]

21

54 Programiranje kretanja

Na liku se trenutno nalazi par stvari Animator Capsule Collider i Rigid Body Sada

je cilj isprogramirati mogucnost odredivanja gdje ce se lik kretati klikom miša na to

mjesto Dodaje se nova komponenta na lika NavMesh Agent Ta komponenta za-

pravo vec ima svoj sudarac te se slobodno može obrisati Capsule Collider jer postaje

nepotreban Igranjem s opcijama pomak od baze (engl Base Offset) te pod izbjegava-

nje prepreka (engl Obstacle Avoidance) radijus (engl Radius) i visina (engl Height)

prilagodi se sudarac od (engl NavMesh Agent-a) kako bi se obujmilo njime igraca i

sprijecilo propadanje kroz tlo od prije Sada kada postoji komponenta navigacije mora

se dodati skripta koja ce odrediti kada se lik krece te kada se pokrecu njegove anima-

cije iz Animator-a

Da bi se znalo gdje se miš nalazi mora se takoder dodati nova skriptu na kameru Kako

bi se izracunalo gdje trenutno kursor pokazuje Unity koristi vec prethodno spomenuto

bacanje zraka Da bi se moglo koristiti navigaciju putem klika mišem mora se napisati

skripta za glavnu kameru koja ce omoguciti bacanje zraka Skripta BacanjeZraka

dodaje se na objekt Main Camera koja se dodala pod prazni objekt Kamera Ova

skriptu se takoder koristi za razlikovanje raznih vrsta objekata Naime svaki objekt

kao što ima i Tag ima i sloj (engl Layer) Sloj služi kako bi mogli npr razlikovati

neprijatelje od obicnih objekata ili mjesto na koje želimo doci hodanjem Zato cemo

takoder dodati i jednu enumeraciju koja ce nam zasad služiti samo da razlikujemo je li

mjesto prohodno ili ne te jesmo li kliknuli na neprijatelja Kako bi dodali svoje nove

slojeve za objekte moramo kliknuti na Layer i dodaj sloj (engl Add Layer) kao na slici

52 što nas dovodi do novog prozora prikazanog na slici 53

Programski kod 51 bacanjeZrakacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

sluzi za dodavanje novih slojeva u Unity

public enum Sloj

Prohodno = 8

Neprijatelj = 9

KrajSvijeta = -1

22

Slika 52 Dodavanje novog sloja

public class BacanjeZraka MonoBehaviour

hijerarhija slojeva tj koji ima veci prioritet

public Sloj[] prioritetiSlojeva =

SlojNeprijatelj

SlojProhodno

SlojKrajSvijeta

udaljenost do pozadine je neka izmisljena vrijednost nakon

koje se prestane provjeravati zraka

public float udaljenostDoPozadine = 100f

Camera kamera

RaycastHit _udara

dohvaca varijable ove klase

public RaycastHit udara

get return _udara

Sloj _udaraSloj

23

Slika 53 Prozor za dodavanje novog sloja

public Sloj udaraSloj

get return _udaraSloj

deklariraj novi tip delegata

public delegate void priPromjeniSloja(Sloj noviSloj)

instanciraj skup promatraca

public event priPromjeniSloja promatraciPromjeneSloja

void Start ()

dohvat glavne kamere

kamera = Cameramain

void Update ()

nadi sloj po prioritetu u koji zraka udara

foreach(Sloj sloj in prioritetiSlojeva)

provjeravamo udara li zraka u neki od slojeva

24

var udar = BacanjeZrakaZaSloj(sloj)

if(udarHasValue)

_udara = udarValue

ako se sloj promjenio

if(_udaraSloj = sloj)

spremi novi sloj u varijablu trenutnog sloja

_udaraSloj = sloj

obavijesti promatrace da se sloj promjenio

promatraciPromjeneSloja(sloj)

spremi novi sloj u varijablu trenutnog sloja

ali ne moras obavjestavati promatrace jer je

sloj jednak starom sloju

_udaraSloj = sloj

return

inace vrati da zraka udara u pozadinu i obavijesti

promatrace

_udaradistance = udaljenostDoPozadine

_udaraSloj = SlojKrajSvijeta

promatraciPromjeneSloja(udaraSloj)

RaycastHit BacanjeZrakaZaSloj(Sloj sloj)

kreira se maska za slojeve bit se pomice ulijevo za

onoliko mjesta koliki je redni broj prioriteta sloja

int maska = 1 ltlt (int)sloj

sprema se mjesto pozicije kursora pretvoreno iz tocke u

zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

RaycastHit udar

PhysicsRaycast sprema zraku u varijablu tipa

RaycastHit prima jos i maksimalnu udaljenost za koju

provjerava zraku i masku sloja i potom vraca istinu (

engl True) ili laz (engl False) ako je zraka udarila

u sloj

25

bool udarioJe = PhysicsRaycast(zraka out udar

udaljenostDoPozadine maska)

ako zraka udara u sloj vrati vrijednost udarca

if(udarioJe)

return udar

return null

U programskom kodu 51 se koristi funkcija za primjenu obrasca promatraca pod

nazivom delegat (engl Delegate) Što je obrazac promatraca (engl Observer) To je

oblikovni obrazac koji se u programiranju koristi

bull kad promjena jednog objekta zahtijeva promjene u drugim objektima koji nisu

unaprijed poznati

bull kad objekt treba obavještavati druge objekte

bull uz uvjet da bude što neovisniji o njima

bull kad je potrebno prikazivati razlicite aspekte nekog dinamickog stanja a želimo

izbjeci ciklicku ovisnost izmedu stanja i pogleda

bull kad postoje dva koncepta jedan ovisan o drugome a zgodno ih je razdvojiti

S obzirom na to da mi samo pri promjeni sloja želimo obavještavati pretplacene pro-

matrace uvodenje delegata nam dosta ubrzava kod Obrazac promatraca funkcionira

tako da glavni objekt igra ulogu izdavaca (izvora informacija) u ovom slucaju to je

glavna kamera Ostali ovisni objekti (promatraci) pretplacuju se kod izdavaca te iz-

davaci obavještavaju pretplatnike o promjenama Promatraci prekidaju pretplatu kad

više ne trebaju obavještavanje Funkcija priPromjeniSloja se definira kao delegat i u

ovom slucaju prima sloj Nakon toga se definira dogadaj (engl Event) tipa tog delegata

(priPromjeniSloja) u ovom slucaju naziva promatraciPromjeneSloja i odsad se unutar

subjekta tim nazivom i poziva Kako bi se neki promatrac pretplatio na informacije

koje izdaje kamera dodaje ove dvije linije koda u svoju skriptu

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

Programski kod 52 služi za kretanje korištenjem NavMesha i lijevog klika miša

26

Programski kod 52 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

public float dovoljnoBlizu = 01f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora

[SerializeField] float hodajKreciStaniRadijus = 02f

void Start ()

pronadi igraca koji je tipa agenta navigacijskog sustava

(engl NavMeshAgent)

agent = GetComponentltUnityEngineAINavMeshAgentgt()

pronadi prethodno napisanu klasu BacanjeZraka

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

spremi trenutnu poziciju kursora

trenutnaPozicijaKursora = transformposition

void Update()

ako je igrac dosao na zeljeno mjesto zaustavi animaciju

hodanja

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

ako je stisnut lijevi klik misa

if (InputGetMouseButtonDown(0))

ovisno o sloju primjeni akciju

switch(bacanjeZrakaudaraSloj)

ako se po objektu na koji je igrac kliknuo moze

hodati

27

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 25: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

omogucava dodavanje navigacijskih precaca koji se ne mogu predstaviti kao površina

po kojoj se može hodati npr skakanje preko ograde ili otvaranje vrata prije nego što

se ude u neku prostoriju NavMesh Obstacle opisuje prepreke koje se krecu te koje bi

agenti trebali izbjegavati dok hodaju svijetom npr neke bacve koje se kotrljaju prema

igracu Dok se bacva krece agent ce izracunati put oko nje najbolje što može no nakon

što ona naposljetku stane postat ce dio neprohodnog NavMesha te ce se agenti kretati

oko nje [3]

Slika 51 Prikaz navigacijskog sustava u Unityu

52 Pronalazak puta

Dva glavna problema postoje kod pronalaženja puta kako pronaci destinaciju na ni-

vou na kojem se igrac nalazi te kako se onda tamo pomaknuti Pronalaženje destinacije

uzima u obzir cijelu scenu Pomicanje tamo je dinamicnije u obzir uzima samo smjer

kretanja i kako da sprijeci sudaranje s drugim agentima Da bi se pronašao put izmedu

dvije lokacije prvo se moraju oznaciti pocetna i konacna lokacija njihovim najbližim

poligonima Tada se krece tražiti od pocetne lokacije posjecujuci sve susjedne dok se

ne dode do zadane destinacije Onda se prati unatrag vec posjecene poligone kako bi

se našao konacan niz poligona koji vode od pocetka do kraja Algoritam koji Unity

koristi te se cesto koristi za pronalazak puta naziva se A (A zvjezdica) Taj niz po-

ligona koji opisuje put od pocetka do kraja se naziva hodnik Agent ce doci do svoje

20

destinacije tako da se uvijek usmjerava prema sljedecem vidljivom kutu hodnika Ta

logika usmjeravanja uvijek uzima poziciju sljedeceg kuta i ovisno o tome nade željeni

smjer i brzinu potrebnu za dolazak na destinaciju Korištenje brzine po želji progra-

mera bi moglo dovesti do sudara s ostalim agentima Izbjegavanje prepreka takoder

pronalazi svoju novu brzinu koja traži ravnotežu izmedu kretanja prema destinaciji i

sprjecavanja buducih sudara s ostalim agentima i kutevima u navigacijskom sustavu

Nakon usmjeravanja i izbjegavanja prepreka izracuna se konacna brzina Unity ta-

koder uzima u obzir i akceleraciju kako bi simulirao realisticnije kretanje Takoder

treba razumjeti razliku izmedu globalne i lokalne navigacije Globalna navigacija se

koristi za pronalazak hodnika u svijetu Linearna lista poligona koja opisuje taj put je

podatkovna struktura koja se koristi za usmjeravanje te se može lokalno prilagodavati

i mijenjati kako se pozicija agenta mijenja Lokalna navigacija pokušava naci efika-

san nacin kako da se igrac pomakne prema sljedecem kutu bez da se sudari s ostalim

agentima ili objektima koji se krecu [3]

53 Kreiranje navigacijskog sustava

Proces kreiranja NavMesha iz geometrije nivoa se naziva pecenje navigacijske mreže

(engl NavMesh Baking) Skuplja sve terene i mreže objekata koji su oznaceni kao

navigacijski staticko (engl Navigation Static) i onda ih procesira kako bi kreirao navi-

gacijski sustav koji aproksimira prohodne površine nivoa Izgradnja (engl NavMesha)

je vrlo jednostavna Prvo se selektira geometrija koja bi trebala utjecati na navigaciju

tj površine po kojima možemo hodati i prepreke Oznaci se Navigation Static da bi ih

ukljucili u NavMesh Baking proces Prilagode se postavke kako bi odgovarale velicini

agenta - radijus (npr koliko blizu se može doci zidovima) visina (koliko su nisko

prostori koje agent može doseci) maksimalni nagib (koliko su kose rampe po kojima

se agent može uspeti) visina stube(koliko su visoke prepreke na koje agent može za-

koraciti) Onda jednostavno stisnemo ispeci (engl Bake) da izgradimo svoj NavMesh

Izgradeni NavMesh cemo moci vidjeti kao plavu površinu kao na slici 51 te ce se stvo-

riti nova datoteka s nazivom trenutne scene (ako vec ne postoji) i unutra ce se spremiti

kreiran navigacijski sustav [3]

21

54 Programiranje kretanja

Na liku se trenutno nalazi par stvari Animator Capsule Collider i Rigid Body Sada

je cilj isprogramirati mogucnost odredivanja gdje ce se lik kretati klikom miša na to

mjesto Dodaje se nova komponenta na lika NavMesh Agent Ta komponenta za-

pravo vec ima svoj sudarac te se slobodno može obrisati Capsule Collider jer postaje

nepotreban Igranjem s opcijama pomak od baze (engl Base Offset) te pod izbjegava-

nje prepreka (engl Obstacle Avoidance) radijus (engl Radius) i visina (engl Height)

prilagodi se sudarac od (engl NavMesh Agent-a) kako bi se obujmilo njime igraca i

sprijecilo propadanje kroz tlo od prije Sada kada postoji komponenta navigacije mora

se dodati skripta koja ce odrediti kada se lik krece te kada se pokrecu njegove anima-

cije iz Animator-a

Da bi se znalo gdje se miš nalazi mora se takoder dodati nova skriptu na kameru Kako

bi se izracunalo gdje trenutno kursor pokazuje Unity koristi vec prethodno spomenuto

bacanje zraka Da bi se moglo koristiti navigaciju putem klika mišem mora se napisati

skripta za glavnu kameru koja ce omoguciti bacanje zraka Skripta BacanjeZraka

dodaje se na objekt Main Camera koja se dodala pod prazni objekt Kamera Ova

skriptu se takoder koristi za razlikovanje raznih vrsta objekata Naime svaki objekt

kao što ima i Tag ima i sloj (engl Layer) Sloj služi kako bi mogli npr razlikovati

neprijatelje od obicnih objekata ili mjesto na koje želimo doci hodanjem Zato cemo

takoder dodati i jednu enumeraciju koja ce nam zasad služiti samo da razlikujemo je li

mjesto prohodno ili ne te jesmo li kliknuli na neprijatelja Kako bi dodali svoje nove

slojeve za objekte moramo kliknuti na Layer i dodaj sloj (engl Add Layer) kao na slici

52 što nas dovodi do novog prozora prikazanog na slici 53

Programski kod 51 bacanjeZrakacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

sluzi za dodavanje novih slojeva u Unity

public enum Sloj

Prohodno = 8

Neprijatelj = 9

KrajSvijeta = -1

22

Slika 52 Dodavanje novog sloja

public class BacanjeZraka MonoBehaviour

hijerarhija slojeva tj koji ima veci prioritet

public Sloj[] prioritetiSlojeva =

SlojNeprijatelj

SlojProhodno

SlojKrajSvijeta

udaljenost do pozadine je neka izmisljena vrijednost nakon

koje se prestane provjeravati zraka

public float udaljenostDoPozadine = 100f

Camera kamera

RaycastHit _udara

dohvaca varijable ove klase

public RaycastHit udara

get return _udara

Sloj _udaraSloj

23

Slika 53 Prozor za dodavanje novog sloja

public Sloj udaraSloj

get return _udaraSloj

deklariraj novi tip delegata

public delegate void priPromjeniSloja(Sloj noviSloj)

instanciraj skup promatraca

public event priPromjeniSloja promatraciPromjeneSloja

void Start ()

dohvat glavne kamere

kamera = Cameramain

void Update ()

nadi sloj po prioritetu u koji zraka udara

foreach(Sloj sloj in prioritetiSlojeva)

provjeravamo udara li zraka u neki od slojeva

24

var udar = BacanjeZrakaZaSloj(sloj)

if(udarHasValue)

_udara = udarValue

ako se sloj promjenio

if(_udaraSloj = sloj)

spremi novi sloj u varijablu trenutnog sloja

_udaraSloj = sloj

obavijesti promatrace da se sloj promjenio

promatraciPromjeneSloja(sloj)

spremi novi sloj u varijablu trenutnog sloja

ali ne moras obavjestavati promatrace jer je

sloj jednak starom sloju

_udaraSloj = sloj

return

inace vrati da zraka udara u pozadinu i obavijesti

promatrace

_udaradistance = udaljenostDoPozadine

_udaraSloj = SlojKrajSvijeta

promatraciPromjeneSloja(udaraSloj)

RaycastHit BacanjeZrakaZaSloj(Sloj sloj)

kreira se maska za slojeve bit se pomice ulijevo za

onoliko mjesta koliki je redni broj prioriteta sloja

int maska = 1 ltlt (int)sloj

sprema se mjesto pozicije kursora pretvoreno iz tocke u

zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

RaycastHit udar

PhysicsRaycast sprema zraku u varijablu tipa

RaycastHit prima jos i maksimalnu udaljenost za koju

provjerava zraku i masku sloja i potom vraca istinu (

engl True) ili laz (engl False) ako je zraka udarila

u sloj

25

bool udarioJe = PhysicsRaycast(zraka out udar

udaljenostDoPozadine maska)

ako zraka udara u sloj vrati vrijednost udarca

if(udarioJe)

return udar

return null

U programskom kodu 51 se koristi funkcija za primjenu obrasca promatraca pod

nazivom delegat (engl Delegate) Što je obrazac promatraca (engl Observer) To je

oblikovni obrazac koji se u programiranju koristi

bull kad promjena jednog objekta zahtijeva promjene u drugim objektima koji nisu

unaprijed poznati

bull kad objekt treba obavještavati druge objekte

bull uz uvjet da bude što neovisniji o njima

bull kad je potrebno prikazivati razlicite aspekte nekog dinamickog stanja a želimo

izbjeci ciklicku ovisnost izmedu stanja i pogleda

bull kad postoje dva koncepta jedan ovisan o drugome a zgodno ih je razdvojiti

S obzirom na to da mi samo pri promjeni sloja želimo obavještavati pretplacene pro-

matrace uvodenje delegata nam dosta ubrzava kod Obrazac promatraca funkcionira

tako da glavni objekt igra ulogu izdavaca (izvora informacija) u ovom slucaju to je

glavna kamera Ostali ovisni objekti (promatraci) pretplacuju se kod izdavaca te iz-

davaci obavještavaju pretplatnike o promjenama Promatraci prekidaju pretplatu kad

više ne trebaju obavještavanje Funkcija priPromjeniSloja se definira kao delegat i u

ovom slucaju prima sloj Nakon toga se definira dogadaj (engl Event) tipa tog delegata

(priPromjeniSloja) u ovom slucaju naziva promatraciPromjeneSloja i odsad se unutar

subjekta tim nazivom i poziva Kako bi se neki promatrac pretplatio na informacije

koje izdaje kamera dodaje ove dvije linije koda u svoju skriptu

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

Programski kod 52 služi za kretanje korištenjem NavMesha i lijevog klika miša

26

Programski kod 52 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

public float dovoljnoBlizu = 01f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora

[SerializeField] float hodajKreciStaniRadijus = 02f

void Start ()

pronadi igraca koji je tipa agenta navigacijskog sustava

(engl NavMeshAgent)

agent = GetComponentltUnityEngineAINavMeshAgentgt()

pronadi prethodno napisanu klasu BacanjeZraka

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

spremi trenutnu poziciju kursora

trenutnaPozicijaKursora = transformposition

void Update()

ako je igrac dosao na zeljeno mjesto zaustavi animaciju

hodanja

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

ako je stisnut lijevi klik misa

if (InputGetMouseButtonDown(0))

ovisno o sloju primjeni akciju

switch(bacanjeZrakaudaraSloj)

ako se po objektu na koji je igrac kliknuo moze

hodati

27

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 26: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

destinacije tako da se uvijek usmjerava prema sljedecem vidljivom kutu hodnika Ta

logika usmjeravanja uvijek uzima poziciju sljedeceg kuta i ovisno o tome nade željeni

smjer i brzinu potrebnu za dolazak na destinaciju Korištenje brzine po želji progra-

mera bi moglo dovesti do sudara s ostalim agentima Izbjegavanje prepreka takoder

pronalazi svoju novu brzinu koja traži ravnotežu izmedu kretanja prema destinaciji i

sprjecavanja buducih sudara s ostalim agentima i kutevima u navigacijskom sustavu

Nakon usmjeravanja i izbjegavanja prepreka izracuna se konacna brzina Unity ta-

koder uzima u obzir i akceleraciju kako bi simulirao realisticnije kretanje Takoder

treba razumjeti razliku izmedu globalne i lokalne navigacije Globalna navigacija se

koristi za pronalazak hodnika u svijetu Linearna lista poligona koja opisuje taj put je

podatkovna struktura koja se koristi za usmjeravanje te se može lokalno prilagodavati

i mijenjati kako se pozicija agenta mijenja Lokalna navigacija pokušava naci efika-

san nacin kako da se igrac pomakne prema sljedecem kutu bez da se sudari s ostalim

agentima ili objektima koji se krecu [3]

53 Kreiranje navigacijskog sustava

Proces kreiranja NavMesha iz geometrije nivoa se naziva pecenje navigacijske mreže

(engl NavMesh Baking) Skuplja sve terene i mreže objekata koji su oznaceni kao

navigacijski staticko (engl Navigation Static) i onda ih procesira kako bi kreirao navi-

gacijski sustav koji aproksimira prohodne površine nivoa Izgradnja (engl NavMesha)

je vrlo jednostavna Prvo se selektira geometrija koja bi trebala utjecati na navigaciju

tj površine po kojima možemo hodati i prepreke Oznaci se Navigation Static da bi ih

ukljucili u NavMesh Baking proces Prilagode se postavke kako bi odgovarale velicini

agenta - radijus (npr koliko blizu se može doci zidovima) visina (koliko su nisko

prostori koje agent može doseci) maksimalni nagib (koliko su kose rampe po kojima

se agent može uspeti) visina stube(koliko su visoke prepreke na koje agent može za-

koraciti) Onda jednostavno stisnemo ispeci (engl Bake) da izgradimo svoj NavMesh

Izgradeni NavMesh cemo moci vidjeti kao plavu površinu kao na slici 51 te ce se stvo-

riti nova datoteka s nazivom trenutne scene (ako vec ne postoji) i unutra ce se spremiti

kreiran navigacijski sustav [3]

21

54 Programiranje kretanja

Na liku se trenutno nalazi par stvari Animator Capsule Collider i Rigid Body Sada

je cilj isprogramirati mogucnost odredivanja gdje ce se lik kretati klikom miša na to

mjesto Dodaje se nova komponenta na lika NavMesh Agent Ta komponenta za-

pravo vec ima svoj sudarac te se slobodno može obrisati Capsule Collider jer postaje

nepotreban Igranjem s opcijama pomak od baze (engl Base Offset) te pod izbjegava-

nje prepreka (engl Obstacle Avoidance) radijus (engl Radius) i visina (engl Height)

prilagodi se sudarac od (engl NavMesh Agent-a) kako bi se obujmilo njime igraca i

sprijecilo propadanje kroz tlo od prije Sada kada postoji komponenta navigacije mora

se dodati skripta koja ce odrediti kada se lik krece te kada se pokrecu njegove anima-

cije iz Animator-a

Da bi se znalo gdje se miš nalazi mora se takoder dodati nova skriptu na kameru Kako

bi se izracunalo gdje trenutno kursor pokazuje Unity koristi vec prethodno spomenuto

bacanje zraka Da bi se moglo koristiti navigaciju putem klika mišem mora se napisati

skripta za glavnu kameru koja ce omoguciti bacanje zraka Skripta BacanjeZraka

dodaje se na objekt Main Camera koja se dodala pod prazni objekt Kamera Ova

skriptu se takoder koristi za razlikovanje raznih vrsta objekata Naime svaki objekt

kao što ima i Tag ima i sloj (engl Layer) Sloj služi kako bi mogli npr razlikovati

neprijatelje od obicnih objekata ili mjesto na koje želimo doci hodanjem Zato cemo

takoder dodati i jednu enumeraciju koja ce nam zasad služiti samo da razlikujemo je li

mjesto prohodno ili ne te jesmo li kliknuli na neprijatelja Kako bi dodali svoje nove

slojeve za objekte moramo kliknuti na Layer i dodaj sloj (engl Add Layer) kao na slici

52 što nas dovodi do novog prozora prikazanog na slici 53

Programski kod 51 bacanjeZrakacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

sluzi za dodavanje novih slojeva u Unity

public enum Sloj

Prohodno = 8

Neprijatelj = 9

KrajSvijeta = -1

22

Slika 52 Dodavanje novog sloja

public class BacanjeZraka MonoBehaviour

hijerarhija slojeva tj koji ima veci prioritet

public Sloj[] prioritetiSlojeva =

SlojNeprijatelj

SlojProhodno

SlojKrajSvijeta

udaljenost do pozadine je neka izmisljena vrijednost nakon

koje se prestane provjeravati zraka

public float udaljenostDoPozadine = 100f

Camera kamera

RaycastHit _udara

dohvaca varijable ove klase

public RaycastHit udara

get return _udara

Sloj _udaraSloj

23

Slika 53 Prozor za dodavanje novog sloja

public Sloj udaraSloj

get return _udaraSloj

deklariraj novi tip delegata

public delegate void priPromjeniSloja(Sloj noviSloj)

instanciraj skup promatraca

public event priPromjeniSloja promatraciPromjeneSloja

void Start ()

dohvat glavne kamere

kamera = Cameramain

void Update ()

nadi sloj po prioritetu u koji zraka udara

foreach(Sloj sloj in prioritetiSlojeva)

provjeravamo udara li zraka u neki od slojeva

24

var udar = BacanjeZrakaZaSloj(sloj)

if(udarHasValue)

_udara = udarValue

ako se sloj promjenio

if(_udaraSloj = sloj)

spremi novi sloj u varijablu trenutnog sloja

_udaraSloj = sloj

obavijesti promatrace da se sloj promjenio

promatraciPromjeneSloja(sloj)

spremi novi sloj u varijablu trenutnog sloja

ali ne moras obavjestavati promatrace jer je

sloj jednak starom sloju

_udaraSloj = sloj

return

inace vrati da zraka udara u pozadinu i obavijesti

promatrace

_udaradistance = udaljenostDoPozadine

_udaraSloj = SlojKrajSvijeta

promatraciPromjeneSloja(udaraSloj)

RaycastHit BacanjeZrakaZaSloj(Sloj sloj)

kreira se maska za slojeve bit se pomice ulijevo za

onoliko mjesta koliki je redni broj prioriteta sloja

int maska = 1 ltlt (int)sloj

sprema se mjesto pozicije kursora pretvoreno iz tocke u

zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

RaycastHit udar

PhysicsRaycast sprema zraku u varijablu tipa

RaycastHit prima jos i maksimalnu udaljenost za koju

provjerava zraku i masku sloja i potom vraca istinu (

engl True) ili laz (engl False) ako je zraka udarila

u sloj

25

bool udarioJe = PhysicsRaycast(zraka out udar

udaljenostDoPozadine maska)

ako zraka udara u sloj vrati vrijednost udarca

if(udarioJe)

return udar

return null

U programskom kodu 51 se koristi funkcija za primjenu obrasca promatraca pod

nazivom delegat (engl Delegate) Što je obrazac promatraca (engl Observer) To je

oblikovni obrazac koji se u programiranju koristi

bull kad promjena jednog objekta zahtijeva promjene u drugim objektima koji nisu

unaprijed poznati

bull kad objekt treba obavještavati druge objekte

bull uz uvjet da bude što neovisniji o njima

bull kad je potrebno prikazivati razlicite aspekte nekog dinamickog stanja a želimo

izbjeci ciklicku ovisnost izmedu stanja i pogleda

bull kad postoje dva koncepta jedan ovisan o drugome a zgodno ih je razdvojiti

S obzirom na to da mi samo pri promjeni sloja želimo obavještavati pretplacene pro-

matrace uvodenje delegata nam dosta ubrzava kod Obrazac promatraca funkcionira

tako da glavni objekt igra ulogu izdavaca (izvora informacija) u ovom slucaju to je

glavna kamera Ostali ovisni objekti (promatraci) pretplacuju se kod izdavaca te iz-

davaci obavještavaju pretplatnike o promjenama Promatraci prekidaju pretplatu kad

više ne trebaju obavještavanje Funkcija priPromjeniSloja se definira kao delegat i u

ovom slucaju prima sloj Nakon toga se definira dogadaj (engl Event) tipa tog delegata

(priPromjeniSloja) u ovom slucaju naziva promatraciPromjeneSloja i odsad se unutar

subjekta tim nazivom i poziva Kako bi se neki promatrac pretplatio na informacije

koje izdaje kamera dodaje ove dvije linije koda u svoju skriptu

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

Programski kod 52 služi za kretanje korištenjem NavMesha i lijevog klika miša

26

Programski kod 52 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

public float dovoljnoBlizu = 01f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora

[SerializeField] float hodajKreciStaniRadijus = 02f

void Start ()

pronadi igraca koji je tipa agenta navigacijskog sustava

(engl NavMeshAgent)

agent = GetComponentltUnityEngineAINavMeshAgentgt()

pronadi prethodno napisanu klasu BacanjeZraka

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

spremi trenutnu poziciju kursora

trenutnaPozicijaKursora = transformposition

void Update()

ako je igrac dosao na zeljeno mjesto zaustavi animaciju

hodanja

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

ako je stisnut lijevi klik misa

if (InputGetMouseButtonDown(0))

ovisno o sloju primjeni akciju

switch(bacanjeZrakaudaraSloj)

ako se po objektu na koji je igrac kliknuo moze

hodati

27

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 27: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

54 Programiranje kretanja

Na liku se trenutno nalazi par stvari Animator Capsule Collider i Rigid Body Sada

je cilj isprogramirati mogucnost odredivanja gdje ce se lik kretati klikom miša na to

mjesto Dodaje se nova komponenta na lika NavMesh Agent Ta komponenta za-

pravo vec ima svoj sudarac te se slobodno može obrisati Capsule Collider jer postaje

nepotreban Igranjem s opcijama pomak od baze (engl Base Offset) te pod izbjegava-

nje prepreka (engl Obstacle Avoidance) radijus (engl Radius) i visina (engl Height)

prilagodi se sudarac od (engl NavMesh Agent-a) kako bi se obujmilo njime igraca i

sprijecilo propadanje kroz tlo od prije Sada kada postoji komponenta navigacije mora

se dodati skripta koja ce odrediti kada se lik krece te kada se pokrecu njegove anima-

cije iz Animator-a

Da bi se znalo gdje se miš nalazi mora se takoder dodati nova skriptu na kameru Kako

bi se izracunalo gdje trenutno kursor pokazuje Unity koristi vec prethodno spomenuto

bacanje zraka Da bi se moglo koristiti navigaciju putem klika mišem mora se napisati

skripta za glavnu kameru koja ce omoguciti bacanje zraka Skripta BacanjeZraka

dodaje se na objekt Main Camera koja se dodala pod prazni objekt Kamera Ova

skriptu se takoder koristi za razlikovanje raznih vrsta objekata Naime svaki objekt

kao što ima i Tag ima i sloj (engl Layer) Sloj služi kako bi mogli npr razlikovati

neprijatelje od obicnih objekata ili mjesto na koje želimo doci hodanjem Zato cemo

takoder dodati i jednu enumeraciju koja ce nam zasad služiti samo da razlikujemo je li

mjesto prohodno ili ne te jesmo li kliknuli na neprijatelja Kako bi dodali svoje nove

slojeve za objekte moramo kliknuti na Layer i dodaj sloj (engl Add Layer) kao na slici

52 što nas dovodi do novog prozora prikazanog na slici 53

Programski kod 51 bacanjeZrakacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

sluzi za dodavanje novih slojeva u Unity

public enum Sloj

Prohodno = 8

Neprijatelj = 9

KrajSvijeta = -1

22

Slika 52 Dodavanje novog sloja

public class BacanjeZraka MonoBehaviour

hijerarhija slojeva tj koji ima veci prioritet

public Sloj[] prioritetiSlojeva =

SlojNeprijatelj

SlojProhodno

SlojKrajSvijeta

udaljenost do pozadine je neka izmisljena vrijednost nakon

koje se prestane provjeravati zraka

public float udaljenostDoPozadine = 100f

Camera kamera

RaycastHit _udara

dohvaca varijable ove klase

public RaycastHit udara

get return _udara

Sloj _udaraSloj

23

Slika 53 Prozor za dodavanje novog sloja

public Sloj udaraSloj

get return _udaraSloj

deklariraj novi tip delegata

public delegate void priPromjeniSloja(Sloj noviSloj)

instanciraj skup promatraca

public event priPromjeniSloja promatraciPromjeneSloja

void Start ()

dohvat glavne kamere

kamera = Cameramain

void Update ()

nadi sloj po prioritetu u koji zraka udara

foreach(Sloj sloj in prioritetiSlojeva)

provjeravamo udara li zraka u neki od slojeva

24

var udar = BacanjeZrakaZaSloj(sloj)

if(udarHasValue)

_udara = udarValue

ako se sloj promjenio

if(_udaraSloj = sloj)

spremi novi sloj u varijablu trenutnog sloja

_udaraSloj = sloj

obavijesti promatrace da se sloj promjenio

promatraciPromjeneSloja(sloj)

spremi novi sloj u varijablu trenutnog sloja

ali ne moras obavjestavati promatrace jer je

sloj jednak starom sloju

_udaraSloj = sloj

return

inace vrati da zraka udara u pozadinu i obavijesti

promatrace

_udaradistance = udaljenostDoPozadine

_udaraSloj = SlojKrajSvijeta

promatraciPromjeneSloja(udaraSloj)

RaycastHit BacanjeZrakaZaSloj(Sloj sloj)

kreira se maska za slojeve bit se pomice ulijevo za

onoliko mjesta koliki je redni broj prioriteta sloja

int maska = 1 ltlt (int)sloj

sprema se mjesto pozicije kursora pretvoreno iz tocke u

zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

RaycastHit udar

PhysicsRaycast sprema zraku u varijablu tipa

RaycastHit prima jos i maksimalnu udaljenost za koju

provjerava zraku i masku sloja i potom vraca istinu (

engl True) ili laz (engl False) ako je zraka udarila

u sloj

25

bool udarioJe = PhysicsRaycast(zraka out udar

udaljenostDoPozadine maska)

ako zraka udara u sloj vrati vrijednost udarca

if(udarioJe)

return udar

return null

U programskom kodu 51 se koristi funkcija za primjenu obrasca promatraca pod

nazivom delegat (engl Delegate) Što je obrazac promatraca (engl Observer) To je

oblikovni obrazac koji se u programiranju koristi

bull kad promjena jednog objekta zahtijeva promjene u drugim objektima koji nisu

unaprijed poznati

bull kad objekt treba obavještavati druge objekte

bull uz uvjet da bude što neovisniji o njima

bull kad je potrebno prikazivati razlicite aspekte nekog dinamickog stanja a želimo

izbjeci ciklicku ovisnost izmedu stanja i pogleda

bull kad postoje dva koncepta jedan ovisan o drugome a zgodno ih je razdvojiti

S obzirom na to da mi samo pri promjeni sloja želimo obavještavati pretplacene pro-

matrace uvodenje delegata nam dosta ubrzava kod Obrazac promatraca funkcionira

tako da glavni objekt igra ulogu izdavaca (izvora informacija) u ovom slucaju to je

glavna kamera Ostali ovisni objekti (promatraci) pretplacuju se kod izdavaca te iz-

davaci obavještavaju pretplatnike o promjenama Promatraci prekidaju pretplatu kad

više ne trebaju obavještavanje Funkcija priPromjeniSloja se definira kao delegat i u

ovom slucaju prima sloj Nakon toga se definira dogadaj (engl Event) tipa tog delegata

(priPromjeniSloja) u ovom slucaju naziva promatraciPromjeneSloja i odsad se unutar

subjekta tim nazivom i poziva Kako bi se neki promatrac pretplatio na informacije

koje izdaje kamera dodaje ove dvije linije koda u svoju skriptu

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

Programski kod 52 služi za kretanje korištenjem NavMesha i lijevog klika miša

26

Programski kod 52 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

public float dovoljnoBlizu = 01f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora

[SerializeField] float hodajKreciStaniRadijus = 02f

void Start ()

pronadi igraca koji je tipa agenta navigacijskog sustava

(engl NavMeshAgent)

agent = GetComponentltUnityEngineAINavMeshAgentgt()

pronadi prethodno napisanu klasu BacanjeZraka

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

spremi trenutnu poziciju kursora

trenutnaPozicijaKursora = transformposition

void Update()

ako je igrac dosao na zeljeno mjesto zaustavi animaciju

hodanja

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

ako je stisnut lijevi klik misa

if (InputGetMouseButtonDown(0))

ovisno o sloju primjeni akciju

switch(bacanjeZrakaudaraSloj)

ako se po objektu na koji je igrac kliknuo moze

hodati

27

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 28: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

Slika 52 Dodavanje novog sloja

public class BacanjeZraka MonoBehaviour

hijerarhija slojeva tj koji ima veci prioritet

public Sloj[] prioritetiSlojeva =

SlojNeprijatelj

SlojProhodno

SlojKrajSvijeta

udaljenost do pozadine je neka izmisljena vrijednost nakon

koje se prestane provjeravati zraka

public float udaljenostDoPozadine = 100f

Camera kamera

RaycastHit _udara

dohvaca varijable ove klase

public RaycastHit udara

get return _udara

Sloj _udaraSloj

23

Slika 53 Prozor za dodavanje novog sloja

public Sloj udaraSloj

get return _udaraSloj

deklariraj novi tip delegata

public delegate void priPromjeniSloja(Sloj noviSloj)

instanciraj skup promatraca

public event priPromjeniSloja promatraciPromjeneSloja

void Start ()

dohvat glavne kamere

kamera = Cameramain

void Update ()

nadi sloj po prioritetu u koji zraka udara

foreach(Sloj sloj in prioritetiSlojeva)

provjeravamo udara li zraka u neki od slojeva

24

var udar = BacanjeZrakaZaSloj(sloj)

if(udarHasValue)

_udara = udarValue

ako se sloj promjenio

if(_udaraSloj = sloj)

spremi novi sloj u varijablu trenutnog sloja

_udaraSloj = sloj

obavijesti promatrace da se sloj promjenio

promatraciPromjeneSloja(sloj)

spremi novi sloj u varijablu trenutnog sloja

ali ne moras obavjestavati promatrace jer je

sloj jednak starom sloju

_udaraSloj = sloj

return

inace vrati da zraka udara u pozadinu i obavijesti

promatrace

_udaradistance = udaljenostDoPozadine

_udaraSloj = SlojKrajSvijeta

promatraciPromjeneSloja(udaraSloj)

RaycastHit BacanjeZrakaZaSloj(Sloj sloj)

kreira se maska za slojeve bit se pomice ulijevo za

onoliko mjesta koliki je redni broj prioriteta sloja

int maska = 1 ltlt (int)sloj

sprema se mjesto pozicije kursora pretvoreno iz tocke u

zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

RaycastHit udar

PhysicsRaycast sprema zraku u varijablu tipa

RaycastHit prima jos i maksimalnu udaljenost za koju

provjerava zraku i masku sloja i potom vraca istinu (

engl True) ili laz (engl False) ako je zraka udarila

u sloj

25

bool udarioJe = PhysicsRaycast(zraka out udar

udaljenostDoPozadine maska)

ako zraka udara u sloj vrati vrijednost udarca

if(udarioJe)

return udar

return null

U programskom kodu 51 se koristi funkcija za primjenu obrasca promatraca pod

nazivom delegat (engl Delegate) Što je obrazac promatraca (engl Observer) To je

oblikovni obrazac koji se u programiranju koristi

bull kad promjena jednog objekta zahtijeva promjene u drugim objektima koji nisu

unaprijed poznati

bull kad objekt treba obavještavati druge objekte

bull uz uvjet da bude što neovisniji o njima

bull kad je potrebno prikazivati razlicite aspekte nekog dinamickog stanja a želimo

izbjeci ciklicku ovisnost izmedu stanja i pogleda

bull kad postoje dva koncepta jedan ovisan o drugome a zgodno ih je razdvojiti

S obzirom na to da mi samo pri promjeni sloja želimo obavještavati pretplacene pro-

matrace uvodenje delegata nam dosta ubrzava kod Obrazac promatraca funkcionira

tako da glavni objekt igra ulogu izdavaca (izvora informacija) u ovom slucaju to je

glavna kamera Ostali ovisni objekti (promatraci) pretplacuju se kod izdavaca te iz-

davaci obavještavaju pretplatnike o promjenama Promatraci prekidaju pretplatu kad

više ne trebaju obavještavanje Funkcija priPromjeniSloja se definira kao delegat i u

ovom slucaju prima sloj Nakon toga se definira dogadaj (engl Event) tipa tog delegata

(priPromjeniSloja) u ovom slucaju naziva promatraciPromjeneSloja i odsad se unutar

subjekta tim nazivom i poziva Kako bi se neki promatrac pretplatio na informacije

koje izdaje kamera dodaje ove dvije linije koda u svoju skriptu

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

Programski kod 52 služi za kretanje korištenjem NavMesha i lijevog klika miša

26

Programski kod 52 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

public float dovoljnoBlizu = 01f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora

[SerializeField] float hodajKreciStaniRadijus = 02f

void Start ()

pronadi igraca koji je tipa agenta navigacijskog sustava

(engl NavMeshAgent)

agent = GetComponentltUnityEngineAINavMeshAgentgt()

pronadi prethodno napisanu klasu BacanjeZraka

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

spremi trenutnu poziciju kursora

trenutnaPozicijaKursora = transformposition

void Update()

ako je igrac dosao na zeljeno mjesto zaustavi animaciju

hodanja

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

ako je stisnut lijevi klik misa

if (InputGetMouseButtonDown(0))

ovisno o sloju primjeni akciju

switch(bacanjeZrakaudaraSloj)

ako se po objektu na koji je igrac kliknuo moze

hodati

27

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 29: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

Slika 53 Prozor za dodavanje novog sloja

public Sloj udaraSloj

get return _udaraSloj

deklariraj novi tip delegata

public delegate void priPromjeniSloja(Sloj noviSloj)

instanciraj skup promatraca

public event priPromjeniSloja promatraciPromjeneSloja

void Start ()

dohvat glavne kamere

kamera = Cameramain

void Update ()

nadi sloj po prioritetu u koji zraka udara

foreach(Sloj sloj in prioritetiSlojeva)

provjeravamo udara li zraka u neki od slojeva

24

var udar = BacanjeZrakaZaSloj(sloj)

if(udarHasValue)

_udara = udarValue

ako se sloj promjenio

if(_udaraSloj = sloj)

spremi novi sloj u varijablu trenutnog sloja

_udaraSloj = sloj

obavijesti promatrace da se sloj promjenio

promatraciPromjeneSloja(sloj)

spremi novi sloj u varijablu trenutnog sloja

ali ne moras obavjestavati promatrace jer je

sloj jednak starom sloju

_udaraSloj = sloj

return

inace vrati da zraka udara u pozadinu i obavijesti

promatrace

_udaradistance = udaljenostDoPozadine

_udaraSloj = SlojKrajSvijeta

promatraciPromjeneSloja(udaraSloj)

RaycastHit BacanjeZrakaZaSloj(Sloj sloj)

kreira se maska za slojeve bit se pomice ulijevo za

onoliko mjesta koliki je redni broj prioriteta sloja

int maska = 1 ltlt (int)sloj

sprema se mjesto pozicije kursora pretvoreno iz tocke u

zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

RaycastHit udar

PhysicsRaycast sprema zraku u varijablu tipa

RaycastHit prima jos i maksimalnu udaljenost za koju

provjerava zraku i masku sloja i potom vraca istinu (

engl True) ili laz (engl False) ako je zraka udarila

u sloj

25

bool udarioJe = PhysicsRaycast(zraka out udar

udaljenostDoPozadine maska)

ako zraka udara u sloj vrati vrijednost udarca

if(udarioJe)

return udar

return null

U programskom kodu 51 se koristi funkcija za primjenu obrasca promatraca pod

nazivom delegat (engl Delegate) Što je obrazac promatraca (engl Observer) To je

oblikovni obrazac koji se u programiranju koristi

bull kad promjena jednog objekta zahtijeva promjene u drugim objektima koji nisu

unaprijed poznati

bull kad objekt treba obavještavati druge objekte

bull uz uvjet da bude što neovisniji o njima

bull kad je potrebno prikazivati razlicite aspekte nekog dinamickog stanja a želimo

izbjeci ciklicku ovisnost izmedu stanja i pogleda

bull kad postoje dva koncepta jedan ovisan o drugome a zgodno ih je razdvojiti

S obzirom na to da mi samo pri promjeni sloja želimo obavještavati pretplacene pro-

matrace uvodenje delegata nam dosta ubrzava kod Obrazac promatraca funkcionira

tako da glavni objekt igra ulogu izdavaca (izvora informacija) u ovom slucaju to je

glavna kamera Ostali ovisni objekti (promatraci) pretplacuju se kod izdavaca te iz-

davaci obavještavaju pretplatnike o promjenama Promatraci prekidaju pretplatu kad

više ne trebaju obavještavanje Funkcija priPromjeniSloja se definira kao delegat i u

ovom slucaju prima sloj Nakon toga se definira dogadaj (engl Event) tipa tog delegata

(priPromjeniSloja) u ovom slucaju naziva promatraciPromjeneSloja i odsad se unutar

subjekta tim nazivom i poziva Kako bi se neki promatrac pretplatio na informacije

koje izdaje kamera dodaje ove dvije linije koda u svoju skriptu

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

Programski kod 52 služi za kretanje korištenjem NavMesha i lijevog klika miša

26

Programski kod 52 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

public float dovoljnoBlizu = 01f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora

[SerializeField] float hodajKreciStaniRadijus = 02f

void Start ()

pronadi igraca koji je tipa agenta navigacijskog sustava

(engl NavMeshAgent)

agent = GetComponentltUnityEngineAINavMeshAgentgt()

pronadi prethodno napisanu klasu BacanjeZraka

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

spremi trenutnu poziciju kursora

trenutnaPozicijaKursora = transformposition

void Update()

ako je igrac dosao na zeljeno mjesto zaustavi animaciju

hodanja

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

ako je stisnut lijevi klik misa

if (InputGetMouseButtonDown(0))

ovisno o sloju primjeni akciju

switch(bacanjeZrakaudaraSloj)

ako se po objektu na koji je igrac kliknuo moze

hodati

27

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 30: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

var udar = BacanjeZrakaZaSloj(sloj)

if(udarHasValue)

_udara = udarValue

ako se sloj promjenio

if(_udaraSloj = sloj)

spremi novi sloj u varijablu trenutnog sloja

_udaraSloj = sloj

obavijesti promatrace da se sloj promjenio

promatraciPromjeneSloja(sloj)

spremi novi sloj u varijablu trenutnog sloja

ali ne moras obavjestavati promatrace jer je

sloj jednak starom sloju

_udaraSloj = sloj

return

inace vrati da zraka udara u pozadinu i obavijesti

promatrace

_udaradistance = udaljenostDoPozadine

_udaraSloj = SlojKrajSvijeta

promatraciPromjeneSloja(udaraSloj)

RaycastHit BacanjeZrakaZaSloj(Sloj sloj)

kreira se maska za slojeve bit se pomice ulijevo za

onoliko mjesta koliki je redni broj prioriteta sloja

int maska = 1 ltlt (int)sloj

sprema se mjesto pozicije kursora pretvoreno iz tocke u

zraku

Ray zraka = kameraScreenPointToRay(InputmousePosition)

RaycastHit udar

PhysicsRaycast sprema zraku u varijablu tipa

RaycastHit prima jos i maksimalnu udaljenost za koju

provjerava zraku i masku sloja i potom vraca istinu (

engl True) ili laz (engl False) ako je zraka udarila

u sloj

25

bool udarioJe = PhysicsRaycast(zraka out udar

udaljenostDoPozadine maska)

ako zraka udara u sloj vrati vrijednost udarca

if(udarioJe)

return udar

return null

U programskom kodu 51 se koristi funkcija za primjenu obrasca promatraca pod

nazivom delegat (engl Delegate) Što je obrazac promatraca (engl Observer) To je

oblikovni obrazac koji se u programiranju koristi

bull kad promjena jednog objekta zahtijeva promjene u drugim objektima koji nisu

unaprijed poznati

bull kad objekt treba obavještavati druge objekte

bull uz uvjet da bude što neovisniji o njima

bull kad je potrebno prikazivati razlicite aspekte nekog dinamickog stanja a želimo

izbjeci ciklicku ovisnost izmedu stanja i pogleda

bull kad postoje dva koncepta jedan ovisan o drugome a zgodno ih je razdvojiti

S obzirom na to da mi samo pri promjeni sloja želimo obavještavati pretplacene pro-

matrace uvodenje delegata nam dosta ubrzava kod Obrazac promatraca funkcionira

tako da glavni objekt igra ulogu izdavaca (izvora informacija) u ovom slucaju to je

glavna kamera Ostali ovisni objekti (promatraci) pretplacuju se kod izdavaca te iz-

davaci obavještavaju pretplatnike o promjenama Promatraci prekidaju pretplatu kad

više ne trebaju obavještavanje Funkcija priPromjeniSloja se definira kao delegat i u

ovom slucaju prima sloj Nakon toga se definira dogadaj (engl Event) tipa tog delegata

(priPromjeniSloja) u ovom slucaju naziva promatraciPromjeneSloja i odsad se unutar

subjekta tim nazivom i poziva Kako bi se neki promatrac pretplatio na informacije

koje izdaje kamera dodaje ove dvije linije koda u svoju skriptu

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

Programski kod 52 služi za kretanje korištenjem NavMesha i lijevog klika miša

26

Programski kod 52 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

public float dovoljnoBlizu = 01f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora

[SerializeField] float hodajKreciStaniRadijus = 02f

void Start ()

pronadi igraca koji je tipa agenta navigacijskog sustava

(engl NavMeshAgent)

agent = GetComponentltUnityEngineAINavMeshAgentgt()

pronadi prethodno napisanu klasu BacanjeZraka

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

spremi trenutnu poziciju kursora

trenutnaPozicijaKursora = transformposition

void Update()

ako je igrac dosao na zeljeno mjesto zaustavi animaciju

hodanja

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

ako je stisnut lijevi klik misa

if (InputGetMouseButtonDown(0))

ovisno o sloju primjeni akciju

switch(bacanjeZrakaudaraSloj)

ako se po objektu na koji je igrac kliknuo moze

hodati

27

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 31: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

bool udarioJe = PhysicsRaycast(zraka out udar

udaljenostDoPozadine maska)

ako zraka udara u sloj vrati vrijednost udarca

if(udarioJe)

return udar

return null

U programskom kodu 51 se koristi funkcija za primjenu obrasca promatraca pod

nazivom delegat (engl Delegate) Što je obrazac promatraca (engl Observer) To je

oblikovni obrazac koji se u programiranju koristi

bull kad promjena jednog objekta zahtijeva promjene u drugim objektima koji nisu

unaprijed poznati

bull kad objekt treba obavještavati druge objekte

bull uz uvjet da bude što neovisniji o njima

bull kad je potrebno prikazivati razlicite aspekte nekog dinamickog stanja a želimo

izbjeci ciklicku ovisnost izmedu stanja i pogleda

bull kad postoje dva koncepta jedan ovisan o drugome a zgodno ih je razdvojiti

S obzirom na to da mi samo pri promjeni sloja želimo obavještavati pretplacene pro-

matrace uvodenje delegata nam dosta ubrzava kod Obrazac promatraca funkcionira

tako da glavni objekt igra ulogu izdavaca (izvora informacija) u ovom slucaju to je

glavna kamera Ostali ovisni objekti (promatraci) pretplacuju se kod izdavaca te iz-

davaci obavještavaju pretplatnike o promjenama Promatraci prekidaju pretplatu kad

više ne trebaju obavještavanje Funkcija priPromjeniSloja se definira kao delegat i u

ovom slucaju prima sloj Nakon toga se definira dogadaj (engl Event) tipa tog delegata

(priPromjeniSloja) u ovom slucaju naziva promatraciPromjeneSloja i odsad se unutar

subjekta tim nazivom i poziva Kako bi se neki promatrac pretplatio na informacije

koje izdaje kamera dodaje ove dvije linije koda u svoju skriptu

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

Programski kod 52 služi za kretanje korištenjem NavMesha i lijevog klika miša

26

Programski kod 52 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

public float dovoljnoBlizu = 01f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora

[SerializeField] float hodajKreciStaniRadijus = 02f

void Start ()

pronadi igraca koji je tipa agenta navigacijskog sustava

(engl NavMeshAgent)

agent = GetComponentltUnityEngineAINavMeshAgentgt()

pronadi prethodno napisanu klasu BacanjeZraka

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

spremi trenutnu poziciju kursora

trenutnaPozicijaKursora = transformposition

void Update()

ako je igrac dosao na zeljeno mjesto zaustavi animaciju

hodanja

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

ako je stisnut lijevi klik misa

if (InputGetMouseButtonDown(0))

ovisno o sloju primjeni akciju

switch(bacanjeZrakaudaraSloj)

ako se po objektu na koji je igrac kliknuo moze

hodati

27

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 32: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

Programski kod 52 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

public float dovoljnoBlizu = 01f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora

[SerializeField] float hodajKreciStaniRadijus = 02f

void Start ()

pronadi igraca koji je tipa agenta navigacijskog sustava

(engl NavMeshAgent)

agent = GetComponentltUnityEngineAINavMeshAgentgt()

pronadi prethodno napisanu klasu BacanjeZraka

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

spremi trenutnu poziciju kursora

trenutnaPozicijaKursora = transformposition

void Update()

ako je igrac dosao na zeljeno mjesto zaustavi animaciju

hodanja

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

ako je stisnut lijevi klik misa

if (InputGetMouseButtonDown(0))

ovisno o sloju primjeni akciju

switch(bacanjeZrakaudaraSloj)

ako se po objektu na koji je igrac kliknuo moze

hodati

27

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 33: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

case SlojProhodno

spremi u trenutnu poziciju kursora mjesto na

koje je igrac kliknuo

trenutnaPozicijaKursora = bacanjeZrakaudara

point

pokreni animaciju kretanja

GetComponentltAnimatorgt()SetInteger(Move 1)

postavi odrediste agenta na poziciju gdje

je igrac kliknuo misem

agentdestination = trenutnaPozicijaKursora

break

case SlojNeprijatelj

print(Ne mogu hodati prema neprijatelju)

break

default

print(Neocekivani sloj)

return

funkcija za pomoc sa usporavanjem agenta na vrijeme

if (agenthasPath ampamp agentremainingDistance lt

dovoljnoBlizu)

agentdestination = new Vector3(thistransform

positionx agentdestinationy thistransform

positionz)

Takoder želi se dodati novi dizajn kursora pa se povuku psd datoteke koje su prona-

dene na Internetu na stranici Freepik u Unity Kako bi ih Unity doživljavao kao kursore

moraju im se promijeniti teksturu u Kursor (engl Cursor) kao na slici 54 i stisne se

na primijeni (engl Apply)

Programski kod 53 kursorcs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

28

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 34: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

Slika 54 Dodavanje dizajna kursora

trazi obavezno komponentu BacanjeZraka

[RequireComponent(typeof(BacanjeZraka))]

public class Kursor MonoBehaviour

teksture kursora

[SerializeField] Texture2D kursorZaHodanje = null

[SerializeField] Texture2D kursorZaNapad = null

[SerializeField] Texture2D nepoznatiKursor = null

pomak od gornjeg lijevog kuta teksture koji ce sluziti kao

ciljna tocka

[SerializeField] Vector2 kursorHotspot = new Vector2(0 0)

BacanjeZraka bacanjeZraka

void Start ()

nadi komponentu BacanjeZraka i pretplati se kao promatrac

bacanjeZraka = GetComponentltBacanjeZrakagt()

bacanjeZrakapromatraciPromjeneSloja += priPromjeniSloja

void priPromjeniSloja (Sloj noviSloj)

29

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 35: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

ovisno o novom sloju postavi teksturu kursora

switch(noviSloj)

case SlojProhodno

CursorSetCursor(kursorZaHodanje kursorHotspot

CursorModeAuto)

break

case SlojKrajSvijeta

CursorSetCursor(nepoznatiKursor kursorHotspot

CursorModeAuto)

break

case SlojNeprijatelj

CursorSetCursor(kursorZaNapad kursorHotspot

CursorModeAuto)

break

default

DebugLog(Ne znam koji kursor prikazati)

return

Još jedan slucaj kretanja je prikazan programskim kodom 53 Kako programirati

kretanje putem tipkovnice Pa vrlo jednostavno takoder samo i dalje se mora paziti

na pokretanje animacija Konacno mehanika kretanja je riješena programskim kodom

54

Programski kod 54 kretanjecs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

public class Kretanje MonoBehaviour

[SerializeField] float hodajKreciStaniRadijus = 02f

[SerializeField] float napadniKreciStaniRadijus = 5f

UnityEngineAINavMeshAgent agent

BacanjeZraka bacanjeZraka

Vector3 trenutnaPozicijaKursora tockaKlika

bool jeUDirektnomKretanju = false

30

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 36: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

float brzina = 50f

float brzinaRotacije = 50f

Use this for initialization

void Start ()

agent = GetComponentltUnityEngineAINavMeshAgentgt()

bacanjeZraka = CameramainGetComponentltBacanjeZrakagt()

trenutnaPozicijaKursora = transformposition

private void FixedUpdate()

stisni G za prebacivanje na upravljanje s tipkovnicom

misem

if(InputGetKeyDown(KeyCodeG))

promjeni tip upravljanja i spremi trenutnu poziciju

kursora

jeUDirektnomKretanju = jeUDirektnomKretanju

trenutnaPozicijaKursora = transformposition

ako se koristi tipkovnica

if (jeUDirektnomKretanju)

ugasi navigacijski sustav i pozovi funkciju kretanja

tipkovnicom

agentResetPath()

ProcesuirajDirektnoKretanje()

else

pozovi funkciju kretanja misem

ProcesuirajKretanjeMisem()

private void ProcesuirajDirektnoKretanje()

ako je pritisnuta tipka W pokreni animaciju kretanja i

pomakni se u smjeru prema naprijed za umnozak brzine i

vremena

31

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 37: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

if (InputGetKey(KeyCodeW))

GetComponentltAnimatorgt()SetInteger(Move 1)

thistransformTranslate(Vector3forward Time

deltaTime brzina)

inace ugasi animaciju kretanja

else

GetComponentltAnimatorgt()SetInteger(Move 0)

ako je pritisnuta tipka A rotiraj lika u suprotnom

smjeru kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeA))

thistransformRotate(Vector3up (-1)brzinaRotacije

)

ako je pritisnuta tipka D rotiraj lika u smjeru

kazaljke na satu za brzinu rotacije

if (InputGetKey(KeyCodeD))

thistransformRotate(Vector3up brzinaRotacije)

vec objasnjeno u prijasnjem kodu

private void ProcesuirajKretanjeMisem()

if (agentremainingDistance == 0)

thisGetComponentltAnimatorgt()SetInteger(Move 0)

agentvelocity = Vector3zero

if (InputGetMouseButtonDown(0))

tockaKlika = bacanjeZrakaudarapoint

switch (bacanjeZrakaudaraSloj)

case SlojProhodno

trenutnaPozicijaKursora = SkratiDestinaciju(

32

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 38: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

tockaKlika hodajKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

case SlojNeprijatelj

trenutnaPozicijaKursora = SkratiDestinaciju(

tockaKlika napadniKreciStaniRadijus)

GetComponentltAnimatorgt()SetInteger(Move

1)

agentdestination = trenutnaPozicijaKursora

agentspeed = 5f

break

default

print(Neocekivani sloj)

return

funkcija koja sluzi za zaustavljanje agenta prije same

destinacije odredene klikom misem sluzi za implementaciju

napadanja na daljinu

Vector3 SkratiDestinaciju(Vector3 destinacija float

skracenje)

Vector3 vektorRedukcije = (destinacija - transform

position)normalized skracenje

return destinacija - vektorRedukcije

funkcija za crtanje gizmoa

private void OnDrawGizmos()

Gizmoscolor = Colorblack

GizmosDrawLine(transformposition

trenutnaPozicijaKursora)

GizmosDrawSphere(trenutnaPozicijaKursora 01f)

GizmosDrawSphere(tockaKlika 015f)

napadanje na daljinu

33

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 39: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

Gizmoscolor = new Color(255f 0f 0 5f)

GizmosDrawWireSphere(transformposition

napadniKreciStaniRadijus)

Dodana je i funkcija OnDrawGizmos() u programskom kodu 54 koju Unity vec sa-

drži te je dostupna za vlastitu implementaciju Gizmo se koriste za vizualno traženje

grešaka u programskom kodu ili za postavljanje svojevrsne pomoci u pogledu scene

Ovdje se koriste da se lakše vidi gdje je kursor kliknuo na ekran naprema gdje ce se

igrac zaustaviti kao što se vidi na slici 55 u obliku dvije sfere [2]

Slika 55 Prikaz korištenja gizmo-a

Sve crtanje gizmoa se treba obaviti unutar funkcija OnDrawGizmos ili OnDrawGiz-

mosSelected OnDrawGizmos se poziva u svakom okviru dok se OnDrawGizmosSe-

lected poziva samo ako je objekt na kojem se skripta nalazi selektiran [2]

Funkcija skrati destinaciju je dodana kako bi lik krenuo usporavati ranije prije nego

što se npr zabije u zid te zbog buduce implementacije napadanja na daljinu

34

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 40: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

6 Korisnicko sucelje

Korisnicko sucelje je jedno od najbitnijih dijelova svake igre Obicno se koristi za

prikaz osvojenih nagradabodova preostalog života igraca trenutno korištenog oružja

i sl U ovom poglavlju se opisuju neki osnovni koncepti dodavanja korisnickog sucelja

u Unityu Cilj je da se do kraja poglavlja postavi linija s postotkom preostalog života

igraca te linije preostalih života iznad svakog neprijatelja u igri

61 Platno

Platno je objekt s komponentom platno (engl Canvas) na kojeg se slažu svi ostali

elementi korisnickog sucelja koji moraju onda biti djeca tog objekta Kreira ga se s

GameObject -gt UI (korisnicko sucelje (engl User Interface)) -gt Canvas ili bilo cime

iz GameObject -gt UI što automatski onda dodaje platno u scenu ako vec tamo ne

postoji Prikazuje se kao pravokutnik u sceni Svi elementi se crtaju na platno redom

kojim ih se složi u hijerarhiji (lijevi prozor u Unityu) prvo dijete se crta prvo drugo

se crta drugo itd Platno sadrži opciju nacin iscrtavanja (engl Render Mode) s kojom

se odreduje hoce li se platno prikazati u prostoru ekrana ili cijelog svijeta igre Prikaz

u prostoru ekrana se još dijeli i na prikaz u prostoru ekrana - prekrivanje (engl Screen

Space - Overlay) i prikaz u prostoru ekrana - kamera (engl Screen Space - Camera)

Prikaz u prostoru ekrana - prekrivanje iscrtava korisnicko sucelje i njegove elemente

na zaslon na vrhu scene Ako se promijeni velicina scene ili se promijeni rezolucija

platno ce takoder automatski promijeniti svoju velicinu Prikaz u prostoru ekrana -

kamera je slicno samo što ce se platno smjestiti na zadanu udaljenost ispred kamere

Elementi korisnickog sucelja ce biti prikazani tom kamerom što znaci da ce ostale

postavke kamere utjecati na prikaz Npr ako se za kameru odabere perspektivna

distorzija ona ce se odnositi i na te elemente Takoder ako se ekran smanji promjeni

rezoluciju i sl platno ce isto promijeniti svoju velicinu da odgovara kameri Preostaje

još prikaz u prostoru svijeta (engl World Space) Tu ce se platno ponašati kao svi

ostali objekti u sceni Može mu se promijeniti velicina koristeci opciju transformiraj

35

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 41: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

pravokutnik (engl Rect Transform) Njegovi elementi ce se prikazati ispred ili iza

ostalih objekata u sceni ovisno o 3D položaju [5]

62 Osnovne komponente

Osnovne komponente koje se dodaju na platno su tekst slike sirove slike (engl Raw

Image) i maska ciji primjer možemo vidjeti na slici 61 Komponenta tekst koja se još

naziva i oznaka (engl Label) ima podrucje za upisivanje teksta koji ce biti prikazan

Moguce je namjestiti font stil fonta velicinu i još ostale opcije za poravnavanje teksta

Slika 61 Osnovne komponente platna

Slika se sastoji od dvije komponente Rect Transform i komponente slike U

komponentu slike se obicno dodaje slika (engl Sprite) u polje ciljni graficki prikaz

(engl Target Graphic) i bira joj se boja u polju boja (engl Color) Takoder se može

dodati i materijal u komponentu slike Polje tip slike (engl Image Type) odreduje kako

ce dodana slika biti prikazana Neke od opcija su jednostavna (engl Simple) - jednako

skalira cijelu sliku rezana (engl Sliced) - koristi 3x3 podjelu slika da promjena veli-

cine ne iskrivi kuteve i samo se središnji dio razvuce poplocana (engl Tiled) - slicna

rezanoj samo se slike ponavljaju umjesto da se rastegnu popunjena (engl Filled) -

prikazuje na isti nacin sliku kao i jednostavni prikaz samo što popuni sliku od ishodi-

šta u zadanom smjeru metodi i kolicini Slike se mogu unijeti kao sprite korisnickog

sucelja tako da se odabere Sprite(2DUI) pod postavkama tip teksture (engl Texture

Type) Razlika izmedu slike i raw image-a je da raw image umjesto sprite slike prima

36

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 42: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

teksturu Maska služi kako bi modificirala izgled elemenata svoje djece Ona ogra-

nicava izgled elemenata djece na oblik roditelja Dakle ako je npr dijete vece od

roditelja prikazat ce se samo dio djeteta koje stane unutar oblika roditelja[ ]

63 Korisnicko sucelje igraca

Platno igre ovog projekta se sastoji od tri komponente teksta raw image-a i maske

Tabla koja prikazuje postotak života igraca lako se izradi koristeci program Bojanje

(engl Paint) u kojem napravimo liniju 2048x32 piksela koju podijelimo na dva dijela

Jedan dio se oboja zelenom bojom a drugi crvenom Maska je isto jedna linija velicine

2048x128 piksela koja ce služiti kao okvir Kreira se platno sa Component -gt UI -gt

Canvas Na njega se doda desnim klikom miša UI -gt Tekst (engl Text) cije postavke se

mogu vidjeti na slici 62 Tablu života i masku table života se obje dodaju jednaki pos-

tupkom samo dodamo raw image umjesto teksta UI -gt Raw Image Njihove postavke

se takoder mogu vidjeti na slici 63 Na tablu života se sada dodaje skripta prikazana

programskim kodom 61 koja ce translatirati tu sliku lijevodesno ovisno o preostalom

postotku života igraca

Programski kod 61 tablaZivotaIgracacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

[RequireComponent(typeof(RawImage))]

public class TablaZivotaIgraca MonoBehaviour

RawImage slikaTableZivota

GospodinLijepi gospodinLijepi

void Start()

nadi igraca i sliku table zivota

gospodinLijepi = FindObjectOfTypeltGospodinLijepigt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

37

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 43: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

pomici sliku table zivota po x osi za xVrijednost koja

ovisi o postotku zivota igraca

float xVrijednost = -(gospodinLijepipostotakZivota 2f)

- 05f

slikaTableZivotauvRect = new Rect(xVrijednost 0f 05f

1f)

Konacan izgled korisnickog sucelja igraca može se vidjeti na slici 64

Slika 62 Postavke teksta u korisnickom sucelju

64 Korisnicko sucelje neprijatelja

Za ovaj primjer izmodelirani su neprijatelji u obliku vuka Jednakim postupkom kao i

ostali blend modeli povlacenja iz datoteke u kojoj se nalaze se unose u Unity Na njih

se dodaje jednostavna skripta prikazana programskim kodom 62 koja ce odredivati

njihov postotak života

Programski kod 62 neprijateljcs

using SystemCollections

using SystemCollectionsGeneric

38

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 44: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

Slika 63 Postavke table života i maske table života u korisnickom sucelju

using UnityEngine

public class Neprijatelj MonoBehaviour

[SerializeField] float punZivot = 100f

float trenutnoZivota = 100f

vraca postotak zivota neprijatelja

public float postotakZivota

get

return trenutnoZivota punZivot

Takoder im se mora postaviti layer na Neprijatelj Sad se na neprijatelja desnim

klikom dodaje Create Empty objekt koji ce nam služiti za implementaciju korisnickog

39

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 45: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

Slika 64 Trenutno korisnicko sucelje igre

sucelja neprijatelja Na taj prazni objekt dodaje se nova skripta prikazana programskim

kodom 63

Programski kod 63 platnoNeprijateljacs

using UnityEngine

public class UINeprijatelja MonoBehaviour

[SerializeField] GameObject platnoNeprijatelja = null

Camera kamera

void Start()

nadi glavnu kameru i postavi platno neprijatelja na

poziciju neprijatelja

kamera = Cameramain

Instantiate(platnoNeprijatelja transformposition

Quaternionidentity transform)

void LateUpdate()

okreci platno neprijatelja ovisno o smjeru pogleda kamere

transformLookAt(kameratransform)

transformrotation = QuaternionLookRotation(kamera

transformforward)

40

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 46: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

Ta skripta zahtjeva dodavanje platna neprijatelja koje se sastoji samo od table života

Dakle kreira se novo platno i na njega opet raw image table života jednaka kao i kod

platna igraca bez maske i bez teksta To platno se sada može povuci u polje zahti-

jevanog platna neprijatelja skripte Jedina razlika je što ce taj raw image table života

neprijatelja sada na sebi imati prilagodenu skriptu neprijatelju prikazanu programskim

kodom 64

Programski kod 64 tablaZivotaNeprijateljacs

using SystemCollections

using SystemCollectionsGeneric

using UnityEngine

using UnityEngineUI

public class TablaZivotaNeprijatelja MonoBehaviour

RawImage slikaTableZivota = null

Neprijatelj neprijatelj = null

void Start()

pronadi neprijatelja i sliku njegove table zivota

neprijatelj = GetComponentInParentltNeprijateljgt()

slikaTableZivota = GetComponentltRawImagegt()

void Update()

pomici po x osi sliku table zivota ovisno o postotku

zivota neprijatelja

float xValue = -(neprijateljpostotakZivota 2f) - 05f

slikaTableZivotauvRect = new Rect(xValue 0f 05f 1f)

41

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 47: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

7 Teren

Sustav za teren koji Unity nudi omogucava dodavanje razlicitih pejzaža u igre Prikaz

terena je jako optimiziran te se teren mijenja i kreira koristeci jednostavne alate Izra-

divanje visinskih mapa i poligona matrica za kretanje programeru obicno predstavlja

poveci problem i uzima dosta vremena Unity to spušta na jako nisku razinu znanja

omogucavajuci korisniku da samo povlacenjem miša mijenja visine brda i dolina svo-

jeg terena Cilj ovog poglavlja je izraditi okvirno teren za igru i nauciti bojati teren

razlicitim teksturama [4]

71 Kreiranje i uredivanje terena

Teren se u scenu dodaje postupkom GameObject -gt 3D Object -gt Teren (engl Ter-

rain) iz menija Dobije se velika ravnina bez ikakvih visinskih anomalija No zato u

prozoru novostvorenog terena postoje mnogi alati za kreiranje raznih detalja kao što se

vidi na slici 71 Vecina alata su zapravo kistovi sa svojim opcijama za velicinu kista

i prozirnost Koristeci te kistove teksture se doslovno bojaju po terenu Skroz lijevi

alat na slici 71 služi za spuštanje ili podizanje terena Ovisno o obliku kista velicini i

jakosti kreiramo razlicite oblike planina dolina i sl Svi alati osim alata za postavljanje

drveca imaju jednake opcije i služe za dodavanje boje biljaka visine i sl [4]

72 Visinske mape

Na slici 72 vidimo tri alata koja služe za mijenjanje visine terena Prvi gumb aktivira

alat za podizanje i spuštanje terena Kada se teren boja s ovim alatom visina ce

se mijenjati kako se prelazi lijevim klikom miša po terenu Visina se povecava ako

se dulje vrijeme drži lijevi klik miša na istom podrucju Ako se drži i shift i lijevi

klik miša visina se spušta Primjer kreiranog terena za projekt može se vidjeti na slici

73 Drugi alat s lijeva na slici 72 je slican osim što se dodatno može odrediti tocno

željena visina Kada se s njime boja po terenu teren ce se spustiti na podrucjima

42

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 48: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

Slika 71 Alati za kreiranje terena

iznad zadane visine i povisiti na podrucjima ispod nje Takoder ako se želi postaviti

visina na neku koja vec postoji na terenu koja je bila vec korištena ali se ne zna njen

iznos držeci shift klikne se lijevim klikom miša na to podrucje na terenu i postavit

ce se visina alata na tu Uz tu opciju postavljanja visine na zadani iznos postoji i

opcija izravnaj (engl Flatten) koja postavlja cijeli teren na odabranu visinu U ovom

projektu je teren izravnat odmah na visinu 100 kako bi se omogucilo dodavanje dolina

rijeka i sl Ako se teren nalazi na unaprijed zadanoj visini 0 cak i držeci shift ne

može se dodatno spustiti teren jer ne može ici u negativan iznos Treci i zadnji alat

izgladi visinu (engl Smooth Height) ne podiže ni spušta teren znacajno vec izracuna

prosjecnu vrijednost podrucja u blizini To ublažava razliku visina i služi da se teren

neprimjetnije mijenja Visina svake tocke terena je zapravo vrijednost u pravokutnom

nizu Taj niz se može predstaviti koristeci sliku u sivim tonovima koja se zove visinska

mapa (engl Heightmap) Ponekad je bolje raditi na visinskoj mapi u nekom vanjskom

uredivacu kao npr Photoshop-u Unity omogucava uvoz i izvoz visinskih mapa za

teren Na slici 71 se nalazi skroz desni gumb koji predstavlja opcije terena klikom na

njega pojavit ce se dodatna dva gumba uvezi sirovo (engl Import RAW) i izvezi sirovo

(engl Export RAW) Oni omogucuju da se cita iz visinskih mapa ili da se piše u njih

u standardnom RAW formatu koji je 16-bitni format u sivim tonovima kompatibilan s

vecinom uredivaca slika [4]

43

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 49: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

Slika 72 Alati za mijenjanje visine terena

Slika 73 Primjer kreiranog terena

73 Teksture za teren

Teksture su slike koje se stavljaju na površinu terena da mu se doda detalja boje itd S

obzirom na to da su tereni veliki objekti uobicajeno se dodaju teksture koje se nepri-

mjetno ponavljaju i poplocaju cijelu površinu Ponavljanje ne bi trebalo biti primjetno

igracu Jedna tekstura ce služiti kao bazna tekstura po kojoj se dodaju detaljnije teks-

ture i boje Na slici 71 središnji alat u obliku kista predstavlja alat za bojanje tekstura

U pocetku teren nema nikakvih tekstura za bojanje Nove teksture se dodaju klikom na

uredi teksture (engl Edit Textures) i selektiranjem dodaj teksture (engl Add Texture)

To otvara prozor kao na slici 74 gdje se dodaje tekstura i njene opcije Klikom na se-

lektiraj (engl Select) pojavljuju se teksture koje su od prije ubacene u projekt u odvo-

jenom prozoru Opcija velicine (engl Size) omogucava postavljanje visine i duljine

preko koje ce se tekstura razvuci na površini terena Pomak (engl Offset) odreduje

koliko ce daleko od ishodišta terena poceti poplocavanje teksturom kada je postav-

ljen na 0 poplocavanje pocinje iz desnog kuta Prva tekstura koja se doda se koristi kao

bazna tekstura i prekrit ce cijeli prethodno napravljeni teren Sve ostale teksture koje se

naknadno dodaju mogu se stavljati po terenu koristeci alate kista Opet se postavljaju

opcije vidljivosti i velicine kista te se lijevim klikom miša samo bojaju po terenu [4]

44

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 50: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

Slika 74 Dodavanje novih tekstura za teren

45

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 51: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

8 Zakljucak

Unity je razvojna okolina koja pruža beskonacno mnogo razlicitih mogucnosti Kroz

ovaj rad su se obradile neke osnovne tehnike koje pomažu citatelju da postavi sve

osnovne stvari potrebne za kreiranje scena i nivoa u svojoj igri Znanje objektno ori-

jentiranog programiranja i racunarske grafike sigurno pruža prednost pri proucavanju

materijala Krenulo se od prazne scene i bez ikakvog predznanja rada s Unityem Za

svaki problem na koji se naišlo postojao je veliki broj razlicitih rješenja ali su unutar

ovog rada bolje ili lošije riješeni na ovaj nacin Svaka igra je posebna i sastoji se od

vlastitih mehanika i problema tako da ne postoji jedan algoritam po kojem se može

kreirati potpuno funkcionalna igra Potrebna je velika kolicina vremena i široko po-

drucje znanja da se samostalno isprogramira i dizajnira sve željene komponente Unity

je definitivno odlican alat za pocetnike koji pomaže pri snalaženju i ucenju najcešce

korištenih rješenja u svijetu kreiranja igara

46

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 52: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

9 Zasluge

Kursore napravio Freepik od Flaticon licencirano Creative Commons BY 30

47

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 53: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

LITERATURA

[1] Unity User Manual (20171 beta) Cameras URL httpsdocsunity3d

com20171DocumentationManualCamerasOverviewhtml

[2] Unity User Manual (20171 beta) Gizmos URL httpsdocsunity3d

comScriptReferenceGizmoshtml

[3] Unity User Manual (20171 beta) Navigation and Pathfinding URL

httpsdocsunity3dcom20171DocumentationManual

Navigationhtml

[4] Unity User Manual (20171 beta) Terrain Editor URL https

docsunity3dcom20171DocumentationManual

script-Terrainhtml

[5] Unity User Manual (20171 beta) UI URL httpsdocsunity3dcom

20171DocumentationManualUISystemhtml

[6] Cupic i Mihajlovic Interaktivna racunalna grafika kroz primjere u OpenGL-u

2016

48

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 54: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

Izrada digitalnih 3D igara u razvojnoj okolini Unity

Sažetak

Postavlja se pocetna scena i unosi blend model glavnog lika Rješavaju se problemi

vezani uz animacije hodanje gravitaciju svijeta i kontrole Objašnjavanje razlicitih vr-

sta kamera i bacanja zraka te biranje prave kamere za igru u projektu Implementacija

navigacijskog sustava i kodiranje kontrola kretanja Kreiranje korisnickog sucelja za

igraca i neprijatelje Izrada terena i dodavanje tekstura terenu

Kljucne rijeci Unity blend model kamera navigacijski sustav teren korisnicko

sucelje animacije kretanje bacanje zraka

Creating 3D games in Unity game engine

Abstract

Creating a scene and importing blend model of the main game character Dealing

with animation moving gravitation of the world and control problems Explaining

different camera versions and ray casting choosing the right camera for the game in

the project Implementing NavMesh system and coding moving controls Creating a

user interface for the player and the enemies Creating terrain and adding textures to

it

Keywords Unity blend model camera NavMesh terrain user interface animations

moving ray casting

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 55: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

POPIS MODELA

Svi modeli napravljeni u Blenderu skupa sa svojim teksturama i materijalima su uklju-

ceni u ovaj završni rad Njihov popis nalazi se ispod

bull lik viteza (GospodinLijepi)

bull drvo

bull drvo1

bull drvo2

bull mac

bull vuk

bull srednjovjekovna kuca

bull most

bull drvena kabina

50

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura
Page 56: Izrada digitalnih 3D igara u razvojnoj okolini Unity · brojem 2 na slici 2.2 stisne se desni klik i odabere kreiraj (engl. Create) i C# skripta (engl. C# Script) da se doda nova

POPIS PROGRAMSKIH KODOVA

21 HelloWorld1cs 5

22 HelloWorld2cs 5

41 PrimjerViseKameracs 13

42 pratiLikacs 15

43 lociranjeKursoracs 17

44 povecavanjeSlikecs 18

51 bacanjeZrakacs 22

52 kretanjecs 27

53 kursorcs 28

54 kretanjecs 30

61 tablaZivotaIgracacs 37

62 neprijateljcs 38

63 platnoNeprijateljacs 40

64 tablaZivotaNeprijateljacs 41

51

  • Uvod
  • Postavljanje pocetne scene
    • Instalacija
    • Kreiranje prve scene
    • Razvojna okolina Unity
    • Konzola
    • Programski jezik
      • Unos glavnog lika u scenu
        • Skaliranje
        • Kreiranje osnovnih objekata
        • Unos Blender modela u Unity i pocetni problemi
          • Kamera
            • Perspektivna i ortografska kamera
            • Pogled iz prvog lica u pogled iznad glave
            • Fiksirana kamera
            • Bacanje zraka (engl Ray casting)
              • Kretanje
                • Navigacijski sustav u Unityu
                • Pronalazak puta
                • Kreiranje navigacijskog sustava
                • Programiranje kretanja
                  • Korisnicko sucelje
                    • Platno
                    • Osnovne komponente
                    • Korisnicko sucelje igraca
                    • Korisnicko sucelje neprijatelja
                      • Teren
                        • Kreiranje i ureivanje terena
                        • Visinske mape
                        • Teksture za teren
                          • Zakljucak
                          • Zasluge
                          • Literatura