Pokédex på HoloLens

Augmented Reality, eller utvidet virkelighet, er teknologi som legger til noe digitalt, gjerne grafikk, på en persons opplevelse av virkeligheten. I dag, hvor alle har en smarttelefon i lomma, har AR blitt allemannseie. I motsetning til på mobil, hvor du ser AR gjennom skjermen, kan AR-briller legge til grafikk på synsfeltet. AR-teknologi har eksistert siden 90-tallet, men har skutt fart de siste årene.

Med AR-briller utfordres tankegangen om hva som er god UX. AR-briller krever et annet brukergrensesnitt enn en desktop eller mobil. Eksempelvis bør ikke informasjon fremstilles på samme måte som på en flat skjerm, fordi informasjonen må presenteres i et 3D-rom. I dette prosjektet blir nettopp dette testet ut på en AR-brille av typen HoloLens, hvor informasjonen som skal legges fram er i form av en Pokédex.

For å forstå hva en Pokédex er, må man først kjenne til Pokémon. Pokémon er noen rare dyr, som bor inni en ball. Hver Pokémon har ett eller to elementer (vann, ild, gress, jord, etc.), hvor hvert element har sine styrker og svakheter. For eksempel, vann er effektivt mot ild, men fungerer dårlig mot gress. I den klassiske spillserien fanger, bytter og trener Pokémontrenere Pokémon, og bruker dem til å slåss mot hverandre.

Pokémon er verdens nest største spillfranchise og ble skapt i 1995. Eventyret startet med den klassiske spillserien på Game Boy, og har senere utviklet seg til å inkludere konsollspill, animasjonsserie, kortspill, leketøy, m.fl. Et av de nyere tilskuddene er Pokémon GO, som har passert 800 millioner nedlastinger.

Den utviklede applikasjonen tar utgangspunkt i de første spillene i den klassiske spillserien. Dette betyr at det kun er Pokémon fra den første generasjonen som skal ha plass i Pokédexen.

Hvilken informasjon som blir vist var ikke så viktig for prototypingen. Det sentrale med prosjektet var å eksperimentere med informasjonsvisning og UX på en ny og annerledes platform. I tillegg kan de forskjellige pokémonmodellene være såpass komplekse og mange i antall, at ytelse blir et problem. Dette vil da være en fin mulighet for å teste shader performance, som er essensielt for å rendre store datamodeller.

Pokédex

En Pokédex er et digitalt leksikon med oversikt over Pokémon. Hver Pokémon har sin egen side med diverse informasjon, som størrelse, vekt og beskrivelse. I den klassiske spillserien blir en Pokémon først registrert når man ser den, og ekstra informasjon blir registrert hvis man klarer å fange den. Et av målene i spillene er å fylle opp Pokédexen med alle Pokémon som finnes.

Når man åpner Pokédexen på HoloLensen vil et element for hver Pokémon instansieres og finne sin plass, slik at de danner en tabell. Velger man en Pokémon i tabellen, vil man få fram en infoplansje med generell informasjon om Pokémonen. I tillegg til informasjonen får man muligheten til å kalle fram Pokémonen, slik at man kan inspisere en animert modell i full størrelse på stuegulvet.

HoloLens

HoloLens er en AR-brille utviklet av Microsoft. Ved hjelp av kameraer, mikrofoner, akselerometer, gyroskop og flere andre sensorer gir den blant annet støtte for AR, tracking og romforståelse. Med tracking menes her at programvaren kan vite hvor HoloLensen er i rommet. Dette muliggjør, blant annet, at digitale objekter kan låses fast til en faktisk fysisk posisjon. Den fungerer som en selvstendig enhet og trenger ingen tilkobling til en datamaskin for å fungere.

Visjonen bak en applikasjon bør stemme overens med HoloLensens egenskaper. De mest sentrale egenskapene er at den er mobil, handsfree, støtter Wi-Fi og legger til noe ekstra på virkeligheten. Eksempler på applikasjoner som utnytter disse er:

  • En applikasjon som gir brukeren ekstra informasjon om objekter i den virkelige verden
  • En applikasjon som gir brukeren mulighet til å planlegge interiør ved å plassere ut digitale modeller i rommet
  • Applikasjoner som legger til ekstra effekter på en ellers grå hverdag

