Sunteți pe pagina 1din 79

Ministerul Educatiei al Republicii Moldova

Universitatea Tehnica din Moldova


Facultatea de Calculatoare
Informatica si Microelectronica

LUCRAREA DE CURS SDA.

CREAREA UNUI JOC IN UDK.

Autor:

St.Gr. T.I.-132 Antoci Tudor

Profesor:

Lector Superior Mihai Kulev

LUCRAREA DE
CURS SDA

CUPRINS
Introducere1
Interfaa UDK.............2

CREAREA UNUI JOC IN UDK.

Geometria UDK..........4

Introducere.

Content Browser........6

Motor de joc reprezinta compoenentul central de


programare a jocurilor pe calculatorvsau al altor aplicatii
interactive cu grafica ce se prelucreaza in timp direct.
El ofera tehnologiile de baza, simplifica proiectarea
jocului si in multe cazuri
permite ca una si aceeasi joaca sa se porneasca pe mai
multe platforme, precum:GNU/Linux, Mac OS X sau
MIcrosoft Windows.
Functiile de baza ale unui motor de jocuri este
interfata grafica, fizica,sunetul, sistema de scripturi,
animatia, inteligenta artificiala si codul network.Deseori
se foloseste acelasi motor de jocuri la mai multe proiecte
pentru a reduce costul si timpul crearii mai multor jocuri.

ISTORIC
Unreal Engine este un motor de jocuri creat si sustinut
de compania Epic Games. Prima joaca , care a fost
creata pe motorul dat este Unreal, a aparut in 1998. Deatunci diferite versiuni ale acestui motor au fost folosite
pentru a unui numar extrem de mare de jocuri precum:
Deus Ex, Dishonored, Lineage II, Thief:Deadly Shadows,
Postel2, seriile de jocuri: Brothers in Arms, Tom Clancy's
Splinter Cell, Tom Clancy's Rainbow Six, de-asemenea si
proiectul de baza de la Epic Games - Unreal
Tournament.Chiar daca Unreal Engine era proiectat in
special pentru jocuri FPS, el este folositfoarte des si la
crearea RTS,RPG,Arcade,Racing etc.

Colizia....................9
Actor Classes.......11
Lumina......................17
Kismet.......................28
Ui.......................30
Lumina................37
Anunuri..............40
I.A........................42
CheckPoint.........44
Finisarea...................45
Visual Studio.......45
Logo....................48
Conculuzia................48

Bibliografia...............49

Interfata.
UDK are o interfata destul de comoda , unde toate tool-urile mereu
stau sub mina, ceea ce face acest motor mult mai atractiv pe fonul
altora precum CryEngine sau Unity.

Bara laterala
In fig.1 sunt prezente instrumentele de modelare a
nivelului:Geometry Mode permite de schimbat dimensiunele
brush-urile deja create, sau extinderea lor. Butonul Terrain si
Landscape deschide accesul la crearea reliefului si a terenului.
In fig.2 sunt prezente instrumentele geometrice Geometry Brush
cu ajutorul carora se creaza geometria nivelului.
In fig.3 sunt prezente posibilitatile de transformare a brush-urilor
geometrice in dependenta de ceea ce doreste utilizatorul.
In fig.4 sunt prezente posibilitatile de transformare a obiectului
geometric intr-unul de volum. (ex: pentru a crea apa, magma ,
lumina etc.)

Bara Superioara

Bara superioara contine cele mai multe butoane de pe interfata UDK, insa asta nu
trebuie as sperie, totul este foarte intuitiv si usor de folosit.
Butonul din fig.1 permite schimbarea unghiului de vizionare a nivelului in editor
(din fata , din stinga , de sus si din perspectiva) iar la dreapta de dinsul este
prezent butonul ce permite vizionarea nivelului creat in timp-direct (real-time
pentru ca toate efectele si animatiile sa functioneze)
Butoanele din fig.2 permite afisarea nivelului sub diferite forme:doar geometria,
geometria poligonala, geometria cu material fara calculul luminii si cu calculul
luminii.
Butonul din fig.3 permite vizionarea nivelului in acel mod cum el va fi privit de
catre jucator.
Butoanele din fig.4 schimba viteza de miscare a camerei in viziunea din
perspectiva.
Butoanele din fig.5 si 10 pornesc nivelul din editor, butonul 5 din fereastra de
vizionare a nivelului , iar 10 il deschide intr-o fereastra noua.
Butoanele 6,7,8 deschid:Content Browserul, Kismetul si Matinee (mai jos vor
fi explicate functia la toate acestea)
Butoanele din fig.9 ofera insturmente de redactarea a obiectelor din nivel, precum
miscarea lor, marirea,micsorarea scalara si non-scalara si rotirrea lor.
Butonul 11 aprinde sunetul din nivel in editor.
Butoanele din fig.12 sunt vital necesare deoarece ele pornesc functia de
recalcularea a nivelului:construirea obiectelor geometrice,construirea luminii
(recalcularea ei), construirea pathnod-uriloe (obiectelor de interactiune a
jucatorului si a intelegentii artificiale)
Iar butonul 13 porneste nivelul in modul final al editarii, asa cum va arata cind
proiectul va fi finisat.

Ferestrele de navigare

Navigarea in editor prin nivel se indeplineste prin ferestrele de vizionare: 1. Din


fata, 2.din stinga , 3.de sus si 4.din perspectiva.

Geometria.
Geometria nivelului in UDK se creaza (daca nu e importat din alte programe 3D)
prin intermediul instrumentelor Brush
1.Brush cubic
2.Brush conic.
3,5,6. Brush-uri pentru scari.
4.Brush cilindric
7.Brush poligonal.
8.Brush de plan.
9.Brush sferic.
Indiferent de faptul ca sunt tocmai 9 brush-uri, ele in folosinta sunt similare.
Pentru a accesa vreun brush e nevoie de facut click pe butonul sting pe
pictograma necesara, astfel se va crea brush-ul ales de utilizator cu dimensiunele
implicite, insa pentru a oferi propriile dimensiuni , e nevoie de accesat pictograma
cu click-ul pe butonul drept.

( A fost efectuat click drept pe


brush-ul cubic)
In fereastra Brush Builder la
forma cubica, utilizatorul poate
introduce dimensiunele dupa cele 3
axe de coordonate X,Y,Z (NOTA
BENE: in 3D designing este o regula
de aur, toate dimensiunele trebuie
sa fie puterea lui doi (power of
two) adica este mult mai bineprimit
cind dimensiunele nu sunt 100,200
ci 128, 256 etc.)
Tot in aceasta fereastra se poate de
ales grosimea peretilor acestui cub
Wall Thickness
Se poate de oferit nume brush-ului geometric creat de utilizator Gropu Name.
Bifarea cimpului Hollow va crea in interiorul cubului nostru altul mai mic, cu
diferenta de dimensiune egala cu grosimea peretilor (din wall thickness), aceasta
functie se foloseste atunci cind se creaza camere sau case.
De-asemenea se face si la alte brushuri (este accesat brush-ul de scari
curboase)
In Inner Radius se introduce raza
scarilor
In Step Height inaltimea scarilor
In Step Width lungimea scarilor
Angle Of Curve raspunde pentru
curba proeictate de scari, in cazul dat
curba e de 90 de grade.
In Num Steps se introduce
numarul de scari in constructia
geometrica.
Iar Add To First Step se foloseste pentru a adaoga aditional citeva scari sub
prima.

Mai sus a fost explicat cum de consturit un contur prin Builder Brush, insa asta
inca nu e obiectul finalizat, e doar conturul lui, pentru a oferi acesuti contur careva
proprietati fizice, e nevoie de accesat una din optiunele din CSG
1.CSG Add ofera conturului nostru o forma fizica plina.
2.CSG Substract Taie dintr-un obiect deja creat fizic,
obiectul de contur (brush-ul de sus).
3.CSG Intersect Creaza un brush de contur dupa forma
intersectiei a conturului nostru cu un obiect geometric fizic, deja
creat.
4.CSG Deintersect e anapoda la optiunea precedenta, creaza
un brush de contur, fara elementele ce se interseactea cu alt obiect geometric fizi,
deja creat.

Content Browser.

