UNF SCIENCECAMPS. Game Development Camp 2012 GAME BOGEN. DANMARK Ungdommens Naturvidenskabelige Forening

Størrelse: px
Starte visningen fra side:

Download "UNF SCIENCECAMPS. Game Development Camp 2012 GAME BOGEN. DANMARK Ungdommens Naturvidenskabelige Forening www.game.unf.dk"

Transkript

1 UNF SCIENCECAMPS Game Development Camp 2012 GAME BOGEN Din ressource til: 2D - Photoshop - concept art - farve teori - design af GUI 3D - 3D Max - modeling - texturing - animation - rigging Programmering - Unity3D - scripting - input - spillogik Plus andet til spiludvikling: oversigt over Unity - planlægning - lyd - litteratur - links DANMARK Ungdommens Naturvidenskabelige Forening

2 Ungdommens Naturvidenskabelige Forening Game Development Camp 2012 Ungdommens Naturvidenskabelige Forening Game Takker vores Development sponsorer for at gøre årets camp Camp mulig 2012 THE ANIMATION WORKSHOP - THE ANIMATION WORKSHOP -

3 Game Bogen Game Development Camp 2012 Velkommen til GDC s game bog. Denne bog er lavet for at hjælpe dig, både under og efter campen! Indholdsfortegnelse Unity - et overblik over spilmotoren... 5 Opbygningen af et spil i Unity... 5 Scene... 5 Toolbar... 6 The Inspector, GameObjects, and Components... 6 Hierarchy... 7 Project Gode råd til at lave et spil på en uge... 8 At planlægge udviklingen af spillet... 9 Need, Want og Nice To Have D grafik Character design Photoshop Brushtool: Markeringsværktøjerne: Hue & Saturation: Levels/Curves: Layers Paths Farve-teori Colour schemes, you ll probably need it Textures Tiling Skyggefordeling GUI Gode råd

4 Ekstra Greyscaling/values Brug af forskellige slags lag Turnarounds Photocollage Brushes Fototekstur-brug D grafik Hvad er en 3D model? Introduktion til 3DS Max Primitiver Navigation i 3DS Max Basale værktøjer i 3DS Max Manipulering af primitiver Extrude Bevel Inset Modellerings Metoder Edge Modelling Box Modelling Vigtigheden af Edge Loops og Rings Klargørelse af ens model til teksturering Opsætning af rig Skinning af modellen Animation Eksportering til Unity Slutning Programmering En Lille Advarsel Inden I begynder at kode GameObject Transform RigidBody

5 CharacterController Colliders C# scripts Kommentarer Det Allermest Basale Variabler Typer og Objekter Arrays Dynamiske Lister If, else if og else sætninger Løkker Metoder Pass-by-Value vs. Pass-by-Reference Almindelige Fejl Semikolon Stavefejl Uendelige løkker C# i Unity MonoBehaviour Nogle MonoBehaviour Metoder void Start () { void Awake () { void Update () { void LateUpdate () { void FixedUpdate () { void OnMouseDown () { void OnCollisionEnter (Collision collisioninfo) { void OnTriggerEnter (Collider other) { Andre Lyd i computerspil Lyd og musik i computerspil Lyd og musik resourcer på nettet Lyd I Unity

6 Importere lyde til Unity Links Efter Campen Game Design Generelle sider om spiludvikling Programmering D D Litteratur Game Design Efter Campen Hvor kan jeg finde hjælp? Game jams Online Game Jams Normale Game Jams

7 Unity - et overblik over spilmotoren På Game Development Camp skal I lave udvikle spil i den danske spilmotor Unity. Unity vinder mere og mere indpas i spilindustrien, fordi den først og fremmest er meget let at arbejde i, men samtidig giver mulighed for at udgive ens spil på en masse platforme på samme tid. Unity findes også i en gratis version, så I kan blive ved med at lave spil i Unity, når I kommer hjem fra GDC. Opbygningen af et spil i Unity Når du åbner Unity for første gang, får du noget der minder om dette billede: Dette er Unity s Interface. Hvis Interfacet, som er på jeres computere, ikke har samme opsætning som på billedet, kan du gå over i højre øverste hjørne og vælge den toolbar, som hedder Layout. Herfra kan du vælge Wide. Når du klikker på denne, vil jeres opsætning af Interfacet passe til billedet ovenfor. Det har dog ingen betydning for jeres spil hvilken opsætning, man vælger for Unity s Interface, så I kan selv vælge, hvilken I vil bruge. Scene Der, hvor du som spiludvikler kommer til at tilbringe rigtig meget af din tid, er i Unitys Scene vindue. Scene vinduet kommer til at indeholde alt, lige fra jeres fantastisk designede levels, til de utrolige awesome animationer på jeres hovedperson. Nu spørger du sikkert: Jamen hvorfor hedder den en Scene og ikke et Level? Svaret er ganske enkelt: Når man skal lave menuer til sit spil, så sker dette også i en scene, oftest i en seperat scene. Derfor har Unity valgt at kalde det for en scene, så der ikke opstår forvirringer mellem levels og menuer. Man kan også sammenligne det med scenerne i en film. Hvis du kigger oppe i øverste venstre hjørne af Scene vinduet, vil du kunne se et lille faneblad, hvor der står Scene. Lige ved siden af er der en lille pac-man og et faneblad, hvor der står Game. Hvis der klikkes på dette, vil Scene vinduet skifte til det kamera, som findes i jeres Scene. Dette kamera, viser alt det, som 5

8 spilleren vil kunne se, når vedkommende spiller jeres spil. På den måde kan I hurtigt og let at se, hvordan spilleren vil opleve jeres spil. Kameraet, som jeg omtalte før, er et GameObject. Hvad dette er for noget, vender vi tilbage til om lidt, men det du skal huske på, er at Scenen bruges til at vise, hvor alle dine GameObjects er placeret i jeres spil. Toolbar Toolbaren, som vises over Scene vinduet, indeholder en lang række værktøjer, som gør dit arbejde i Scene vinduet noget nemmere. Øverst til venstre kan du se fire navigeringsknapper. Disse fire navigeringsknapper er forklaret i nedenstående tabel: Billede/Navn Shortcut Beskrivelse Drag / Selection Tool Q Bruges til at flytte frit rundt / vælge forskellige GameObjects. Move Tool Rotate Tool Scale Tool W E R Bruges til at flytte rundt på GameObject via X,Y & Z akserne. Bruges til at rotere rundt på GameObjects. Bruges til at skalere op og ned på GameObjects. Disse navigeringsknapper kan du bruge til at placere dine GameObjects helt præcist, som du gerne vil have dem. Foruden disse, så finder du også Play, Pause & Step knapperne, som er placeret i midten af vinduet. Play knappen, som er den knap, du nok kommer til at bruge flest gange, tillader, at du kan spille dit spil, helt præcis som du har udviklet det. Ved at klikke på den, har I, med andre ord, mulighed for at teste jeres spil, så I kan være helt sikker på, at fjenderne for eksempel bevæger sig som de skal, eller at spilkarakteren kan sample points op. For at stoppe, skal man blot trykke på Play igen. En vigtig note skal siges om Play knappen, og den er faktisk så vigtigt, at det skal stå med Caps Lock: ALLE ÆNDRINGER, DU FORETAGER PÅ DINE GAMEOBJECTS, MENS DU HAR KLIKKET PÅ PLAY KNAPPEN, BLIVER IKKE GEMT! Pause & Step knapperne bliver ikke brugt så ofte, men Pause knappen bruges til at pause spillet, således at man kan pause spillet, hvis man finder en fejl i ens spil og har brug for at spillet kører for, at den er synlig. Step knappen tillader, at du kan gå frem i spillet en frame ad gangen. Dette kan være en fordel, hvis man har en fejl, der er svær at finde frem til. The Inspector, GameObjects, and Components Inspectoren, som du finder i højre siden af interfacet, bliver brugt til at få vist flere informationer, om hvad du sidst har klikket på. Dette vil oftest være GameObjects. GameObjects bliver brugt til at opbygge spillet. 6

9 Hvert GameObject indeholder endvidere Components, der er med til at definere hvordan det skal opføre sig. For at opsumere så indeholder jeres spil scener, disse scener indeholder GameObjects og hver af disse indeholder til slut Components. Der findes mange forskellige slags Components. Alle GameObjects har en Transform Component, der fortæller, hvor det befinder sig, hvilken retning det vender, samt dets skalering, altså hvor stort det er. Der findes mange andre Components, men du behøver dog ikke skulle bygge alt helt fra bunden. Unity har allerede en lang liste af GameObjects, som indeholder de mest brugte kombinationer af Components, som du blot kan vælge fra. Disse kan findes i GameObject menuen. Fra Inspectoren kan du med andre ord finjustere på dit GameObject s componenter for at få det til at gøre præcist som du ønsker. Hierarchy Når du begynder at have mange GameObjects i din scene, kan det godt begynde at blive vanskeligt at navigere rundt blandt dem allesammen kun ved hjælp af Scene vinduet. Det er her din nye ven Hierarchy panel melder sig på banden. Hierarchy panellet tillader, at få en meget nem og overskuelig oversigt, over de mange GameObjects, som befinder sig i din Scene. Du slipper med andre ord for at lede hele din scene igennem for at finde det GameObject, som du skal tilføje en Component til. I stedet kan du blot drag & drop, som du kender fra dit styresystem, over på dit GameObjects i Hierarchy Panelet. En anden mulighed som Hierarchy Panellet tilbyder, er at du kan lave en parenting mellem dine GameObjects. En parenting går ud på, at man udvælger et forældre GameObject og alle GameObjects, som efterfølgende bliver tilføjet til dette GameObject, vil så fungere som børn til dette GameObject. Det smarte er, at børne GameObjects altid følger efter deres forældre. Dette kan for eksempel bruges, hvis man har en Power-up, og der skal være en partikel effekt rundt om denne Power-up. Her vil partikel effekten være et barn til Power-up GameObjectet. På denne måde slipper man for at placere to forskellige GameObjects, og man kan i stedet koncentrere sig om kun at placere et GameObject, da det andet altid vil følge med. For at lave en parenting skal du blot drag & droppe det GameObject, som du ønsker skal være et barn - over på det GameObject, som skal være forældre. Project Ved siden af Hierarchy panelet, finder du Project panelet. Project panelet viser en lang liste over alle de filer, som er tilgængelige for hele dit spil - ikke kun din scene. Det vil med andre ord sige, at hvis du skal have noget i dit spil, skal det ligge i Project panelet. Ligesom du kan drag & drop i Hierarchy panelet, kan du også trække nye elementer fra dit skrivebord ind i Project panelet. Hvis I for eksempel har udarbejder en lydeffekt, som ligger på skrivebordet, kan i blot drag & drop denne ind i Unity. Project panelet giver jer også mulighed for at sortere i jeres mange filer via en mappe struktur, som du kender det fra almindelig computere. Der findes to forskellige skoler, for hvordan du skal sortere dine filer i Hierarchy Panelet. Den ene siger, at du skal gemme dine filer efter, hvilken type de er. Det vil sige, at hvis du har et Material, som er den fil der giver dine figurer farver, så skal du gemme den i en mappe ved navn Materials. Den anden skole siger, at du skal gemme dine filer efter hvilket element i dit spil, de skal bruges på. Det vil sige, du opretter en mappe ved navn Player, og i denne mappe finder du både materials, scripts osv., som er tilnyttet din player figur. Det har ingen indfyldelse på dit spil, hvilken 7

10 mappestruktur du vælger. Dog opforder vi til, at den sidst nævnte metode bliver brugt, da du oftest arbejder på en del af spillet ad gangen, og ikke på alle filer af en type. 5 Gode råd til at lave et spil på en uge Make A Toy - Then A Game At udvikle et 100% færdigt computerspil på en uge er ikke nogen let opgave, og I vil sikkert opleve, at I ikke når at blive færdige med alle jeres idéer. Derfor er det bedre at fokusere på, først at få lavet et fedt legetøj. Dvs. få lavet den basale spilmekanik i jeres spil, så det i sig selv er sjovt at lege med. Et godt eksempel kunne være et 2D platformspil i stil med Mario Bros. Her er legetøjet, det at kunne hoppe fra platform til platform, mens det at kunne samle ting op, hoppe på fjender, have en highscore og have mere end én bane, gør det til et spil. Kill Your Darlings Når man går i gang med at udvikle et spil, sker det ofte at man får en idé til en masse fede features, som man bare må have med. Her er det vigtig at huske, at I kun har en uge til at udvikle på jeres spil, og I derfor langt fra kan nå at implementere alle jeres ideer. I bliver med andre ord nød til at udvælge hvilke idéer, der er vigtigst for jeres spil - og slå resten ihjel! Dette kan godt blive svært, fordi man oftest får et personlig forhold til sine idéer. Lad være med det. Se hellere jeres idéer som foreslag til, hvordan I kan forbedre jeres spil. Prøv også at lade være med at personligøre idéen, altså brande den som dine eller mine Ideer, men hellere flyvende ko med laser eller hoppende bold med pink prikker idéen. Tal sammen i jeres gruppe Mange spilprojekter ender med at gå i opløsning, fordi at holdet bag spillet ikke får snakket nok sammen, om hvad spillet skal gå ud på. Når I laver jeres spilkoncept, tal derfor sammen og sæt ord på jeres tanker om spillet og planlæg, hvem der laver hvad. Det er også en idé, at lave daglige feedback samtaler gruppen imellem: I skal samarbejde meget tæt i en uge, og konflikter kan opstå. For at minimere, I alle sammen ryger op i det røde felt, hvor samarbejde er besværligt og kedeligt, kan det være sundt at have et åbent forum, hvor man kan fortælle, både hvad der gik godt og mindre godt den dag. Playtest, playtest, playtest Det kan ikke siges ofte nok, playtesting er super vigtigt. At playteste sit spil vil sige, at man får nogle til at spille jeres spil igennem, for at finde ud af, hvor sjovt det er at spille. Det er nemlig ikke sikkert, at det, du, som spildesigner, synes er sjovt, er hvad dine spillere også vil finde underholdende. En fejl mange spiludviklere også begår, er at lave deres spil for svært. Dette sker, fordi de spiller deres eget spil så meget, at de bliver meget gode til det, og derfor har svært ved at vurder sværhedsgraden for en normal spiller. Dette kan kun blive forbedre ved at playteste spillet. Organisér jeres modeller, scripts og teksturer på en logisk måde For at gøre arbejdet på jeres spil nemt, er det godt at have en struktureret måde at placere filerne på. Vores erfaring er, at det nemmeste er at organisere filer alt efter hvilket objekt de tilhører inde i spillet. 8

11 Hvis man for eksempel har en svamp i sit spil, så gemmer man svampens model, tekstur, og scripts i en mappe kaldet svamp. At planlægge udviklingen af spillet Ved alle projekter, hvor mange personer skal arbejde sammen om at nå et fælles mål, er det at kunne fordele de menneskelige ressourcer mest effektivt, essentielt for at kunne nå opgaven inden for den tid der er sat af til den. Siden I skal arbejde sammen om at udvikle jeres spilkoncept under campen er det derfor nødvendigt, at I har en struktureret metode til at planlægge samarbejdet mellem jer. Need, Want og Nice To Have Vi opfordrer derfor til, at I bruger en simpel, men effektiv, måde at strukturere arbejdsgangen på kaldet Need, Want og Nice To Have-væggen. Denne metode løser følgende problemer: 1. Klargør hvilke opgaver, der skal laves, for at jeres spil bliver spilbart. 2. Sørg for at elementer, som gør spillet sjovt, får høj prioritet. 3. Signalerer til alle i gruppen hvilke opgaver, der arbejdes på lige nu og af hvem. 4. Signalerer til alle i gruppen hvilke opgaver, der allerede er blevet løst, så de ikke bliver lavet mere end en gang. Der er 3 kategorier til at opdele arbejdsopgaver: 1. Need. Herunder er de vigtigste opgaver, som ofte, når de bliver løst, vil resultere i, at man har et Toy. F.eks at spillets karakter kan løbe frem og tilbage eller hoppe. 9

12 2. Want. Herunder er de opgaver, som, når de er færdige, gør at man har et spil. 3. Nice To Have. Dette er små ting, som får spillet til at virke poleret. Dette kan f.eks. være ekstra visuelle effekter og menuer. For at synliggøre hvilke opgaver, der hører til hvor, bliver disse skrevet på post-its og sat på et et stykke af jeres væg i grupperummet under deres respektive kategorier. F.eks. en post-it med avatar koncept art påskrevet, hænges up under Need. Når alle opgaverne hænger på væggen er det nemt for hele gruppen at se hvilke opgaver, der endnu ikke er løst. Man påtager sig så en post-it ved at tage den ned fra væggen og sætte den på ens arbejdsstation, så at dine gruppemedlemmer kan se, hvad du arbejder på. I stedet for at smide post-iten ud, når opgaven er løst, kan man lave en 4. kategori, med opgaver som er løste. Det er fedt at kunne se, at spillets fremskridt synliggjort i takt med flere og flere post-its tages ned og opgaver løses, også er det et påskud for at blære sig overfor de andre grupper. 10

13 2D 11

14 2D grafik Character design Det første skridt, der skal tages, når man har fundet frem til en spilidé, er, hvordan spilelementerne skal se ud. Det er lige meget om figuren er den ene af ketcherpladerne i Pong, spøgelserne i Pacman eller en dæmon fra helvede. Man skal stadig finde ud af, hvordan figuren skal se ud inden man implementerer den i spillet. Det første man skal gøre, er at spørge sig selv: "Hvilken figur har jeg med at gøre?" Er det helten i spillet? Er det prinsessen, han skal redde? Er det de fremstormende fjender? Eller er det bossen? Når man har på plads hvilken karakters design, man vil arbejde på, kan man for eksempel begynde med en basal form. Disse figurer viser hvordan man hurtigt kan få et karakterdesign ud af en form. 12

15 En basal form er et godt udgangspunkt for en karakter. Denne form kan være med til at give et øjeblikkeligt indtryk af karakteren. Ens publikum vil nemlig altid forbinde bestemte former med forskellige roller - men hvordan kan vi afkode disse? Vi spørger os selv: "Hvordan er formen at sidde på?" 1. Trekanten: Den gør ondt, den virker spids. Ergo, den er ikke rar. 2. Firkanten: Mere behagelig end trekanten, stadig ikke komfortabel, men solid. Ergo er den hård. 3. Cirklen: Den mest behagelige, den virker blød og rar. Derfor tryg og venskablig. Når man har en form på plads, kan man begynde at lave thumbnails. Dette er små, enkle tegninger på størrelse med din negl, der kan give en idé om din figurs udseende. Det er en god idé at starte sådan, fordi det er lettere at kontrollere ens streg, man ender ikke med at gå op i detaljerne for tidligt i karakterudviklingsprocessen, og man sparer tid. Denne teknik kan også bruges til at udvikle miljøer, tanks, borge osv. Alt. Test-thumbs til musik-hund i landskab. Hvis man vil tænke lidt udenfor boksen, er et alternativ til dette, som professionelle ofte bruger inden for spil-industrien, at lave collager ud fra billeder fundet på nettet. De finder en masse billeder af det, der symboliserer deres karakter, eller på anden måde beskriver den, og klipper dem sammen i Photoshop. Der kan det blive vigtigt at holde styr på sine lag, f.eks. ved at navngive dem og gruppere dem. Det kommer der mere om senere. 13

16 Collager af musikdyr Hvis man f.eks. skal designe en ulækker trold, kan man søge efter billeder af rådne træstammer, skovsvampe, mos, grantræer, sten osv. Når man så har fået lavet en række forskellige collager, handler det om, at kunne tegne dem, så de fremstår som en figur med fylde og form. På den måde bliver arbejdet lettere, når man skal til at gøre tegningerne klar til 3D-modellørene. Man kan også være mere i tvivl om sit design og prøve forskellige looks på figuren. Det kan f.eks. gøres på den måde der blevet brugt på billederne nedenunder. Omsætning til 3D-tegning på to af musik-dyrene, ud fra collagerne og Musikhundens to første udkast. 14

17 Photoshop Herover er de basale værktøjer i Photoshop s tool-bar præsenteret. Photoshop er et af de bedste programmer, når det kommer til digital tegning og maling. Men inden man skal igang, er det med at kende de basale værktøjer - disse værktøjer er nogle af dem, man oftest kommer til at bruge. Brushtool: Brushtool et er, som navnet vidner om, en pensel, men denne pensel kan ændres på utallige måder. Der findes utallige typer, der følger med Photoshop, og disse kan modificeres efter eget behov. Man kan gøre den til et lille billede, man kan få den til at dele sig op eller være gennemsigtig. Penselværktøjet kan modificeres til at passe stort set alle behov. Markeringsværktøjerne: Markeringsværktøjerne, eller lasso tool, kan bruges til at markere områder i billedet i enten firkanter, cirkler eller manuel markering. Disse markeringer kan enten bruges til at proppe en del af billedet hen i et andet lag, slette denne del, gøre den mørkere, en anden farve eller lignende. Et meget nyttigt værktøj - også til brug af paths, men det kommer vi ind på. Hue & Saturation: Som før nævnt er der metoder til at gøre dele af sine billeder mere mørke/mere lyse eller med højere eller lavere mætning i farverne. Til dette bruges funktionen Hue & Saturation. Genvejstast: ctrl+u 15

18 Levels/Curves: For at skrue op eller ned for kontrasten i billedet kan man bruge kontrastfunktionen. Men dette er ofte ikke nok til at være synligt. I stedet kan man bruge Levels (genvej: ctrl+l) eller Curves (genvej: ctrl+m). Den eneste forskel på disse er opsætningen. Layers Lag i Photoshop ses i det nederste højre hjørne. De skal forståes som en bunke transparente papirer, som man kan male på. Man kan skifte imellem hvilket lag, man er på, så det ikke påvirker de andre lag. Hvis man tilføjer et nyt lag, lægger man så at sige et nyt transparent papir oven i bunken. Lag har også en anden funktion, de kan ændre hvilken slags lag det er. Der er en hel del af disse, og de kan ændre dit billedes udseende på mange fede måder. Det er vigtigt, når du bruger lag, at du holder styr på dine lag, sørger for, at de er i den rigtige rækkefølge, og at de er navngivet, så du kan finde dem igen. Paths Paths er markeringer, der kan kaldes frem og bruges til enten at beskære billeder eller dele af billeder, begrænse hvor man maler. De fremstår som en en markering, der ligner en lille parade af myrer. Disse kan laves enten ved hjælp af tryllestavsværktøjerne, markeringsværktøjerne eller lassoværktøjerne. Når man indrammer eller vælger et område, kan man også bede Photoshop om at vælge det modsatte af det, man har valgt. Dette gør man ved at vælge højreklikke på det, man har valgt og vælge select inverse. Dette kan ofte være nyttigt, hvis man f.eks. skal have flyttet en farvelagt figur, man vælger alt udenom figuren, vælger select inverse og bruger free transform til at flytte figuren derhen hvor man vil have den. Hvis man har en særlig markering, man gerne vil gemme og hive frem flere gange i løbet af produktionen af et billede, så kan man også gemme sin path. Det gør man ved at højreklikke og vælge save selection, så bliver den gemt under channels, og her kan du vælge den igen ved at holde ctrl+alt nede og klikke på den eller dens nummer. Farve-teori Selvom det er konventionelt, så er det en god idé at lære sig de mest almindelige symboler og farvekoder, når man skal designe elementer i sit spil. Selvom spillet godt kan være utroligt pænt at se på, så handler det i sidste ende om, hvor godt du kan signalere til spilleren, hvad de må gå ind i, og hvad de skal undgå. Hende her har du ikke lyst til at forstyrre. I de tidlige versioner af det første Left 4 Dead var der et rødt tydeligt spotlight fra oven ned på The Witch. Dette signalerede fare. 16