UX på HoloLens

Utvikling for en god brukeropplevelse på HoloLens er litt annerledes enn for et vanlig dataprogram. Forskjellig input og medium gir en annen opplevelse, noe en utvikler må ta hensyn til.

Brukeren kan gi input med håndbevegelser mens man flytter på en musepeker ved å vri på hodet. Dette gir ganske mye mindre nøyaktighet enn med vanlig mus og tastatur. I tillegg må man ta hensyn til at det man skal trykke på finnes i et 3D-rom.

For eksempel kan man ikke bruke vanlig screen overlay for menyer. Menyen vil da flytte seg med musepekeren og gjøre den umulig å trykke på. Istedenfor kan menyen bli plassert ut som en tavle, eller et objekt, som i varierende grad følger etter brukeren. Det kan også være fornuftig bruke billboarding på menyen, som vil si at menyen alltid er rettet mot brukeren. Dette vil hindre at brukeren kommer seg på siden av eller bak den. Det kan også være naturlig å fylle en meny med tredimensjonale knapper, istedenfor todimensjonale bilder.

I kontrast til UX for 2D-applikasjoner, er UX-design for 3D-applikasjoner et nytt og umodent felt. AR/VR introduserer nye utfordringer, som å tenke i 3D og ha en UI som blir påvirket av miljøet rundt. I et 3D-miljø kan UI-elementer, for eksempel, havne bak andre objekter, noe som vil ha en negativ effekt på brukervennligheten. Når man arbeider for å løse disse utfordringene er det viktig at integriteten av applikasjonen opprettholdes; at noe ikke går på tvers av det som føles naturlig. Et godt tips er å se på hvordan dataspill løser disse problemene. Problemstillingen er jo den samme: Hvordan kan man viske ut skillet mellom UI og resten av applikasjonen? Ideelt vil man at UI i et spill er en integrert del av opplevelsen, og ikke en påminnelse om at det kun er et spill.

Unity

Utvikling av HoloLens-applikasjoner skjer i hovedsak i Unity. Unity er en gratis spillmotor som bruker C# som scriptingspråk. I tillegg støtter den drag-and-drop-funksjonalitet og er en lavterskel inngangsportal til spillutvikling.

Unity + Hololens

HoloLens kjører UWP-applikasjoner (Universal Windows Platform) som må kompileres av en native .NET compiler. I praksis betyr dette at applikasjonen må innom Visual Studio, før den kan deployes til HoloLensen. Dette begrenser utvikling til Windows, hvis man da ikke setter opp en remote build server, eller lignende. Nyere versjoner av Unity støtter kun 64-bit og det kreves et grafikkort som støtter DirectX10. Utenom dette er kravene for utvikler-PC avhengig av applikasjonens kompleksitet.

Det første man bør gjøre for å utvikle til HoloLens er å laste ned HoloToolkit. HoloToolkit er et sett med scripts og komponenter som skal gjøre utvikling enklere. Den senker terskelen ved å gi ferdige komponenter for blant annet input, sharing, spatial mapping og spatial understanding. HoloToolkit forenkler også deployment til HoloLens fra Unity ved å legge til en knapp som automatisk setter de korrekte innstillingene i Unity.

Fane lagt til av HoloToolkit

Unity støtter også Holographic Remoting Player, som er det andre man bør sette opp. Denne applikasjonen gjør at man kan strømme fra utvikler-PC til HoloLens i sanntid. Dette gjør at man kan teste ut applikasjonen på HoloLensen uten å bygge og deploye den. Dessverre kan bruken av dette ofte få Unity til å krasje, men tidsbesparelsen er likevel signifikant.