Content Browserul in UDK reprezinta utilita de accesare a modeleleor,


sunetelor, materialeleor, skelet mesh-urilor etc. Este aidoma unei biblioteci cu
toate elementele de gameplay care pot doar sa existe. Prin content browser se
adaoga obiecte in nivel, se creaza materiale noi (cu folosirea kismetului) se
importa si se exporta diferite elemente, se aranjeaza toate modelele asa cum e
comod utilizatorului, se adaoga diferite proprietati la modele, obiecte sau mesh-uri
precum colizie sau posibilitatea de farmitare a obiectului.
In Content Browser obiectele se impart in mai multe categorii
Animation-Animatia
Materials-Materiale (texturi 3D)
Particycle System Systemul de particule
Skeletal Mesh- Plasa scheletica
Sounds- Sunete
Static Mesh Plasa statica (obiectele 3D)
Textures- Texturi (2D)

Materiale

Dupa ce este creat obiectul geometric fizic, el trebuie imbracat cu un material.


(NOTA BENE: Material si textura sunt 2 lucruri diferite, Textura e doar imagine 2D,
Materialul e un sistem complex de functii matematice aplicate pe o textura care ii

ofera o anumita iluminare, reflectie (albido) si umbre pentru a oferi un anumit


volum)
Pentru a adaoga un material de-asupra la obiectul nostru, trebuie sa accesam
Content Browser>Materials, facem click pe materialul dorit, iar apoi click dreapta
pe obiectul nostru fara material si aplly material

Dupa cum putem observa, uneori materialul nu se pune drept si uniform, de-aceea
apasat click drept (dintii inseram toate suprafetele) si accesam Surface
Propoerties.

Pentru ca materialul sa se aseze bine pe suprafata, trebuie de ales alinierea


necesara (Aligment) in cazul nostru ele trebuie sa fie complanare (planar) apoi
apply. In acelasi compartiment poate fi setat alinierea dupa boxa(box) si
intinderea dupa suprafata (fit), mai sus avem meniul Scaling unde putem sa
marim textura noastra ori s-o micsoram, iar inca mai sus Pan prin acest meniu
putem sa miscam materialul nostru in granita formei geometrice orizontal (V) si
vertical (U) pentru a aranja textura.
Colizia- reprezinta proprietatea de ciocnirea obiectelor, adica daca obiectul nu are
colizie, atunci modelul jucatorului va trece prin obiectul dat.
Unele obiecte in Content Browser
sunt lipsite de colizie pentru ca ele
mai repede sa se incarce si sa nu
foloseasca resurse suplimentare ale
sistemului daca nu e nevoie.
Pentru a adaoga colizie , este
nevoie de a gasit obiectul dorit in

Conent Browser si de facut dublu-click pe dinsul.


(Va aparea fereastra data)

Apoi este nevoie de facut click pe show colision (fig.1)(pentru ca sa ne arate


schematic poligoanele coliziei) dupa aceasta de accesat Collision (fig.2) si de
ales Auto Convex Colission.
In fereastra Convex Decomposition putem da obiectului numarul de poligoane
si taisuri pentru a oferi lui colizie sau sistem de farmitare (in cazul nostru doar
colizie)
Cu cit mai mult vom misca cursorul (slider-ul) in dreapta, cu atit mai multe
poligoane va avea obiectul nostru si de mai multe resurse va fi nevoie pentru
recalcularea nivelului.
In cazul nostru ridicam:
Depth pina la 7
Max Hull Verts pina la 24
Allow Splits pina la 27
Apoi apasam Apply Gata obiectul nostru a primi colizie.

10

Actor Classes

11

Din utilita Content Browser poate fi accesata fereastra Actor Classes care contine
toate obiectele interactive din Content Browser, prin Actor Classes se poate de
adaogat in proiectul nostru: arme, vehicule, jumpadu-uri, healthpack-uri, amunitie
si multe altele precum vint, sunet,apa, lumina, efecte etc.

Arme
Pentru a adaoga arme prin Actor Classes in UDK selectam
NavigationPoint>PickUpFactory>UDKPickUpFactory>UTPickUpFactory>UTWeaponL
ocker_Content
(desigur se poate deodata de ales Pickups>Weapon>UTWeaponLocker_Content ,
insa in cazul dat armele vor fi vazute doar de jucator, iar botii (inteligenta
artificiala) nu va putea interactiona cu ele , de-aceea in pirmul caz noi alegem
NavigationPoint ca I.A. al nostru sa le recunoasca.)

Apoi facem click pe obiectul UTWeaponLocker_Conent dupa asceasta click


drept unde dorim noi sa apara acest obiect in nivelul nostru si alegem Add
UTWeaponLocker_Conent Here. [Referinta la codul sursa: ShockRifle]
Acum acestui
obiect trebuie
de oferit
anumite
proprietati ca
sa fie
prezente
armele care
noi dorim sa
le oferim.

12

UTWeaponLocker reprezinta o zona in care intra jucatorul si imediat primeste


anumite arme, poate fi una sau mai multe.
Pentru a configura acest obiect , accesam prina linie UTWeapon Locker facem
click pe + si alegem arma care dorim s-o adaogam (Rocket
Launcher,Shock Rifle sau Link Gun), pentru a adaoga mai multe arme ,
mai apasam pe + atit cite arme dorim sa adaogam.

Jumpad
Jumpad-ul reprezinta o zona in care intra jucaturul si imediat este aruncat, printro sariturat in alt loc, progrmat de noi.
Pentru a adaoga un Jumpad trebuie dintii sa-l gasim in Actor Classes :
NavigationPoint>PickUpFactory>UDKPickUpFactoryUTPickUpFactory>UTP
owerPickUpFactory>UTPickUpFactory_JumpBoots

Acum trbeuie sa configuram acest obiect.

13

Pentru ca Jumpad-ul nostru sa functioneze, trebuie dintii de creat unde noi dorim
sa aterizeze jucatorul un PathNode, pentru asta e nevoie de apasat pe click
drept si alegem Add Actor>Add PathNode
Apoi intram in setarile jumpad-ului creat mai inainte (accesam meniul prin
inserarea obiectului (jumpad) si apasarea tastei F4)
Dupa inseram pathnode-ul creat si in meniul Jumpad-ului , in compartimentul
UDKJump Pad la linia Jump Target apasam pe sageata <= , astfel se va
copia numele pathnode-ului impreuna cu coordonatele sale si se va transfera la
jumpad ca acesta sa calculeze traiectoria zborului personajului.
Acum daca prsonajul se va atinge de jumpad-ul nostru, el va fi lansat in zbor spre
punctul de pathnode.

Vehicul
Vehicolele in UDK se adaoga la fel cum si obiectele de mai sus, adresa lui fiind:
NavigationPoint>UDKVehicleFactory>UTVehicleFactory>UTVehicleFactory
_Cicada [Referinta la codul sursa: UTVehicle_Cicada]

14

Teleport
Teleportul in UDK are functia de a teleporta jucatorul dintr-un punct in altul ,
indiferent daca sunt obstacole geometrice. El lucreaza dupa acelasi principiu cum
si Jumpad-ul, este nevoie de un pathnode care va fi introdus ca target (URL)
in proprietatile teleportului (F4), adresa lui fiind :
NavigationPoint>Teleporter>UDKTeleporter>UTTeleporter

15

[Referinta la codul sursa:UTTeleport]

Obiectele
Toate obiectele in UDK , indiferent daca sunt adaogate prin Content Browser sau
din Actor Classes, pot fi miscate, rotite, micsorate-marite scalar si non-scalar.
1.Pentru a misca obiectul , e nevoie doar de
facut click sting pe dinsul si va aparea axele
de miscare: XYZ.

16

2.Pentru a micsora sau mari obiectul e nevoie


de ales (precum am facut mai sus) si apoi de
apasat space o singura data, miscind
cursorul dupa axe obiectul se va mari sau
micsora.

3. Pentru a roti obiectul, e nevoie sa alegeti


obiectul dat, apoi sa apasati de doua ori
space, acum este posibilitatea de a roti
obiectul adiacent axelor de coordonate.