19 De mest almindelige symboler, er hvid med rød, som health pack, grøn er "go ahead", og rød er sandsynligvis fjenden, eller at nu kører du altså den forkerte vej. Dertil kommer også de farver, som naturen selv bruger. Her bruges også rød, og i øvrigt gul, som typiske advarselsfarver. Og du kan også bruge farveintensitet som signal: Hvis du har et meget harmonisk grønt spil, så kan en skarp blå sagtens signalere fare. Overordnet handler det om at lede spillerens opmærksomhed ved hjælp af kontraster - dem får øjet nemlig først øje på. Et eksempel kunne være: Hvis jeg er nu er en italiensk VVS mand, må jeg så tage mønterne og skal jeg holde mig fra rørene? Så husk at sørge for signalet er utroligt klart i forhold til konceptet og i øvrigt meget svært at misforstå! First aid kit i de klassiske health pack farver. Sammen med den stærke, konstrastfyldte hvide får den røde farve en helt ny betydning. Colour schemes, you ll probably need it. En ting, som kan forstærke følelsen og forståelsen i et spil, er farveskemaet. Dette sætter stemning, gør symboler klarere og kan gøre ting klarere generelt. En anden vigtig detalje er at få farverne såvel som spil verdenen og koncepterne, til at harmonere; at hænge sammen. Denne harmoni er meget vigtig og bliver ofte også glemt af større firmaer. Harmoni er vigtigt! Men hvor skal du starte? Tænk over hvilken stemning du forsøger at sætte ind i scenen, er det uhyggeligt? Er det et sted der skal virke trygt? Eller er det et sted ind i mellem? Når du har fundet ud af hvilken følelse publikum skal sidde med kan du begynde at kigge efter farver der enten signalerer fare (kølige farver, skarpe farver, kontrast farver) eller tryghed (varme farver, rolige farver). En anden mulighed er at kigge på et farvehjul. 17

20 Textures Nu ved du lidt om farver. Hvordan skal det så bruges? Jo, som 2D-grafiker på GDC kommer du højst sandsynligt til at skulle farvelægge 3D-modeller. Dette gøres ved at 3D-modellen foldes ud. Forestil dig f.eks. at 3D-modellen er en mælkekarton som foldes ud. Nu er der en yderside og en inderside. Indersiden kan vi være ligeglade med, eftersom den alligevel ikke bliver set. Det er for 2D-grafikerne ydersiden, der er interessant. Dette kaldes et unwrap. Det er nemlig herpå, man maler, for at give 3D-modellen det der kaldes en texture, altså dens farve. For at optimere din brug af textures kan du lave dem i nogle særlige størrelser, der vil passe bedst til alle skærmstørrelser og derfor bruge mindre plads. Dette kaldes The Power of Two. Skærmstørrelserne er følgende: Her ses en 3Dmodel af et lille tårn (t.v.), som det ser ud når 2D-grafikeren får unwrappet. På det andet billede kan ses hvordan det er blevet til et bambus-tårn efter 2Dgrafikeren har været igang. Tiling Når man laver textures til et landskab eller til bygninger, sker det tit at man bliver nødt til at lave en texture, der kan duplikeres ved siden af hinanden. Dette kan f.eks. være et stenhegn, en sump eller, oftest set, en græsmark. Old school tiling 18

21 Dette kan gøres ved at tile texturen. Det betyder i bund og grund, at uanset hvordan man propper texturen sammen, så kan det ikke ses ved en klar afskåret linje midt i texturen. Derfor kaldes det også en seemless texture. Dette kan gøres i Photoshop ved at gå ind under filter - other - OFFSET - her er der nogle parametre du kan rette på indtil din textur laver et kryds i midten. Herfra handler det så om enten at male texturen over til det passer, eller om nødvendigt bruge clone-tool et. Skyggefordeling På en texture skal man huske, at man ikke behøver at lægge skygger eller højlys, det klarer 3D-delen for en. Men af og til er der eksempler, hvor man godt kan tilføje en smule skygge for at få texturen til at hjælpe modellen med udvidet dybde. Et eksempel kunne være ved overlappende metaldele på et rumskib, eller ved indersiden af et skjorteærme på en figur. Det eneste du skal spørge dig selv om, er hvorvidt der vil komme lys det sted du maler skyggen, og om det vil hjælpe med at bringe dybde i figuren. GUI GUI står for Graphical User Interface. Det er i bund og grund det der er oppe eller nede i hjørnet, der fortæller dig hvor meget ammo, hvor mange penge, og hvor meget health du har i spillet. Disse dele laves som PNG er. Dette gør det nemlig muligt at gøre baggrunden gennemsigtig, og dermed kan det bruges som en maske. Hvis det skal animeres kræver det, at der ændres lidt i GUI et for hvert trin. Gode råd Når det handler om GUI er der ingen gylden regel der kan kan afgøre hvad der er rigtigt og forkert. Men der er dog nogle gode råd man kan følge for at få sit GUI til at fungere. På samme måde som med det overordnede colour scheme så er det vigtigt at dit GUI indgår i den harmoni og stil der er lagt i resten af spillet. Det duer ikke at have lyserøde skyer der indikerer hvor meget liv du har hvis du laver et survival/horror-spil. Det der er vigtigt at have for øje er, om det fungerer. Og vel at mærke om det fungerer i forhold til den målgruppe du forsøger at nå. I spil som Mass Effect spillene eller EVE spillene er GUI et designet på en måde der meget nemt kan forvirre nye brugere, men som superbrugere og hardcore gamers ikke har problemer med. Så de når stadig ud til deres publikum på trods af mangel på simpelhed. 19

22 Eksempel på GUI i EVE. I den modsatte side af spektrumet er der de spil der skal være lige til at samle op, selv for yngre brugere. Pokemonspillene er et godt eksempel på et spil der har et forholdsvist simpelt GUI, der appelerer til yngre brugere. Eksempel på GUI i Pokemon Når man står overfor at skulle lave et GUI må man også tænke på hvordan det påvirker det overordnede gameplay. I The Elder Scrolls V: Skyrim er ens inventory system et GUI der overtager skærmen når man samler ting op eller søger efter interessante genstande på ens faldne fjender. Eftersom Skyrim er et spil der i høj grad satser på action, så kan dette inventory system godt ses som en blokering i det momentum man opnår i en ophedet kamp. Hvis man helt fra design fasen af sin produktion er fastsat på at spare lidt på sit GUI kan man forsøge at implementere GUI-elementerne som en del af spil-elementerne i stedet for en slags skærm der er smækket ovenpå bagefter. Det er forsøgt en del gange og der er både eksempler på spil hvor det har fungeret og spil hvor det ikke har fungeret. 20

23 Et af de spil hvor det virkede mere søgt end decideret funktionelt var i King Kong: The Game. Her skulle man f.eks. tjekke sit magasin på sit våben for at se hvor meget ammunition man har tilbage. Eksempel på spil uden synligt GUI - King Kong: The Game. Et eksempel på et spil, hvor man på samme måde ville gøre GUI et så minimalt så muligt, er Dead Space. Her ses ens health bar på ryggen, som en del af ens character model. På samme måde kan man se hvor meget ammo ens special-våben (stasis) har tilbage, cirklen ved højre skulderblad. Også våbnene i Dead Space har deres egne små displays, hvor man kan se antallet af skud man har tilbage. Modsat det førnævnte eksempel, så virkede denne metode ikke søgt eller unaturlig i Dead Space. Så husk på at overveje hvilket slags spil det er I laver og derefter find ud af hvilken slags GUI der vil passe bedst. Eksempel på implementeret GUI - Dead Space. Men som ved alt andet inden for spiludvikling, så hold det så simpelt så muligt. 21

24 Ekstra Greyscaling/values Greyscalingen er også generelt kendt som Values. Dette er når man laver sit billede i ren sort og hvid. Men vel og mærke uden at bruge særlig meget af hverken decideret sort eller decideret hvid. Når man først har farvelagt sit billede på denne måde vil man dels få meget mere form på sin tegning, dels kan man bruge nogle af de andre lagfunktioner og dermed male indenunder ens tegning. Eksempel på greyscaling. I dette tilfælde opdagelsesfartøjer. Brug af forskellige slags lag Der findes forskellige typer lag, man kan indstille laget til at være. Disse kan gøre laget lysere, mørkere, gøre farverne mere mættede, desaturere og gøre det gennemsigtigt af forskellige variationer. Dette kan bruges, hvis man synes ens billede mangler lidt pift, eller hvis man har lavet et value maleri. Det er ofte svært fra start af at forudse, hvad de forskellige lagtyper kan gøre ved dit billede, så det er bare at prøve sig frem, og hvis det ser dårligt ud, kan man altid skifte tilbage til den normale lagtype. Turnarounds Et turnaround er et hjælpemiddel fra 2D grafikeren til 3D grafikeren, for at få styr på, hvordan figuren skal se ud i 3D. Det involverer for det meste at karakteren, fartøjet eller figuren ses fra siden og forfra, hvis man føler sig modig kan man også forsøge med et ¾ view. Klassisk turnaround - et mere sketchy et af slagsen. 22

25 Photocollage Når du laver photocollage i Photoshop er der et par ting du skal tænke over. Du skal holde øje med dine lag når du har skåret de dele af billederne ud som du vil bruge. Lagene er der hvor hver del af billederne du har skåret ud vil lægge sig. Det er en god ide at holde hver del på et lag for sig selv så man kan redigere i det hen af vejen. Det er derudover en rigtig god ide at navngive dem så man kan finde rundt i dem. Men sørg også for at du ikke sidder med en million lag for så bliver filen du arbejder med pludselig meget tung. Når du klipper dele ud fra et billede i Photoshop, bruger du lasso-tools eller andre af markeringsværktøjerne. Du kan skifte mellem de to lasso-tools ved at holde alt inde. Genvejen til det normale lasso-tool er L. Når du skal flytte rundt på dele af collagen bruger du movetool. Der er en fiks genvej til at bruge dette, frem for at gå op i værktøjsmenu og finde det. Hvis du holder ctrl inde bliver dit tool automatisk til movetool, hvilket får ting til at gå lidt hurtigere. Hvis den del du klipper ud af billedet har en besværlig silhuet, pels eller lignende så kan det hurtigt blive et problem. Til den slags er det en god ide at bruge kombinationen af quick selection tool og refine egde. Med quick selection tool vælger du den del du vil have klippet ud, Photoshop prøver at finde siluetten så præcist så muligt (hvis dette ikke lykkes må du ty til et af lasso-tools ne) og derefter trykker du refine egde oppe i toppen af skærmen, lidt til venstre for midten. Her kan du definere hvordan delen skal skæres ud, om det skal være en blød beskæring, om der skal fjernes hakkede kanter osv. Brushes I photoshop har du muligheden for, ligesom i virkeligheden, at vælge mellem et stort udvalg af pensler/brushes. Fra start af er der allerede en del forskellige som burde dække de mest basale behov, men hvis du har lyst kan du også lave dine egne der passer lige præcis til det formål du skal bruge dem til. Skal du f.eks. have malet en kriger der er viklet ind i lænker? Det ville være besværligt at skulle sidde og male hvert af de små led i lænkerne, men hvis du laver en brush der består af, måske, 3 led fra en lænke, så kan du lave en lænke bare ved at trække en streg. Men hvis det ikke lige er dig at sidde og lave den slags selv, så er der også et kæmpe udvalg af gratis brushpakker der passer til dit behov, om det så er skyer, eksplosioner eller træer. Fototekstur-brug Fototekstur kan godt forvirres med textures og for at gøre det endnu mere forvirrende kan de også godt være noget hen af det samme. Men lad os prøve at holde det simpelt. Når du laver en texture til en 3D model, så er det ofte som om man ikke helt kan fange den samme følelse, f.eks. af skæl på en drage eller alle de små dele på en ringbrynje. Er der så ikke en lettere vej end at skulle sidde og male hver af delene selv? Jo, det er her vi bruger fototeksturer. Det er i bund og grund når man finder et fotografi som man lægger over det man har malet, om det så er texture eller koncept art. Man kan ofte sidde og prøve forskellige lagtyper igennem for et bedre resultat ellers kan man også bare redigere på gennemsigtigheden. 23

26 Eksempel på markant tekstur brugt i textures - se zombiens skulder Eksempel på tekstur brugt i koncept art - metallets rust og skidt er sikkert lavet med tekstur 24

27 How to 3D 25

28 3D grafik Hvad er en 3D model? Hvad er en 3D model? Det er vigtigt at forstå dette før man begynder at modellere, mange af jer har måske aldrig arbejdet med 3D før, men frygt ikke, det er det denne del af gamebogen vil hjælpe jer med at komme igang med. En 3D model er en samling af punkter i et tredimensionelt rum, ved hjælp at softwaren bliver der så lavet en overflade mellem disse punkter, det er denne overflade som folk ser. Derfor, i modsætning hvad man skulle tro, er der ingenting inden i en 3D model, den er lidt ligesom en ballon lavet af ler. Men en ensfarvet ballon lavet af ler er der ikke ret meget ved. Derfor har man forskellige værktøjer i 3DS max som kan hjælpe en med at farvelægge og animere ens model. Introduktion til 3DS Max Her vil jeg skrive en kort introduktion til 3Ds Max Interface, nedenunder er der et screenshot af hvordan 3DS Max ser ud når du starter det første gang. Rød(1) er værktøjslinjen, det er heroppe du vil finde nogle af de mest basale værktøjer til manipulering af 3D objekter, blandt disse er Move Tool, Rotate Tool og Scale Tool. Blå(2) er dine viewports, dette er vinduet ind i den digitale 3D verden hvor du kan skabe alt hvad man har lyst til, indenfor 3 dimensioner altså. Som standard er der 4 viewports, Front, Back, Top og Perspective. De første 3 ser 3D objekterne fra forskellige vinkler, uden nogen form for dybde, og den sidste ser 3D objekterne i 3D, altså i perspektiv. 26

29 At have nogle viewports hvor der ingen dybde er kan være rigtig godt hvis man skal have modelleret noget præcist, eller sammenligne et 3D objekt med et andet. Lilla(3) er din timeline, denne bliver brugt når man skal animere, den tæller i frames i stedet for sekunder. Orange(4) er din navigations menu, det er her du finder værktøjer der lader dig navigere din 3D scene. Gul(5) er din Menu, det er her du finder alle dine primitiver, forskellige modifiers og meget, meget andet. Primitiver Primitiver er som navnet antyder, de mest primitive objekter i 3Ds Max, herunder er der et billede af de forskellige primitiver. Du finder dem ved at trykke på Create (blå pil), derefter Geometry(rød pil), og så Standard primitives (sort pil). Jeg vil lige gennemgå de forskellige primitiver: Box Standard primitiv i form af en kasse, rektangel eller kube. Cone En kegle, hvor du kan indstille højden og radius i top og bund. Sphere En kugle hvor du kan indstille radius, om den skal være Squashed og hvor mange polygoner den skal have. GeoSphere En Sphere, men uden de samme indstillinger, den består af trekanter i modsætning til spheren som består af firkanter. Cylinder Navnet siger lidt sig selv. Tube En cylinder hvor du kan indstille ydre og indre radius, samt højden. Pyramid En pyramide. 27

30 Teapot Vores mest komplekse primitiv, den er egentlig i 3DS Max som en slags joke, men bliver ofte brugt hvis man har nogle grafik indstillinger der skal testes. Plane Mit foretrukne primitiv, det er en flad polygon, bliver ofte brugt som basis for edge modelling (mere om dette senere). Navigation i 3DS Max At navigere i 3Ds Max er nok noget af det vigtigste du vil komme til at lære, det er nemlig rimelig svært at lave noget i 3D hvis man ikke kan se ens objekt fra flere forskellige synsvinkler. I Dette afsnit vil jeg forklare de forskellige funktioner af navigations menuen som man kan finde nederst i højre hjørne. 1. Dette er vores Zoom Tool, giver dig lov til at zoome ind og ud på dit valgte object 2. Zoom All, Ikke et videre meget brugt tool, Men det giver dig lov til at Zoome i alle dine viewports på en gang. 3. Zoom Extents Selected, Zoomer dig ind på dit valgte object, så alle dele af dit object er indenfor viewportens rammer. 4. Zoom Extents All, Samme som Nr. 3, men hvor alle viewports zoomer ind på det valgte object. 5. Field of View, Dette kan ændre din FoV Angle, lad være med at pille for meget ved dette tool. 6. Pan View, Giver dig lov til at flytte dit kamera til siden, samt op og ned, meget brugt værktøj. 7. Orbit, Giver dig lov til at rotere om dit valgte object, midten af scenen, eller midten af dit Field of View. 8. Maximize Viewport Toggle, Når du trykker på denne knap bliver din valgte viewport maximeret, hvilket giver meget mere skærmplads til dit arbejde. Det kan være meget bøvlet at bevæge sig ned i denne menu hver gang man vil bevæge sig rundt i scenen, derfor er der genvejstaster til samtlige af disse funktioner, de kan findes på cheatsheetet. Basale værktøjer i 3DS Max Dette er dit Move tool, du kan finde den i den røde(1) værktøjslinje. Med dette værktøj kan du flytte objekter, polygoner, lines, bones og vertexer, samt det meste andet, rundt i scenen. Genvejstasten er E. Dette er dit Rotate tool, den ligger lige til højre for dit Move Tool i den røde(1) værktøjslinje. Du kan bruge dette værktøj til at rotere objekter i scenen. Genvejstasten er R. 28

31 Dette er dit Scale tool, det kan findes til højre for dit Rotate tool i den røde(1) værktøjslinje. Du kan bruge det på de samme objekter som med Rotate og Scale, men man skal passe på, hvis du skal skalere en model, så gør det under edit poly hvor du har valgt alle polygonerne/lines eller vertexer. Genvejstasten er T. Skalér aldrig bones! Hvis du ikke skal flytte, rotere eller skalere objekter så kan du bruge dit Select Tool, det ligger en smule til venstre for dit Move tool. Genvejstasten er Q. Manipulering af primitiver Hvis man vil lave en mere kompleks model, så er det ofte ikke nok at nøjes med primitiver. For at gøre det muligt for os at gøre vores model mere kompleks, skal den først laves om til en Editable Poly. Dette kan gøres ved at vælge et object, højreklikke på det, og så trykke på Convert to Editable Poly under submenuen Convert To. Når du har gjort dette vil du måske ligge mærke til at menuen til højre har ændret sig. Når man laver et objekt om til en Editable Poly skifter menuen til højre automatisk til Modify, når Editable Poly er valgt i ens modifier vindue, vil ens menu se sådan ud. I toppen af menuen har vi Selection, knapperne herunder lader dig vælge forskellige komponenter af din model. Fra venstre har vi: Select Vertex, Select Edge, Select Border, Select Polygon og Select Element. 29

32 De vertexer/edges/bordes/polys/elements der er blevet valgt er de røde. Umiddelbart kan det være svært at se forskellen mellem Select Edge/Border og Select Polygon/Element. Forskellen ligger i at, ved Border og Element skal man bare trykke en gang for at vælge enten alle kanterne på en åben model, eller alle de polygoner som rører ved hinanden på en model. Når man har valgt en del af sit mesh kan man flytte/skalere/rotere delen som man lyster, der er dog ikke de store effekter i at skalere eller rotere en vertex, da en vertex bare er et punkt i et koordinat system. En anden måde at modificere overflader på er ved at bruge en af følgende metoder: Extrude, Bevel og Inset metoderne. Extrude Extrusion er en måde at trække en overflade ud på hvor selve geometrien adapter til det udtrukkede flade. 30

33 Bevel Bevel fungerer lidt ligesom extrude bortset fra at det giver os muligheden for at kunne gøre den udtrukkede flade mindre i toppen så den danner en trapez-lignende figur. Inset Inset er et modelleringsværktøj som trækker det markerede område ind uden at modificere geometrien. Ved at flytte rundt på vertexer/edges/polygoner kan man hurtigt opnå nogle forskellige former. Men der er forskellige måder at opnå resultatet på, hvilket bringer mig til det næste kapitel. Modellerings Metoder Jeg vil i dette kapitel gennemgå de 2 mest brugte modellerings metoder i 3DS max, Edge modelling og Box modelling. Personligt foretrækker jeg en blanding mellem disse. Edge Modelling Når man begynder at lave en model ved Edge modelling, vil man som regel starte ud med at placere et enkelt primitiv, en plane, hvorefter man trækker i kanterne til man får det resultat man gerne vil have. Her er et eksempel på hvordan man hurtigt kan lave en tudegrim sko ud fra en enkelt plane. Først starter man med at placere sin plane et sted i ens scene, hvorefter man laver den om til en editable poly. 31

34 Det næste trin er så at tilføje nogle ekstra edges, det kan gøres med Cut Tool som ligger under Edit Geometry når man har valgt sin Editable poly under modifiers. For at tilføje flere Edges og polygoner til sin model kan man også holde Shift nede mens kan bruger sit move/rotate/scale tool. Dette skaber en ny polygon, i stedet for at flytte/skalere/rotere den valgte edge. Lad være med at gøre dette med vertexer. Ellers fortsætter man stille og roligt med at trække ud i, og flytte rundt på, ens edges indtil man får en form man er tilfreds med. På modellen ser det ud til at nogle af mine polygoner er trekantede. Dette er fordi alle firekantede polygoner egentlig består af trekanter, det samme gælder også for alle andre polygoner(polygon betyder mangekant). Fordi jeg ikke har nogen smoothing på denne model kan man se disse trekanter. Box Modelling Nu vil jeg prøve at lave en lignende model, men med Box modelling i stedet. Boxmodelling benytter sig ikke af shift+drag, som jeg bruge til edge modelling, derimod bruger man meget Extrude og Cut. Extrude ligger i Edit Polygons, mens Cut ligger i Edit Geometry. 32

35 Som man kan se er resultaterne næsten ens, der er bare lidt flere polygoner på den lilla sko, men formen er næsten den samme. Vigtigheden af Edge Loops og Rings Når man laver en kompliceret model med runde former, som et menneske, eller et ansigt, så er det vigtigt at have nogle gode edge loops. Et edge loop er en løkke af edges der ligger i forlængelse, på billedet til venstre. På billedet til højre er der en Ring selection, det er en selection af de edges some ligger parallelle med hinanden. Her er et eksempel på edge loops og rings der bliver brugt på en karakter. 33

