Prestandarekommendationer för Unity
Den här artikeln bygger på prestandarekommendationerna för mixad verklighet, men fokuserar på Unity-specifika förbättringar.
Vi släppte nyligen ett program med namnet Kvalitetsgrunder som omfattar vanliga prestanda-, design- och miljöproblem och lösningar för HoloLens 2-appar. Den här appen är en bra visuell demo för innehållet som följer.
Använda rekommenderade Unity-projektinställningar
Det viktigaste första steget när du optimerar prestanda för appar för mixad verklighet i Unity är att se till att du använder de rekommenderade miljöinställningarna för Unity. Den artikeln innehåller innehåll med några av de viktigaste scenkonfigurationerna för att skapa högpresterande Mixed Reality-appar. Några av de här rekommenderade inställningarna är också markerade nedan.
Profilera med Unity
Unity tillhandahåller Unity Profiler inbyggt, vilket är en bra resurs för att samla värdefulla prestandainsikter för din specifika app. Även om du kan köra profileraren i redigeringsprogrammet representerar dessa mått inte den sanna körningsmiljön, så resultaten bör användas försiktigt. Vi rekommenderar att du fjärrprofilerar ditt program när du kör på enheten för de mest exakta och användbara insikterna.
Unity tillhandahåller bra dokumentation för:
- Så här ansluter du Unity Profiler till UWP-program via fjärranslutning
- Så här diagnostiserar du prestandaproblem effektivt med Unity Profiler
GPU-profilering
Unity-profilerare
Med Unity Profiler ansluten och efter att du har lagt till GPU-profileraren (se Lägg till Profiler i det övre högra hörnet) kan man se hur mycket tid som spenderas på CPU respektive GPU i mitten av profileraren. På så sätt kan utvecklaren få en snabb uppskattning om deras program är CPU- eller GPU-avgränsat.
Kommentar
Om du vill använda GPU-profilering måste du inaktivera grafikjobb i Unity Player-Inställningar. Mer information finns i Unitys modul GPU Usage Profiler.
Felsökningsprogram för Unity-ram
Unitys Frame Debugger är också ett kraftfullt och insiktsfullt verktyg att använda. Det ger dig en bra översikt över vad GPU:n gör varje bildruta. Saker att hålla utkik efter är ytterligare renderingsmål och blit-kommandon att kopiera mellan dem eftersom dessa är mycket dyra på HoloLens. Helst ska inga mål för återgivning utanför skärmen användas på HoloLens. Dessa läggs vanligtvis till när du aktiverar dyra återgivningsfunktioner (till exempel MSAA, HDR eller helskärmseffekter som bloom) som bör undvikas.
Överlägg för HoloLens-bildfrekvens
Sidan Systemprestanda för enhetsportalen innehåller en bra sammanfattning av processor- och GPU-prestanda för enheten. Du kan aktivera Display frame rate counter in headset (Visa bildfrekvensräknare i headsetet ) och Visa bildfrekvensdiagram i headsetet. De här alternativen aktiverar en FPS-räknare respektive graf som ger dig omedelbar feedback i alla program som körs på enheten.
PIX
PIX kan också användas för att profilera Unity-program. Det finns också detaljerade instruktioner om hur du använder och installerar PIX för HoloLens 2. I en utvecklingsversion visas samma omfång som du ser i Unitys Frame Debugger även i PIX och kan inspekteras och profileras mer detaljerat.
Kommentar
Unity gör det enkelt att ändra programmets målmatchning vid körning via egenskapen XR Inställningar.renderViewportScale. Den slutliga avbildningen som visas på enheten har en fast upplösning. Plattformen provar utdata med lägre upplösning för att skapa en bild med högre upplösning för återgivning på skärmar.
UnityEngine.XR.XRSettings.renderViewportScale = 0.7f;
Rekommendationer för CPU-prestanda
Innehållet nedan beskriver mer djupgående prestandametoder, särskilt riktade till Unity &C#-utveckling.
Cachereferenser
Vi rekommenderar cachelagring av referenser till alla relevanta komponenter och GameObjects vid initiering eftersom upprepade funktionsanrop som GetComponent<T>() och Kamera.main är dyrare i förhållande till minneskostnaden för att lagra en pekare. . Kamera.main använder bara FindGameObjectsWithTag() under, vilket dyrt söker i scendiagrammet efter ett kameraobjekt med taggen "Main Kamera".
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour
{
private Camera cam;
private CustomComponent comp;
void Start()
{
cam = Camera.main;
comp = GetComponent<CustomComponent>();
}
void Update()
{
// Good
this.transform.position = cam.transform.position + cam.transform.forward * 10.0f;
// Bad
this.transform.position = Camera.main.transform.position + Camera.main.transform.forward * 10.0f;
// Good
comp.DoSomethingAwesome();
// Bad
GetComponent<CustomComponent>().DoSomethingAwesome();
}
}
Kommentar
Undvik GetComponent(sträng)
När du använder GetComponent()finns det en handfull olika överlagringar. Det är viktigt att alltid använda de typbaserade implementeringarna och aldrig den strängbaserade sököverlagringen. Det är betydligt dyrare att söka efter sträng i din scen än att söka efter typ.
(Bra) Komponenten GetComponent(typ)
(Bra) T GetComponent<T>()
(Dåligt) Komponenten GetComponent(sträng)>
Undvik dyra åtgärder
Undvik användning av LINQ
Även om LINQ kan vara rent och enkelt att läsa och skriva, kräver det vanligtvis mer beräkning och minne än om du skrev algoritmen manuellt.
// Example Code using System.Linq; List<int> data = new List<int>(); data.Any(x => x > 10); var result = from x in data where x > 10 select x;
Vanliga Unity-API:er
Vissa Unity-API:er kan, även om de är användbara, vara dyra att köra. De flesta av dessa handlar om att söka i hela scendiagrammet efter en matchande lista över GameObjects. Dessa åtgärder kan vanligtvis undvikas genom att cachelagra referenser eller implementera en chefskomponent för GameObjects för att spåra referenserna vid körning.
GameObject.SendMessage() GameObject.BroadcastMessage() UnityEngine.Object.Find() UnityEngine.Object.FindWithTag() UnityEngine.Object.FindObjectOfType() UnityEngine.Object.FindObjectsOfType() UnityEngine.Object.FindGameObjectsWithTag() UnityEngine.Object.FindGameObjectsWithTag()
Kommentar
SendMessage() och BroadcastMessage() bör elimineras till varje pris. Dessa funktioner kan vara i storleksordningen 1000x långsammare än direktfunktionsanrop.
Akta dig för boxning
Boxning är ett grundläggande begrepp i C#-språket och körningen. Det är processen att omsluta värdetypade variabler som
char
,int
,bool
osv. i referenstypade variabler. När en värdetypsvariabel är "boxad" omsluts den i enSystem.Object
, som lagras på den hanterade heapen. Minnet allokeras och så småningom när det tas bort måste det bearbetas av skräpinsamlaren. Dessa allokeringar och frigöringar medför en prestandakostnad och i många scenarier är de onödiga eller kan enkelt ersättas av ett billigare alternativ.För att undvika boxning måste du se till att variabler, fält och egenskaper som du lagrar numeriska typer och structs i (inklusive
Nullable<T>
) är starkt inskrivna som specifika typer somint
,float?
ellerMyStruct
, i stället för att använda objekt. Om du placerar dessa objekt i en lista bör du använda en starkt skriven lista, till exempelList<int>
i stället förList<object>
ellerArrayList
.Exempel på boxning i C#
// boolean value type is boxed into object boxedMyVar on the heap bool myVar = true; object boxedMyVar = myVar;
Upprepande kodsökvägar
Alla upprepande Unity-återanropsfunktioner (t.ex. uppdatering) som körs många gånger per sekund och/eller ram bör skrivas noggrant. Eventuella dyra åtgärder här kommer att ha en enorm och konsekvent inverkan på prestandan.
Tomma återanropsfunktioner
Även om koden nedan kan verka oskyldig att lämna i ditt program, särskilt eftersom varje Unity-skript initieras automatiskt med en uppdateringsmetod, kan dessa tomma återanrop bli dyra. Unity fungerar fram och tillbaka mellan en ohanterad och hanterad kodgräns, mellan UnityEngine-koden och programkoden. Kontextväxling över den här bron är ganska dyrt, även om det inte finns något att köra. Detta blir särskilt problematiskt om din app har 100-talet GameObjects med komponenter som har tomma upprepade Unity-återanrop.
void Update() { }
Kommentar
Update() är den vanligaste manifestationen av det här prestandaproblemet, men andra upprepade Unity-återanrop, till exempel följande kan vara lika dåliga, om inte värre: FixedUpdate(), LateUpdate(), OnPostRender", OnPreRender(), OnRenderImage() osv.
Åtgärder för att gynna körning en gång per bildruta
Följande Unity-API:er är vanliga åtgärder för många Holographic Apps. Även om det inte alltid är möjligt kan resultaten från dessa funktioner ofta beräknas en gång och resultaten återanvändas i hela programmet för en viss ram.
a) Det är bra att ha en dedikerad Singleton-klass eller -tjänst för att hantera din blick Raycast in i scenen och sedan återanvända detta resultat i alla andra scenkomponenter, istället för att göra upprepade och identiska Raycast-åtgärder av varje komponent. Vissa program kan kräva raycasts från olika ursprung eller mot olika LayerMasks.
UnityEngine.Physics.Raycast() UnityEngine.Physics.RaycastAll()
b) Undvik GetComponent()-åtgärder i upprepade Unity-återanrop som Update() genom att cachelagra referenser i Start() eller Awake()
UnityEngine.Object.GetComponent()
c) Det är bra att instansiera alla objekt, om möjligt, vid initiering och använda objektpooler för att återvinna och återanvända GameObjects under hela körningen av ditt program
UnityEngine.Object.Instantiate()
Undvik gränssnitt och virtuella konstruktioner
Att anropa funktionsanrop via gränssnitt kontra direkta objekt eller anropa virtuella funktioner kan ofta vara mycket dyrare än att använda direkta konstruktioner eller direktfunktionsanrop. Om den virtuella funktionen eller gränssnittet inte behövs bör den tas bort. Prestandaträffen för dessa metoder är dock värd kompromissen om användningen av dem förenklar utvecklingssamarbete, kodläsbarhet och kodunderhållbarhet.
I allmänhet är rekommendationen att inte markera fält och funktioner som virtuella om det inte finns en tydlig förväntan på att den här medlemmen måste skrivas över. Man bör vara särskilt försiktig kring kodsökvägar med hög frekvens som kallas många gånger per bildruta eller till och med en gång per bildruta, till exempel en
UpdateUI()
metod.Undvik att skicka structs efter värde
Till skillnad från klasser är structs värdetyper och när de skickas direkt till en funktion kopieras deras innehåll till en nyskapad instans. Den här kopian lägger till CPU-kostnader samt ytterligare minne på stacken. För små structs är effekten minimal och därmed acceptabel. Men för funktioner som upprepade gånger anropas varje bildruta samt funktioner som tar stora structs, om möjligt ändra funktionsdefinitionen så att den skickas med referens. Läs mer här
Diverse
Fysik
a) I allmänhet är det enklaste sättet att förbättra fysiken att begränsa den tid som ägnas åt fysik eller antalet iterationer per sekund. Detta minskar simuleringsnoggrannheten. Se TimeManager i Unity
b) Typerna av kolliderare i Unity har vitt skilda prestandaegenskaper. I ordningen nedan visas de mest högpresterande kolliderarna till minst högpresterande kolliderare från vänster till höger. Det är viktigt att undvika Mesh Colliders, som är betydligt dyrare än de primitiva kolliderarna.
Sphere < Capsule < Box <<< Mesh (konvext) < nät (icke-konvext)
Mer information finns i Metodtips för Unity-fysik
Animationer
Inaktivera inaktiva animeringar genom att inaktivera Animator-komponenten (om du inaktiverar spelobjektet får du inte samma effekt). Undvik designmönster där en animatör sitter i en loop och anger ett värde till samma sak. Det finns betydande omkostnader för den här tekniken, utan att programmet påverkas. Mer information finns här.
Komplexa algoritmer
Om ditt program använder komplexa algoritmer som inverterade kinematik, sökvägssökning osv. kan du försöka hitta en enklare metod eller justera relevanta inställningar för deras prestanda
Prestandarekommendationer för CPU-till-GPU
I allmänhet beror cpu-till-GPU-prestanda på de anrop som skickas till grafikkortet. För att förbättra prestandan måste anrop göras strategiskt a) minskas eller b) omstruktureras för optimala resultat. Eftersom själva anropen är resursintensiva minskar det totala arbete som krävs om du minskar dem. Dessutom kräver tillståndsändringar mellan anrop kostsamma validerings- och översättningssteg i grafikdrivrutinen och därmed kan omstrukturering av programmets anrop för att begränsa tillståndsändringar (dvs. olika material osv.) öka prestandan.
Unity har en bra artikel som ger en översikt och går in på batchdragningsanrop för deras plattform.
Instansåtergivning med enkel passering
Med enkel passinstansåtergivning i Unity kan anrop för varje öga minskas till ett instansat anrop. På grund av cachesammansättning mellan två anrop finns det också en viss prestandaförbättring på GPU:n.
Så här aktiverar du den här funktionen i ditt Unity-projekt
- Öppna OpenXR Inställningar (gå till Redigera>Project Inställningar> XR Plugin Management>OpenXR).
- Välj Enkel direktinstans i listrutan Återgivningsläge.
Mer information om den här återgivningsmetoden finns i följande artiklar från Unity.
Kommentar
Ett vanligt problem med enkel passinstansåtergivning uppstår om utvecklare redan har befintliga anpassade skuggor som inte har skrivits för instancing. När du har aktiverat den här funktionen kan utvecklare märka att vissa GameObjects endast renderas i ett öga. Det beror på att de associerade anpassade skuggningarna inte har rätt egenskaper för instancing.
Statisk batchbearbetning
Unity kan batcha många statiska objekt för att minska anropen till GPU:n. Static Batching fungerar för de flesta renderarobjekt i Unity som 1) delar samma material och 2) markeras alla som statiska (Markera ett objekt i Unity och markera kryssrutan längst upp till höger i inspektören). GameObjects som markerats som Statisk kan inte flyttas under programmets körning. Statisk batchbearbetning kan därför vara svår att utnyttja på HoloLens där praktiskt taget alla objekt måste placeras, flyttas, skalas osv. För uppslukande headset kan statisk batchbearbetning avsevärt minska anropen och därmed förbättra prestandan.
Mer information finns i Static Batching under Draw Call Batching i Unity .
Dynamisk batchbearbetning
Eftersom det är problematiskt att markera objekt som statiska för HoloLens-utveckling kan dynamisk batchbearbetning vara ett bra verktyg för att kompensera för den saknade funktionen. Det kan också vara användbart på uppslukande headset också. Dynamisk batchbearbetning i Unity kan dock vara svår att aktivera eftersom GameObjects måste a) dela samma material och b) uppfylla en lång lista med andra kriterier.
Läs Dynamisk batchbearbetning under Batchbearbetning av anrop i Unity för den fullständiga listan. Vanligtvis blir GameObjects ogiltiga för batchbearbetning dynamiskt, eftersom de associerade nätdata inte får vara fler än 300 hörn.
Andra tekniker
Batchbearbetning kan bara ske om flera GameObjects kan dela samma material. Detta blockeras vanligtvis av behovet av att GameObjects har en unik struktur för respektive material. Det är vanligt att kombinera texturer till en enda stor struktur, en metod som kallas texturatlasering.
Dessutom är det bättre att kombinera nät i en GameObject där det är möjligt och rimligt. Varje renderare i Unity har sina associerade anrop jämfört med att skicka ett kombinerat nät under en renderare.
Kommentar
Om du ändrar egenskaperna för Renderer.material vid körning skapas en kopia av materialet och därmed kan batchbearbetningen brytas. Använd Renderer.sharedMaterial för att ändra egenskaper för delat material i GameObjects.
GPU-prestandarekommendationer
Läs mer om hur du optimerar grafikrendering i Unity
Bandbredds- och fyllningshastigheter
När du återger en ram på GPU:n är ett program antingen bundet av minnesbandbredd eller fyllningshastighet.
- Minnesbandbredd är frekvensen för läsningar och skrivningar som GPU:n kan göra från minnet
- I Unity ändrar du Texturkvalitet i Redigera>projekt Inställningar> Kvalitet Inställningar.
- Fyllningshastighet refererar till de bildpunkter som kan ritas per sekund av GPU:n.
- I Unity använder du egenskapen XR Inställningar.renderViewportScale.
Optimera delning av djupbuffert
Vi rekommenderar att du aktiverar djupbuffertdelning för att optimera för hologramstabilitet. När du aktiverar djupbaserad reprojektion i sen fas med den här inställningen rekommenderar vi att du väljer 16-bitars djupformat i stället för 24-bitars djupformat. 16-bitars djupbuffertar minskar drastiskt den bandbredd (och därmed ström) som är associerad med djupbufferttrafik. Detta kan vara en stor förbättring både när det gäller energiminskning och prestanda. Det finns dock två möjliga negativa resultat med hjälp av 16-bitars djupformat.
Z-Fighting
Den minskade djupområdesåtergivningen gör z-fighting mer sannolikt att inträffa med 16 bitar än 24-bitars. För att undvika dessa artefakter ändrar du de när-/fjärran klippplan som finns i Unity-kameran för att ta hänsyn till den lägre precisionen. För HoloLens-baserade program kan ett långt klippplan på 50 m i stället för Unity standard 1000 m i allmänhet eliminera alla z-fighting.
Inaktiverad stencilbuffert
När Unity skapar en återgivningsstruktur med 16-bitars djup skapas ingen stencilbuffert. Om du väljer 24-bitars djupformatet, enligt beskrivningen i Unity-dokumentationen, skapas en 24-bitars z-buffert och en 8-bitars stencilbuffert (om 32-bitars är tillämpligt på en enhet (till exempel HoloLens), vilket vanligtvis är fallet).
Undvik helskärmseffekter
Tekniker som körs på helskärmsläge kan vara dyra eftersom deras storleksordning är miljontals åtgärder varje bildruta. Vi rekommenderar att du undviker efterbearbetningseffekter som aliasskydd, blomning med mera.
Optimala belysningsinställningar
Global belysning i realtid i Unity kan ge enastående visuella resultat men omfattar dyra belysningsberäkningar. Vi rekommenderar att du inaktiverar global belysning i realtid för varje Unity-scenfil via Window>Rendering>Lighting Inställningar> Avmarkera global belysning i realtid.
Dessutom rekommenderar vi att du inaktiverar all skugggjutning eftersom dessa också lägger till dyra GPU-pass till en Unity-scen. Skuggor kan inaktiveras per ljus men kan också kontrolleras holistiskt via kvalitetsinställningar.
Redigera>Project Inställningar och välj sedan kategorin > Kvalitet Välj låg kvalitet för UWP-plattformen. Man kan också bara ange egenskapen Shadows till Inaktivera skuggor.
Vi rekommenderar att du använder bakad belysning med dina modeller i Unity.
Minska antalet polyer
Antalet polygoner minskas med antingen
- Ta bort objekt från en scen
- Decimering av tillgångar, vilket minskar antalet polygoner för ett givet nät
- Implementera ett LOD-system (Level of Detail) i ditt program, som återger fjärranslutna objekt med lägre polygonversion av samma geometri
Förstå skuggningar i Unity
En enkel uppskattning för att jämföra skuggningar i prestanda är att identifiera det genomsnittliga antalet åtgärder som varje kör vid körning. Detta kan enkelt göras i Unity.
Välj din skuggningstillgång eller välj ett material. I det övre högra hörnet i kontrollfönstret väljer du kugghjulsikonen följt av "Välj skuggning"
När skuggningstillgången är markerad väljer du knappen Kompilera och visa kod under kontrollfönstret
När du har kompilerats letar du efter statistikavsnittet i resultatet med antalet olika åtgärder för både hörn- och pixelskuggning (Obs! pixelskuggare kallas ofta även fragmentskuggor)
Optimera pixelskuggare
Om du tittar på de kompilerade statistikresultaten med hjälp av metoden ovan kör fragmentskuggningen vanligtvis fler åtgärder än hörnskuggningen i genomsnitt. Fragmentskuggaren, även känd som pixelskuggaren, körs per bildpunkt på skärmens utdata medan hörnskuggningen bara körs per hörn av alla nät som ritas till skärmen.
Därför har inte bara fragmentskuggare fler instruktioner än hörnskuggor på grund av alla belysningsberäkningar, fragmentskuggor körs nästan alltid på en större datamängd. Om skärmutdata till exempel är en bild på 2 000 gånger 2 000 kan fragmentskuggningen köras 2 000*2 000 = 4 000 000 gånger. Om du återger två ögon fördubblas det här antalet eftersom det finns två skärmar. Om ett program för mixad verklighet har flera pass, fullskärmseffekter efter bearbetning eller återgivning av flera nät till samma pixel, ökar det här antalet dramatiskt.
Därför kan en minskning av antalet åtgärder i fragmentskuggningen i allmänhet ge mycket större prestandavinster jämfört med optimeringar i hörnskuggningen.
Alternativ för Unity Standard-skuggning
I stället för att använda en fysiskt baserad rendering (PBR) eller en annan skuggning av hög kvalitet kan du titta på hur du använder en mer högpresterande och billigare skuggning. Mixed Reality Toolkit tillhandahåller standardskuggningen MRTK som har optimerats för projekt med mixad verklighet.
Unity tillhandahåller också ett oupplyst hörn, diffust och andra förenklade skuggningsalternativ som är snabbare jämfört med Unity Standard-skuggningen. Mer detaljerad information finns i Användning och prestanda för inbyggda skuggor .
Förinläsning av skuggning
Använd Shader-förinläsning och andra knep för att optimera skuggningstiden. I synnerhet innebär skuggningsförinläsning att du inte ser några problem på grund av körningsskuggningskompilering.
Begränsa övertrassering
I Unity kan man visa övertrassering för sin scen genom att växla ritningslägesmenyn i det övre vänstra hörnet i scenvyn och välja Övertrassering.
I allmänhet kan övertrassering minimeras genom gallring av objekt i förväg innan de skickas till GPU:n. Unity innehåller information om hur du implementerar Occlusion Culling för motorn.
Minnesrekommendationer
Överdriven minnesallokering och frigöringsåtgärder kan ha negativa effekter på ditt holografiska program, vilket resulterar i inkonsekventa prestanda, frusna ramar och annat skadligt beteende. Det är särskilt viktigt att förstå minnesöverväganden när du utvecklar i Unity eftersom minneshantering styrs av skräpinsamlaren.
Skräpinsamling
Holografiska appar förlorar bearbetningstiden till skräpinsamlaren (GC) när GC aktiveras för att analysera objekt som inte längre finns i omfånget under körningen och deras minne måste frigöras, så att det kan göras tillgängligt för återanvändning. Konstanta allokeringar och avallokeringar kräver vanligtvis att skräpinsamlaren körs oftare, vilket skadar prestanda och användarupplevelsen.
Unity har gett en utmärkt sida som i detalj förklarar hur skräpinsamlaren fungerar och tips för att skriva effektivare kod när det gäller minneshantering.
En av de vanligaste metoderna som leder till överdriven skräpinsamling är inte cachelagring av referenser till komponenter och klasser i Unity-utveckling. Referenser ska samlas in under Start() eller Awake() och återanvändas i senare funktioner som Update() eller LateUpdate().
Andra snabbtips:
- Använd klassen StringBuilder C# för att dynamiskt skapa komplexa strängar vid körning
- Ta bort anrop till Debug.Log() när de inte längre behövs, eftersom de fortfarande körs i alla versioner av en app
- Om din holografiska app vanligtvis kräver mycket minne kan du överväga att anropa System.GC.Collect() under inläsningsfaser, till exempel när du presenterar en inläsnings- eller övergångsskärm
Objektpooler
Objektpooler är en populär teknik för att minska kostnaden för kontinuerlig objektallokering och frigöring. Detta görs genom att allokera en stor pool med identiska objekt och återanvända inaktiva, tillgängliga instanser från den här poolen i stället för att ständigt skapa och förstöra objekt över tid. Objektpooler är bra för återanvändbara komponenter som har variabel livslängd under en app.
Startprestanda
Överväg att starta appen med en mindre scen och sedan använda SceneManager.LoadSceneAsync för att läsa in resten av scenen. På så sätt kan din app komma till ett interaktivt tillstånd så snabbt som möjligt. Det kan finnas en stor CPU-topp medan den nya scenen aktiveras och att allt renderat innehåll kan stamma eller koppla. Ett sätt att kringgå detta är att ställa in egenskapen AsyncOperation.allowSceneActivation på "false" på scenen som läses in, vänta tills scenen läses in, rensa skärmen till svart och sedan ställa in den på "true" för att slutföra scenaktiveringen.
Kom ihåg att medan startscenen läses in visas den holografiska välkomstskärmen för användaren.