Lumina.
Lumina este unul din cele mai importante elemente a unui joc, datorita luminii se
paote de creat o atmosfera macabra sau mai vesela, fara de lumina corecta
pestera nu va mai arata aidoma unei pesteri iar orasul subacvatic va fi fara de
suflet.
In UDK luminile se impart in mai multe feluri:PointLight, SpotLight,
DirectionalLight SkyLight.
1. PointLight-urile (punct de lumina) reprezinta cel mai simplu element de lumina
a carui contur de iluminare este sferic, adica nu are unghi de iluminare intern si
extern.

17

In setarile luminii (PointLight) se poate de modificat raza iluminarii (Radiusul)


Brightness-ul (puterea luminii), Shadow Falloff (consistenta umbrelor), Ligh
Color(culoarea luminii) si multe alte particularitati complexe ale luminii.

2.SpotLight (Pata de lumina) este un element mai complex de lumina, care are
traiectorie conica de iluminare , cu unghi intern si extern de iluminare.

18

In setarile la SpotLight sunt aceleasi posibilitati ca si la PointLight, doar ca mai


exista si Inner Cone Angle Unghiul intern de iluminare care amplifica lumina
unghiului extern in raza (radiusul) dat, Outer Cone Angle unghiul exter de
iluminare.

19

3.DirectionalLight ofera o liluminare la toate obiectele din nivel si ofera umbra in


dependenta de directia si unghiul luminii.

4.SkyLight (lumina de cer) reprezinta un element de iluminare global asemanator


cu luma din lumea reala, ilumineaza toate obiectele din nivel, dar mai slab, aidoma
luminii de la cer.

Toate aceste lumini mai pot fi transformate in ToggleLight ceea ce va permite


de creat un trigger care sa stinga ori sa aprinda lumina chiar in itmpul jocului ,
printr-o functie din Kismet.

Emisive Light
In UDK unele obiecte pot avea lumina proprieEmisive Light, ceea ce usureaza
lucrul cu nivelul. Pentru a aprinde aceasta functie, este nevoie de intrat in
optiunele obiectului si de pus bifa la Use Emisive Light

20

In setarile obiectelor se pot modifica optiunele la Emisive Light, implicit la Radius


Influence e dat 0, iar 0 in UDK este egal cu infinitate, de-aceea trebuie de prescris
raza de iluminare pentru ca lumina de la obiect sa nu treaca prin obiectele fizice
(pereti de exemplu). Emisive Boos si Diffuse Boost sunt niste parametre care
influenteaza la PostProcessLightVolume.

Light Importance Volume


Cind in UDK se creaza nivele mari, e nevoie de multe surse de lumina, care trebuie
recalculate pentru ca tot sa lucreze, iar recalcularea este un proces ce des se face,
pentru ca acest proces sa decurga mai repede se creaza LighImportanceVolume

21

accesind aceasta pictrograma, apoi noi vom avea de construit un contur


pentru tot nivelul nostru. Acest LighImportanceVolume impune ca UDK sa
calculeze lumina doar in interiorul acestui contur(contur galben), ceea ce
optimizeaza foarte mult procesul dat.

PostProcessVolume.
PostProcessVolume reprezinta o prelucrarea a luminii complexa , pentru a crea
efecte mai vii, desigur aceasta necesita mai multe resurse dar si rezultatul e mult
mai frumos.

Setarile la PostProcessVolume

22

Enable DOF-efectul de spalare a imagineii


Enable Motion Blur- efectul de estompare
Ambient Oclusion- Lumina e mai moale
Bloom Scale Efectul orbirii slabe de la sursele de lumina.

Scene High Lights, Scene Mid Tones Lights si Scene Shadow raspund pentru
canalale de culoare RGB (Red Green Blue) pe diferite nivele, nivelul superior,
tonurile medii si al umbrelor.
Daca la Scene High Lights si mid Tones valorile apropiate de 1 ofera lumina
simpla, pai la Scene Shadow e viceversa, pentru a intelege mai bine, va propun sa
eperimentati cu valorile XYZ ca sa intelegeti cum ele schimb gama cromaticala
nivel, mai jos sunt prezentate exemplele folosite in proiectul de curs.

23

Cu PostProcess: High-1,0.8,0.8 Mid-1,1,1 Shadow-0.01,0,0

Fara PostPorcess.

24

Cu PostProcess.
High-1,1,1 Mid-0.4,0.4,0.9 Shadow-0.5,0.1,0.1

Fara PostPorcess.

25

Cu PostProcess. High-1,1,1 Mid-0.7,0.1,1 Shadow-0,0,0

Fara PostPorcess.

26

Cu PostProcess. High-0.7,0.7,1 Mid-1,0.9,1 Shadow-0.003,0.05,0.03

Fara PostPorcess.

27

Kismet
Kismet este un instrument extrem de felxibil si puternic care permite de a
programa joaca si elementele din gameplay fara de a scrie cod. Modul de lucru in
acest sistem consta in unirea a mai multor secvente functionale simple in scopul
crearii unei mai complexe. Toate secventele din Kismet sunt aranjate dupa ierarhie
si classe functionale, astfel tot de ce are nevoie un programator in Kismet e doar
logica si gindire analitica.
In compartimentul dat vor fi explicate doar functiile care au fost folosite in
proiectul de curs.

BehindView
Pentru a crea un joc de la a treea persoana e nevoie de scris o functie prin care
UDK va intelege unde se amplaseaza camera fata de jucator.
Pentru aceasta trebuie dintii de accesat World Propreties ca sa punem tipul de joc
utGame care presupune careva functii implicite pentur un joc FPS (First Person
Shooter)

(View>WorldPropreties> cauta Default Game Type)


Acum noi avem dat un sablon de joaca shooter de la prima persoana.
Intram in Kismet

28

In kismet , facem click drept selectam New Evenet>Player>PlayerSpawned


Apoi New Action>Misc>ConsoleCommand si New Variable>Player>player apoi
le unim conform schemei date

Alegem Console Command la Commands scriem comanda behindview


Explicatia: Schema incepe sa functioneze cind este evenimentulEvent>PlayerSpawned, dupa ce apare Playerul se produce o comanda in consola
(behindview-vizionare din spate), si se rasfringe asupra la un anumit target, care e
AllPlayers. Acum avem o setare de shooter de la a treea persoana.

29

Usi
Pentru a crea in Kismet o functie care sa deschida usa nu e de-ajuns doar
schemele bloc , mai e nevoie de animatia deschiderii usii, pentru asta se foloseste
instrumentul Matinee din UDK
La inceput , se creaza trebuie sa se deschida.
Dupa ce usa a fost inclusa in nivel,
ea se insereaza si se apasa clickdrept, se alege Conver>Convert to
mover.

In Kismet se creaza New Matinee apoi se face dublu-click


pe schema

Se va deschide fereastra de Aniamtie-Matinee, in partea din stinga jos facem click


dreapta>Add New Empty Group, apoi click drept pe New Group si New Movement

30

Track, astfel noi am creat in librarie loc pentru animatia noastra si am definit ca e
animatie de miscare.

Cursorurile verzi definesc timeline-ul de miscare in animatia data, iar cursorurile


rosii toata animatia, adica miscarea poate sa nu se mai produca , dar animatia
inca ruleaza, de-aceea aceste cursoruri trebuie sa fie in acelasi punct, miscind
cursorurie mai la dreapta noi marim timpul efectuarii miscarei din aminatie (in
cazul nostru 4 secunde)
Apoi se misca banda neagra de sub primul cursor, in acea zona a animatiei, unde
se va termina miscare (deobicei la sfirsit)

31

Apoi in camera de perspectiva se amplaseaza usa asa cum ea trebuie sa stea la


sfirsitul animatiei (rotind-o la 90 de grade)

Apoi in fereastra Matinee


facem click pe <Movement>
ai apasam butonul Enter.
Astfel noi am creat miscarea
unei usi dind doar punctul
initial si cel final, iar UDK
singur va calcula animatia.

Acum noi avem nevoie de Trigger (buton de declansare a animatiei)