36 Man kan se hvordan de forskellige edges ligger i loops omkring øjne og mund. Årsagen til at de skal ligge på denne måde, er at animationer der bliver lavet på meshet deformerer på en mere naturlig måde. Det samme koncept gælder for skulder og hofteled, der skal helst være nogle loops omkring det, så leddene kommer til at deformere rigtigt, det ville jo se fjollet ud hvis halvdelen af ryggen flytter sig hver gang ens karakter tager et skridt Udover det, så er et ordentligt mesh slik for øjnene for enhver 3D modellør. Klargørelse af ens model til teksturering Et unwrap er det kanvas du tegner på når man vil ligge en tekstur på sin model, det kan nemmest forklares som en mælkekarton hvor al limen er fjernet, så man kan folde den fladt ud på et bord. Når man skal have en tekstur på sin model, så skal modellen først gøres klar til det, dette kaldes for Unwrapping. For at gå igang med at unwrappe en model skal man først have tilføjet en Unwrap UVW Modifier til sin model. Dette gør du ved at trykke på den dropdown liste der hedder Modifier list mens du har valgt det objekt der skal unwrappes. I den liste finder du modifieren Unwrap UVW og trykker på den. Listen skulle gerne ligne ovenforstående billede nu. Når du vælger din Unwrap UVW modifier i din stack, får du et interface der minder en smule omkring editable poly, men i stedet for 5 måder at vælge dit mesh på, har du nu kun 3. Hvis man skulle unwrappe en kasse kan man gøre det på følgende måde. Du starter med at vælge polygon selection (1. billede i serien), herefter vælger du alle polygonerne på din kasse så hele kassen er rød. Herefter kigger du under projection methods og trykker på box map (2. billede i serien), når du har trykket på den har du nogle forskellige muligheder for at få dit boxmap til at passe bedre, prøv at leg lidt med dem og se om noget ændrer sig. 34

37 Når du er færdig med at tilpasse dit boxmap, trykker du igen på boxmap knappen, så den ikke er valgt mere. Derefter går du ned i den tab der hedder Edit UV s og trykker på Open UV Editor (3. billede i serien). Dette åbner et nyt vindue som skulle se sådan ud: Når man er færdig med at sætte sit unwrap op, og alle delene er indenfor firkanten, skal unwrappet exporteres fra 3ds Max så man kan komme til at lave sine texturer. Dette gør man ved at gå op i Tool -> Render UVW Template. Her har man de forskellige indstillinger for eksportering af Unwraps, de vigtige dele her er Width, Height og Render UV Template. Height og Width kontrollerer hvor stort det færdig renderede Unwrap er, eller hvor meget plads du har at tegne på. Værdierne her skal helst være i Power of two, dvs 512x512, 1024x1024, 2048x2048 da Unity og andre programmer og game engines har svært ved at arbejde i textures i andre formater end disse. Opsætning af rig Husk man ikke må skalere på bones! Et rig er en mængde af knogler, herefter refereret til som bones, som er sat op til at følge de bevægelser som du vil have din karakter til at foretage sig. Normalt 35

38 bruger man ikke lige så mange bones i et rig som et menneske har, men man nøjes derimod kun med de mest vigtige led og knogler, såsom arme, ben, ryg, hals og hoved. Et godt eksempel på et sådan rig kan være World of Warcraft, Mass Effect, Mass Effect 2 og Dragon Age, for hvis man ligger mærke til det, så vil man se at de aldrig bevæger deres fingre, men derimod går fra en stationær position til en anden stationær position. Knappen til at lave bones kan findes under: Create -> System -> Bones. Den nemmeste måde at sætte bones op på er at starte arbejde i front/left/top viewports, da det gør at du ikke skal flytte videre meget rundt med dine bones når du først har placeret dem. Når man skal lave en rygsøjle, skal man starte ved hoften, på grund af forward kinematics. Forward kinematics er en måde hvorpå bones bevæger sig i forhold til hinanden, ved forward kinematics bestemmer bone 1 hvor bone 2 skal være. Det er derfor man skal starte ved hoften når man skal lave en rygsøjle, for ellers vil den ikke bevæge sig korrekt når man skal animere den. Når man skal lave en arm skal man gøre det på samme måde, starte oppe ved skulderen og arbejde sig ud mod fingrene. Og igen ved benene. Som det er nu så vil armene og benene ikke følge med hvis man flytter bækkenet, eller riggets rod, dette kan vi ændre på ved at bruge vores link tool. Link tool til venstre og unlink til højre. For at linke benene til vores bækken og rygsøjle vælger man lårbenen, trykker på link-toolet, klikker på en af de valgte knogler, holder musen nede, og slipper den igen over det bækkenet. Hvis det er gjort rigtig vil benene følge med rundt når man trækker i bækkenet, det samme procedure gentages for a linke arme, fingre, hænder og andre ekstremiteter til ens bone opsætning. Forward kinematics er nice, men hvis man skal animere arm og benbevægelser kan det komme til at tage lang tid hvis man hele tiden skal ind og rotere knoglerne manuelt. For at gøre arbejdet lettere kan vi bruge inverse kinematics, i stedet for forward kinematics. 36

39 Hvis man bruger inverse kinematics vil det være bone 3 der kontrollerer bone 1 og 2. For at tilføje inverse kinematics skal man vælge Bone3, og oppe i Animations menuen i toppen af max, trykker man på IK Limp Solver under IK Solvers. Når man har valgt hvilken IK solver man vil bruge skal man trykke på et andet bone, i det her tilfælde bone 1. Når IK er tilføjet til et objekt vil der være et handle som man kan tage fat i, når man flytter rundt med dette handle vil de bones som man har inkluderet bevæge sig. 37

40 Inverse Kinematics er ikke noget som man skal tilføje til alle objekter, det bliver primært brug til arme og ben. Du kan prøve at lege lidt med det og se hvordan IK opfører sig på forskellige bone opsætninger, for at fjerne Inverse Kinematics igen sletter man det handle som blev tilføjet da man lavede sin IK chain. Når alle bones er linket som de skal og alle IK chains er sat op, er det tid til at binde vores rig til vores model. Skinning af modellen For at koble vores model til vores rig skal vi tilføje en Skin modifier til modellen, skin gør det muligt for dig at vælge de bones som skal kontrollere din model, og dernæst kontrollere hvilke vertexer der skal påvirkes af hvilke bones. Man tilføjer bones til sin skin modifier ved at gå ned i menuen til man finder knappen der siger add, dette åbner en menu hvor man kan vælge bones, personligt plejer jeg at vælge alle bones i scenen, da jeg som regel kun har 1 karakter i en scene af gangen. Når bones er tilføjet til modellen kan man prøve at rotere lidt på nogle bones og flytte på ens IK controllers for at se hvordan de forskellige vertexer er sat på. Når man har tilføjet ens bones til skin modifieren kan man ændre på hvordan ens vertexer er bundet til de forskellige knogler ved at ændre på sine envelopes. Envelopes er det område som et bone har indflydelse over, hvis to envelopers krydser hinanden vil de dele vægten af de forskellige vertices. Den helt gode grund til at gå ind og manipulere manuelt med ens vertex weights er fordi max ikke kan finde ud af hvordan en karakter ser ud, så hvis man bare bruger standard opsætningern af envelopes, kan det let ske at de bones man har i hænderne, har fat i noget mesh ved karakterens hofte. Som man kan se af billedet er der 2 envelopes, den røde og den mørkerøde, den inderste viser hvor gradienten mellem 2 bones skal stoppe, og den yderste viser hvor den skal begynde. Den gule streg er det valgte bone. 38

41 Men at ændre på envelopes er ofte ikke nok, det er godt til at sætte et skin op meget hurtigt, men hvis man skal have det mere præcist, bliver man nødt til at gå ind for at ændre vægten på den enkelte vertex. Dette gør man ved at trykke på Edit Envelopes når man har valgt sin skin modifier. Husk at sætte et flueben ved Vertices lige nedenunder. Her er et billede så du ved hvordan dine indstillinger skal være når du skal arbejde med de individuelle vertexer: Under display er der nogle flere flueben som skal slås til og fra, Show colored vertices/faces skal være slået til så du kan se hvordan vægten er fordelt, det giver dig et visuelt feedback på hvordan vægten er fordelt på de forskellige vertexer, hvilket er meget nemmere end at tjekke værdien for vertexerne en efter en. Jeg har slået alle envelopes fra når jeg arbejder med de enkelte vertexer fordi de er en forstyrrelse, og det kan være skadeligt for arbejdet hvis man ved et uheld kommer til at rykke rundt med ens envelopes. For at ændre på vægten på de forskellige vertexer skal du først vælge et bone, mens du har Edit Envelopes aktiv, og så trykke på en eller flere vertexer. 39

42 På billedet ovenover til venstre kan man se hvordan det ser ud når man har valgt nogle vertexer mens Edit Envelopes er aktiv, og til højre er vinduet hvor man ændrer hvilken vægt vertexen skal have på det valgte bone. Når man sidder og skinner en karakter er det ofte at den er symmetrisk, og hvis det er tilfældet ville det være lidt trist at skulle skinne begge sider af modellen når det hele er identisk sat op. For at undgå at skulle skinne halvdelen af modellen igen har vi vores Mirror Mode, så for at spejle alle vertexernes vægt aktiverer man Mirror mode. Når Mirror Mode er aktiveret vil vertexerne få 3 forskellige farver, alt afhængig af deres position i forhold til spejlet. På den ene side af spejlet vil alle vertexerne være grønne, og på den anden side vil de være blå, i midten af spejlet vil vertexerne være røde. De røde vertexer bliver ikke spejlet, da de gerne skulle være i midten af ens mesh. Spejlet er den gule firkant på billedet. For at spejle ens skins skal man bruge knapperne Paste Blue to to green verts og paste green to blue verts, de ligger til højre lige neden under Mirror mode knappen. Her er det ekstremt vigtigt at du husker på hvilken side du har skinnet, ellers kan du komme til at slette alt dit hårde skinning arbejde. Når al skinning er færdiggjort, og man er tilfreds med den måde ens model deformerer på når man bevæger de forskellige led, så er det tid til at gå over til animation. 40

43 Animation Animation i 3ds Max foregår ikke som animation i 2D, i den forstand at man ikke flytter rundt på ens bones for hver frame der skal animeres, derimod går man fra den ene ekstreme position til den anden og 3ds Max vil så lave bevægelsen i mellem de to positioner, interpolering. Et eksempel kunne være at animere en gående karakter. Til at starte med placerer du karakterens fod helt fremme i frame 1 hvorefter du i frame 20 har foden på jorden og til sidst i frame 40 er foden ved at lætte sig fra jorden og er på vej tilbage til den samme position som den havde i frame 1. Dette giver dog kun en meget grov animation, det virker rigtig godt hvis ens karakter er meget lille på skærmen, kører en primitiv stil i spillet, eller er under et stort tidspres. Hvis man så skal raffinere sin animation, vil man i de mellemliggende frames flytte lidt rundt på nogle ekstra bones så anklen bevæger sig, spidsen af foden bøjer når man er ved at sætte af, og andre små detaljer. Det kan dog være meget svært at få en god animation op og stå ved kun at bruge sinhukommelse, så en ting der er rigtig godt at gøre når man laver en animation, er at rejse sig op og gentage den bevægelse man gerne vil lave, indtil man har helt styr på hvordan ens krop bevæger sig. En anden god ide kunne være at få en ven til at gennemgå bevægelsen, og så optage det. Ellers kan det være en god ide at gå på youtube eller vimeo og finde en video der beskriver den bevægelse man gerne vil animere. For at komme igang med at animere skal man først lære de forskellige animationsværktøjer at kende. De fleste af dem ligger i animationsbaren i bunden af skærm, nummer 3 på billedet i kapitlet Introduktion til 3ds Max Din timeline udgør langt størstedelen af animationsbaren, det er her du kan se hvor du har placeret dine keys, hvor du kan navigere i tiden og flytte på de keys du allerede har placeret. Du kan navigere i tiden ved at bruge ctrl+alt+<en af knapperne på musen>, for at udvide din timeline mod venstre bruger du venstre museknap, for at udvide til højre bruges højre museknap, og for at bevæge sig frem og tilbage skal man bruge den midterste museknap. Den nemmeste måde at animere på er at bruge Autokey funktionen, det betyder at hver gang du laver en ny bevægelse i en frame, så sætter 3ds max automatisk en key Før man begynder at Animere er det vigtigt at man vælger alt i ens scene og trykker Set Key, det betyder at du altid har en frame som du kan vende tilbage til hvor der ikke er nogen transformationer på dine objekter. 41

44 Noget lignende skal gøres når man skal bevæge noget som ikke tidligere har bevæget sig. Selve animations processen er meget enkel, du flytter et bone, og en key kommer frem i din timeline. For at sætte den næste frame skal du flytte din navigationsbar og så bevæge dit bone hvorved en ny key bliver lavet. De keys der er blevet placeret kan flyttes og slettes som man lyster ved at vælge dem og så enten trykke på delete eller flytte dem rundt. For at kopiere keys vælger man de keys man gerne vil kopiere, holder shift nede og trækker dem. Hvis man flytter en key ovenpå en anden key, hvor begge keys ligger på det samme bone, så bliver den ene key overskrevet og man mister noget data. En vigtig ting at huske på når man laver animationer til spil, er at ens karakter ikke skal bevæge sig fra punk a til punkt b i 3d programmet, da det bliver gjort i Unity, eller en anden engine man har valgt til at lave sit spil med. Eksportering til Unity Vi er så heldige at vi har 3Ds Max installeret på alle vores computere i år, dette går nemlig eksporterings processen meget nemmere. Unity3D accepterer nemlig 3ds max filer så længe max er installeret på computeren, så det eneste man skal gøre er at trække 3ds max filen ind i unitys asset liste og så arbejde videre derfra. Hvis dette af underlige årsager ikke skulle virke bliver man nødt til at eksportere sit mesh fra 3Ds Max på den manuelle måde. Der er mange formater man kan eksportere til i Max, men vi kommer kun til at bruge et format i dette sammenhæng, nemlig fbx formatet. For at eksportere til fbx vælger man de objekter i scenen man gerne vil eksportere og trykker på max logoet oppe i venstre hjørne af vinduet. Under den menu der kommer op er der en submenu der hedder Eksport, inde i den trykker du på knappen eksport selected Efter man har valgt hvor du vil gemme filen, formatet, navnet på den og trykket gem, så får man en stor grim menu smidt i hovedet. I denne menu kan du vælge hvad der skal eksporteres med din fil, hvilket kan være meget nyttigt hvis man har valgt at eksportere hele scenen, men ikke vil have lyset eksporteret med. Man kan i øvrigt ikke eksportere lys fra max ind i Unity. Når man har valgt hvilke ting der skal eksporteres med trykker man på Export og eksporteringen går igang. Derfra taget programmørerne over og får magi til at ske. Slutning Hvis der er nogen som har yderligere spørgsmål til 3Ds Max, og har lyst til at vide noget af det mere avancerede så kan man hive fat i mig, Jens-Ole, eller Stefan under campen, skrive til os på facebook, eller på mail / 42

45 Programmering 43

46 Programmering En Lille Advarsel Programmerings-delen af GDC Bogen er skrevet med henblik på nybegyndere eller let øvede, og der bliver sprunget over hvor gærdet er lavest. Vi bruger præcise termer lidt løst, så forvent ikke at du altid møder samme ordbrug som du møder her, især ikke i 400-siders undervisningsmateriale. Vi spiller fast and loose her. Spørg os, hvis der er forvirring. Inden I begynder at kode Den største fordel ved at bruge en Game Engine som Unity, er, at der i forvejen er en masse funktionalitet, som I ikke selv behøver at kode. Det betyder dog ikke, at I er tvunget til at bruge disse komponenter, hvis I ikke har brug for dem. Men så snart I har brug for bare et minimum af interaktion mellem elementerne i jeres spil, bliver det meget hurtigt svært hvis I ikke benytter jer af de foruddesignede komponenter. Herunder er listet nogle, som I med garanti får brug for: GameObject Alle ting, som bliver tilføjet til scenen er af typen GameObject. Et GameObject sørger automatisk for at håndtere en masse ting, som kan bruges til at kopiere ting i scenen og holde styr på hvilken model eller texture, der bliver brugt. Meget af det er optional og bliver kun relevant når man faktisk bruger det, med undtagelse af Transform komponenten... Transform En Transform indeholder data som position, rotation og størrelse. Siden at dette er noget som alle objekter i spillet skal have har et GameObject altid en Transform component. RigidBody Et GameObject med en komponent af typen RigidBody, vil blive påvirket af Unitys indbyggede fysikmotor. Det betyder, at Unity vil forsøge at få elementet til at opføre sig, som et element fra den virkelige verden. Med andre ord vil elementet altså falde nedad, hvis det hænger i den frie luft, vælte, hvis man skubber til det, eller glide eller trille, hvis det ligger på et skråt underlag. Ved brug af Scripts har I mulighed for at gå direkte ind og påvirke elementet. I kan derfor hurtigt kode jer til at elementet får tilført en kraft nedefra, hvis I for eksempel ønsker at lave en raket, en helikopter eller noget helt tredje. Til at lave Scripts bruger vi C# (C sharp) på GDC. CharacterController Inden I begynder at benytte CharacterController, skal I være opmærksomme på, at det IKKE er et fysisk element på linje med RigidBody. Det vil derfor ikke indgå i fysikmotoren, på samme måde som et RigidBody. Til gengæld kan I slippe for en masse besvær, hvis I ønsker en let og enkelt måde at styre jeres spiller og/eller fjender rundt i jeres bane. CharacterController har de fordele, at den ignorerer udefra kommende kræfter, så som slag fra andre fysiske elementer. Endvidere kan den selv finde ud af at gå op ad trapper, så I ikke skal bøvle med at den går i stå ved kanten til hver eneste trappetrin. 44

47 Colliders Hvis jeres GameObjects falder igennem jorden eller hinanden, er det nok fordi en af dem ikke har en Collider. Denne komponent har intet med udseende at gøre. Den fortæller derimod noget om, hvordan det pågældende element skal opføre sig i fysikmotoren. I langt de fleste tilfælde, vil man helst have Collideren til at minde så meget som muligt om den grafiske repræsentation af elementet, men man kan sagtens tilføje en SphereCollider til en kasse - sådan en kasse vil opføre sig som en kugle, på trods af at den på skærmen bliver vist som en kasse. Hvis I vil lave Power Ups, så som ekstra liv, ammunition eller guldmønter, er det en fordel at sætte hak i boksen Is Trigger. Det sikrer jer, at jeres spiller ikke kolliderer med de enkelte elementer, men blot sender en besked til jeres program, om at spilleren bevæger sig igennem Collideren. C# scripts På Game Development Camp har vi valgt at bruge C# (udtales C sharp). Det er et lidt mere avanceret sprog end fx JavaScript, som Unity også kan håndtere, men det er mere ensartet og har nogle ekstra funktioner, der kan spare en masse tid. C# er stadigvæk ret let at lære og vores mål med campen er ret overskuelige, så vi får kun brug for en del af de mest basale funktioner. Der er en del kode man skal skrive inden et C# script kan fungere, men når man opretter et nyt C# script i Unity skriver den automatisk alt det man normalt skal bruge. Først vil vi gennemgå hvordan man skriver kommentarer i sin kode så man kan gøre den nemmere at læse for andre. Kommentarer //Alt der står efter to skråstreger på en linje, bliver ignoreret af computeren //(dvs. ikke medtaget i koden). /* Hvis man vil skrive en længere kommentar, kan man bruge en skråstreg og en stjerne til at indikere, at computeren skal ignorere det næste stykke tekst. Det er en god idé at skrive kommentarer i jeres kode, så I også ved hvad den gør på dag 7. Det er også vigtigt for at andre i gruppen kan forstå jeres kode hurtigt. En stjerne og en skråstreg indikerer, hvornår det ignorerede område afsluttes. */ Det Allermest Basale Når man skal til at skrive kode er der nogle basale ting, der gør sig gældende. Ligesom et punktum slutter en sætning på dansk, gør et punktum eller en parentes nogle helt bestemte ting i C#. Lad os hurtigt kigge på en linje kode, før vi begynder at forklare de mere specifikke ting. Det er OK hvis du ikke helt forstår hvad der sker her, vi skal kun kigge på nogle enkelte dele. 45

48 float distance = Vector3.Distance(firstVector, secondvector); Den blå tekst float er en type af variabel, der kan indeholde kommatal. Vi gennemgår variabler som det første, nedenunder. distance er det navn, vi giver variablen - variabelnavne kan ikke have mellemrum. Værdien af vores variabel er beskrevet efter lig med tegnet. Til at finde en værdi bruger vi, i dette eksempel, en metode. En metode er ligesom en meget simpel regnemaskine: Du giver den noget bestemt information, og får resultatet af udregningen tilbage. Vi vil gerne finde afstanden mellem vektorerne firstvector og secondvector her. Derfor bruger vi metoden Vector3.Distance( Vector3 a, Vector3 b ), som vi på forhånd ved giver os et float tal som resultat (det står i et opslagsværk for programmører, der kaldes scripting reference i Unity)... Og hvad betyder Vector3.Distance? Tænk på Vector3 som en overskrift. I kapitlet Vector3 finder vi de ting, vi skal bruge for at arbejde med 3-dimensionelle vektorer. Vi vil gerne finde afstanden mellem 2 punkter, så derfor bliver vi nødt til at finde et mere præcist afsnit, Distance. Vi bruger et punktum for at få adgang til den slags subsektioner, derfor: Vector3.Distance. Denne simple måde at få adgang til ting, der ligger længere inde under store overskrifter, kommer du med garanti til at bruge rigtigt mange gange. Udover at Vector3 er en overskrift til alle almindelige værktøjer, man bruger med 3-dimensionelle vektorer, er det også en type variabel. Vi kan se i parentesen her: Vector3.Distance( Vector3 a, Vector3 b ) at Distance metoden gerne vil have to informationer, begge af typen Vector3. De behøver ikke hedde noget bestemt, men de skal være af den rigtige type, og de skal være opdelt med et komma. Variabler Variabler er det mest grundlæggende I bruger når I skal få noget til at ske i jeres Scripts. En variabel er et sted hvor man kan gemme informationer. For at regne noget ud et sted i script et skal man gemme vigtige informationer i variabler - der er ikke nogen magisk måde at fortælle computeren den skal gå tilbage i programmet og se hvad den lavede, så man kommer til at bruge mange variabler og man kommer til at bruge dem til ting, man ikke normalt tænker over. Hvis man tænker på en variabel som en kasse, så kan man tænke på forskellige typer variabler, som forskellige former kassen kan have. Det man ligger ned i kassen skal passe i den form kassen har. Lad os tage et eksempel: int mittal; Ovenstående kode består af 3 (!) dele, tilsammen udgør linjen en definition af en variabel. De 3 dele er int, mittal, og et semi-kolon til at afslutte ( ; ). 1. int betyder integer på menneskesprog. Det er variablens type. Ordet integer betyder et helt tal (fx 1, 2, 3, osv.) som også kan være 0 og negativt (0, -1, -2, -3, osv.). 46