Når Unity er satt opp, er ikke utviklingen av en HoloLens-applikasjon så annerledes enn for andre Unity-applikasjoner. Ved bruk av HoloToolkit slipper man unna en del kompleksiteter ved, for eksempel, spatial mapping og input handling. Mange problemer kan ofte løses ved å finne riktig komponent eller script, og legge det til i hierarkiet.

Ved utvikling av Pokédexen ble all logikk og funksjonalitet først programmert og testet med enkle placeholder-objekter. Unity har enkle figurer som kuber, kuler og sylindre som er mer enn nok for testing. Disse ble senere byttet ut med egne modeller.

Funksjonalitet

Den ferdige pokédexapplikasjonen kan deles opp i 3 forskjellige faser: pokédexfasen, tabellfasen og inspiseringsfasen.

Pokédexfasen

I pokédexfasen er Pokédexen lukket og kan flyttes på. Brukeren bør da flytte den til et sted hvor det er naturlig å instansiere en relativt stor tabell før den åpnes. Pokédexen åpnes når brukeren trykker på den, og instansierer tabellen. Brukeren kan alltid komme tilbake til pokédexfasen ved bruk av stemmekontroll.

Tabellfasen

Når pokédexen åpnes starter tabellfasen. I tabellfasen kan man velge hvilken Pokémon man vil ha informasjon om ved å trykke på et element i tabellen. Ved trykk instansieres et nytt element, i passelig avstand fra brukeren. Dette elementet har tekstfelter, en modell av Pokémonen og knapper for videre bruk. Hvis brukeren trykker på Inspect-knappen, starter inspeksjonsfasen.

Inspeksjonsfasen

Inspeksjonsfasen starter med instansiering av en Pokéball. Pokéballen kan flyttes på samme måte som med Pokédexen. Når brukeren trykker på Pokéballen, åpnes den og en modell i full størrelse av Pokémonen instansieres. På forhånd har HoloLensen scannet gulvet, slik at når Pokémonen kommer ut av ballen, så skal den bli stående på det. For å komme tilbake til tabellfasen trykker man på et nytt element i tabellen.

Eksempelkode: Initialisering av tabell:

Vi vil gjerne at tabellen skal ende opp slik at Pokédexens posisjon samsvarer med midten på tabellen. For å oppnå dette regnes det ut hvor mye vi må flytte elementene i x- og y-retning. På forhånd har vi satt hvor mange rader og kolonner tabellen skal ha, samt hvor mange elementer det er. Dette er variabler en designer kan sette i Unity, uten å gå inn i koden. For hvert element regner vi så ut sluttposisjonen. Disse dataene blir så matet inn i en Coroutine, som instansierer hvert element med et passende tidsintervall, og starter animasjonen. Til slutt justeres alfaen til tittelteksten, slik at den blir synlig.

Initialiseringen av tabellen

Modellering i Blender

Etter at funksjonaliteten var tilfredsstillende ble det estetiske satt mer i fokus. Spillressurser, som ble brukt for å få applikasjonen til å se fin ut, ble modellert og animert i Blender. Blender er et open-source program med støtte for blant annet 3D-modellering, animasjon, teksturering, simulering og videoredigering. Blender blir oftest brukt av hobby- og indieutviklere, først og fremst på grunn av pris, men jevnlige oppdateringer gjør at Blender nærmer seg sine konkurrenter i funksjonalitet. Personlig har jeg til gode å oppleve at jeg mangler en funksjon i Blender.

Tre ressurser ble modellert og animert i Blender: En Pokémon, en Pokédex og en Pokéball.

Pokéballen og pokédexen ble modellert ved basic modellering, ren manipulasjon av geometri, mens Pokémonen først ble skulpturert. Et tegneserieaktig utseende på ressursene ble valgt, fordi det da er enklere og billigere ytelsesmessig å få noe til å se bra ut. Det bør også understrekes at alle ressurser bærer preg av at de er lagd for prototyping.

Dynamic Topology gjør at ekstra geometri blir generert ved skulpturering