Pentru asta linga usa , in camera de perspectiva apasam click-drept>Add
Actor>Add Trigger. Apoi intram in Kismet, apasam clickdrept>NewEventUsingTrigger>Touch (daca alegem touch , atunci, cind personajul
va nimeri in zona de actiune a trigerului (care poate fi marita prin instrumentul
scale) se va produce animatia, daca vom alege used atunci va fi nevoie de
apasat un buton, destroyed- e nevoie de distrus acest trigger,Take Damage-de
impuscat, Hit Wall-de atins peretele)

32

Unim Trigger>Used cu Matinee>Reverse si Trigger>Unused cu Matinee>Reverse.


(cind atingem zona-usa se deschide, cind nu ne atingem-ea se inchide)
Indicam la Sequence Event (in optiuni) Max Trigger Count 0 (ca aceasta zona sa
poate fi folosita o infinitate de ori)
Asta-i tot pentru animatia usii, se mai poate adaogat sunete prin click-drept (in
Kismet) Add Action>Sound>PlaySound

33

In proprietatile Play Sound , la linia Play Sound, apasind pe sageata <= vom
importa sunetul care-l vom alege in Content Browser in compartimentul Sounds.
Sunetele trebuie sa fie prezente la inceputul deschiderii usii, la sfirsitul deschiderei
usii, la inceputul inchiderii usii si la sfirsitul inchiderii usii.
Dupa acest model si schimbindu-l putin lucreaza toate usile din proiectul de curs.

34

Exemple: 2 usi ce se deschid concomitent cu sunet de la apasarea butonului si se


inchid cu sunet cind jucatorul intra intr-o anumita zona.

35

2 usi ce se deschid de la apasarea diferitor butoane, cu sunet si o zona care


inchide usile, cu sunet cind jucatorul calca in ea, plus amplasarea unui anunt cu
mesaj.

36

Toate usile din proiectul de curs.

Lumina.
Pentru a crea un punct de lumina care se aprinde prin intermediul unui buton, este
nevoie: 1.De creat un trigger care sa fie introdus in schema ksimet ca
NewEventUsingTrigger>Used, 2.De creat SpotLight sau PointLight care sa
fie Toggable(click drept pe Light-ul creat>Convert Light>Convert__Toggable
si inclus in Kismet prin click-drept New Object ____LightToggable3.De amplasat in
nivel un static mesh care sa aiba rol de buton.(Triggerul trebuie sa fie amplasat
linga Static Mesh)

37

Deodata predifinim ca trigerul nostru sa aiba Max Trigger Count=0 (ca sa poata
fi folosit de o infinitate de ori) si punem bifa la Aim To Interact pentru ca
jucatorul sa fie nevoit sa priveasca la buton cind il va folosi.

38

Pentru ca lumina sa se aprinda de la apasarea butonului trebuie de creat o functie


ce va avea rolul de un intrerupator. In kismet adaogam un obiect nou New
Action>Toggle>Toggle, iar pentru ca sa fie mai performant cream si un Sound
ca atunci cind vom apasa butonul sa se produca un sunet, le unim ca in Schema.
Explicatia: Cind jucatorul ce sta linga Static Mesh (buton) si e in zona Triggerului
, apasa pe butonul de actiune E , se incepe rularea functiei noastre, adica se
produce un sunet si daca lumina e stinsa- ea se aprinde, iar daca e aprinsa atunci
se stinge (datorita blocului Toogle).
La fel se poate de facut si cu mai mult lumini concomitent, exemple:
Intrerupator pentru mai multe lumini , cu sunet si anuntare.

39

Toate luminele din proiectul de curs:

Anunturi
Anunturile se folosesc pentru a amplasa pe ecran un mesaj pentru jucator pentru
a-l informa despre ceva.
Pentru asta in Kismet e nevoie de: 1.Trigger>Touch/Used(Touch cind jucatorul
intra intr-o zona, Used atunci cind el a activat ceva) 2.Functie de anuntare.
Triggerul se amplaseaza in nivel unde doriti sa apara mesajul, apoi se introduce in
Kismet (deja stiti cum)
Functia de anuntare se creaza in Kismet: New Event>Voice
/Announcements>Play Announcement.

40

Triggerul se configureaza cu 0 la Trigger Count daca mesajul trebuie sa apara


de mai multe ori , sau predifinim singuri numarul.
In Play Announcement noi putem sa adaogam un sunet (la fel cum faceam cu Play
Sound) textul care dorim sa apara pe ecran il scriem in Announcement Text

41

I.A (Inteligenta Artificiala)


Inteligenta artificiala in lucrarea data de curs este reprezentat de catre boti
(jucatori controlati de calculator).
Pentru a crea un bot ce va avea inteligenta artificiala vom avea nevoie
de:PathNode-uri (pe care deja stim cum sa-l cream) si o functie in Kismet Actory
Factory.
In cursul crearii unui bot vom avea nevoie de mai multe PathNode-uri , deoarece
ele servesc aidoma punctelor de traiectorie care indica unde bot-ul ar trebui sa
tinda sa mearga (sa nu stea pe loc) , la fel obiectele create mai sus prin
intermediul la Actor Classes (Armele prin PickUpFactory) slujesc ca puncte de
traiectorie.
Schema , in Kismet, pentru crearea unui bot arata astfel:

42

Secventa Actor Factory se leaga cu PathNode-ul anterior creat si amplasat pe


nivel, unde dorim sa apara un bot.
In proprietatile la Actor Classes e nevoie sa fie bifa la enable pentru a face
activa aceasta secventa, Force DeathMatch AI ca bot-ul sa aiba prescrisa functia
de atac, Use Compartment, Controller Class trebuie sa fie setat la AI Controler
ca I.A. din UDK sa-l minueze, iar Pawn Class la UTPawn ca sa I se ofera un
model de comportament specific shooterului.
Partea cu Inventory List raspunde pentru echipamentul care il va avea botul la
inceput (cind se va face spawn-ul lui)
Team Index este parametrul de echipa la care apartine (in cazul nostru joaca e
construita VCTF, ceea ce presupune ,implicit, ca jucatorii sa fie divizati in 2 echipe)
, 1-echipa albastr, 0-echipa rosie, 255-nu are echipa.
Pentru ca botul sa apara e nevoie de un eveniment, pentru asta se poate de folosit
evenimentul de incarcare a nivelului Level Loaded, de aparitie a jucatorului
Player Spawned, de punerea in functiune a unui trigger, fie de atingere fie de
executie Trigger sau altelele, toate fiind create in Kismet.
Exemple: Schema aparitiei a 6 boti (a cite 3 in fiecare echipa), evenimentul fiind
atingerea zonei de actiune a unui Trigger.

43

CheckPoint
CheckPoint-urile in jocuri reprezinta zona in care jucatorul se reintoarce dupa
moarte, ele sunt amplasate pe nivelul jocului pentur ca jucatorul sa nu reinceapa
nivelul de la capat , ci mai aproape de locul unde a murit.
In UDK checkpoint-urile la fel ca si alte functii logice se creaza prin Kismet ,
pentru asta e nevoie de: 1. Un Trigger (indiferent ce tip) , 2. O functie din
Kismet-Player Star, 3. Si un comutator (toggle).
Triggerul va reprezinta zona in care trebuie sa ajunga jucatorul ca sa-si salveze
joaca (sa se creeze checkpoint-ul), punctul de Player Start reprezinta zona de
unde va incepe utilizatorul joaca, daca va muri ne-atingind urmatorul checkpoint,
iar comutatorul deconecteaza checkpoint-ul precedent si-l include in functiune pe
acel care e legat de trigger-ul creat mai sus.
Schema in Kismet arata astfel:
In proprietate la Trigger se
indicaMax Trigger
Count-1 daca
checkpoint-ul se va
aprinde odata (in cazul de
jocuri de tip coridor) sau 0
ca el sa poate fi reaprins in
cazaul jocurilor cu
deplasare deschisa in
lume.

44

Exemple: Schema la 2 checkpoint-uri,cu 3 puncte de incepere,


anuntare si obiect-indicator ce dispare la atingere.

Finisarea.
Dupa ce am creat nivelul, cu toate elementele sale, l-am setat, e nevoie sa
arhivam tot proiectul intr-un install, pentru aceasta folosim programara ce vine
impreuna cu UDK , Frontend.

Visual Studio
Pentru a personaliza proiectul de curs , eu am folosit Visual Studio pentru a crea
un launcher, in care am programt functia de deschidere a jocului, iesirea din
launcher si un meniu de setare a proprietatilor grafice de pornire a jocului:
Resolution Ambient Oclusion Motion Blur.

45

Codul:
Public Class MainForm
Private Sub SettingsBtn_Click(sender As System.Object, e As System.EventArgs) Handles
SettingsBtn.Click
SettingsForm.ShowDialog()
End Sub
Private Sub StartBtn_Click(sender As System.Object, e As System.EventArgs) Handles
StartBtn.Click
Try
Shell(Application.StartupPath & "\Binaries\Win32\UDK.exe")
Me.Close()
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Critical)
Me.Close()
End Try
End Sub