49 2. mittal er et navn, man som programmør giver variablen. Fordi man som programmør tit arbejder med rigtigt mange variabler og der også er andre typer ting, der skal have navne, er det en god idé at starte alle variabelnavne med småt og give dem et navn, der beskriver hvad der er gemt i den. Kig evt. i afsnittet At Skrive God Kode, i slutningen af programmerings-delen, for at se hvordan man navngiver variabler. 3. semi-kolon afslutter alle argumenter i koden (hvad det betyder helt præcist er en anden snak). For nye programmører er den mest udbredte fejl at glemme dette! Langt de fleste linjer skal afsluttes på denne måde og I vil lære de mest udbredte undtagelser. Som du måske har gættet har vi nu oprettet en variabel til hele tal, der hedder mittal. Den har ikke fået en værdi endnu - den kan vi sætte når vi begynder at bruge den. Indtil da kan vi ikke bruge mittal til noget fordi værdien er ikke-eksisterende! - Lad os derfor kigge kort på hvordan vi giver variablen en værdi og bruger den: int mittal; mittal = 5; print( mittal ); Ovenfor har vi udvidet koden lidt så den indeholder 3 argumenter: 1. Først definitionen af variablen mittal, som vi kender fra før. 2. Så giver vi variablen en værdi. Efter variablen er defineret behøver vi ikke at bruge int igen, for computeren ved allerede hvilken slags variabel vi arbejder med. 3. Til sidst viser vi indholdet af mittal på skærmen ved at bruge metoden print og give den mittal som information. For nemheds skyld kan man også sætte en værdi af en variabel i samme øjeblik som man definerer den. Nedenstående eksempel betyder præcis det samme som det ovenfor. int mittal = 5; print ( mittal ); Typer og Objekter Husk på at vi kunne tænke på forskellige typer variabler som forskellige former af kasser, hvor vi kan lægge ting med samme form i. Her er nogle simple typer: 1. int: Hele tal, både positive og negative. Bruges tit til at gemme informationer som fx hvor mange skud man har til et våben. 47

50 2. float: Kommatal, både positive og negative. Bruges tit til at gemme 3D-positioner eller størrelser som længde eller afstand. 3. bool: Betyder Boolean, og det er en type variabel, der kun kan være 0 (false) eller 1 (true). Bruges typisk til at huske ja/nej information. 4. string: Til vores formål er String også en simpel type, som gemmer tekst. I virkeligheden er den lidt mere avanceret, men det bliver sandsynligvis ikke vigtigt. Nogle typer variabler består af flere andre variabler. Unity bruger et par stykker, som er vigtige at kende til. Fordi de indeholder mange simple variabler kaldes de ofte for klasser (classes) i stedet, for at adskille dem fra simplere variabler: 1. Vector2: Gemmer 2 float værdier. Tilsammen udgør det en vektor i 2-dimensionelt rum (som fx en streg på et stykke papir). 2. Vector3: Gemmer 3 float værdier. Tilsammen udgør det en vektor i 3-dimenstionelt rum (som fx en pil på en bue). 3. GameObject: En meget avanceret variabel, der gemmer utallige informationer om et objekt i Unity. Det inkluderer et navn, en position, en rotation, samt en masse andet - men det behøver vi ikke bekymre os om. Vi skal ofte kun bruge selve objektet eller én af dets værdier (som fx position). Der er masser af andre typer variabler, men dem gider vi ikke tænke på nu. Vector3 er en af de variabeltyper I sandsynligvis vil bruge mest, fordi den kan repræsentere 3D-positioner. Så lad os kigge lidt nærmere på hvad den kan: Den består af 3 float værdier, med hver deres navn: x, y og z. Nedenstående kode viser hvordan man definerer en Vector3 med værdier og derefter ændrer x-værdien: Vector3 myvector = new Vector3( 2.5f, 2.5f, 2.5f ); myvector.x = 0f; Hovsa, her sker der nogle nye ting! Lad os først kigge på hvad der rent funktionelt sker: 1. Vi definerer en vektor og, i samme linje, giver vi den værdien 2½ i alle 3 retninger. 2. Vi sætter x-værdien til 0, så myvector nu har værdierne 0, 2½ og 2½. Det er standard at bruge punktum for adgang til værdierne i en klasse, derfor: myvector (punktum) x. Nu sidder du sikkert med et par spørgsmål: Hvorfor er der et f efter tallene og hvad er det for en mærkelig måde vi skal give vores Vector3 en værdi på? Hvad er det for noget rod med new?! Det mærkelige f kommer fordi værdierne er af typen float. Det skal gøres helt tydeligt for programmet, ellers brokker computeren sig. Den mærkelige måde at giver værdierne til en vektor på hænger sammen med at de mere avancerede variabler også kaldes for klasser. Klasser skal bruge new i koden så vi kan fortælle programmet at vi vil have 48