Skulpturering innebærer å jobbe med modellen som om den var av leire. Ved å, for eksempel, dra i noen områder, legge til og fjerne på andre områder, kan man litt om litt forme modellen til det man ønsker. For å kunne skulpturere, må man forsikre seg om at man har nok geometri å jobbe med, eller eventuelt aktivere Dynamic Topology, som legger til geometri etterhvert som man trenger det.

Resultatet av en skulpturering er ofte en vakker modell med altfor mange polygoner. Hvis man bare skal ta et stillbilde av modellen hadde det vært OK, selv om renderingtiden kan bli unødvendig høy. Hvis modellen skal brukes i et spill, må detaljnivået drastisk ned. En skulpturert modell kan, avhengig av kompleksiteten av figuren og detaljnivået, ha millioner av polygoner, mens det anbefalte for et mobilspill er mellom 300 og 1500. Som regel tillater man et litt høyere antall på en hovedperson eller modeller som er sentrale i spillet, enn på bakgrunnsobjekter.

For å redusere antall polygoner i en skulpturert modell benyttes retopology. Retopology innebærer å lage overflaten på nytt, med en mer optimal geometri. I praksis gjøres dette ved å lage en ny modell over den skulpturerte. Ved å få den nye modellens endepunkter til å klistre seg på den gamle kan man lage en god tilnærming med færre polygoner. Det finnes forskjellige verktøy for å lage en retopology, men for å ha mest mulig kontroll kan det gjøres manuelt. Hvis figuren skal animeres, anbefales det også å gjøre det manuelt, for å sikre at modellen deformeres korrekt ved bevegelse.

Geometri før og etter retopology.

Etter endt skulpturering hadde Pokémonen rundt 250,000 polygoner. Ved bruk av retopology ble antallet polygoner redusert til rundt 5000. Dette er fortsatt over det anbefalte antallet for et mobilspill, men siden ingen andre modeller kom til å være aktive samtidig, ble det antatt at antallet var tilfredsstillende lavt for en prototype. Testing bekreftet dette. Hvis ytelsen begynner å bli lav er det mulig å optimalisere geometrien ytterligere i etterkant.

Modell + tekstur = Pokémon

Da har vi en modell vi kan lage en tekstur til. Teksturer er representert som et todimensjonalt bilde, som nødvendigvis er flatt. Dette betyr at vi må ta grep for å få en flat representasjon av modellen vår også. For å oppnå dette brukes UV-unwrapping, som kan sammenlignes med å brette ut figuren. Ved å markere en kant som en crease, som tilsvarer kanter man kan klippe opp, prøver man så godt man kan å brette ut figuren uten å strekke geometrien for mye. Til slutt har man en representasjon av geometrien som et bilde, som da vil samsvare med en tekstur man legger til.

Animasjon i Blender

De ressursene som ble animert i Blender ble rigget på to forskjellige måter: mekanisk og organisk. Forskjellen mellom de to måtene er at geometrien i en organisk animasjon må deformeres. Det at Pokédexen, eller Pokéballen, åpner og lukker seg, krever ingen deformering fordi de har hengsler og ledd som er tilrettelagt for dette. På Pokémonen vil vi få deformering, på samme måte som at huden din strekkes når du bøyer et ledd. Mekanisk rigging handler derfor i hovedsak om å tilrettelegge for enkel manipulasjon, mens organisk rigging krever mer arbeid.

Animasjon av Pokéball og Pokédex

For å rigge Pokémonen legger man først til et skjelett. Ved modeller som ligner på dyr, noe Pokémonen gjør, etterligner man ofte virkelige skjeletter for å få til en naturlig bevegelse. Forskjellen i skjelettet mellom pattedyr er liten, og forskjellen er ofte kun i beinas dimensjoner og størrelse. Etter at man har plassert ut et skjelett, bestemmer man hvor stor påvirkning et bein skal ha på et område av modellen. Denne prosessen kalles weight painting. Man kan la Blender automatisk binde modell og skjelett sammen, men som regel må man gå over med weight painting i etterkant for å unngå tearing og unaturlige deformasjoner.

Modell med skjelett. Til høyre er resultatet av weight painting av venstre framfot.