46

Private Sub ExitBtn_Click(sender As System.Object, e As System.EventArgs) Handles


ExitBtn.Click
Me.Close()
End Sub
End Class
Imports Launcher.GameLauncher
Public Class SettingsForm
Private Sub SettingsForm_Load(sender As System.Object, e As System.EventArgs) Handles
MyBase.Load
ResolutionSelector.Text = My.Settings.ResolutionSetting
EnableMotionBlur.Checked = My.Settings.MotionBlurSetting
EnableAmbientOcclusion.Checked = My.Settings.AOSetting
End Sub
Private Sub SaveBtn_Click(sender As System.Object, e As System.EventArgs) Handles
SaveBtn.Click
GetINI(Application.StartupPath & "\UDKGame\Config\UDKEngine.ini")
If ResolutionSelector.SelectedIndex = 0 Then
SaveToINI("SystemSettings", "ResX", "1366")
SaveToINI("SystemSettings", "ResY", "768")
ElseIf ResolutionSelector.SelectedIndex = 1 Then
SaveToINI("SystemSettings", "ResX", "1600")
SaveToINI("SystemSettings", "ResY", "900")
Else
SaveToINI("SystemSettings", "ResX", "1920")
SaveToINI("SystemSettings", "ResY", "1080")
End If
SaveToINI("SystemSettings", "MotionBlur", EnableMotionBlur.Checked)
SaveToINI("SystemSettings", "AmbientOcclusion", EnableAmbientOcclusion.Checked)
My.Settings.ResolutionSetting = ResolutionSelector.Text
My.Settings.MotionBlurSetting = EnableMotionBlur.Checked
My.Settings.AOSetting = EnableAmbientOcclusion.Checked
My.Settings.Save()
Me.Close()
End Sub
Private Sub CancelBtn_Click(sender As System.Object, e As System.EventArgs) Handles
CancelBtn.Click
Me.Close()
End Sub
Private Sub ResolutionSelector_SelectedIndexChanged(sender As Object, e As EventArgs)
Handles ResolutionSelector.SelectedIndexChanged
End Sub
End Class

47

Logo
E cert ca fiecare joaca trebuie sa aiba semnul ei , ce o va defini, un logou si
denumire: PROJECT Maricha.

(Logo-ul a fost creat impreuna cu Cotofana Leonid, coleg de grupa si simplu bun
prieten).

Concluzia.

48

In urma efectuarii primei lucrari de curs in viata mea, am ramas placut


surprins intelegind ce-I asta pentru prima data sa creez ceva propriu, o aplicatie
pe care sa o stiu de la inceput pina l asfirsit in care am depus nu doar timp , ci si
suflet.

Programatorii de le Epic Games in opinia mea au creat unul din cele mai
bune instrumente (motor de joc) pentru crearea diferitor proiecte, UDK se
evidentiaza extrem de mult pe fonul altor motoare precum: Unity3D, CryEngine
sau GameMaker prin aceea ca el este mult mai performant, codul este generat in
timp direct cind utilizatorul face modificari in proiect, nu este nevoie obligatorie ,
desi e binevenit, cunostinta unui limbaj la perfectiune ( UDK foloseste Uscript ,
bazat pe C,C++,Java)- ceea ce e total diferit de Unity3D, posibilitatea de
importare a proiectelor grafice, sunetelor, modelelor , animatiilor, efectelor din alte
programe , precum 3DsMax, Maya, zBrush etc.
Crearea proiectului in UDK necesita cel mai mult de imaginatie si logica
foarte buna, insa are si careva ne-ajunsuri, in primul rind , comparativ cu Unity si
GameMaker el este mai complex, asta nu inseamna ca e mult mai greu de inteles,
ba dincontra el e destul de intuitiv, insa are atitea posibilitati pe care utilizatorul le
doreste sa implementeze in proiect incit el se zapaceste, deci primul minus consta
in aceea ca e nevoie de o echipa intreaga de oameni , unde fiecare trebuie sa-si
stie lucrul sau(Landscape-ul, Lumina, Geometria nivelului, I.A. etc.)
Al doilea minus consta in optimizarea rea cu Windows 8 si 8.1 , intrucit am
intilnit numeroase crash-uri, insa aceasta cu timpul se va rezolva, mai mult ca atit,
degraba va aparea UDK si la Linux , unde se preconizeaza ca totul va lucra mult
mai stabil.
In fine as dori sa ma repet ca UDK e un insturment perfect pentru o echipa de
oameni cu initiativa si inspiratie de a crea o joaca de nivel destul de inalt.

Bibliografia.
Pentru crearea acestui proiect de curs, am folosit cunostintele obtinute din
documentatia oficiala a UDK-ului , de pe site-ul sau oficial:
https://www.unrealengine.com/products/udk/documentation
Si din lectiile video de pe Youtube a lui SneakyJoes Russian Salad:
https://www.youtube.com/watch?v=7vDbqQxhJ2s&list=PL8kfl_eyvRGTUtrhLMQF1
9V1Pgktc_SIy

49

Referinta: codul sursa ShockRifle


/**
* Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
*/
class UTWeap_ShockRifle extends UTWeap_ShockRifleBase;

// AI properties (for shock combos)


var UTProj_ShockBall ComboTarget;
var bool bRegisterTarget;
var bool bWaitForCombo;
var vector ComboStart;

var bool bWasACombo;


var int CurrentPath;
//----------------------------------------------------------------// AI InterFface
function float GetAIRating()
{
local UTBot B;

B = UTBot(Instigator.Controller);
if ( (B == None) || (B.Enemy == None) || Pawn(B.Focus) == None )
return AIRating;

50

if ( bWaitForCombo )

return 1.5;
if ( !B.ProficientWithWeapon() )
return AIRating;
if ( B.Stopped() )
{
if ( !B.LineOfSightTo(B.Enemy) && (VSize(B.Enemy.Location Instigator.Location) < 5000) )
return (AIRating + 0.5);
return (AIRating + 0.3);
}
else if ( VSize(B.Enemy.Location - Instigator.Location) > 1600 )
return (AIRating + 0.1);
else if ( B.Enemy.Location.Z > B.Location.Z + 200 )
return (AIRating + 0.15);

return AIRating;
}

/**
* Overriden to use GetPhysicalFireStartLoc() instead of
Instigator.GetWeaponStartTraceLocation()
* @returns position of trace start for instantfire()
*/
simulated function vector InstantFireStartTrace()

51

return GetPhysicalFireStartLoc();
}

function SetComboTarget(UTProj_ShockBall S)
{
if ( !bRegisterTarget || (UTBot(Instigator.Controller) == None) ||
(Instigator.Controller.Enemy == None) )
return;

bRegisterTarget = false;
bWaitForCombo = true;
ComboStart = Instigator.Location;
ComboTarget = S;
ComboTarget.Monitor(UTBot(Instigator.Controller).Enemy);
}

function float RangedAttackTime()


{
local UTBot B;

B = UTBot(Instigator.Controller);
if ( (B == None) || (B.Enemy == None) )
return 0;

if ( B.CanComboMoving() )

52

return 0;

return FMin(2,0.3 + VSize(B.Enemy.Location Instigator.Location)/class'UTProj_ShockBall'.default.Speed);


}

function float SuggestAttackStyle()


{
return -0.4;
}

simulated function StartFire(byte FireModeNum)


{
if ( bWaitForCombo && (UTBot(Instigator.Controller) != None) )
{
if ( (ComboTarget == None) || ComboTarget.bDeleteMe )
bWaitForCombo = false;
else
return;
}
Super.StartFire(FireModeNum);
}