51 en ny udgave af klassen, fuldstændigt ren. Efter new bruger vi Vector3 s såkaldte constructor. En constructor sørger for at sætte alle værdierne i den nye klasse på en korrekt måde (constructor en her er Vector3( 2.5f, 2.5f, 2.5f ) ). Fordi klasser kan være meget avancerede er der ikke nogen simpel måde at oprette dem på, som vi ellers kender det fra int. Man kan også bruge værdier fra andre vektorer til direkte at give værdierne til sin nye vektor. I nedenstående kode finder vi rigidbody.velocity - det er et standard-element på alle objekter der har en RigidBody - og bruger denne værdi til direkte at give værdien af myvelocity. Vector3 myvelocity = rigidbody.velocity; float xvelocity = myvelocity.x; Arrays Enkelte variabler er glimrende, men ofte får man brug for kæmpe samlinger af variabler, der hænger sammen. For eksempel kan vi beskrive hver motor på en rumraket med en float værdi, der viser hvor meget kraft motoren har. Hvis vi nu har en Super-Star Destroyer med 100 motorer ville det være råkedeligt at have hundrede variabler med navnene engineone, enginetwo, osv. Der findes en meget nemmere måde at gøre det på, kaldet arrays. Et array er, i talesprog, en helt almindelig liste (selvom en list i C# er noget lidt andet). Lad os se på et script, der opretter 100 float værdier i array et engines og herefter sætter motor 1 og 25 til en værdi. float[] engines; engines = new float[100]; engines[0] = 2.2f; engines[24] = 3f; float[] betyder at variablen er af typen float array. Læg mærke til brugen af square brackets ( [ og ] ). Fordi arrays har mange værdier opfører de sig lidt som klasser når vi definerer dem. Jeg har valgt at definere navn og indhold i 2 linjer her, men ligesom før kan det gøres i én linje. Tallet markeret med lilla (100), bestemmer hvor mange ting der er i array et. Men hver enkelt ting har ikke en værdi endnu - lad os først manuelt kigge på at give 2 af motorerne værdier. Man kan få adgang til den enkelte værdi ved at bruge array ets navn og dets index; et nummer der beskriver værdiens position i array et. Læg mærke til at arrays starter med index 0! Første motor, motor 1, har derfor index 0. Motor 2 har index 1, motor 3 har index 2 osv. For at ændre værdien af motor 25 skal vi derfor kigge på index 24. Det virker lidt dumt til at starte med men efterhånden som I bruger det, bliver det hurtigt naturligt. Det største problem med et array er at det ikke kan ændre størrelse når det er oprettet (det er til gengæld meget hurtigt for computeren at bruge det). 49

52 Dynamiske Lister Hvis man skal lave et array hvor man kan tilføje og fjerne enkelte elementer, skal man bruge en list i C#. Det kræver lidt forarbejde. Aller øverst i script et tilføjes linjen: using System.Collections.Generic; Denne linje sørger for at C# ved hvor computeren skal finde instruktionerne på at lave en list. Nu kan du bruge list i koden! Første gang man kigger på definitionen af list virker den lidt mærkelig, fordi den skal have at vide hvilken type variabel den er på en lidt anden måde. Lad os definere en liste af motorer og tilføje to aktive motorer, ligesom før. Vi kan dog ikke give de to motorer specifikke pladser i listen, så på denne måde kan vi ikke illustrere at den ene motor er motor nummer 25. List<float> activeengines; activeengines = new List<float>(); activeengines.add(2.2f); activeengines.add(3f); list bruger mindre end ( < ) og større end ( > ) tegn til at vise hvilken type variabel den bruger. Læg mærke til at constructor en, som vi kender fra Vector3 tidligere, også bruger < og > som en del af dens navn, og samtidigt har en tom parentes. Den tomme parentes har den samme funktion som Vector3 s constructor parentes - det er her man giver start-input - men en list kræver ingen start-input, derfor er parentesen tom. list er en mægtig fin ting når man skal finde specifikke genstande. Lad os antage at vi vil have et inventory system i et spil, hvor vi kan have ting med navne, fx crappy sword og awesome sword, gemt som en string, dvs. vi gemmer bare navnet. List<string> myinventory; myinventory= new List<string>(); myinventory.add( crappy sword ); myinventory.add( awesome sword ); myinventory.add( crappy sword );... Så vidt så godt; vi har lavet et inventory kaldet myinventory og lagt 3 navne på sværd i det. 1 awesome sword, og 2 crappy swords. Vi kan finde ud af om vores liste indeholder et bestemt navn, så vi kan tjekke det et andet sted i programmet! 50

53 Det gør vi ved at bruge metoden.contains. Læg mærke til at jeg ikke skal skrive List.Contains(listenstNavn, hvadjeglederefter), men i stedet kan nøjes med at sætte.contains direkte efter navnet på min liste. Hvis jeg har et awesome sword i min liste, vil resultatet af minlist.contains( awesome sword ) være true (eller ja ). if (myinventory.contains( awesome sword )) { print( Du har stadig dit seje sværd! ); else { print( Du har lagt dit seje sværd fra dig, klaphat! ); Dét var en fælde; nu bliver jeg nødt til også at introducere noget kaldet if-else sætninger. Du kan nok nogenlunde gætte hvad der sker ovenfor - hvis myinventory indeholder (.Contains) et awesome sword, så skal programmet skrive lykønskningen. Hvis myinventory ikke længere indeholder det, skal programmet skælde spilleren ud. If, else if og else sætninger En if-sætning gør det muligt at opstille et spørgsmål og køre forskellig kode alt afhængigt af svaret på spørgsmålet. Computere er dumme, så de kan som udgangspunkt kun svare ja eller nej. Til gengæld kan vi stille dem en række forskellige spørgsmål. Lad os starte med at spørge hvor awesome vi er (jeg antager at vi allerede har en variabel kaldet powerlevel): if (powerlevel > 9000) { print( Over nine thousand ); Læg mærke til at if ikke bruger et semikolon. Spørgsmålet bliver stillet i parentesen og hvis svaret er ja, køres koden i tuborg-klammerne ( { og ). Spørgsmålet er her om powerlevel er større end En metode, der giver et boolean resultat (altså ja/nej) kan også bruges i en if-sætning, som jeg fx gjorde i afsnittet om dynamiske lister: if (myinventory.contains( awesome sword )) {... Det kan vi bruge lidt mere avanceret. Lad os antage at vi vil tjekke om vores kampvogn og fjendens kampvogn kan angribe hinanden. På forhånd har vi fundet afstanden distance og defineret vores rækkevidde weaponrange: 51

54 if (distance < weaponrange) { print( Fire everything! ); else { print( Drive me closer! ); Du har nok gættet at koden i tuborg-klammer efter else køres hvis svaret på spørgsmålet er nej. Programmet vil altid kun køre den ene af disse, fordi den ene ting udelukker den anden. Fordi der ikke er nogen krav efter else, vil computeren altid skrive en af de to bidder tekst. For det meste vil man spørge computeren om et tal er større, mindre eller lig med et andet tal. Herunder er en liste af matematiske spørgsmål man kan stille i en if sætning. Jeg kalder de to tal i spørgsmålet for tal1 og tal2 her... tal1 < tal2 tal1 <= tal2 tal1 > tal2 tal1 >= tal2 tal1 == tal2 tal1!= tal2 Mindre end: Svarer ja hvis tal1 er mindre end tal2. Mindre end el. lig med: Svarer ja hvis tal1 er mindre end eller lig med tal2. Større end: Svarer ja hvis tal1 er større end tal2. Mindre end el. lig med: Svarer ja hvis tal1 er større end eller lig med tal2. Lig med: Svarer ja kun hvis tal1 og tal2 er nøjagtigt ens. Husk to lighedstegn! Ikke lig med: Svaret er ja i alle andre tilfælde end hvis tal1 og tal2 er nøjagtigt ens. Man kan kombinere spørgsmål. For eksempel kan jeg spørge om vi slås mod en 13-hovedet drage og har et epic anti-dragon sword, der kun kan slå 13-hovede drager ihjel. if (numberofheads == 13 && myinventory.contains(epicantidragonsword)) { print( The 13-headed dragon is doomed. ); Her bliver de to enkelte spørgsmål ( har dragen 13 hoveder? og har jeg et epic anti-dragon sword? ) først svaret hver for sig. Hvis vi fx ser en 14-hovedet drage og har sværdet, vil svaret på de to spørgsmål være nej (dragen har ikke 13 hoveder) og ja (vi har sværdet). && betyder at begge svar skal være ja for at vi kan fortsætte. Hvis ét af dem er nej, kører koden i tuborg-klammerne ikke. Der er to almindelig måder at stille flere spørgsmål på. Jeg vil her angive hvert spørgsmål med ordene que1 for spørgsmål 1 og que2 for spørgsmål 2. 52

55 que1 && que2 que1 que2 Og: Det samlede svar er ja kun hvis begge spørgsmål resulterer i ja. Eller: Det samlede svar er ja hvis en af de to, eller begge, spørgsmål resulterer i et ja. Vi kan nu lave et mere realistisk scenarie. Vi vil først tjekke om du har et våben. Hvis du har det, vil vi tjekke hvor svært det bliver at slå dragen ihjel. Hvis du ikke har et våben vil vi tjekke hvor meget du er på spanden. Jeg antager at dragen altid har mindst 1 hovede. if (myinventory.contains( awesome sword ) myinventory.contains( crappy sword ) ) { print( You have a weapon, and... ); if (numberofheads == 1) { print( The dragon only has one head - easy kill ); else { print( The dragon has more heads - fight well! ); else if (numberofheads == 1) { print( No weapon, but only one dragon head. You escape safely. ); else { print( You are dead :( ); Som du kan se kan man også sætte if-sætninger ind i andre if-sætninger og på den måde ende med mange forskellige muligheder for svar. Men på trods af hvor komplekst det endelige svar er, vil alle de enkelte dele af spørgsmålet stadig være simple ja/nej spørgsmål. Løkker Hvis man har et stykke kode, som man gerne vil kunne gentage, er løkker sagen! Der findes to løkker, som I kan komme til at bruge. Disse er for-løkken og while-løkken. En for-løkke er specielt velegnet, hvis man laver noget, hvor man på forhånd ved hvor mange gange løkken skal køres igennem. Skal man for eksempel finde summen af alle værdierne i et array, bør man bruge en for-løkke. Lad os kigge på en for-løkke, der lægger alle tal mellem 1 og 10 sammen. float total = 0; for(int i = 0; i < 10; i++) { 53

56 total = total + i + 1; print(total); En for-løkke tager 3 argumenter, separeret med semi-kolon. 1. int i = 0 opretter en integer variabel med startværdien 0 2. i < 10 betyder at løkken skal stoppe, før den når 10 (dvs. sidste del af løkken vil være i = 9) Man kan også bruge større end ( > ) eller de andre sammenligninger, vi kender fra if sætninger. 3. i++ sørger for at lægge 1 til i, efter hver gang. Variablen i indeholder således hvilket nummer gentagelse, løkken er i gang med på et givent tidspunkt. Inden i løkken har vi skrevet: total = total + i + 1; Det betyder at total i hver eneste gentagelse af løkken vil blive sat til at være lig med sig selv, plus løkkens nummer, plus 1. Hvorfor plus 1? Husk at denne løkke starter ved 0, og stopper ved 9! For at lægge tallene mellem 1 og 10 sammen, bliver vi nødt til at lægge 1 til løkke-gentagelsens nummer. (Resultatet er i øvrigt 55) Noget man typisk kommer til at bruge er for-løkker i samspil med arrays eller lister... Her er et eksempel, som skriver alle dele af et array ud på skærmen:... for(int i = 0; i < myarray.length; i++) { print(myarray[i]); Det, der sker her er såmænd bare at vi i stedet for at give et bestemt antal gentagelser, siger til computeren at den skal gentage det lige præcis så mange gange, som der er data i vores array. myarray.length giver jer et tal, der svarer til array ets størrelse i dét øjeblik. Vi kan bruge variablen i til at kigge det rigtige sted i array et efterhånden som vi går igennem gentagelser af løkken. Den anden type løkke, en while-løkke, gentager et bestemt stykke kode så længe dens betingelse(r) er opfyldt. Nedenfor er der en while-løkke, som looper uendeligt så længe thisistrue er true. bool thisistrue = true; while (thisistrue) { print("looping..."); 54

57 Løkker af begge typer, men især while, kan komme til at loope uendeligt! I eksemplet ovenfor er der ikke noget, der ændrer thisistrue værdien til false - så den vil aldrig stoppe. Det er en meget udbredt fejl i programmering, og er typisk synderen hvis jeres spil fryser og ikke svarer på jeres input. Metoder Nu har jeg nævnt metode ret mange gange i teksten, så tid til at afmystificere det. Som før nævnt kan man tænke på enhver metode som en lille regnemaskine, der tager nogle informationer og udregner et resultat. Metoder behøver faktisk ikke gøre nogen af delene, men de gør det ofte. Her en et eksempel på en metode, der altid vil give værdien 1337 som resultat: public int MakeThis1337 (int number) { if (number!= 1337) { return 1337; else { return number; Vi tager lige et nærmere kig på øverste linje om lidt... For god ordens skyld, så husk at if (number!= 1337) betyder hvis number ikke er Linjen return 1337; sørger for at sende 1337 som resultat af metoden, hvor linjen return number sørger for at returnere værdien af number. public int MakeThis1337 (int number) { Denne linje beskriver hvilken type metode det er, hvad dens navn er, og hvilke informationer den behøver, og indeholder en tuborg-klamme som fungerer ligesom ved if-sætninger (alt i tuborg-klammerne er en del af metoden). public betyder at alle dele af programmet har adgang til at bruge denne metode. Man kan også bruge private, men så kan man kun bruge metoden i samme fil som den er skrevet. int er hvilken slags resultat, metoden resulterer i. Det kan være enhver type variabel eller klasse, fx Vector3 eller GameObject, så længe vi sørger for rent faktisk at give vores resultat videre! Alt i parentesen er den information, vi skal bruge til at lave vores udregning, altså vores input. Det fungerer lidt som når man definerer en ny variabel. number vil altid have en værdi, også selvom vi ikke giver den en værdi i metoden, for når man bruger metoden bliver man nødt til at indtaste en værdi. Fx: int mynumber = 88; mynumber = MakeThis1337(myNumber); print(mynumber); Ovenstående kodeeksempel vil altid skrive 1337 ud på skærmen. En metode kan også se sådan her ud: public void Example () { 55

58 I dette tilfælde tager funktionen ingen input (tom parentes) og returnerer ikke noget direkte (den returnerer typen void, som groft oversat betyder tom ). Tuborg-klammerne er også tomme her, men det er kun for eksemplets skyld. Selvom det måske virker lidt mærkeligt at lave en metode, der hverken tager input eller giver output, så kan det nogen gange være brugbart fordi metoden stadigvæk kan manipulere med andre variabler, den har adgang til. På den måde kan man dele sin kode bedre op, så den bliver mere overskuelig. Her er et eksempel på en metode, der giver mening selv uden designeret input og output: string myname = ""; public void Initialize () { if (myname == "") { myname = "No name"; print ("Initialized: " + this.tostring() + ", with name: " + myname); Metoden Initialize() kan altså ændre myname, uden at det nødvendigvis er beskrevet som metodens output. Initialize() sørger også for automatisk at skrive: Initialized: (navn på scriptet), with name: (værdien af myname) på skærmen. Pass-by-Value vs. Pass-by-Reference Når man i koden giver en værdi til en variabel, bruger C# to forskellige måder at gøre det på... Den nemmeste og mest ligetil er Pass-by-Value, som er det vi kender fra eksemplerne. int mynumber = 88; int othernumber = 0; othernumber = mynumber; Hvis man skriver koden ovenfor vil computeren kopiere tal-værdien fra mynumber og give den til othernumber. Men udover at have den samme værdi, har de ikke noget med hinanden at gøre. Mere avancerede data-typer som fx GameObject bruger Pass-by-Reference. I stedet for at kopiere enkelte tal og værdier, får man en reference, et slags hyper-link. GameObject mygameobject = new GameObject("first"); GameObject othergameobject = new GameObject("second"); othergameobject = mygameobject; Ovenstående laver ikke en ny kopi af GameObject et med navnet first. othergameobject og mygameobject refererer til gengæld til nøjagtigt det samme GameObject. Eller kan man bruge det som en 56

59 normal variabel, men det er vigtigt at huske på at vores GameObject ikke er kopieret. Hvis jeg ændrer noget, fx mygameobject.transform.position vil samme ændring ske for othergameobject.transform.position. Der findes masser af måder at arbejde sig udenom problemet på, men det går vi ikke i detaljer med her. Almindelige Fejl Alle programmører laver fejl, så vi kan lige så godt vænne os til det. Det er kropumuligt at undgå at lave fejl, men man kan bekæmpe dem på mere eller mindre effektiv vis. Her er en liste over de mest almindelige fejl for nybegyndere og let øvede programmører. Nogle af disse fejl bliver også begået af meget erfarne programmører fra tid til anden! Semikolon Det er helt almindeligt at skøjte rundt i det med semikolon. Det skal efter langt de fleste linjer, og man glemmer dem mange gange, eller også kommer man til at sætte semikolon et sted, hvor det ikke skal være. Heldigvis er computeren som regel god til at anbefale semikolon eller finde ud af, hvad der skal stå i stedet og informere programmøren om det. Ikke desto mindre slipper der altid noget igennem og det kan godt betale sig at tjekke programmet igennem for semikolon hvis man får underlige fejl. Stavefejl Juhuu! Sørg for altid at give dine variabler tydelige navne, der både klart beskriver variablens brug, men også adskiller den fra fx navne på metoder eller andre variabler. Det er en rigtig god idé at kigge i afsnittet At Skrive God Kode i slutningen af programmeringsdelen for nogle helt almindelige tricks, der sørger for at din kode bliver mere forståelig. Stavefejl i kodesprog dækker også over andet end et enkelt bogstav, der er forkert (det brokker computeren sig også som regel over!). Den hyppigst forekommende stavefejl er at man har copy-pastet noget kode, hvor man skal ændre alle referencer til en bestemt variabel - så glemmer man bare lige at ændre en eller to referencer, der gemmer sig et sted og får koden til at opføre sig som en struds på steroider. Sørg altid for at dobbelt-tjekke når i copy-paster kode i jeres scripts, for at undgå denne tidssluger. Uendelige løkker Uendelige løkker kan opstå på mange udspekulerede måder. Det er normalt nemt at gætte, hvis fejlen er en uendelig løkke, for programmet fryser og svarer sandsynligvis ikke. Det er straks sværere at besvare hvilken løkke, der kører uendeligt og hvorfor. Vi kommer senere til at kigge på begrebet debugging, som er et fancy ord for fejlsøgning, som gør det nemt at finde ud af hvilken løkke, der er skyldig. Her er et par standard-fejl, der får dem til at opføre sig sådan: for (int i = 0; i < 100; i++) { //A lot of code here... i = 0; 57

60 Medmindre det er absolut nødvendigt skal man aldrig sætte værdien af i (det kan være den hedder noget andet) inden i for-løkken. Nix pille. int a = 0; int max = 9; bool something = true; while (a < max) { //A lot of code here... if (something) { a = a-1; a = a+1; Ovenstående eksempel er en gammel klassiker, når det kommer til uendelige løkker. while løkken her stopper kun hvis a er større end, eller lig med, max. Men løkken her både tilføjer og fratrækker 1 ved hver gentagelse... Det betyder at a aldrig bliver over max på 9, så vi når aldrig en tilstand, hvor while løkken stopper. Det kan også være man sammenligner to floats (altså kommatal) på denne måde: float a = 0.0f; float b = 1.0f; while (a!= b) { a = a + 0.1f; Det ser måske harmløst ud... Selvfølgelig vil a blive til 1 efter nogle gentagelser. Men sådan fungerer float ikke... Der er altid en lille bitte smule mangel på præcision, så det kan være at a på et tidspunkt går fra 0.9 til Og så når a ikke at blive præcis 1 på noget tidspunkt, og så stopper while løkken ikke. Når vi sammenligner to kommatal bliver vi desværre nødt til at tage højde for den slags. Læs mere om hvordan man kan sammenligne kommatal på en stabil måde i afsnittet At Skrive God Kode, sidst i programmerings-delen. C# i Unity Grunden til at vi bruger Unity er at det kan alt muligt smart og har en masse gode standard-funktioner man ofte får brug for som spiludvikler. Det gælder også for programmørerne. I de følgende afsnit vil vi redegøre for de mest udbredte ting i Unity, man som programmør kommer ud for. MonoBehaviour Når I opretter et nyt C# script i Unity, ser det sådan her ud, inkl. den grønne kommentar-tekst: 58

61 using UnityEngine; using System.Collections; public class NewScript : MonoBehaviour { // Use this for initialization void Start () { // Update is called once per frame void Update () { Lad os lige hurtigt gennemgå hvad alt dette betyder om et øjeblik. Dette kapitel handler om, hvad MonoBehaviour almindeligvis bruges til, og det afsluttes med en række eksempler. Hvis du har brug for at kigge i eksemplerne i løbet af forklaringen, så gør endelig det, de findes under overskriften Eksempler i dette kapitel. De to linjer med using i starten beskriver hvilke libraries programmet bruger. Libraries er en slags ordbøger, eller samlinger med nye funktioner. Som regel får I ikke brug for at tilføje mere end disse to linjer. public class NewScript : MonoBehaviour er en meget vigtig linje. Den fortæller computeren at vi opretter en class, som er den mest basale måde at indeholde data og metoder. Højst sandsynligt skal alt kode I skriver være i de efterfølgende tuborg-klammer. public betyder at ting i denne class er tilgængelig for andre scripts. class betyder at det er en class (woop woop!). NewScript er vores selvvalgte navn på class en. : MonoBehaviour betyder at vores nye class nedarver fra MonoBehaviour. MonoBehaviour er en class Unity bruger til alle scripts, der skal fungere på GameObjects, og den indeholder en masse smarte standardværktøjer og funktioner. At vi nedarver betyder at vi tager alle MonoBehaviour s standarder og importerer dem - vi kan så udvide på dem eller bruge dem på vores egen måde i NewScript. void Start () { og void Update () { er to nye metoder, vi opretter i vores NewScript. Fordi vores script nedarver fra MonoBehaviour vil metoder med bestemte navne (som fx Start) have en standard opførsel. Nedenunder finder du en liste over de mest udbredte og brugte af den slags metoder, som findes i MonoBehaviour. Nogle MonoBehaviour Metoder void Start () { Denne metode vil blive aktiveret én gang, når script et skal til at starte for første gang. Hvis du skal finde nogle værdier i spillet og gemme dem, så du kan bruge dem senere, er det en god idé at gøre det i Start metoden. 59

62 void Awake () { Denne metode vil blive aktiveret én gang, når GameObject et er igang med at blive skabt. Det sker altid før Start (). Medmindre det er nødvendigt at gøre noget før Start () er det ikke anbefalet at bruge Awake (), men det kan nogle gange være vigtigt. void Update () { Denne metode vil blive aktiveret én gang hver frame i spillet. Det er som regel her det meste af din kode vil stå. void LateUpdate () { Gør nøjagtigt det samme som Update (), men den gør det altid lige efter alle normale Update () er færdige. Det er fx en god idé at skrive ting som kamera-kontrol ind i LateUpdate (), så kameraet altid har de mest opdaterede tal at arbejde med. void FixedUpdate () { Endnu en slags Update, men denne er synkroniseret med fysik-udregninger i Unity. Hvis man skal lege med fysik-regler (fx AddForce eller lignende) er det nødvendigt at gøre det i FixedUpdate () i stedet for en almindelig Update (). Fysik-udregninger sker nemlig ikke med samme hastighed som udregning af nye frames. void OnMouseDown () { Aktiveres én gang hver gang musen klikker på objektet. Dette er en meget fast and loose måde at finde ud af om man klikker på noget, men til vores formål er den sandsynligvis god nok. void OnCollisionEnter (Collision collisioninfo) { Aktiveres én gang lige når en Collider rører, eller er inde i, dette GameObject s egen Collider. Hvis de bevæger sig væk fra hinanden og støder sammen igen, vil metoden aktiveres en gang til. Argumentet i parentesen gør at I har data tilgængeligt om kollisionen ved at tjekke variablen collisioninfo, som er en variabel af typen Collision. void OnTriggerEnter (Collider other) { Beslægtet med OnCollisionEnter, denne metode aktiveres når en Collider rører ved/er inde i dette GameObject s Trigger. En Trigger er en speciel form af Collider, som ikke har effekt på andre Colliders. Argumentet i parentesen gør at I kan finde den Collider, der er stødt ind i jeres Trigger, ved at kigge på variablen other, som er af typen Collider. Andre Der er mange flere navne til metoder, som bliver aktiveret under bestemte forhold. Unity s dokumentation af MonoBehaviour har en liste af dem alle sammen og mere uddybende tekster, der beskriver hvad de gør. Brug af MonoBehaviour Scripts For at MonoBehaviour skal gøre noget af alt det smarte, det er bygget til, skal det tilføjes til et GameObject i spilverdenen. Jeg har valgt at demonstrere det med en simpel kube. 60

63 Til højre under fanen inspector er der en række komponenter: Transform, Cube (Mesh Filter), Box Collider, Mesh Renderer og vores eget NewScript. Læg mærke til at Unity automatisk tilføjer mellemrum til navne på komponenter - disse mellemrum er ikke del af koden. Jeg har tilføjet vores NewScript ved at bruge simpel drag-and-drop, så det er ret nemt. For scripts, der skal køre i spillet konstant kan man tilføje et tomt GameObject (uden nogen model og collider) og tilføje disse globale scripts til det GameObject. For at skabe et GameObject bruger man GameObject menuen i Unity... Via denne menu kan man skabe en række standard-objekter, som er gode at have ved hånden. I denne del af bogen kommer vi nok kun til at bruge Create Empty og Create Other->Cube. 61

64 Eksempler Et eksempel på brug af Start () metoden er at finde et vigtigt GameObject til senere eller regne vigtige værdier ud. Man kan også bruge den til at gemme den præcise tid, script et startede så man kan finde ud af hvor lang tid det har eksisteret i spillet. GameObject savethisobjectforlater; float initialvalue; float starttime; void Start () { savethisobjectforlater = GameObject.FindWithTag("MyTag"); initialvalue = savethisobjectforlater.somevalue * 3f; starttime = Time.time; Update () metoden kan bruges til et væld af forskellige ting. Følgende eksempel viser et script, der bevæger det GameObject, det hører til, fremad med 0,5 meter i sekundet - men kun når A bliver holdt nede. Bemærk: Vi vil forklare nogle af de ting, der sker her lige efter eksemplet. float speedpersecond = 0.5f; void Update () { if (Input.GetKey(KeyCode.A)) { transform.position = transform.position + Vector3.forward * speedpersecond * Time.deltaTime; Input.GetKey( KeyCode.A ) er en metode, der giver et bool svar (så vi kan bruge den til en if-sætning). GetKey finder ud af om en given key, altså en knap på mus eller tastatur, holdes nede den pågældende frame. KeyCode.A bruger vi, fordi alle knapper har unikke numre, som vi ikke kan huske i hovedet. KeyCode.A finder nummeret på A knappen. transform.position er en Vector3. Fordi script et er MonoBehaviour har det automatisk en reference til GameObject ets Transform komponent, som bestemmer placering, rotation og størrelse. Denne standardreference har navnet transform (med lille begyndelsesbogstav, fordi det er en variabel). Time.deltaTime er tiden i sekunder, der går på den nuværende frame. Uden denne del ville vi bevæge os med ½ meter pr. frame (hvilket ikke bare er ustyrligt hurtigt, men også kan variere hastighed hvis framesper-second ændrer sig!) OnMouseDown () er nyttigt hvis man vil lave en interface, der er afhængig af at man klikker på bestemte objekter i scenen, fx et strategi- eller adventure spil. Nedenstående eksempel skriver Mouse clicked on this 62

65 object: (objektets navn) på skærmen, når man klikker på det. Læg mærke til at gameobject.name er med lille begyndelsesbogstav, fordi vi bruger MonoBehaviour s standard-reference til det GameObject, vi har tilføjet script et til. void OnMouseDown () { print("mouse clicked this object: " + gameobject.name); Variabler og Unitys Interface Lad os beskæftige os en smule mere med, hvad variabler er for nogle ting. Variabler eksisterer ikke for evigt. Derfor er der en række måder hvorpå C# håndterer variabler, så der er helt klart styr på hvornår de eksisterer og hvornår, de muligvis ikke gør. Her er et eksempel på kode, der giver fejl: void MethodOne () { float myvariable = 1.0f; void MethodTwo () { print(myvariable); Variabler eksisterer ikke udenfor den tuborg-klamme, de er inden i. Fx giver følgende kode også fejl: void MyMethod () { for (int i = 0; i < 1; i++) { float myvariable; print(myvariable); Det er en god ting! Tænk hvis du havde et meget langt script, fx 1000 linjer, og skulle finde på unikke navne til alle variabler! Derfor kan det være smart at manage sine variabler, så de kun er dér, hvor der er brug for dem. Det giver ikke optimal performance, men på det niveau vi er på gør det ikke den store forskel. Med det sagt er det kraftigt anbefalet at alle centrale variabler, som fx hastighed eller maxhp er skrevet så alle i script et har adgang til dem. Det er der to grunde til - den ene er at man for at ændre hastigheden på sin spilfigur kun skal ændre ét tal i stedet for at finde det 30 steder i koden. Den anden er at Unity tillader ikke-programmører at ændre i den slags variabler nemt og uden at kende det 63

66 mindste til koden. Følgende eksempel demonstrerer hvordan man nemt kan definere, hvor mange hoveder en drage skal have. public class DragonScript : MonoBehaviour { public int numberofheads = 1; void Start () { //Code to spawn the correct number of heads... Lad os kigge på det i Unity s interface: Allernederst kan vi se vores public int numberofheads, der automatisk har fået et lidt pænere navn i Unity. Navnet i koden er stadig den samme. Enhver bruger kan ændre tallet ved at klikke på det og skrive et nyt - det bliver gemt som en del af scenen i Unity. Læg mærke til at selvom koden definerer værdien som numberofheads = 1 overskriver Unity den information i scenen - men hvis du laver et nyt GameObject og tilføjer DragonScript til det, vil det nye objekt starte på 1 (det gamle vil beholde sin værdi). Hvis man vil undgå at en variabel viser sig i Unity for andre kan man undlade public når man opretter variablen, eller man kan skrive private i stedet, for at være helt tydelig. Print og Debugging Det er uundgåeligt at lave fejl i sin kode, så den bedste måde at komme fejl til livs er ikke ved at være bange for dem og skrive kode langsomt, men at fixe fejlene hurtigt og effektivt. Til at hjælpe med det er det vigtigt at kende til Unity s debugging værktøjer (debugging er et fancy ord for at fixe fejl i programmering. Det kommer af at gamle radiorør-baserede computere kunne få brændt deres komponenter af, når et insekt fløj ind i dem. At skifte radiorørene efter den slags fejl blev kaldt de-bugging. Programmør humor!). 64

67 I har allerede stiftet bekendtskab med et af værktøjerne: Metoden print(). Lad os kigge på, hvordan den slags ser ud i praksis. Følgende Start() metode er i scriptet DragonScript, som er blevet sat på et GameObject ved navn MyLittleDragon. void Start () { print("the Dragon has awoken! Its name is " + gameobject.name); Print samler et stykke tekst (variabeltypen string) og viser det på skærmen. En string + en anden string sætter de to strings sammen til én lang string. Fordi tekst i anførselstegn og gameobject.name er strings, bliver det derfor automatisk sat sammen. Koden ovenfor giver følgende resultat i Unity vinduet Console (hvis Console vinduet ikke er synligt, så kan du få det frem via menuen Window Console). Så længe inputtet til print () starter med en string, kan man lægge andre ting til som fx tal, og de vil så blive konverteret automatisk til string. Kig evt. i eksemplet nedenfor: print("" + numberofheads + " is the total number of heads. The game time is: " + Time.time); Læg mærke til at inputtet starter med to anførselstegn ( ). Det er en hurtig måde at skrive en tom string på, så computeren ved at den ikke skal lægge tal sammen, men derimod sætte en string sammen. I eksemplet ovenfor er der brugt både int og float talværdier. Mange af Unity s komponenter har også en.tostring() metode, som man fx kan bruge for at tjekke om man har gemt det rigtige GameObject. Lad os kigge på et eksempel fra afsnittet Almindelige Fejl. 65

68 int a = 0; int max = 9; bool something = true; while (a < max) { //A lot of code here... if (something) { a = a-1; a = a+1; Det er tydeligt for os nu, hvorfor script et ikke kommer til at fungere (vi trækker både fra og lægger til a), men det kan være viklet ind i en masse andet kode. Her er en af mine standard-metoder til at lede efter fejl i loops: int a = 0; int max = 9; bool something = true; int iteration = 0; while (a < max) { iteration++; if (iteration > 1000) { break; //A lot of code here... if (something) { a = a-1; print ("a = " + a + ", iteration " + iteration); a = a+1; print ("a = " + a + ", iteration " + iteration); Jeg introducerer en ny variabel, kaldet iteration, for at holde styr på hvornår løkken skifter til næste gentagelse. Derfor har jeg også linjen iteration++; øverst i løkken. ++ er en hurtig måde at lægge 1 til en variabel. Den nye if-sætning aktiveres ved gentagelse nr af løkken og dens break; kommando sørger for at afslutte løkken (så vi ikke sidder fast i den for evigt). 66

69 Hver gang jeg giver en værdi til a har jeg også en print () kommando, der viser værdien af a i dét øjeblik. Her bruger jeg også iteration for at kunne identificere de linjer tekst, der bliver skrevet ud til sidst. Koden giver os 1998 beskeder i Console vinduet (999 beskeder x 2). Det ser således ud: Her kan vi så præcist følge variablen a s opførsel i løbet af hver iteration. Vi kan se at den i hver iteration starter med at have værdien -1 ved første print (), og værdien 0 ved andet print (). Det er helt klart at fejlen ligger i at vi både trækker fra og lægger til a med samme hastighed. Vi kan nu ændre koden så vi kan undgå denne fejl. Nogle Ekstra Kommandoer Udover print (), som i virkeligheden bare er en genvej til Debug.Log (), har i 2 andre smarte kommandoer I kan bruge til at lede efter fejl. Debug.LogWarning () vises med et gult advarselsskilt, så den er nemmere at se i Console. Debug.LogError () vises med et rødt advarselsskilt og er en god måde at sikre sit program på - hvis man ved at der er noget, der absolut ikke må ske, som fx at spilleren ikke har et våben eller at der mangler et vigtigt usynligt komponent, kan det være en god idé at indsætte en Debug.LogError () i forvejen, så man øjeblikkeligt bliver advaret hvis dette sker. Lad være med at overforbruge de to mere synlige kommandoer - hvis alt har et gult advarselsskilt er vi lige vidt mht. synligheden af beskeder, og så har vi snart brug for et spam filter. Input og Det Første Lille Spil Uden input er det pænt svært at have et spil. Derfor er det helt sikkert at I får brug for at kigge lidt nærmere på det... Game Bogen to the rescue! Lad os antage at vi vil lave mini-spillet Smack my Dragon. Hver gang vi smack er dragen skal den rotere en omgang om sig selv, fordi vi giver den en lussing. Først har jeg tilføjet et hovede til dragen, så det er tydeligt 67

70 hvilken vej den peger. Så tilføjede jeg også nogle fødder, i et helhjertet forsøg på programmer art, noget I med sikkerhed vil stifte bekendtskab med snart... Vi skal nu have lavet et script, der roterer dragen. Først skal vi finde ud af hvilken knap, der skal være vores Smack knap. For at have fleksibilitet når spillet skal udgives på PC, PS3, XBOX, WII og iphone (efter det er blevet Game of the Year) er det bedst hvis vi bruger Unity s indbyggede system til at administrere kontrolknapper. Det findes under menuen Edit Project Settings Input. Udvid fanen Axes. Unity har en række standard-kontroller, som jeg har valgt at ignorere - jeg har også reduceret antallet af kontrol-akser til 1, nemlig vores Smack knap. 68

71 Vi kan nu bruge knappen i vores script. Hele script et for dragen ser sådan her ud: using UnityEngine; using System.Collections; public class DragonScript : MonoBehaviour { float smackrotationspeed = 360f; float smacktime = 0f; bool rotating = false; void Update () { if (Input.GetButtonDown("Smack") &&!rotating) { rotating = true; smacktime = Time.time; if (rotating) { if (Time.time - smacktime < 1f) { float degrees = (Time.time - smacktime) * smackrotationspeed; transform.rotation = Quaternion.Euler(new Vector3(0, degrees, 0)); else { transform.rotation = Quaternion.Euler(new Vector3(0, 0, 0)); rotating = false; Ro på! Det er ikke så slemt som det ser ud. Vi har allerede gennemgået hvad de øverste par linjer med using betyder, og hvad en class med MonoBehaviour er for noget. Vi har 3 variabler at lege med. smackrotationspeed, smacktime, og rotating. Det er meningen at smackrotationspeed aldrig ændres, men det er rart at have den slags centrale tal stående i toppen, ét enkelt sted. smacktime skal bruges til at udregne hvor langt vi er nået i vores rotation. rotating skal bruges til at finde ud af om vi allerede er i gang med at rotere dragen. Vores Update () funktion har to hoveddele, begge af dem er if-sætninger. Den første, lille if-sætning er hvor vi fanger vores input. if (Input.GetButtonDown( Smack ) &&!rotating) betyder, på menneskesprog: Hvis knappen med navnet Smack er blevet aktiveret denne frame, og vi ikke er i gang med at rotere allerede.... Grunden til at vi tjekker om vi allerede roterer, er for at forhindre at vi starter en rotation oven i den allerede aktive. Hvis vi smack er og ikke allerede roterer, sætter vi rotating til true og vi noterer tiden i smacktime. Næste if-sætning, if (rotating) aktiveres hvis rotating er true. Det kan den enten lige være blevet i koden ovenfor, eller den kan være true fra en tidligere frame. Denne anden del har selv to dele. Den første del aktiveres når vi bare roterer almindeligt. Den anden del sørger for at stoppe rotationen og nulstille, så vi kan smack e dragen en gang til. Måden vi finder ud af det på er at sammenligne Time.time med smacktime. Jeg antager her at vi vil have en rotation, der varer ét sekund, derfor tjekker vi om Time.time - smacktime < 1f, altså om Time.time - smacktime er mindre end 1. Hvis regnestykket er mindre end 1, er 69

72 der gået under 1 sekund siden vi smack ede dragen. Hvis der er gået 1 sekund eller mere aktiveres else delen, som sørger for at sætte rotating tilbage til false. Nu kommer vi til det, måske, sværeste i koden... transform.rotation = Quaternion.Euler(new Vector3(0, degrees, 0));... Rotation i Unity (og snart sagt alle game engines) foregår ved brug af en mærkelig 4- dimensionel vektor, der hedder en quaternion. Matematikken bag sådan nogle sjovere er noget udover vores niveau, heldigvis giver Unity os en masse metoder, der tillader almindelige dødelige mennesker at arbejde med det her. Quaternion.Euler(...) er en metode, der giver en quaternion som resultat. Det er lidt det samme som at definere en variabel og give den en værdi - her har vi bare ikke brug for at gemme værdien til senere, så vi springer mellemledet over, og sender resultatet direkte til transform.rotation. Quaternion.Euler(...) tager en Vector3 som input, der beskriver hvor mange grader vi skal rotere om x, y og z-aksen, i den rækkefølge. Næsten på samme måde har jeg valgt at, i stedet for at navngive en variabel af typen Vector3 som jeg kun skal bruge ét sted, skrive en ny Vector3 direkte ind i udtrykket. Siden vi roterer sidelæns roterer vi altså om y-aksen (aksen, der går direkte op). Derfor har den nye vektor delene 0 grader for x-aksen, degrees grader for y-aksen og 0 grader for z-aksen. Lidt Flere Input Metoder Udover Input.GetButtonDown(...), som vi brugte til Smack my Dragon ovenfor er der nogle vigtige metoder, I også lige skal kende til: Input.GetButton(...) er true hver eneste frame, den pågældende knap er aktiv. Input.GetButtonDown(...) er true kun den ene frame, hvor knappen blev trykket ned. Input.GetButtonUp(...) er true kun den ene frame, hvor knappen blev sluppet. Der er en række tilsvarende metoder, der bruger ordet key istedet, fx Input.GetKey(...). Disse metoder kan ikke bruges med Unity s egen håndtering af knapper. Her skal man i stedet skrive i koden hvilken knap, man ønsker ved at bruge KeyCode.A for A tasten, osv. Til sidst er der metoden Input.GetAxis(...), som gør brug af Unity s egen input håndtering. En akse i denne forstand kan være styring af figurens bevægelser med piletaster eller wasd. De er lidt mere fancy end on/off knapper, så de giver en mere smooth kontrol, hvis man bruger det rigtigt. Input.GetAxis(...) returnerer en float værdi mellem -1 og +1, hvor 0 er den inaktive værdi. Et eksempel er en akse, der beskriver bevægelse frem og tilbage for en spilfigur: 70

73 Gravity fungerer som en nulstiller efter brugeren ikke længere trykker på en af de aktive knapper (højere gravity nulstiller hurtigere) og Sensitivity bestemmer hvor hurtigt aksen når sin max værdi efter brugeren trykker på en knap. Dead er mest beregnet til joysticks eller thumbpads og er en nedre grænse - alt under Dead-værdien vil være 0. Til keyboards bør Dead være meget lille. Fysik og Bevægelse Som det blev nævnt tidligere kan man i MonoBehaviour metoden FixedUpdate() lege med fysikudregningerne i Unity. I mit Smack my Dragon spil brugte jeg den helt almindelige Update() metode til at rotere dragen, men det er ikke altid en god idé. Især ikke hvis det, der bevæger sig har en RigidBody komponent og skal interagere med andre fysik-elementer i scenen! Folk med engelsk-kendskab har nok allerede gættet at modsat Update(), som kan foregår hurtigt eller langsomt, alt afhængig af spillets frames-per-second, så har FixedUpdate() en helt fast timing. Som standard i Unity opdateres fysik-udregninger hvert 0,02 sekund - altså 50 gange i sekundet. FixedUpdate() aktiveres hver gang spillets fysik opdateres. Det er typisk for spil, som skal spilles på moderne desktops, at forøge denne mængde, så der er endnu flere FixedUpdate() i sekundet (det kan ændres i Edit Project Settings Time). Lad os antage at vi gerne vil lave mini-spillet Punch my Dragon. Først skal dragen have et gulv at stå på. Til det formål bruger vi en kube, der er strukket ud til 20x20 meter i vandrette retninger. Det er en god idé ikke at gøre gulvet til et helt fladt plan, fordi spilobjekter med høj fart kan skippe igennem det meget nemmere. 71

74 Herefter tilføjes der et RigidBody komponent både til dragen og til gulvet. Det gør man via menuen Components Physics RigidBody. Gulvets RigidBody skal have flueben ved Is Kinematic. Dette betyder at gulvet ikke vil blive påvirket af almindelige kræfter i spilverdenen - ligesom gulvet under dig ikke flytter sig når du hopper på det. Man kan stadigvæk flytte på Is Kinematic objekter via kode. Følgende kode skrives til dragen: float punchforce = 500.0f; Vector3 punchdirection = new Vector3(0, 0, -1); void FixedUpdate () { if (Input.GetButtonDown("Smack")) { rigidbody.addforce(punchdirection * punchforce); Jeg antager at vi allerede har sat vores Smack knap op, som i kapitlet Input og Det Første Lille Spil. punchdirection er sat op så den passer med den vinkel, mit kamera kigger på scenen. Det er som regel en god idé at have den slags vektorer justeret så de har en længde på præcis 1, fordi det giver bedre kontrol med kræfterne, der tilføjes. Ved tryk på knappen vil dragen blive sendt tværs over gulvet af vores slag. Dragen vil gerne bevæge sige for at undgå vores slag, så lad os sætte den til at løbe rundt i en cirkel. Det gøres også i FixedUpdate(), med to linjer. Én linje for at flytte sig fremad, og én linje for at dreje.... float forwardspeed = 10.0f; float turningspeed = 360.0f; void FixedUpdate () {... transform.translate(new Vector3(1,0,0) * forwardspeed * Time.fixedDeltaTime, Space.Self); transform.rotate(0, turningspeed * Time.fixedDeltaTime, 0); 72

75 Vores new Vector3(...) i translate-linjen matcher retningen på dragens hoved, altså den vej, der er fremad for den. Time.fixedDeltaTime er tiden for en enkelt opdatering i fysik-udregningerne. Den fungerer nøjagtigt ligesom Time.deltaTime, som I måske kan huske fra før, men den er bare tilpasset FixedUpdate() i stedet for den almindelige Update(). Space.Self kræver lidt forklaring. I vores situation gør dette argument at dragen bevæger sig fremad i forhold til dens egen opfattelse af frem. Når den roterer, bevæger den sig altså en lidt anden vej (fordi dens opfattelse af frem er ændret). Uden Space.Self ville øverste linje bare skubbe dragen i én retning, mens den lavede piruetter om sig selv pga. rotationen i anden linje. Heldigvis kan vi stadig nemt ramme dragen ved at trykke på vores Smack knap. Ærgerligt for dragen at ingen fortalte den det. Kollisioner Kollisioner i Unity-sammenhæng betyder desværre ikke at ting eksploderer eller smadre hinanden - de er af en lidt mere mondæn natur. En kollision forekommer når to Collider objekter rører ved hinanden. Lad os antage at vi vil lave mini-spillet Wreck my Dragon, hvor vi vil vide hvornår en wrecking ball har ramt dragen. Denne wrecking ball er sat ind i scenen lige over dragen, og har også fået tilføjet en RigidBody, med en kraftig masse - 3 i mit tilfælde. Unity håndterer automatisk at skubbe til dragen, når den bliver ramt. Via kode kan vi også få at vide hvad der rammer dragen ved at bruge OnCollisionEnter(Collision collisioninfo) fra MonoBehaviour. Følgende kode er sat op på dragen: void OnCollisionEnter (Collision collisioninfo) { print(collisioninfo.gameobject.name + " has hit the dragon!"); float force = collisioninfo.relativevelocity.magnitude * collisioninfo.rigidbody.mass; print("the force was: " + force); Collision variabeltypen gemmer på en masse saftig information om sammenstødet, men vi starter med at finde ud af hvilket GameObject, der er ansvarlig for kollisionen og skrive dets navn ud på skærmen. Vi udregner også kraften af sammenstødet, så vi kan se hvor nas det gør på dragen. collisioninfo.relativevelocity er en Vector3, som beskriver retningen af sammenstødets fart, derfor tager vi.magnitude, for at få længden af denne fart-vektor. Vi har også adgang til den RigidBody, der er ansvarlig for kollisionen via collisioninfo.rigidbody. Derfor kan vi finde wrecking ball ens masse og dermed finde den force, dragen bliver ramt af. 73

76 Lad os være rar ved dragen. Vi vil give den en fair advarsel når vores wrecking ball falder, ved at bruge en Trigger. Først indsætter vi en kube lige under vores wrecking ball, så den falder igennem den før den når dragen. Kubens Collider komponent skal have et flueben i Is Trigger. På kuben kan vi så tilføje følgende script, der skriver en advarsel til vores Console. void OnTriggerEnter (Collider other) { print("look OUT! " + other.gameobject.name + " is falling!"); Både triggers og colliders har 3 metoder i MonoBehaviour, som svarer lidt til det vi lærte om buttons tidligere: 1. OnTriggerEnter(...) bliver aktiv den fysik-frame hvor en Collider rører vores trigger første gang. Hvis de kommer væk fra hinanden og støder sammen igen, aktiveres denne metode igen. 2. OnTriggerStay(...) aktiveres hver eneste fysik-frame en Collider rører vores trigger. 3. OnTriggerExit(...) aktiveres på den fysik-frame, hvor en Collider som har rørt trigger en kommer for langt væk. 4. OnColliderEnter(...) som med triggers, fungerer kun med en Collider, der ikke er sat til Is Trigger. 5. OnColliderStay(...) som med triggers, fungerer kun med en Collider, der ikke er sat til Is Trigger. 6. OnColliderExit(...) som med triggers, fungerer kun med en Collider, der ikke er sat til Is Trigger. 74

77 Instantiate og Destroy Det er ikke alle objekter, der nødvendigvis er til stede i scenen når den starter. Det er heller ikke sikkert alle objekter bliver i scenen, selvom de er der i starten. Til det bruges metoderne Instantiate(...) og Destroy(...). Vores hidtidige success med... my Dragon serien har fået EA Games til at efterspørge en sportstitel i serien. Vi vil derfor lave Tennis my Dragon. Dragen skal træne mod en maskine, der skyder bolde afsted mod den. Uheldigvis kan dragen ikke holde en ketcher. Vi får brug for at kunne skabe og ødelægge tennisbolde løbende, så lad os først lave en såkaldt Prefab - et GameObject vi kan skabe kopier af, udelukkende via kode. Jeg har lavet en kugle med et RigidBody komponent, dens størrelse er 0,3 i alle retninger, og dens masse er noget mindre end dragens. Bolden gøres til en Prefab ved at hive den fra scenens Hierarchy vindue, over i Project vinduet. Jeg opretter også en kube og kalder den TennisMachine. Herfra kan vi skabe vore bolde og sende dem afsted. Husk at denne kube ikke skal have en RigidBody. Jeg deaktiverer maskinens Collider, så den ikke forstyrrer tennisboldene. Maskinen får et script, der ser således ud: public GameObject tennisballprefab; float ballforce = 6.0f; float balltimestamp = 0.0f; float timebetweenballs = 1.0f; void Update () { if (Time.time - balltimestamp > timebetweenballs) { balltimestamp = Time.time; LaunchBall(); void LaunchBall () { if (tennisballprefab == null) { Debug.LogError("No prefab for tennis ball!"); else { GameObject ball = (GameObject) Instantiate(tennisBallPrefab, this.transform.position, Quaternion.identity); ball.rigidbody.addforce(this.transform.forward * ballforce / Time.fixedDeltaTime); Update() funktionen sørger for at aktivere LaunchBall() med det rigtige interval. Første if-sætning under LaunchBall() møder vi noget nyt: if (tennisballprefab == null)... Denne if-sætning tjekker om tennisballprefab har en værdi. null er et nøgleord, som betyder at en variabel ikke er blevet tildelt en værdi - overhovedet. Hvis tennisballprefab ikke har en værdi, kan vi ikke bruge Instantiate(...), så i stedet advarer vi spiludvikleren med Debug.LogError(...). tennisballprefab får en værdi ved at vi i Unity s interface kan drag-and-drop e vores tennis ball prefab ind i script et. Det kan vi gøre fordi tennisballprefab er public, og derfor viser sig i Unity s Inspector vindue, ligesom vi så at man kunne ændre talværdier direkte i Unity, uden at kigge i koden tidligere. 75

78 Så vidt så godt - nu er vi klar til at diskutere Instantiate(...). Vi giver følgende input: En variabel som indeholder den prefab, der skal bruges; en position; en rotation. tennisballprefab er naturligvis vores prefab variabel. Positionen er this.transform.position - ordet this refererer til script et selv, så det er altså script ets egen transform - ikke boldens - der er tale om her (this er ikke nødvendig her, men jeg har inkluderet det for at tydeliggøre det ikke er boldens position). Quaternion.identity er en rotation, som roterer med 0 grader. Det vil sige ingen rotation, men Instantiate(...) kræver at få det eksplicit at vide. Instantiate(...) giver, som resultat, en reference til det objekt, der netop er blevet skabt. Man kunne tro at man kunne bruge GameObject ball = Instantiate(...) men så nemt er det ikke. Instantiate(...) giver resultatet med variabeltypen Object. Vi er nødt til at fortælle computeren at den skal behandle det som et GameObject - det gøres ved en kommando, der hedder type casting: GameObject ball = (GameObject) Instantiate(...) fortæller computeren at den skal type caste resultatet til GameObject variabeltypen, før den prøver at sende det videre. I sidste linje tilføjer vi fart til bolden. Denne del burde vi kunne genkende fra afsnittet Fysik og Bevægelse. Normalt vil man ikke tilføje forces udenfor en FixedUpdate(), men når vi kun skal gøre det én gang kan vi godt tillade os det. Der opstår nu tennisbolde ud af ingenting, som skydes i retning af dragen (hvis altså TennisMachine har den rigtige position/rotation). Men de hober sig op. Vi vil derfor give hver tennisbold en begrænset levetid før de selvdestruerer! Heldigvis for dragen selvdestruerer de ganske harmløst, uden brug af eksplosiver. Følgende script tilføjes til vores tennisbold-prefab. float spawntime = 0.0f; float lifetime = 3.0f; void Start () { spawntime = Time.time; void Update () { if (Time.time - spawntime > lifetime) { Destroy(this.gameObject); Hvis der er gået mere tid end lifetime, selvdestruerer scriptet den bold, det sidder på. Fordi script et er tilføjet til prefab en er der en kopi af dette script på alle bolde nu. Flere Levels I de fleste spil bliver der på et tidspunkt behov for at loade en ny bane, eller ny scene. Tennis my Dragon solgte desværre dårligt fordi det var blevet for mainstream for... my Dragon fans. Franchisen er blevet solgt til et lille firma i en skurvogn, som vil lave opsamlingen Remember my Dragon: The Complete Anthology. Til det har vi brug for at kunne skifte imellem banerne fra de foregående spil. 76

79 For at kunne bruge Unity s metode til dette, skal scenerne være tilføjede til Build Settings, som er tilgængelig under menuen File i Unity. Jeg har valgt at sætte knappen L til at være min ChangeLevel knap i Unity s Input settings. Vi har 4 baner at skifte imellem: Smack-, Punch-, Wreck- og Tennis my Dragon. Ved hvert tryk på ChangeLevel vil vi skifte til den næste bane - og tilbage til den første, når vi er færdige med den sidste. Lad os starte med at sætte et script op i 1. bane (Smack my Dragon), der loader bane 2. Scriptet sidder på sit eget tomme GameObject, der hedder LevelLoadObject. void Update () { if (Input.GetButtonDown("ChangeLevel")) { Application.LoadLevel(Application.loadedLevel + 1); Application.LoadLevel(...) kan enten modtage navnet på den ønskede bane, eller dens nummer. Siden vi ønsker at loade banerne efter hinanden i nummerisk rækkefølge er det nemmest at holde sig til tallene. Application.loadedLevel er nummeret på den bane, der er aktiv lige nu. Vi har dog to problemer: 1; vores LevelLoadObject forsvinder sammen med resten af de gamle objekter, når vi loader en ny bane. 2; hvis vi når til sidste bane får vi en fejl, fordi vi forsøger at loade et nummer bane, der er over max. Løsningen på første problem er Unity s metode DontDestroyOnLoad(...). Den tager et GameObject som input. Dette GameObject vil ikke blive ændret, når en ny bane bliver loadet. Vi kan derfor tilføje disse linjer kode til vores LevelLoadObject: void Start () { DontDestroyOnLoad(this.gameObject); Løsningen på andet problem er at nulstille hvilken bane, der skal loades, hvis vi overskrider vores max. Vores nye Update() metode ser således ud: void Update () { if (Input.GetButtonDown("ChangeLevel")) { int leveltoload = Application.loadedLevel + 1; if (leveltoload >= Application.levelCount) { leveltoload = 0; 77

80 Application.LoadLevel(levelToLoad); Application.levelCount giver os antallet af baner i alt, men ligesom med arrays fra tidligere i bogen starter banernes numre med 0, 1, 2, 3, osv. Derfor er det vigtigt at vi skriver if (leveltoload >= Application.levelCount) med større-end-eller-lig-med sammenligning ( >= ). Grafisk Brugerflade Det er relativt hurtigt at få noget helt basal grafisk brugerflade op at stå i Unity. Unity bruger termen GUI (står for Graphical User Interface). Efter en blandet modtagelse af Remember my Dragon: The Complete Anthology besluttede skurvognsfirmaet sig for at være innovative sammen med alle de andre innovative, og sigte efter sociale medier med deres næste udgivelse. Derfor vil udviklerne gerne give dragen noget personlighed, så unge tweens vil blive mere attached til dragen og betale micro-transactions for at gøre den glad. Vi vil derfor, i Smack my Dragon, have en indikator i øverste højre hjørne af skærmen, der viser dragens humør som en smiley. Jeg antager at dragen som udgangspunkt er glad, men bliver ked af det, når den bliver smack ed. Alt der har med GUI at gøre i Unity skal som udgangspunkt stå i metoden OnGUI(), som aktiveres automatisk via MonoBehaviour ligesom de gængse Update() metoder. Vi gør sådan her: void OnGUI () { string texttodisplay; if (rotating) { texttodisplay = ":'("; else { texttodisplay = ":)"; Rect textbox = new Rect(Screen.width - 50, 0, 50, 25); GUI.Label(textBox, texttodisplay); Vores rotating variabel fra før afgør hvordan dragen har det. Hvis vi er igang med at rotere er dragen lige blevet smack ed, og er derfor ked af det. Den nye Rect variabeltype beskriver et rektangel med 4 informationer: Venstre kant, øverste kant, bredde og højde. Skærm-koordinater starter i øverste venstre hjørne med 0, 0. Siden vi skal vise teksten i øverste højre hjørne sættes venstre kant til at være i koordinatet Screen.width - 50, som er spillets skærmbredde minus 50. De minus 50 er fordi tekstboksens bredde er

81 Til sidste skal GUI.Label(...) vide, hvad den skal gøre, så den får vores tekstboks og tekst som input. Som standard bruger Unity et GUISkin, hvor al tekst er i skrifttypen Ariel i en bestemt størrelse og med hvid farve. Hvis man vil ændre noget her, bliver man nødt til at oprette en ny GUISkin opsætning. Dette gøres under menuen Assets Create GUI Skin. Det skal også implementeres i koden. Det er nemmest at bruge samme fremgangsmåde som med prefabs tidligere: En public variabel, som man kan drag-and-drop e det rigtige GUISkin i. Herefter sætter man GUI.skin som det første i den relevante OnGUI() metode. public GUISkin dragonskin;... void OnGUI () { GUI.skin = dragonskin;... Denne slags tekst-interface fungerer fint til prototyper, men hvis noget i brugerfladen skal være mere finpudset er nogle af de mere avancerede GUI metoder ikke til at slippe udenom - fx GUI.DrawTexture(...), som tillader jer at vise jeres helt eget 2D billede som et komponent i GUI en. Fremgangsmåden er dog grundlæggende den samme som før. Coroutines Coroutines i Unity er fantastiske og dejlige. Billedet til højre beskriver mit humør, da jeg fandt ud af hvordan Coroutines virkede og hvad det kunne løse for mig. Coroutines er et stykke kode, der kører parallelt (ikke helt, men så godt som) med hovedprogrammet. Det er perfekt til store regnestykker, der ellers ville forpeste jeres performance, eller til at ordne ting, der skal ske 79

82 over tid. Hjørnestenen i Coroutines mange evner er noget, der hedder et yield statement. Et yield statement tillader jer at stoppe eksekveringen af en Coroutine midlertidigt, men vende tilbage til den og fortsætte nøjagtigt hvor I slap. De to vigtigste versioner er muligvis: yield return new WaitForSeconds(float time); - denne kommando stopper Coroutine en i et bestemt antal sekunder. yield return null; - denne kommando stopper Coroutine en og vender tilbage til den efter alle Update() metoder næste frame er færdige. En af de mere syrede ting vi kan gøre med dem, er at at vi nu godt må bruge uendelige løkker uden at programmet fryser (det er selvfølgelig også farligt, for det gør stadig programmet langsommere!). Et eksempel kunne være en drage, der hoppede hvert 10. sekund. For eksemplets skyld vil jeg bruge en uendelig løkke. Hver gang løkken skal til at gentage sig selv, bruger jeg et yield statement til at pause løkken i 10 sekunder. IEnumerator MyCoroutine () { while (true) { DragonJump(); yield return new WaitForSeconds(10.0f); I stedet for at være af typen void eller int, har Coroutines en helt speciel datatype: IEnumerator. Man kan ikke sende resultatet af en Coroutine tilbage på samme måde, som vi er vant til fra almindelige metoder. Vi kan faktisk heller ikke starte dem på samme måde, som almindelige metoder! Vi er nødt til at bruge en af Unity s indbyggede metoder til at gøre dette for os: void Start () { StartCoroutine(MyCoroutine()); Animationer Højst sandsynligt vil jeres spil involvere en eller anden form for animation af dets figurer. Figurer med animationer bliver importeret fra animations-programmet (3Ds Max på GDC) med alle animationer i én lang smøre. Heldigvis understøtter Unity en nem måde at dele denne ene lange animation op i de bidder, animatoren har tiltænkt. Personen, der har lavet animationerne, kan se hvilke frames animationerne starter og slutter på og disse tal skal indtastes i Unity s Inspector, når I klikker på den importerede model og kigger under Animation komponentet. Husk at navngive jeres animationer simpelt og forståeligt! 80

83 Det er noget, der hovedsageligt foregår i Unity uden programmør-indblanding. Men der er dog en vigtig ting, som man skal huske: De såkaldte WrapModes. Der er 4 WrapModes, med hver deres formål. WrapModes har kun noget at sige, når vi bevæger os udenfor animationens tidsrum - hvis animationen er 1 sekund lang og vi forsøger at vise den efter 1,5 sekunder, hvad sker der så? - og ligesådan kan man også nogle gange prøve at vise animation med tiden -1,5 sekunder. Once - Animationen nulstiller til sit udgangspunkt, når den er ved slutningen, og forbliver i sin udgangsposition. ClampForever - Animationen beholder sin position fra sidste definerede frame, uanset hvor langt ud i fremtiden vi kigger. Loop - Animationen spoler tilbage når den er ved slutningen og starter forfra. PingPong - Animationen vender om når den er ved slutningen. Den spiller animationen baglæns, indtil den når tilbage til start, hvorefter den starter animationen den rigtige vej igen. Sådan fortsætter den. Alle animationer kan tilgås på følgende måde. Eksemplet viser en metode, som kan aktiveres, når vi ønsker at dragen skal brøle: void ActivateRoar () { animation.play("roaranimation"); 81

84 Andetsteds i samme script kan man tjekke om animations-systemet er aktivt eller ikke afspiller en animation ved at bruge animation.isplaying, som er en bool variabel. Lad os antage at dragen ikke kan spise, mens den er i gang med noget andet. Hvis andre animationer er aktive, udelukker det altså vores eating animation. Bemærk endnu en gang at udråbstegn foran en bool variabel betyder ikke, dvs. det modsatte. void StartEating () { if (!animation.isplaying) { animation.play("eatinganimation"); else { print("dragon is busy doing something else!"); Der er meget mere at gøre med animationer, som også har indstillinger for BlendModes og AnimationLayer. Det er dog ikke alle der vil få brug for det, så det er udeladt her. Lyd Lyd er en vigtig del af spillet og godt lyddesign kan redde selv ret ringe sekvenser i et spil. Lyd bliver i Unity håndteret som et samspil mellem 3 vigtige komponenter: AudioClip - selve variabeltypen, der kan indeholde en bid lyd parat til at blive afspillet. AudioSource - højtaleren eller afspilleren for lyden i et AudioClip. AudioListener - mikrofonen i spilverdenen. Der sidder automatisk en på scenens hovedkamera, og der er som regel ikke brug for mere. Lad os antage at de oprindelige udviklere efter 15 års tovtrækkeri har fået deres licens tilbage til Smack my Dragon. De ønsker at lave Smack my Dragon: HD med federe effekter og lyd, for at genskabe interessen. Lad os tilføje en god, heftig lyd til når vi smækker dragen én på skallen. Først tilføjer vi en AudioSource komponent til dragen, via menuen Component Audio Audio Source. Dette komponent har en blank plads, hvor vi kan drag-and-drop e vores lyd til. Husk at deaktivere Play on Awake. Leg evt. med de simple lydindstillinger, der findes under 3D Sound Settings. Nu er vores AudioSource på plads. Så skal den bare afspilles fra koden - og det gøres ret nemt. Vi indsætter blot audio.play() samme sted som vi aktiverer rotationen. if (Input.GetButtonDown("Smack") &&!rotating) { rotating = true; smacktime = Time.time; audio.play(); Så er Smack my Dragon: HD klar til butikshylden! 82

85 Lidt Mere om Lyd Unity s AudioSource har en masse andre funktionaliteter vi ikke er kommet ind på, og lidt ligesom animationer er der forskellige modes for lyd, fx audio.loop = true. Man kan også få adgang til mange af AudioSource ens indstillinger direkte i koden, som volumen: audio.volume = minfloat. Derudover er der en række metoder, som vi ikke har beskæftiget os med. Én af dem er særlig vigtig, nemlig audio.playoneshot(audioclip clip) som tillader os at bruge én AudioSource til forskellige lyde, der kan gives som input til metoden. Mange spil optager let forskellige lyde af den samme ting, så lyden varieres en lille smule hele tiden (Halo: Combat Evolved havde eksempelvis 18 unikke lyde for et skud med Assault Rifle en), men der er helt klart også andre situationer hvor det kan betale sig at manage AudioClips i koden. At Skrive God Kode Her er nogle gode retningslinjer, der sørger for overskuelig kode. På vores niveau handler det mest om hvordan, man skriver navne på variabler og metoder. Efterhånden som man bliver mere fortrolig med at kode kan man også begynde at kigge på strukturen i ens metoder og scripts, og hvordan de har indflydelse på hinanden. Navngivning af Variabler og Metoder Det er meget almindeligt (faktisk helt ekstremt almindeligt) at man navngiver variabler med lille begyndelsesbogstav og metoder med stort begyndelsesbogstav. Man skriver derudover deres navne i det, der populært hedder camel case, hvor startbogstavet af alle ord er med stort. På den måde kan man have beskrivende navne uden mellemrum. Her er et par eksempler: detteeretvariabelnavn enandenvariabel DetteErEtMetodeNavn JegErOgsaaEnMetode Der er visse undtagelser, bl.a. noget der hedder attributes, som opfører sig som en variabel men som regel starter med stort som en metode. Det er sandsynligvis ikke noget I selv skal lave, men det er en god idé at huske at I kan komme ud for noget, hvor det ved første øjekast ligner mærkelig navngivning. Men prøv at huske disse simple navne-regler for jer selv... De gør det virkeligt meget nemmere i sidste ende! Sørg også for at vælge gode navne. Det kan være svært at hjælpe en anden med hans kode, hvis alle hans variabler hedder fuck, fuckfuck, test, thisone og så videre (That happens sometimes!). Som hovedregel er det bedre med lidt for lange variabelnavne end navne, man ikke kan huske hvad betyder. Linjeskift Når computeren læser jeres kode er den flintrende ligeglad med, hvor der er linjeskift. Derfor er det fuldstændigt op til jer, hvordan I vil skifte linjer i løbet af koden. Ligesom før er der dog nogle almindelige måder at gøre det på, som ofte virker ret godt (ellers ville folk nok ikke bruge dem?). Det er standard altid at skifte linje efter semikolon. Ved tuborg-klammer er der 2 udbredte metoder for linjeskift: 83

86 public void MyMethod () { //Code goes here og public void MyMethod () { //Code goes here Det er en smags sag, men det vigtigste er at man holder sig til én af disse metoder for at skabe overblik. Sammenligning af Kommatal Når man sammenligner kommatal (fx float) er det meget sjældent at det er en god idé at sammenligne dem direkte, fordi der er en lille smule præcisions-fejl i dem. Navnet float kommer af ordet floating-point, hvilket groft oversat betyder flydende komma. Det er fordi en float værdi er et 7-cifret tal, hvor computeren kan flytte kommaet. Fx og Så lige omkring nul har vi ret god præcision: 7 decimaler - en ti-milliontedel af en meters præcision (vi kan beskrive diameteren på et rødt blodlegeme!). Men efter bare 100 meter er vi nede på 5 decimaler - en hundred-tusindedel af en meters præcision (efterhånden svært at beskrive tykkelsen af et menneskehår). Det lyder måske ikke af meget, men i visse spil kan det skabe alvorlige problemer - især hvis spillet involverer store afstande. Det er helt klart anbefalet aldrig nogensinde at sammenligne to kommatal som floata == floatb. Fordi der er begrænset mængde decimaler kan der snige sig en lille afrundingsfejl ind og så er de to tal ikke præcist det samme. Heldigvis findes der andre metoder; man kan fx bruge Unity s egen sammenlignings-metode: Mathf.Approximately(floatA, floatb); Denne metode returnerer en bool (ja/nej) baseret på hvor tæt de to værdier er på hinanden, som kan bruges som svar til fx en if-sætning eller en while-løkke. 84

87 Lyd 85

88 Lyd i computerspil Næsten lige så vigtigt som grafik, er lyd og musik til at formidle stemningen og oplevelsen, jeres spil forsøger at frembringe. På selve campen vil der dog ikke være noget undervisning i lyd, da der simpelthen ikke er tid til det. I stedet kan du, I dette kapitel finde ud af, hvordan man finder lyd til sit spil og får lyd ind i Unity. Lyd og musik i computerspil Lyd er et meget kraftfuldt virkemidel i et spil, og det kan både bruges til at give spillet den rigtige stemning og til at give spilleren informationer, om hvad der sker, ja, sommetider er lyd den eneste måde, det kan gøres på. I mange spil sker der også ting udenfor skærmen, som det er nødvendigt at gøre spilleren opmærksom på, og her er det kun lyd, der kan bruges. Når det kommer til musik, kan man groft sagt dele det op i 2 kategorier: Musik, der sætter stemningen for de enkelte baner, og musik, der fungerer som et tema for spillet, og gør det nemt for spillerne at huske spillet. Still Alive fra Portal er et godt eksempel på den sidste type. Lyd og musik resourcer på nettet Siden at spillene, der bliver lavet på GDC kommer til at ligge på vores hjemmeside, er det vigtigt, at der er styr på at den lyd og musik, der bliver brugt i jeres spil er lovligt at bruge! Man kan heldigvis finde mange gratis, frie og gode ressourcer på nettet uden at skulle lege pirat. Hvis du skal finde lyde er en fantastisk side. Det er et online for community for lydfanatikere, der lægger deres optagelser og kunstigt frembragte lyde op på nettet til fri afbenyttelse. Hvis du skal finde musik til dit spil er der en del flere muligheder: Mange genrer - også polka! Det gode ved denne side er, at der er mange genrer, og at musikken er nem at finde og fuld tilgængelig. Her er der mulighed for at finde musik under forskellige licenser. Der skal dog tages kontakt til den enkelte kunstner om lov til at bruge deres nummer. De gratis numre ligger dog åbne til download. Creative commons musik, lidt svær at finde rundt i, men et stort udvalg at vælge imellem. Mere creative commons musik - dejligt! Endnu mere creative commons. Har en meget rar kategori inddeling og mere overskuelig end opsound. 86

89 Lyd I Unity Der er mange indstillinger for, hvordan AudioSources opfører sig, men de, som der oftest er behov for at justerere, er: 1. AudioClip - Den lyd som AudioSourcen skal afspille, kan sættes ved at trække lyden fra project view og over til AudioClip feltet. 2. Play on Awake - Bestemmer om lyden bliver afspillet, når objektet den sidder på bliver instantieret. 3. Loop - Om lyden skal bliver ved med at spille. 4. Volume - Hvor højt lyden skal afspilles. Importere lyde til Unity Ligesom med alle andre assets, får du lyd ind i Unity ved at ligge det ind i asset folderen, hvorefter Unity automatisk importerer det ind for dig. Der findes forskellige valgmuligheder for, hvordan lyde bliver importeret, men den vigtigste er, om den skal bruges som en 3D lyd eller en 2D lyd. Som en 3D lyd bliver lyden afspillet, der hvor jeres AudioSource er. Hvis den er sat som 2D lyd, bliver den afspillet som en stereo lyd. Dette er godt til baggrundsmusik, der helst skal kunne høres, uanset hvor spilkarakteren befinder sig i spillet. 87

Unity Guide 1 CONTENTS

Unity Guide 1 CONTENTS Unity Guide 1 CONTENTS Unity interface... 2 Components... 4 Materials... 7 Scripts opbygning... 8 Terrain... 8 Animations... 9 Particle system... 11 Audio... 11 Sprites... 12 GUI... 14 UNITY INTERFACE

Læs mere

GENERELT PROGRAMMERING LYD. Game Development Camp 2015 GAME BOGEN

GENERELT PROGRAMMERING LYD. Game Development Camp 2015 GAME BOGEN GENERELT 2D 3D PROGRAMMERING LYD Game Development Camp 2015 GAME BOGEN GENERELT GAME BOGEN Game Development Camp 2013 Velkommen til GDCs Game Bog. Denne bog er lavet for at hjælpe dig - både under og efter

Læs mere

The GIMP. The GIMP til windows kan hentes fra siden: http://gimp win.sourceforge.net/stable.html

The GIMP. The GIMP til windows kan hentes fra siden: http://gimp win.sourceforge.net/stable.html The GIMP The GIMP er et gratis grafikprogram som kan hentes på nettet. Alle nye opdateringer af programmet bliver lagt på nettet, så snart de er færdige. Tilbehør (bl.a. særlige funktioner) kan også hentes

Læs mere

PHOTOSHOP - BILLEDREDIGERING

PHOTOSHOP - BILLEDREDIGERING PHOTOSHOP - BILLEDREDIGERING Billeder åbnes via: File - Open... Et billede kan roteres via: Image - Rotate Canvas Under Image - Image Size... kan billedets størrelse og opløsning ændres. Under Image -

Læs mere

Billedbehandling i praksis

Billedbehandling i praksis Billedbehandling i praksis Øvelser til værktøjerne i simpel billedbehandling Version: August 2012 Indholdsfortegnelse Dette hæfte...4 Billedstørrelse, billedformater m.m...4 Billedstørrelse...4 Sideformat...5

Læs mere

1. Værktøjspaletten i Photoshop Elements.

1. Værktøjspaletten i Photoshop Elements. Introduktion til redigering af billeder i Photoshop Elements Kort om brug af billeder til hjemmesiden. Som udgangspunkt må du ALDRIG bruge billeder, som du har fundet på Google. Eneste undtagelse er bogforsider.

Læs mere

GRAFIK & BILLEDBEHANDLING. Billedbehandling og samkopieringsopgave for en bryllupsfotograf. Design af mønster til bryllupstakkekort.

GRAFIK & BILLEDBEHANDLING. Billedbehandling og samkopieringsopgave for en bryllupsfotograf. Design af mønster til bryllupstakkekort. GRAFIK & BILLEDBEHANDLING Billedbehandling og samkopieringsopgave for en bryllupsfotograf. Design af mønster til bryllupstakkekort. OPGAVEBESKRIVELSE En bryllupsfotograf kontaktede mig privat med en sammenkopieringsopgave.

Læs mere

Photoshop. Basis - værktøjer. Indhold

Photoshop. Basis - værktøjer. Indhold Photoshop Basis - værktøjer Indhold Kapitel 06 Lag / Layers................ side 2 Kapitel 07 Afmaskning................ side 4 Kapitel 08 Pathværktøj............... side 7 Kapitel 09 Shape..................

Læs mere

Sådan laver du en animationsfilm

Sådan laver du en animationsfilm Sådan laver du en animationsfilm i Animtoon Først skal du åbne Animtoon. I start menuen trykker du på Film Værkstedetikonet, som er billedet af et ben der går, se figur 1. Figur 1: Film Værkstedetikonet.

Læs mere

GRAFIK OG BILLEDE. 1 Grafik og Billede

GRAFIK OG BILLEDE. 1 Grafik og Billede GRAFIK OG BILLEDE 1 2 Opgavebeskrivelse I denne fiktive opgave har jeg valgt at lave artworket til forsiden af et playstation spil. Opgaven er inspireret af et rigtigt playstation spil ved navn Heavy Rain.

Læs mere

Introduktion til Rhinoceros 3d

Introduktion til Rhinoceros 3d Introduktion til Rhinoceros 3d September 2012, ruben.borup@aarch.dk, Arkitektskolen Aarhus Interfacets opbygning B A C D F E G H I a) Den øverst menu (alle kommandoer, kategoriseret browse) b) Kommandoprompt

Læs mere

10. Fra midtpunktet tegnede jeg en sekskant med polygon tool, som blev logoets ramme.

10. Fra midtpunktet tegnede jeg en sekskant med polygon tool, som blev logoets ramme. GRAFIK Grafik Beskrivelse Opgaven Design af nyt logo til Tipsbladet Programmer Adobe Illustrator Værktøjer Polygon tool Rectangle tool Align to pixel grid Guides Transform Outline Stroke Proces 1. Jeg

Læs mere

Workshop G3 MicroStation V8 XM edtion nye værktøjer 1

Workshop G3 MicroStation V8 XM edtion nye værktøjer 1 Workshop G3 MicroStation V8 XM edtion nye værktøjer 1 FØR I BEGYNDER......1 ELEMENT SELECTION...2 TEGNEVÆRKTØJER...4 ARRAY / ALONG ELEMENT...4 STRETCH...6 MOVE TO CONTACT...7 BREAK ELEMENT...8 COPY FENCE

Læs mere

Elements Lektion 4. I denne lektion, skal du først downloade det billede, du skal bruge at arbejde med.

Elements Lektion 4. I denne lektion, skal du først downloade det billede, du skal bruge at arbejde med. Elements Lektion 4 Så er det tid til næste lektion. Denne gang bliver det lidt mere avanceret og jeg går ud fra, at du nu har fået sat dig grundigt ind i de forberedende ting du skal igennem med hvert

Læs mere

GRAFIK & BILLEDE. Programvalg Til opgaven har jeg brugt Photoshop.

GRAFIK & BILLEDE. Programvalg Til opgaven har jeg brugt Photoshop. GRAFIK & BILLEDE Opgaven Jeg vil, ved hjælp af funktionen Refine Edge i Photoshop, fritlægge af en dreng med krøllet hår ind på en ny baggrund og samtidig forsøge at få drengen til blende ind, så det ligner

Læs mere

Workflow REDEGØRELSE WORKFLOW OPGAVE WHO WOULD YOU SMACK FOR A NEW RECORD?

Workflow REDEGØRELSE WORKFLOW OPGAVE WHO WOULD YOU SMACK FOR A NEW RECORD? REDEGØRELSE WORKFLOW OPGAVE WHO WOULD YOU SMACK FOR A NEW RECORD? Forord Spil har altid været en stor del af mit liv, og har altid spillet meget Playstation, siden jeg var helt lille. Eftersom jeg blev

Læs mere

AFTER EFFECTS DET GRUNDLÆGGENDE INTERFACE

AFTER EFFECTS DET GRUNDLÆGGENDE INTERFACE AFTER EFFECTS DET GRUNDLÆGGENDE INTERFACE PROJEKT VINDUE KOMPOSITIONS OMRÅDE TIDS KONTROL EFFEKTER LAGSTRUKTUR TIDSLINJE AFTER EFFECTS PROJEKT VINDUET Når filerne er importeret, kan de frit omdøbes og

Læs mere

Mohammad Zubair Rana. Grafik og Billede

Mohammad Zubair Rana. Grafik og Billede Mohaad Zubair Rana Grafik og Billede Grafik og Billede En privat kunde har med henblik på nykøbt iphone 5 henspurgt til om det var muligt at lave et cover til mobilen. Kunde: Privat Medie: Tryk Værktøj:

Læs mere

Skab Din Egen Verden

Skab Din Egen Verden Scratch 2 Skab Din Egen Verden All Code Clubs must be registered. Registered clubs appear on the map at codeclubworld.org - if your club is not on the map then visit jumpto.cc/ccwreg to register your club.

Læs mere

Rumfart. Introduktion. Scratch. Nu skal du lære hvordan du programmerer din egen animation! Arbejdsliste. Test dit Projekt.

Rumfart. Introduktion. Scratch. Nu skal du lære hvordan du programmerer din egen animation! Arbejdsliste. Test dit Projekt. Scratch 1 Rumfart All Code Clubs must be registered. Registered clubs appear on the map at codeclubworld.org - if your club is not on the map then visit jumpto.cc/ccwreg to register your club. Introduktion

Læs mere

ÆSTETIK Da billedet skal bruges i markedsførings-sammenhæng, må det ikke kunne ses, at det er manipuleret.

ÆSTETIK Da billedet skal bruges i markedsførings-sammenhæng, må det ikke kunne ses, at det er manipuleret. BILLED- BEHANDLING OPGAVEN Opgaven gik ud på at indsætte et læhegn på et miljøfoto af en terrasse med andre SILVAN-produkter, og at åbne billedet op, så det blev mere sommerligt og friskt. Billedet skal

Læs mere

For at få 3D-kommandoer til at virke skal AutoCAD LT 2002 først sættes op Vælg Start->Programmer->BYG-CAD>LTSetup

For at få 3D-kommandoer til at virke skal AutoCAD LT 2002 først sættes op Vælg Start->Programmer->BYG-CAD>LTSetup For at få 3D-kommandoer til at virke skal AutoCAD LT 2002 først sættes op Vælg Start->Programmer->BYG-CAD>LTSetup Herefter startes AutoCAD LT 2002 Tryk F2 og se om LT-extender er indlæst Nu vælges Tools->Options

Læs mere

Udskæring med Vegas Pro multi-kamera redigeringsværktøjer

Udskæring med Vegas Pro multi-kamera redigeringsværktøjer Udskæring med Vegas Pro multi-kamera redigeringsværktøjer Gary Rebholz Med høj kvalitet kameraer bliver mere og mere overkommelig et stigende antal redaktører står nu over for at skære sammen flere optagelser,

Læs mere

Billedbehandling Pixlr.com Side 1. Opgaver. Annemette Søgaard Hansen/www.dinwebvejleder.dk

Billedbehandling Pixlr.com Side 1. Opgaver. Annemette Søgaard Hansen/www.dinwebvejleder.dk Billedbehandling Pixlr.com Side 1 Opgaver Billedbehandling Pixlr.com Side 2 Indholdsfortegnelse Opgave 1... Åbne/Gemme/Størrelse... Side 3 Opgave 2... Autoniveauer... Side 4 Opgave 3... Manuelle justeringger...

Læs mere

MicroStation 3D for begyndere

MicroStation 3D for begyndere MicroStation 3D for begyndere Indledning Indhold Indledning... 1 Terræn model... 2 FÅ VIST TERRÆN MODELLEN MED FLADER PÅ... 3 Drapere raster refererence over terrænet... 4 NU ER DU IGEN KLAR TIL AT FÅ

Læs mere

Start SketchUp vælg File Open og åben filen Milimeters.skp under Templates

Start SketchUp vælg File Open og åben filen Milimeters.skp under Templates For at få SketchUp til at virke skal programmet først sættes op Start SketchUp vælg File Open og åben filen Milimeters.skp under Templates Herefter vælges Window -> Entity Info Kontroller at units er i

Læs mere

Vejledning til Photofiltre nr. 105 Side 1

Vejledning til Photofiltre nr. 105 Side 1 Side 1 Denne vejledning er et smalt grafikbillede man kan bruge i toppen af en mail lavet i PhotoFiltre 7 hvor man nu kan arbejde i lag. Med PhotoFiltre 7 er det nu endnu nemmere at sammensætte grafik

Læs mere

IT i dagtilbud. Begynder manual VIFIN. Af Elin B. Odgaard

IT i dagtilbud. Begynder manual VIFIN. Af Elin B. Odgaard IT i dagtilbud Begynder manual Af Elin B. Odgaard VIFIN Indholdsfortegnelse IPad'en og dens dele Sådan ser ipad'en ud - Forsiden Sådan ser ipad'en ud - Bagsiden For at komme igang Hjemmeskærm som funktion

Læs mere

Redegørelse. Curves Kontrast Skygge Lysjustering Skarphed

Redegørelse. Curves Kontrast Skygge Lysjustering Skarphed Redegørelse Opgaven Jeg har valgt at finde flere forskellige billeder som sammenkopieres og gøres naturligt med et nutidigt look. Jeg har valgt elementer som både udfordrer mig og som kunne være en opgave

Læs mere

PowerPoint Intro 2010 Segment - en del af dit netværk

PowerPoint Intro 2010 Segment - en del af dit netværk PowerPoint Intro 2010 7 Arbejde med objekter Formål Udover at arbejde med almindelig tekst og punktopstillinger, kan du i PowerPoint indsætte diverse objekter. Med objekter menes der fx; billeder, figurer,

Læs mere

Opstart. I gang med Dreamweaver. Læs mere om... Generelle bemærkninger. Hvilken skærmopløsning? OBS

Opstart. I gang med Dreamweaver. Læs mere om... Generelle bemærkninger. Hvilken skærmopløsning? OBS Generelle bemærkninger Programmet Dreamweaver har været på markedet i nogle år efterhånden. Den seneste version hedder Dreamweaver CS4, og programmet er på engelsk. Dreamweaver er en såkaldt grafisk editor,

Læs mere

KOMPENDIUM i Google SketchUp

KOMPENDIUM i Google SketchUp KOMPENDIUM i Google SketchUp UDVIKLINGSKURSUS Design og IT d. 21. maj 2008 ved arkitekter maa Cecilia Nilsson og Susanne Andersen fra SCAN arkitekter (www.scan-ark@mail.dk) Formålet med kurset er at give

Læs mere

01-04-2014 SketchUp 2014

01-04-2014 SketchUp 2014 01-04-2014 SketchUp 2014 Hans Lyche Dahl Heiselberg SKIVETS.DK Hans Heiselberg - Skive Tekniske Skole Side : 1/16 SketchUp i undervisningen SketchUp er et let tilgængeligt tegneprogram, hvor brugeren kommer

Læs mere

Opstart. I gang med Dreamweaver. Læs mere om...

Opstart. I gang med Dreamweaver. Læs mere om... Generelle bemærkninger Programmet Dreamweaver har været på markedet i nogle år efterhånden. Den seneste version hedder Dreamweaver CS5, og programmet er på engelsk. Dreamweaver er en såkaldt grafisk editor,

Læs mere

Selection Udvælgelse. For at markere mere end en polygon, holdes Ctrl samtidig. Klik på næste polygon. Gentag for i alt 5 polygoner.

Selection Udvælgelse. For at markere mere end en polygon, holdes Ctrl samtidig. Klik på næste polygon. Gentag for i alt 5 polygoner. Selection Udvælgelse Der er flere metoder til at udvælge data i GIS. I de følgende opgaver arbejdes med 3 kategorier: Select med mus Select med udtryk Select med Spatial Query Åbn filen Markblok.shp fra

Læs mere

Tips til figurdesign og tegneserietegning

Tips til figurdesign og tegneserietegning Tips til figurdesign og tegneserietegning Tekst og illustrationer Jakob Kramer Hero Tænk geometrisk Byg din figur op af simple geometriske former kugler, kasser, cylindre osv. Det gør den meget lettere

Læs mere

GRAFISK WORKFLOW. 1 Grafisk workflow

GRAFISK WORKFLOW. 1 Grafisk workflow GRAFISK WORKFLOW 1 Opgavebeskrivelse I forbindelse med et nyt online koncept Web in a box skulle jeg lave en Photoshop-skabelon, der kan eksportere materiale til en hjemmeside automatisk. Selve konceptet

Læs mere

Dit velkendte Windows, bare bedre. Din introduktion til Windows 8.1 til virksomheder

Dit velkendte Windows, bare bedre. Din introduktion til Windows 8.1 til virksomheder Dit velkendte Windows, bare bedre. Din introduktion til Windows 8.1 til virksomheder Opdag startskærmen. Startskærmen indeholder alle dine vigtigste oplysninger. Dynamiske felter sørger for, at du altid

Læs mere

Grafik & Billede Billedbehandling

Grafik & Billede Billedbehandling Grafik & Billede Billedbehandling OPGAVEN Jeg ville lave et billede der virkeliggjorde et motiv, som jeg havde på en t-shirt. Opgaven var udelukkende til mig selv og gjorde derfor også at jeg kunne ændre

Læs mere

GRAFIK OG BILLEDE Være Sammen folder reklame

GRAFIK OG BILLEDE Være Sammen folder reklame GRAFIK OG BILLEDE Være Sammen folder reklame REDEGØRELSE Hvad går opgaven ud på? Dette var en fiktiv opgave som jeg stillede mig selv. Her ville jeg lave en reklame for en folder, som skulle kunnes bruges

Læs mere

GRAFIK & BILLEDE. Grafisk Design Grafik & Billede Typografi & Ombrydning Grafisk Workflow. 2015 Sine Schrøder Christensen KIRK & HOLM Skoleophold H3

GRAFIK & BILLEDE. Grafisk Design Grafik & Billede Typografi & Ombrydning Grafisk Workflow. 2015 Sine Schrøder Christensen KIRK & HOLM Skoleophold H3 GRAFIK & BILLEDE 28/53 2015 Sine Schrøder Christensen KIRK & HOLM Skoleophold H3 Grafisk Design Grafik & Billede Typografi & Ombrydning Grafisk Workflow GRAFIK & BILLEDE Opgaven Dette er en fiktiv plakatopgave.

Læs mere

Vejledning til online-redigering i Danmarks Arealinformation

Vejledning til online-redigering i Danmarks Arealinformation Vejledning til online-redigering i Danmarks Arealinformation Redigeringsfunktioner i Danmarks Arealinformation Med denne vejledning vil Danmarks Miljøportal give en kort introduktion til de mest brugte

Læs mere

GRAFIK & BILLEDBEHANDLING

GRAFIK & BILLEDBEHANDLING GRAFIK & BILLEDBEHANDLING INDHOLD Dokumentation.... 3 Procesbeskrivelse.... 4 Photoshop indstillinger.... 5 Anvendt billedmateriale.... 6 Oversigt layers.... 7 Smart Object & Filter.... 8 Fritlægninger

Læs mere

Manual til Explain Everthing

Manual til Explain Everthing Manual til Explain Everthing Af Randi Majgård Høgh VIFIN Indholdsfortegnelse Forord Hjælp & indstillinger Oprettelse af dokumenter Gennemgang af værktøjer Video - og lydoptagelser Hvordan deler og eksporter

Læs mere

Introduktion til billeddatabasen

Introduktion til billeddatabasen Introduktion til billeddatabasen Colourbox.dk Colourbox.dk er den billeddatabase som Odense Kommune har købt licens til. Det er vigtigt at bemærke, at der ikke er ubegrænset download af billeder. I materialet

Læs mere

Arbejde med Vegas Pro digital skiltnings værktøjer

Arbejde med Vegas Pro digital skiltnings værktøjer Arbejde med Vegas Pro digital skiltnings værktøjer Gary Rebholz Disse dage, digital skiltning er overalt. Utvivlsomt du har set det, selvom du måske ikke har identificeret, hvad du oplevede som digital

Læs mere

Beskæring af et billede med Vegas Pro

Beskæring af et billede med Vegas Pro Beskæring af et billede med Vegas Pro Gary Rebholz Event Pan / Crop værktøj, som du finder på alle video begivenhed i dit projekt giver dig masser af power til at justere udseendet af din video. Du har

Læs mere

Vejledning til online-redigering i Danmarks Arealinformation

Vejledning til online-redigering i Danmarks Arealinformation Vejledning til online-redigering i Danmarks Arealinformation Redigeringsfunktioner i Danmarks Arealinformation Med denne vejledning vil Danmarks Miljøportal give en kort introduktion til de mest brugte

Læs mere

GRAFIK OG BILLEDREDIGERING

GRAFIK OG BILLEDREDIGERING GRAFIK OG BILLEDREDIGERING 2 VEKTOR TEGNINGER I ILLUSTRATOR OM TEGNINGERNE Jeg har lavet en serie af små mænd, som jeg derefter har fået printet på tykt papir og lamineret, og bruger som bogmærke. SYMETRI

Læs mere

Kom godt i gang. Værktøjspaletten. Pensler. 4 www.mikrov.dk

Kom godt i gang. Værktøjspaletten. Pensler. 4 www.mikrov.dk Forord Fresko er et spændende, nyskabende program til faget Billedkunst men med de mange maleteknikker og effekter er det en kreativ udfordring for alle med lyst til at male. Du kan male akvarel, male

Læs mere

Hvordan gør jeg? Gennemgang af fotoredigeringsprogrammet Picasa

Hvordan gør jeg? Gennemgang af fotoredigeringsprogrammet Picasa Hvordan gør jeg? Gennemgang af fotoredigeringsprogrammet Picasa Velkommen til Picasa! Start med at importere dine billeder til programmet. (1-2) 1) Inde i hovedbiblioteket trykker du på Importer, og du

Læs mere

Billeder og tegninger i Writer Indhold

Billeder og tegninger i Writer Indhold Billeder og tegninger i Writer Indhold Indhold...1 Introduktion...2 Indsætte billeder...2 Formater billedet...3 Layout...3 Beskære billedet...4 Størrelse...5 Streger/ramme...6 Skygge...7 Justering af billedet...8

Læs mere

Vejledning til brug af MiljøGIS ved ansøgning om privat skovtilskud.

Vejledning til brug af MiljøGIS ved ansøgning om privat skovtilskud. NOTAT Vejledning til brug af MiljøGIS ved ansøgning om privat skovtilskud. Denne vejledning beskriver, hvordan der kan tegnes kort til brug for ansøgning om privat skovtilskud. Naturplanlægning, naturprojekter

Læs mere

Kom it. lavet af Martin Hejgaard Sørensen. Vi skal i denne øvelse tegne et kattebur dvs. et bur til at transportere en kat.

Kom it. lavet af Martin Hejgaard Sørensen. Vi skal i denne øvelse tegne et kattebur dvs. et bur til at transportere en kat. Vi skal i denne øvelse tegne et kattebur dvs. et bur til at transportere en kat. Vi skal først have SketchUp sat op så vi kan tegne fornuftigt. Hvis vi ikke har den venstre toolbar skal vi have den slået

Læs mere

Kunde Nestlé Barnmat. Brief Levering af billeder til HTML5 website

Kunde Nestlé Barnmat. Brief Levering af billeder til HTML5 website 1 Billedbehandling I kerneområdet Grafik og Billedbehandling har jeg valgt at vise et udsnit af den billedredigering jeg har lavet til en Nestlé hjemmeside. Jeg fik til opgave at stå for hele opsætningen

Læs mere

OPGAVEN PROGRAMMER VÆRKTØJER ARBEJDSPROCESS KVALITETSVURDERING

OPGAVEN PROGRAMMER VÆRKTØJER ARBEJDSPROCESS KVALITETSVURDERING GRAFIK & BILLEDE REDEGØRELSE GRAFIK & BILLEDE 14 OPGAVEN MadDedektiven har fået taget billeder, som han skal bruge på sin nye hjemmeside. Jeg har lånt billederne til at lave en fiktiv magasin-forside til

Læs mere

Edb-tekstbehandling, præsentation mm

Edb-tekstbehandling, præsentation mm Edb-tekstbehandling, præsentation mm I denne lektion skal du: - hente kopier et skærmbillede og sætte det ind i et dokument - beskære billedet, så det passer til dit dokument Der findes specielle programmer

Læs mere

Til at starte med vil jeg lige vis nogle små ændringer på opsætningen som jeg har lavet.

Til at starte med vil jeg lige vis nogle små ændringer på opsætningen som jeg har lavet. Microstation brugermøde 10. og 11. november 2008. Indlæg af Else-Marie Lorenzen. Vejdirektoratet Til at starte med vil jeg lige vis nogle små ændringer på opsætningen som jeg har lavet. Som det første

Læs mere

4 trin + en dag REDOK

4 trin + en dag REDOK Årstid: Hele året Forløbets varighed: 4 trin + en dag Udfordringen Formålet I dette mærke bliver pigerne udfordret på deres kommunikationsevner, kreative tænkning og logiske sans. Pigerne vil lære om skjulte

Læs mere

Kilder: Troldspejlets Spilskolen, yoyogames.com

Kilder: Troldspejlets Spilskolen, yoyogames.com Kilder: Troldspejlets Spilskolen, yoyogames.com Indholdsfortegnelse Gamemaker 7.0... 3 Installation... 3 Det første spil.... 5 Trin 1: Spilidéen... 5 Trin 2: Grafik og lyd.... 6 Trin 3: Objekter og spilpladen....

Læs mere

Pinnacle Studio Titler

Pinnacle Studio Titler Pinnacle Studio Titler En enkel titel Du kan starte med at oprette en titel, så skal du blot klikke på "T"-ikonet i venstre side af medie vinduet og dine indsatte medieklip vil blive erstattet af et udvalg

Læs mere

Brugervejledning for Microstation til OpenSceneGraph konverter

Brugervejledning for Microstation til OpenSceneGraph konverter Brugervejledning for Microstation til OpenSceneGraph konverter - sidste rettelse: 10/06/2005 side 1 Indholdsfortegnelse Kort oversigt over dgn2osg... 3 Systemkrav... 3 Funktionalitet...4 Geometri...4 Materialer...

Læs mere

Skrifttype og størrelse

Skrifttype og størrelse Tekstbehandling med Microsoft Word 2007 GRUNDLÆGGENDE INTRO (PC) Når du starter Word 2007, så ser du normal-skabelonen og kan straks begynde at skrive tekst. Normal-skabelonen indeholder bl.a. indstillinger

Læs mere

Quick Guide Ditmer edagsorden Oktober 2013

Quick Guide Ditmer edagsorden Oktober 2013 Quick Guide Ditmer edagsorden Oktober 2013 Quick Guide Indhold For dig der skal i gang med at bruge ditmer edagsorden på ipad eller web 1. Sådan får du adgang til ditmer edagsorden... 2 2. Find udvalg

Læs mere

Vejledning til Mozart Viewer 12

Vejledning til Mozart Viewer 12 Vejledning til Mozart Viewer 12 Programmet kan downloades gratis på http://www.mozart.co.uk Husk at det er den der hedder Mozart Viewer du skal hente. Den er gratis, i modsætning til Mozart som koster

Læs mere

Manual til Dynamicweb Februar 2010

Manual til Dynamicweb Februar 2010 Manual til Dynamicweb Februar 2010 Login... 2 Skabeloner og formater... 3 Filarkivet... 4 Lav en PDF... 5 Opret en ny side... 7 Navngiv siden... 9 Aktiver siden... 9 Sorter sider... 9 Flyt siden... 11

Læs mere

Når du er færdig Efter vejledningen er gennemlæst kan dit Word ende med at se således ud:

Når du er færdig Efter vejledningen er gennemlæst kan dit Word ende med at se således ud: Fejlretter Smarte tricks til tilpasning af værktøjslinjen Hurtig adgang Følgende vejledning beskriver, hvordan du kan optimere din brug af Fejlretter, således at rettearbejdet bliver endnu mere effektivt

Læs mere

Vejledning for LOF s afdelingshjemmeside - redigeret i Umbraco

Vejledning for LOF s afdelingshjemmeside - redigeret i Umbraco Vejledning for LOF s afdelingshjemmeside - redigeret i Umbraco Adresse: http://dinafdeling.lof.dk/ Rediger hjemmeside i Umbraco: http://dinafdeling.lof.dk/umbraco/ HUSK ingen www i adressen, skriv blot

Læs mere

Vejledning for LOF s afdelingshjemmeside

Vejledning for LOF s afdelingshjemmeside Vejledning for LOF s afdelingshjemmeside - redigeret i Umbraco Marts 2012 Adresse: http://dinafdeling.lof.dk/ Rediger hjemmeside i Umbraco: http://dinafdeling.lof.dk/umbraco/ Mobilside: Der er lavet en

Læs mere

KERNEOMRÅDE. Grafik & Billeder

KERNEOMRÅDE. Grafik & Billeder KERNEOMRÅDE Grafik & Billeder Case HOFOR havde udstedt en plakatkonkurrence hvor det store tema var at unge brugte for meget vand. Vinderens plakat ville blive hængt på alle størrere kollegier i København

Læs mere

Vektorgrafik - Chokolade projekt

Vektorgrafik - Chokolade projekt 1 Vektorgrafik - Chokolade projekt Udvalgte billeder Opgaven Vi fik til opgave at sælge eksklusiv chokolade for den fiktive producent Chokolademesteren. Til dette skulle vi finde nogle illustrationer,

Læs mere

Billeder på hjemmeside

Billeder på hjemmeside Billeder på hjemmeside Indholdsfortegnelse Emne 1. Billedredigering (Microsoft Picture Manager) Side 3 a. Komprimer billeder b. Beskæring af billeder 3 9 2. Billeder og tekst ved hjælp af en skabelon (Template

Læs mere

Quick guide til Condes 8.

Quick guide til Condes 8. Quick guide til Condes 8. Quick guide til Condes 8.... 1 Starte Condes:... 2 Opret poster.... 6 Opdatere post detaljer:... 7 Finjustere postcirklen.... 8 Flytte postnummer... 9 Sætte poster sammen til

Læs mere

Computerundervisning

Computerundervisning Frederiksberg Seminarium Computerundervisning Koordinatsystemer og Funktioner Lærervejledning 12-02-2009 Udarbejdet af: Pernille Suhr Poulsen Christina Klitlyng Julie Nielsen Indhold Introduktion... 3

Læs mere

Fang Prikkerne. Introduktion. Scratch

Fang Prikkerne. Introduktion. Scratch Scratch 2 Fang Prikkerne All Code Clubs must be registered. Registered clubs appear on the map at codeclubworld.org - if your club is not on the map then visit jumpto.cc/ccwreg to register your club. Introduktion

Læs mere

Vurdering af billedmanipulation Opgave 1

Vurdering af billedmanipulation Opgave 1 Vurdering af billedmanipulation Opgave 1 Beskriv de enkelte funktioner i dit tegneprogram... Er der tale om en korrektion eller en modifikation? Før vi kan begynde at kategorisere de forskellige funktioner

Læs mere

Begyndermanual og introduktion til

Begyndermanual og introduktion til Begyndermanual og introduktion til Design 3D parametrisk CAD www.nettocad.dk mail@a-engineering.dk Tlf. 61337807 1 Part Workspace Zoom værktøjer De gule ikoner viser dine konstruktioner fra forskellige

Læs mere

Ved brug af computer handler det derfor mest om, hvordan man får teksten til at stå på papiret og på skærmen.

Ved brug af computer handler det derfor mest om, hvordan man får teksten til at stå på papiret og på skærmen. Side 1 af 21 I dette materiale skal du prøve at arbejde med tekster og billeder. Tekster er bogstaver, der er sammensat til ord. Ord er igen sat sammen, så de danner sætninger. Sætninger kan udtrykke en

Læs mere

Farvelægning i gimp for begyndere

Farvelægning i gimp for begyndere Farvelægning i gimp for begyndere I denne tutorial vi jeg gå ud fra, at læseren selv har klaret at installere the gimp. Hvis man er i stand til det, har man et computerkendskabsniveau, der gør at man sagtens

Læs mere

Men RW-Tool kan mere uden man skal ind og ud af RW hele tiden, for at se hvordan ens ændring tager sig ud.

Men RW-Tool kan mere uden man skal ind og ud af RW hele tiden, for at se hvordan ens ændring tager sig ud. Lille dansk guide til repaints af Rotarii Kort om guiden. Vil guiden igennem holde mig til, at man ikke gør brug af andet end kun lige hvad RW kommer med, altså uden tilkøb og/eller andre ændringer man

Læs mere

Programmering C Eksamensprojekt. Lavet af Suayb Köse & Nikolaj Egholk Jakobsen

Programmering C Eksamensprojekt. Lavet af Suayb Köse & Nikolaj Egholk Jakobsen Programmering C Eksamensprojekt Lavet af Suayb Köse & Nikolaj Egholk Jakobsen Indledning Analyse Læring er en svær størrelse. Der er hele tiden fokus fra politikerne på, hvordan de danske skoleelever kan

Læs mere

Kom i gang med Course Tool 1.2

Kom i gang med Course Tool 1.2 Kom i gang med Course Tool 1.2 Indhold Indledning...2 Pris beregning...2 Anvendelse...2 Open Source...2 Anbefalinger...2 Installation...3 USB-Pen...3 Download Libre Office (Draw)...3 Indstil makrosikkerhed...4

Læs mere

Viditronic NDVR Quick Guide. Ver. 2.0

Viditronic NDVR Quick Guide. Ver. 2.0 Viditronic NDVR Quick Guide Ver. 2.0 1 Indholdsfortegnelse 1. HOVEDMENU 3 1.1 START 5 1.2 AKTIVITETSINDIKATOR: 7 1.3 INFORMATIONS VINDUE: 7 1.4 PTZ KAMERA KONTROL: 7 1.5 SKÆRMMENU 8 1.5.1 AKTIVER BEVÆGELSE:

Læs mere

I. SMART Board. I. SMART Board... 1 II. Forord... 2 III. Smartboard værktøjskasse... 2. IV. Turorials... 3 V. SMART Notebook... 4

I. SMART Board. I. SMART Board... 1 II. Forord... 2 III. Smartboard værktøjskasse... 2. IV. Turorials... 3 V. SMART Notebook... 4 I. SMART Board I. SMART Board... 1 II. Forord... 2 III. Smartboard værktøjskasse... 2 A. Tastatur... 3 B. Optager... 3 C. Kontrolpanel... 3 IV. Turorials... 3 V. SMART Notebook... 4 A. En Notebookside

Læs mere

Skrivebordet Windows 10

Skrivebordet Windows 10 Få adgang til Stifinder, Indstillinger og andre apps, du bruger ofte, i venstre side af menuen Start. Hvis du vil se alle dine apps og programmer, skal du vælge Alle apps. Vises der en pil til højre for

Læs mere

Opret en formular i Dreamweaver

Opret en formular i Dreamweaver Opret en formular i Dreamweaver. Åben det html-dokument hvor du vil have din formular skal være på. 2. Klik i det felt (DIV eller tabel) hvor du vil have din formular skal være. Du kan se du er i feltet

Læs mere

Grafik & billede Maria Clausen Clausen Svendeportf Hovedforl olio øb 3 Grafik & bill Gr ede afik & bill side 1

Grafik & billede Maria Clausen Clausen Svendeportf Hovedforl olio øb 3 Grafik & bill Gr ede afik & bill side 1 Grafik & billede Maria Clausen Svendeportfolio Hovedforløb 3 Grafik & billede side 1 opgaven OPGAVEN Denne fiktive opgave har jeg valgt at lave fordi jeg gerne vil vise så meget som muligt indenfor billede

Læs mere

Adobe InDesign 1.5. Service & Kommunikation HTX / Viby

Adobe InDesign 1.5. Service & Kommunikation HTX / Viby Adobe InDesign 1.5 1 Adobe InDesign 1.5 2 Adobe InDesign 1.5 - Index Folderteori.............................. 3 Placering.............................. 4 Farver og tekst........................... 5 Skriftsnit

Læs mere

Vejledning til Photo Story 3

Vejledning til Photo Story 3 Vejledning til Photo Story 3 Start på billedfortælling Når du har startet programmet, får du dette vindue. Du får 3 valg: 1. Opret en ny fortælling. 2. Redigere et projekt 3. Afspille en fortælling. Den

Læs mere

Henrik Pedersen 3. HTX Jonas Johansen 16/01/2015. Visuel Identitet Ditlev Hellesøe

Henrik Pedersen 3. HTX Jonas Johansen 16/01/2015. Visuel Identitet Ditlev Hellesøe Visuel Identitet Ditlev Hellesøe 1 Indholdsfortegnelse Problemanalyse... 3 K Strategi... 3 Idéudvikling... 4 Medieproduktion... 5 Test... 6 Offentliggørelse... 6 Konklusion... 6 2 Problemanalyse Ditlev

Læs mere

Sådan starter du PowerPoint vha. Start-knappen

Sådan starter du PowerPoint vha. Start-knappen Bliv en haj til IT i hverdagen 4.3 PowerPoint Microsoft PowerPoint er et præsentationsprogram, som kan bruges til at oprette flotte præsentationer, der enten kan udskrives eller afspilles på en computer.

Læs mere

Opstilling af festsange med overskrift og vers.

Opstilling af festsange med overskrift og vers. Side 1 af 12 Opstilling af festsange med overskrift og vers. Spalter 1. Skriv overskrift og vers på normal måde. Lad os sige, at der er 7 vers, hvor de 6 skal stå i 2 spalter. Det sidste skal stå alene

Læs mere

Windows Live Movie Maker-alle funktioner.

Windows Live Movie Maker-alle funktioner. Windows Live Movie Maker-alle funktioner. Her vises brugen af funktionerne i programmet til at lave en film bestående af dine billeder og video/film klip. Læg egen tale og/eller musik på filmen. 1: Åbn

Læs mere

Grafik Billedbehandling

Grafik Billedbehandling Grafik Billedbehandling & Dokumentation Org. billeder Billedet størrelse ses i ppi = pixel per inch = pixel per tomme. Jeg har valgt at lave den i 300. Da den skal bruges til reklame, og skal kunne komme

Læs mere

Bevægelses analyse med SkillSpector. Version 1.0 Sidste opdatering: 14/05-2008

Bevægelses analyse med SkillSpector. Version 1.0 Sidste opdatering: 14/05-2008 Bevægelses analyse med SkillSpector Version 1.0 Sidste opdatering: 14/05-2008 Hvad er SkillSpector SkillSpector er software program til video baseret bevægelses analyse. Der er følgende muligheder med

Læs mere

Grafisk Tekniker Digitalprint. Klistermærker med skærelinjer

Grafisk Tekniker Digitalprint. Klistermærker med skærelinjer Grafisk Tekniker Digitalprint Klistermærker med skærelinjer Klistermærker - opgave En mindre serie forskellige klistermærker skal tegnes i Illustrator. Der defineres en ny fil for hvert enkelt klistermærke,

Læs mere

HCI (Human Computer Interaction)

HCI (Human Computer Interaction) HCI (Human Computer Interaction) HCI står for Human Computer Interaction, hvilket vil sige samspillet mellem computer og bruger. Det er en tankegang om at computeren skal være brugervenlig overfor den

Læs mere

Illustrator Undervisning

Illustrator Undervisning Indhold Illustrator: Pixels kontra Vektor.............. 2 Pathværktøj...................... 3 Værktøjer........................ 4 Nyt dokument..................... 5 Intro til værktøjer....................

Læs mere

Vejledning KPK Online Prøverum

Vejledning KPK Online Prøverum Vejledning KPK Online Prøverum INDHOLD Introduktion side 2 Funktionsliste side 2 Få adgang til systemet side 3 Opload dine billeder side 4 Sådan bruges systemet side 5 Gem dine eksempler side 7 Side 1/7

Læs mere

Kom hurtigt i gang. med. FloorPlan 3D. FloorPlan 3D er et program med mange anvendelsesmuligheder!

Kom hurtigt i gang. med. FloorPlan 3D. FloorPlan 3D er et program med mange anvendelsesmuligheder! Kom hurtigt i gang med FloorPlan 3D FloorPlan 3D er et program med mange anvendelsesmuligheder! Formålet med denne guide, er at give et overblik over de grundlæggende funktioner i FloorPlan 3D og at få

Læs mere