Når modellen er ferdig rigget kan man begynne å animere. Ved å manipulere modellen, ved hjelp av riggen, kan man lage en positur på en spesifikk frame. Overgangen mellom to positurer blir interpolert av Blender, slik at overgangen blir jevn. Man kan tilpasse kurven selv, og hvis man vil ha enda mer kontroll kan man gå tilbake og finpusse på frames mellom de to positurene. På denne måten kan man lage flere forskjellige animasjoner som så kan trigges i Unity.

Animasjon i Unity

I Unity ble det brukt en tredje form for animasjon, i tillegg til den mekaniske og organiske som ble brukt i Blender. Ved hjelp av scripting endres størrelsen og posisjonen til de elementene som blir instansiert når man åpner Pokédexen.

Eksempelkode av animasjon ved lineær interpolasjon

Ved bruk av en startposisjon, sluttposisjon og et tidsintervall, kan man få til en jevn animasjon ved hjelp av lineær interpolasjon. Ved å notere ned tidspunktet man starter animasjonen på, kan man sammenligne dette med tiden som har gått. På starttidspunktet vil tidsdifferansen mellom starttidspunktet og nå være på 0 % av det satte tidsintervallet. For hver loop i koden oppdateres forskjellen og objektet flyttes slik at forholdet i tid er lik forholdet mellom startposisjon og sluttposisjon. Når forskjellen på starttidspunktet og nåtiden er den samme som tidsintervallet, skal objektet ha flyttet seg helt fram til målet. Det samme vil gjelde for endring av størrelse på et objekt.

Animasjon skapt ved hjelp av lineær interpolasjon

For å gi applikasjonen litt mer liv ble det lagt til noen enkle partikkeleffekter i Unity. Eksempelvis aktiveres disse når Pokéballen og Pokédexen åpnes. Partikkeleffekter kan være relativt billige i drift, siden de ofte baserer seg på mange små teksturer, istedenfor 3D-objekter. Det er vanlig å simulere blant annet røyk, eksplosjoner og fosser ved hjelp av partikkeleffekter.

Partikkeleffekt ved åpning av Pokéball

Oppsummering

De håndbevegelsene man har til rådighet er dessverre ikke veldig intuitive for nye brukere. De trenger ofte flere forsøk, og veiledning, for å få til et vanlig klikk. Ofte virker det som om brukeren heller har lyst til å ta på, dra og vri på figurene som om de var ekte. Stemmegjenkjenning derimot, virker det som om nye brukere omfavner. Ofte foretrekker de å snakke seg rundt i menyene, istedenfor å trykke.

Tabellen, som man setter opp et sted i rommet, fungerer tilfredsstillende. Den er stor og man mister den ikke av syne. Elementene i tabellen er dog på kanten til for små. Det krever litt for mye presisjon å interagere med et spesifikt element, og av og til trenger man flere forsøk på å treffe. Dette, i kombinasjon med lite intuitive inputs, kan være ganske frustrerende for en ny bruker.

Små flyttbare objekter, som Pokédexen og Pokéballen, kan ofte bli borte fra brukerens synsfelt. Er man ekstra uheldig, kan objektet havne inni brukeren sin kropp, slik at man må flytte seg flere steg før den blir synlig igjen. Løsninger på dette problemet kan være å legge til en pil på musepekeren som peker mot objektet, eller eventuelt flytte det til midt i synsfeltet ved hjelp av stemmegjenkjenning.

Det viser seg at bruken av HoloLens og AR ikke er så intuitiv for folk flest, og det trengs tilvenning. Spesielt håndbevegelsene man bruker som input, kan være kinkige i starten. Det er viktig å tenke på at det man skal trykke på er stort nok og at brukeren kan miste små ting ut av syne. I tillegg må man alltid huske på at AR foregår i et virkelig 3D-rom, slik at alle interaksjoner og UI er i samsvar med dette.

Hvis dere har spørsmål eller vil vite mer om dette prosjektet kan dere ta kontakt med meg på vegard@kodeworks.no.