function DoCombo()
{

53

if ( bWaitForCombo )
{
bWaitForCombo = false;
if ( (Instigator != None) && (Instigator.Weapon == self) )
{
StartFire(0);
}
}
}

function ClearCombo()
{
ComboTarget = None;
bWaitForCombo = false;
}

/* BestMode()
choose between regular or alt-fire
*/
function byte BestMode()
{
local float EnemyDist;
local UTBot B;

54

bWaitForCombo = false;

B = UTBot(Instigator.Controller);
if ( (B == None) || (B.Enemy == None) )
return 0;

if (B.IsShootingObjective())
return 0;

if ( !B.LineOfSightTo(B.Enemy) )
{
if ( (ComboTarget != None) && !ComboTarget.bDeleteMe &&
B.CanCombo() )
{
bWaitForCombo = true;
return 0;
}
ComboTarget = None;
if ( B.CanCombo() && B.ProficientWithWeapon() )
{
bRegisterTarget = true;
return 1;
}
return 0;
}

EnemyDist = VSize(B.Enemy.Location - Instigator.Location);

55

if ( (EnemyDist > 4*class'UTProj_ShockBall'.default.Speed) || (EnemyDist <


150) )
{
ComboTarget = None;
return 0;
}

if ( (ComboTarget != None) && !ComboTarget.bDeleteMe && B.CanCombo()


)
{
bWaitForCombo = true;
return 0;
}

ComboTarget = None;

if ( (EnemyDist > 2500) && (FRand() < 0.5) )


return 0;

if ( B.CanCombo() && B.ProficientWithWeapon() )


{
bRegisterTarget = true;
return 1;
}

56

// consider using altfire to block incoming enemy fire


if (EnemyDist < 1000.0 && B.Enemy.Weapon != None &&
B.Enemy.Weapon.Class != Class && B.ProficientWithWeapon())
{
return (FRand() < 0.3) ? 0 : 1;
}
else
{
return (FRand() < 0.7) ? 0 : 1;
}
}

// for bot combos


simulated function Projectile ProjectileFire()
{
local Projectile p;

p = Super.ProjectileFire();
if (UTProj_ShockBall(p) != None)
{
SetComboTarget(UTProj_ShockBall(P));
}
return p;
}

57

simulated function rotator GetAdjustedAim( vector StartFireLoc )


{
local rotator ComboAim;

// if ready to combo, aim at shockball


if (UTBot(Instigator.Controller) != None && CurrentFireMode == 0 &&
ComboTarget != None && !ComboTarget.bDeleteMe)
{
// use bot yaw aim, so bots with lower skill/low rotation rate may miss
ComboAim = rotator(ComboTarget.Location - StartFireLoc);
ComboAim.Yaw = Instigator.Rotation.Yaw;
return ComboAim;
}

return Super.GetAdjustedAim(StartFireLoc);
}

simulated state WeaponFiring


{
/**
* Called when the weapon is done firing, handles what to do next.
*/
simulated event RefireCheckTimer()
{
if ( bWaitForCombo && (UTBot(Instigator.Controller) != None) )

58

{
if ( (ComboTarget == None) || ComboTarget.bDeleteMe )
bWaitForCombo = false;
else
{
StopFire(CurrentFireMode);
GotoState('Active');
return;
}
}

Super.RefireCheckTimer();
}
}

simulated function ImpactInfo CalcWeaponFire(vector StartTrace, vector EndTrace,


optional out array<ImpactInfo> ImpactList, optional vector Extent)
{
local ImpactInfo II;
II = Super.CalcWeaponFire(StartTrace, EndTrace, ImpactList, Extent);
bWasACombo = (II.HitActor != None && UTProj_ShockBall(II.HitActor) !=
none );
return ii;
}

59

function SetFlashLocation( vector HitLocation )

{
local byte NewFireMode;
if( Instigator != None )
{
if (bWasACombo)
{
NewFireMode = 3;
}
else
{
NewFireMode = CurrentFireMode;
}
Instigator.SetFlashLocation( Self, NewFireMode , HitLocation );
}
}

simulated function SetMuzzleFlashParams(ParticleSystemComponent PSC)


{
local float PathValues[3];
local int NewPath;
Super.SetMuzzleFlashparams(PSC);
if (CurrentFireMode == 0)
{

60

if ( !bWasACombo )

{
NewPath = Rand(3);
if (NewPath == CurrentPath)
{
NewPath++;
}
CurrentPath = NewPath % 3;

PathValues[CurrentPath % 3] = 1.0;
PSC.SetFloatParameter('Path1',PathValues[0]);
PSC.SetFloatParameter('Path2',PathValues[1]);
PSC.SetFloatParameter('Path3',PathValues[2]);
}
else
{
PSC.SetFloatParameter('Path1',1.0);
PSC.SetFloatParameter('Path2',1.0);
PSC.SetFloatParameter('Path3',1.0);
}
}
else
{
PSC.SetFloatParameter('Path1',0.0);
PSC.SetFloatParameter('Path2',0.0);

61

PSC.SetFloatParameter('Path3',0.0);

simulated function PlayFireEffects( byte FireModeNum, optional vector HitLocation


)
{
if (FireModeNum>1)
{
Super.PlayFireEffects(0,HitLocation);
}
else
{
Super.PlayFireEffects(FireModeNum, HitLocation);
}
}

defaultproperties
{
// Weapon SkeletalMesh
Begin Object class=AnimNodeSequence Name=MeshSequenceA
End Object

// Weapon SkeletalMesh
Begin Object Name=FirstPersonMesh

62

SkeletalMesh=SkeletalMesh'WP_ShockRifle.Mesh.SK_WP_ShockRifle_1P'

AnimSets(0)=AnimSet'WP_ShockRifle.Anim.K_WP_ShockRifle_1P_Base'
Animations=MeshSequenceA
Rotation=(Yaw=-16384)
FOV=60.0
End Object

AttachmentClass=class'UTGameContent.UTAttachment_ShockRifle'

Begin Object Name=PickupMesh

SkeletalMesh=SkeletalMesh'WP_ShockRifle.Mesh.SK_WP_ShockRifle_3P'
End Object

InstantHitMomentum(0)=+60000.0

WeaponFireTypes(0)=EWFT_InstantHit
WeaponFireTypes(1)=EWFT_Projectile
WeaponProjectiles(1)=class'UTProj_ShockBall'

InstantHitDamage(0)=45
FireInterval(0)=+0.77
FireInterval(1)=+0.6

63

InstantHitDamageTypes(0)=class'UTDmgType_ShockPrimary'

InstantHitDamageTypes(1)=None

WeaponFireSnd[0]=SoundCue'A_Weapon_ShockRifle.Cue.A_Weapon_SR_Fir
eCue'
WeaponFireSnd[1]=SoundCue'A_Weapon_ShockRifle.Cue.A_Weapon_SR_Alt
FireCue'
WeaponEquipSnd=SoundCue'A_Weapon_ShockRifle.Cue.A_Weapon_SR_Rais
eCue'
WeaponPutDownSnd=SoundCue'A_Weapon_ShockRifle.Cue.A_Weapon_SR_
LowerCue'
PickupSound=SoundCue'A_Pickups.Weapons.Cue.A_Pickup_Weapons_Shock
_Cue'

MaxDesireability=0.65
AIRating=0.65
CurrentRating=0.65
bInstantHit=true
bSplashJump=false
bRecommendSplashDamage=false
bSniping=true
ShouldFireOnRelease(0)=0
ShouldFireOnRelease(1)=1

ShotCost(0)=1
ShotCost(1)=1

64

FireOffset=(X=20,Y=5)

PlayerViewOffset=(X=17,Y=10.0,Z=-8.0)

AmmoCount=20
LockerAmmoCount=20
MaxAmmoCount=40

FireCameraAnim(1)=CameraAnim'Camera_FX.ShockRifle.C_WP_ShockRifle_
Alt_Fire_Shake'

WeaponFireAnim(1)=WeaponAltFire

MuzzleFlashSocket=MF
MuzzleFlashPSCTemplate=WP_ShockRifle.Particles.P_ShockRifle_MF_Alt
MuzzleFlashAltPSCTemplate=WP_ShockRifle.Particles.P_ShockRifle_MF_Alt
MuzzleFlashColor=(R=200,G=120,B=255,A=255)
MuzzleFlashDuration=0.33
MuzzleFlashLightClass=class'UTGame.UTShockMuzzleFlashLight'
CrossHairCoordinates=(U=256,V=0,UL=64,VL=64)
LockerRotation=(Pitch=32768,Roll=16384)

IconCoordinates=(U=728,V=382,UL=162,VL=45)

WeaponColor=(R=160,G=0,B=255,A=255)

InventoryGroup=4

65

GroupWeight=0.5

IconX=400
IconY=129
IconWidth=22
IconHeight=48

Begin Object Class=ForceFeedbackWaveform


Name=ForceFeedbackWaveformShooting1

Samples(0)=(LeftAmplitude=90,RightAmplitude=40,LeftFunction=WF_Const
ant,RightFunction=WF_LinearDecreasing,Duration=0.1200)
End Object
WeaponFireWaveForm=ForceFeedbackWaveformShooting1
}
Referinta:Codul sursa UTTeleport
/**
* Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
*/

/** UT version of the teleporter with custom effects */


class UTTeleporter extends UDKTeleporterBase
hidecategories(SceneCapture);

/** component that plays the render-to-texture portal effect */

66

var ParticleSystemComponent PortalEffect;

/**
* The base of the teleporter. We hold a reference to it so that
* it gets serialized to disk, and so we can statically light it.
*/
var() StaticMeshComponent TeleporterBaseMesh;

simulated function InitializePortalEffect(Actor Dest)


{
Super.InitializePortalEffect(Dest);
if (Dest != None)
{

SceneCapture2DComponent(PortalCaptureComponent).SetCaptureParameter
s(TextureTarget);

SceneCapture2DComponent(PortalCaptureComponent).SetView(Dest.Locatio
n + vector(Dest.Rotation) * 15.0, Dest.Rotation);
PortalEffect.SetMaterialParameter('Portal', PortalMaterialInstance);
}
}

defaultproperties
{
Components.Remove(Sprite)

67

Begin Object Class=AudioComponent Name=AmbientSound


SoundCue=SoundCue'A_Gameplay.Portal.Portal_Loop01Cue'
bAutoPlay=true
bUseOwnerLocation=true
bShouldRemainActiveIfDropped=true
bStopWhenOwnerDestroyed=true
End Object
Components.Add(AmbientSound)

TeleportingSound=SoundCue'A_Gameplay.Portal.Portal_WalkThrough01Cue'

Begin Object Class=SceneCapture2DComponent


Name=SceneCapture2DComponent0
FrameRate=15.0
bSkipUpdateIfOwnerOccluded=true
MaxUpdateDist=1000.0
MaxStreamingUpdateDist=1000.0
bUpdateMatrices=false
NearPlane=10
FarPlane=-1
End Object
PortalCaptureComponent=SceneCapture2DComponent0

Begin Object Class=StaticMeshComponent Name=StaticMeshComponent0

68

StaticMesh=StaticMesh'Pickups.Base_Powerup.Mesh.S_Pickups_Base_Power
up01'
Translation=(X=0.0,Y=0.0,Z=-30.0)
CollideActors=true
BlockActors=true
CastShadow=true
bCastDynamicShadow=false
bForceDirectLightMap=true

LightingChannels=(BSP=TRUE,Dynamic=FALSE,Static=TRUE,CompositeDyna
mic=TRUE)
Scale=1.25
BlockNonZeroExtent=false
End Object
Components.Add(StaticMeshComponent0)
TeleporterBaseMesh=StaticMeshComponent0

Begin Object Class=ParticleSystemComponent


Name=ParticleSystemComponent0
Translation=(X=0.0,Y=0.0,Z=-40.0)

Template=ParticleSystem'Pickups.Base_Teleporter.Effects.P_Pickups_Telepo
rter_Base_Idle'
End Object
Components.Add(ParticleSystemComponent0)

69

Begin Object Class=ParticleSystemComponent


Name=ParticleSystemComponent1

Template=ParticleSystem'Pickups.Base_Teleporter.Effects.P_Pickups_Telepo
rter_Idle'
End Object
Components.Add(ParticleSystemComponent1)
PortalEffect=ParticleSystemComponent1
PortalMaterial=MaterialInterface'Pickups.Base_Teleporter.Material.M_T_Picku
ps_Teleporter_Portal_Destination'
}
Referinta: Codul sursa UTVehicle_Cicada
/**
* Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
*/

class UTVehicle_Cicada_Content extends UTVehicle_Cicada;

var array<UTDecoy> Decoys;

simulated function PostBeginPlay()


{
Super.PostBeginPlay();

if (Mesh != None)
{

70

JetControl =
UTSkelControl_JetThruster(Mesh.FindSkelControl('CicadaJet'));
}
}

function IncomingMissile(Projectile P)
{
local UTVWeap_CicadaTurret Turret;

// notify the turret weapon


if (Seats.length > 1)
{
Turret = UTVWeap_CicadaTurret(Seats[1].Gun);
if (Turret != None)
{
Turret.IncomingMissile(P);
}
}

Super.IncomingMissile(P);
}

defaultproperties
{
Begin Object Name=CollisionCylinder

71

CollisionHeight=+70.0
CollisionRadius=+240.0
Translation=(X=-40.0,Y=0.0,Z=40.0)
End Object

Begin Object Name=SVehicleMesh


SkeletalMesh=SkeletalMesh'VH_Cicada.Mesh.SK_VH_Cicada'
AnimTreeTemplate=AnimTree'VH_Cicada.Anims.AT_VH_Cicada'
PhysicsAsset=PhysicsAsset'VH_Cicada.Mesh.SK_VH_Cicada_Physics'
AnimSets.Add(AnimSet'VH_Cicada.Anims.VH_Cicada_Anims')
End Object

DrawScale=1.3

Health=500
BigExplosionTemplates[0]=(Template=ParticleSystem'Envy_Effects.VH_Deat
hs.P_VH_Death_SMALL_Far',MinDistance=350)
BigExplosionTemplates[1]=(Template=ParticleSystem'Envy_Effects.VH_Deat
hs.P_VH_Death_SMALL_Near')
BigExplosionSocket=VH_Death

Seats.Empty
Seats(0)={(

GunClass=class'UTVWeap_CicadaMissileLauncher',
GunSocket=(Gun_Socket_02,Gun_Socket_01),
CameraTag=ViewSocket,

72

TurretControls=(LauncherA,LauncherB),

CameraOffset=-400,
CameraBaseOffset=(Z=25.0),
SeatIconPos=(X=0.48,Y=0.25),
GunPivotPoints=(Main),

WeaponEffects=((SocketName=Gun_Socket_01,Offset=(X=80),Scale3D=(X=12.0,Y=15.0,Z=15.0)),(SocketName=Gun_Socket_02,Offset=(X
=-80),Scale3D=(X=12.0,Y=15.0,Z=15.0)))
)}

Seats(1)={(

GunClass=class'UTVWeap_CicadaTurret',

GunSocket=(Turret_Gun_Socket_01,Turret_Gun_Socket_02,Turret_Gun_So
cket_03,Turret_Gun_Socket_04),
TurretVarPrefix="Turret",
TurretControls=(Turret_Rotate),
CameraTag=Turret_ViewSocket,
CameraOffset=0,
GunPivotPoints=(MainTurret_Pitch),
CameraEyeHeight=0,
SeatIconPos=(X=0.48,Y=0.56),
ViewPitchMin=-14000.0,
ViewPitchMax=1.0,

WeaponEffects=((SocketName=Turret_Gun_Socket_04,Offset=(X=80),Scale3D=(X=8.0,Y=10.0,Z=10.0)),(SocketName=Turret_Gun_Socket_03,Offs
et=(X=-80),Scale3D=(X=8.0,Y=10.0,Z=10.0)))

73

)}

TurretBeamTemplate=ParticleSystem'VH_Cicada.Effects.P_VH_Cicada_2ndPr
im_Beam'

VehicleEffects.Empty

VehicleEffects(0)=(EffectStartTag=TurretWeapon00,EffectEndTag=STOP_Tur
retWeapon00,EffectTemplate=ParticleSystem'VH_Cicada.Effects.P_VH_Cicada_2nd
AltFlash',EffectSocket=Turret_Gun_Socket_01)
VehicleEffects(1)=(EffectStartTag=TurretWeapon01,EffectEndTag=STOP_Tur
retWeapon01,EffectTemplate=ParticleSystem'VH_Cicada.Effects.P_VH_Cicada_2nd
AltFlash',EffectSocket=Turret_Gun_Socket_02)
VehicleEffects(2)=(EffectStartTag=TurretWeapon02,EffectEndTag=STOP_Tur
retWeapon02,EffectTemplate=ParticleSystem'VH_Cicada.Effects.P_VH_Cicada_2nd
AltFlash',EffectSocket=Turret_Gun_Socket_03)
VehicleEffects(3)=(EffectStartTag=TurretWeapon03,EffectEndTag=STOP_Tur
retWeapon03,EffectTemplate=ParticleSystem'VH_Cicada.Effects.P_VH_Cicada_2nd
AltFlash',EffectSocket=Turret_Gun_Socket_04)

VehicleEffects(4)=(EffectStartTag=EngineStart,EffectEndTag=EngineStop,Eff
ectTemplate=ParticleSystem'VH_Cicada.Effects.P_VH_Cicada_GroundEffect',Effect
Socket=GroundEffectBase)
VehicleEffects(5)=(EffectStartTag=EngineStart,EffectEndTag=EngineStop,Eff
ectTemplate=ParticleSystem'VH_Cicada.Effects.P_VH_Cicada_Exhaust',EffectSocke
t=LeftExhaust)
VehicleEffects(6)=(EffectStartTag=EngineStart,EffectEndTag=EngineStop,Eff
ectTemplate=ParticleSystem'VH_Cicada.Effects.P_VH_Cicada_Exhaust',EffectSocke
t=RightExhaust)

74

VehicleEffects(7)=(EffectStartTag=DamageSmoke,EffectEndTag=NoDamage
Smoke,bRestartRunning=false,EffectTemplate=ParticleSystem'Envy_Effects.Vehicl
e_Damage.P_Vehicle_Damage_1_Cicada',EffectSocket=DamageSmoke_01)

VehicleAnims(0)=(AnimTag=Created,AnimSeqs=(InActiveStill),AnimRate=1.
0,bAnimLoopLastSeq=false,AnimPlayerName=CicadaPlayer)
VehicleAnims(1)=(AnimTag=EngineStart,AnimSeqs=(GetIn),AnimRate=1.0,
bAnimLoopLastSeq=false,AnimPlayerName=CicadaPlayer)
VehicleAnims(2)=(AnimTag=Idle,AnimSeqs=(Idle),AnimRate=1.0,bAnimLoo
pLastSeq=true,AnimPlayerName=CicadaPlayer)
VehicleAnims(3)=(AnimTag=EngineStop,AnimSeqs=(GetOut),AnimRate=1.0
,bAnimLoopLastSeq=false,AnimPlayerName=CicadaPlayer)

JetEffectIndices=(11,12)
ContrailEffectIndices=(2,3,4,5,13,14)
GroundEffectIndices=(10)

// Sounds
// Engine sound.
Begin Object Class=AudioComponent Name=RaptorEngineSound

SoundCue=SoundCue'A_Vehicle_Cicada.SoundCues.A_Vehicle_Cicada_Engin
eLoop'
End Object
EngineSound=RaptorEngineSound
Components.Add(RaptorEngineSound);

75

CollisionSound=SoundCue'A_Vehicle_Cicada.SoundCues.A_Vehicle_Cicada_C
ollide'
EnterVehicleSound=SoundCue'A_Vehicle_Cicada.SoundCues.A_Vehicle_Cica
da_Start'
ExitVehicleSound=SoundCue'A_Vehicle_Cicada.SoundCues.A_Vehicle_Cicada
_Stop'

// Scrape sound.
Begin Object Class=AudioComponent Name=BaseScrapeSound

SoundCue=SoundCue'A_Gameplay.A_Gameplay_Onslaught_MetalScrape01C
ue'
End Object
ScrapeSound=BaseScrapeSound
Components.Add(BaseScrapeSound);

// Initialize sound parameters.


EngineStartOffsetSecs=2.0
EngineStopOffsetSecs=1.0

IconCoords=(U=988,V=0,UL=33,VL=42)

ExplosionSound=SoundCue'A_Vehicle_Cicada.SoundCues.A_Vehicle_Cicada_
Explode'
JetScalingParam=JetScale

76

PassengerTeamBeaconOffset=(X=-125.0f,Y=0.0f,Z=-105.0f);

ReferenceMovementMesh=StaticMesh'Envy_Effects.Mesh.S_Air_Wind_Ball'

HudCoords=(U=106,V=125,UL=-106,VL=124)
TeamMaterials[0]=MaterialInstanceConstant'VH_Cicada.Materials.MI_VH_Cic
ada_Red'
TeamMaterials[1]=MaterialInstanceConstant'VH_Cicada.Materials.MI_VH_Cic
ada_Blue'

BurnOutMaterial[0]=MaterialInterface'VH_Cicada.Materials.MITV_VH_Cicada
_Red_BO'
BurnOutMaterial[1]=MaterialInterface'VH_Cicada.Materials.MITV_VH_Cicada
_Blue_BO'

SpawnMaterialLists[0]=(Materials=(MaterialInterface'VH_Cicada.Materials.MI
_VH_Cicada_Spawn_Red'))
SpawnMaterialLists[1]=(Materials=(MaterialInterface'VH_Cicada.Materials.MI
_VH_Cicada_Spawn_Blue'))

DamageMorphTargets(0)=(InfluenceBone=Lt_Gun_Yaw,MorphNodeName=n
one,Health=150,DamagePropNames=(Damage2))
DamageMorphTargets(1)=(InfluenceBone=Rt_Gun_Yaw,MorphNodeName=n
one,Health=150,DamagePropNames=(Damage2))
DamageMorphTargets(2)=(InfluenceBone=FrontGuardDamage,MorphNodeN
ame=none,Health=150,DamagePropNames=(Damage1))
DamageMorphTargets(3)=(InfluenceBone=MainTurret_Yaw,MorphNodeName
=none,Health=150,DamagePropNames=(Damage3))

DamageParamScaleLevels(0)=(DamageParamName=Damage1,Scale=3)

77

DamageParamScaleLevels(1)=(DamageParamName=Damage2,Scale=1.5)
DamageParamScaleLevels(2)=(DamageParamName=Damage3,Scale=2.5)

DrivingPhysicalMaterial=PhysicalMaterial'VH_Cicada.materials.physmat_Cica
da_driving'
DefaultPhysicalMaterial=PhysicalMaterial'VH_Cicada.materials.physmat_Cica
da'

bHasEnemyVehicleSound=true
EnemyVehicleSound(0)=SoundNodeWave'A_Character_IGMale.BotStatus.A_
BotStatus_IGMale_EnemyCicada'
}
P.S. Codul sursa la toate obiectele dinjoc, sunt prezente in mapa cu raport
ObjectScript

78

S-ar putea să vă placă și

  • ARTICOL
    ARTICOL
    Document12 pagini
    ARTICOL
    Alina Stanciu
    Încă nu există evaluări
  • Tema 6
    Tema 6
    Document8 pagini
    Tema 6
    Diacon Valeriu
    Încă nu există evaluări
  • Tema 2
    Tema 2
    Document14 pagini
    Tema 2
    ALioncik Poncik
    Încă nu există evaluări
  • Tema 2
    Tema 2
    Document8 pagini
    Tema 2
    Diacon Valeriu
    Încă nu există evaluări
  • Tema 2
    Tema 2
    Document8 pagini
    Tema 2
    Diacon Valeriu
    Încă nu există evaluări
  • Tema 6
    Tema 6
    Document8 pagini
    Tema 6
    Diacon Valeriu
    Încă nu există evaluări
  • Lucrarea de Curs
    Lucrarea de Curs
    Document79 pagini
    Lucrarea de Curs
    Diacon Valeriu
    Încă nu există evaluări