Should unity export WebGL versions?

Optimer din Unity WebGL-oplevelse

10/10/2024

Rating: 4.3 (5949 votes)
Indholdsfortegnelse

Unity WebGL: Optimering af Hukommelse og Ydeevne

Mange udviklere har med succes taget springet og eksporteret WebGL-versioner af deres spil ved hjælp af Unity. Desværre støder mange også på problemer, der kan føre til nedsat ydeevne og ustabilitet, især på ældre maskiner med begrænsede ressourcer. Denne artikel vil dykke ned i flere teknikker til at løse almindelige WebGL-ydelsesproblemer, som vi har observeret med spil udgivet på platforme som Kongregate. Målet er at give dig en god start på at levere en fantastisk, plugin-fri oplevelse med dit WebGL-spil.

Should unity export WebGL versions?
Many Unity developers have taken the plunge and started exporting WebGL versions of their games. Unfortunately, many of them also run into issues that can lead to performance degradation and instability. This is a particularly tricky problem on older machines that have less resources available.

Forståelse af Hukommelsesallokering

En af de mest almindelige fejl, udviklere begår, når de forsøger at optimere deres indhold, er at antage, hvad der optager meget tid eller plads. Med Unity og WebGL sker dette ofte, når man beslutter, hvor meget heap-plads der skal allokeres til WebGL-applikationen i spillerindstillingerne. Uden research kan man nemt antage, at øget hukommelse vil føre til bedre ydeevne. I virkeligheden ønsker man generelt at allokere den mindst mulige mængde hukommelse, hvilket kan virke kontraintuitivt.

At reducere størrelsen på heapen kan i høj grad reducere eller eliminere antallet af "Browseren kunne ikke allokere nok hukommelse til WebGL-indholdet"-fejl, som dine spillere ser. Men hvordan ved du, hvad du skal indstille den til? Heldigvis kan du få en god fornemmelse af, hvor meget hukommelse din applikation bruger, med et simpelt JavaScript-snippet. Dette kan enten indsættes i browserkonsollen (til ad-hoc fejlfinding) eller som en permanent tilføjelse til din index.html-skabelon:

setInterval(function() { if (typeof TOTAL_MEMORY !== 'undefined') { try { var totalMem = TOTAL_MEMORY/1024.0/1024.0; var usedMem = (TOTAL_STACK + (STATICTOP - STATIC_BASE) + (DYNAMICTOP - DYNAMIC_BASE))/1024.0/1024.0; console.log('Memory stats - used: ' + Math.ceil(usedMem) + 'M' + ' free: ' + Math.floor(totalMem - usedMem) + 'M'); } catch(e) {} } }, 5000); 

Dette vil outputte mængden af brugt og ledig hukommelse i konsollen hvert 5. sekund, f.eks.: Memory stats - used: 155M free: 37M. Med denne simple tilføjelse får du indsigt i, hvordan du kan tune din heap-størrelse. Du kan observere disse tal, mens du spiller dit spil, og få en fornemmelse af, hvad du skal begrænse dit hukommelsesforbrug til. Vær dog forsigtig med ikke at sænke den for meget, da du ellers vil begynde at se hukommelsesallokeringsfejl, der beder dig om at øge din heap-størrelse.

En Note om Dynamisk Hukommelsesvækst

Når du søger efter løsninger på problemer med hukommelsesmangel, kan du støde på en Emscripten-flag kaldet ALLOW_MEMORY_GROWTH. Dette lyder som den perfekte løsning på dine problemer. I dag kan aktivering af dette flag have en negativ indvirkning på ydeevnen og kan også forårsage problemer med hukommelsesmangel, da hukommelsesmanageren skal allokere endnu mere plads, når den forsøger at udvide heapen. Unity-teamet har aldrig anbefalet at aktivere dette flag, og vi anbefaler det heller ikke.

Udglatning af Indledende Indlæsning

Når du bruger Unity 5.3 og nyere, vil dine spilaktiver som standard blive komprimeret med gzip og have et gz-præfiks på filnavnene. Som beskrevet i et tidligere WebGL-blogindlæg, hvis du uploader disse til Kongregate, vil vi automatisk sætte Content-Encoding: gzip-headeren, så aktiverne kan dekomprimeres af browseren i stedet for JavaScript, hvilket fører til en meget bedre indlæringsoplevelse.

Hvis du hoster dit spil eksternt, skal du dog manuelt sikre dig, at aktiverne serveres med den korrekte kodning. Du vil vide, om dette er et problem, hvis Unity logger beskeder som Decompressed Release/MyGame-WebGL.jsgz in 500ms i konsollen, browseren kan se ud til at fryse under indlæsning, og din statuslinje ikke fungerer korrekt.

Hvis du bruger Apache eller en kompatibel server, kan du bruge .htaccess-filen, som Unity genererer for dig, til at løse dette problem. Hvis du hoster på S3 eller lignende, kan du tvinge kodningen ved at ændre filnavnene i din index.html for at tilføje gz-suffikset, som følger:

var Module = { TOTAL_MEMORY: 201326592, errorhandler: null, compatibilitycheck: null, dataUrl: "Release/MyGame-WebGL.datagz", codeUrl: "Release/MyGame-WebGL.jsgz", memUrl: "Release/MyGame-WebGL.memgz", }; 

Du skal også sikre dig, at S3 er konfigureret til at sende Content-Encoding: gzip-headeren for hver fil, der slutter med gz, ellers får du dekomprimeringsfejl under indlæsning af spillet. Du kan bruge browserens netværksinspektor til at sikre, at headeren bliver sendt korrekt af serveren.

Optimering af Aktiver Indlæsning

En anden uventet kilde til ydelsesproblemer er indlæsning af asset bundles. For Unity-versioner lavere end 5.5 komprimeres asset bundles som standard med LZMA. Dekomprimering af LZMA-indholdet for WebGL-builds forårsager en meget mærkbar pause. Disse pauser får ikke kun dit spil til at køre dårligt, men kan også udløse den frygtede dialogboks "Dette indhold reagerer ikke". Heldigvis understøtter Unity 5.3 og nyere det hurtigere LZ4-format til asset bundles (og det er standard for WebGL i 5.5+), så du kan løse dette problem relativt nemt.

Det skal bemærkes, at LZ4-aktiver kan være lidt større end LZMA, men afvejningen er generelt acceptabel. Hvis det ikke er tilfældet, kan du bruge gzip-komprimering oven på asset bundles og servere dem med Content-Encoding: gzip-headeren (som nævnt ovenfor) for at få browseren til at dekomprimere dem automatisk.

En af vores udviklere var venlig nok til at dele C#-koden, de bruger i deres build-script til at håndhæve LZ4-komprimering for WebGL:

BuildAssetBundleOptions options = (buildTarget == BuildTarget.WebGL) ? BuildAssetBundleOptions.ChunkBasedCompression : BuildAssetBundleOptions.None; BuildPipeline.BuildAssetBundles(bundlePath, buildMap, options, buildTarget); 

Hold dig Opdateret på Unity Patch-udgivelser

Unity-teamet udgiver hyppigt patches til understøttede versioner af Unity. Hold øje med dem og se, om eventuelle WebGL-relaterede ændringer kan løse problemer, du oplever. For eksempel løste Unity 5.3.6 patch 6 et problem, hvor WebGL-builds allokerede meget mere hukommelse end nødvendigt, hvilket absolut er en fejl, du vil have rettet, når du bygger dit spil. Hvis opgradering ikke er en levedygtig mulighed, dækker de generelt også med workarounds. I dette tilfælde kan du reducere dit fodaftryk på lavere versioner med følgende build-indstilling:

PlayerSettings.SetPropertyString("emscriptenArgs", " -s MEMFS_APPEND_TO_TYPED_ARRAYS=1", BuildTargetGroup.WebGL); 

Opsummering

Optimering af WebGL-builds i Unity kræver en nuanceret tilgang. Ved at forstå hukommelsesallokering, korrekt håndtering af komprimering og ved at holde sig opdateret med Unitys patches, kan udviklere markant forbedre ydeevnen og stabiliteten af deres browserbaserede spil. Fokuser på at minimere heap-størrelsen, sikre korrekt serverkonfiguration for gzip-komprimering og udnytte LZ4 til asset bundles for at opnå den bedste brugeroplevelse.

Ofte Stillede Spørgsmål (FAQ)

Hvorfor er min WebGL-applikation langsom?
Langsom ydeevne kan skyldes flere faktorer, herunder utilstrækkelig hukommelsesallokering, ineffektiv asset-håndtering (f.eks. brug af LZMA i stedet for LZ4) eller problemer med serverkonfigurationen for komprimerede filer.
Hvordan kan jeg tjekke hukommelsesforbruget i mit WebGL-spil?
Du kan bruge et simpelt JavaScript-snippet, der logger hukommelsesstatistikken til browserkonsollen regelmæssigt, som vist i artiklen.
Skal jeg bruge ALLOW_MEMORY_GROWTH?
Nej, det anbefales generelt ikke, da det kan forringe ydeevnen og føre til hukommelsesproblemer.
Hvordan sikrer jeg, at mine gzip-komprimerede filer indlæses korrekt?
Sørg for, at din server sender Content-Encoding: gzip-headeren for alle filer med .gz-suffikset. Hvis du bruger Unitys standardeksport, kan du ofte udnytte den medfølgende .htaccess-fil eller manuelt tilpasse filnavne og serverkonfiguration.
Hvad er forskellen på LZMA og LZ4 for asset bundles?
LZ4 er en hurtigere komprimeringsalgoritme for asset bundles, der resulterer i kortere indlæsningstider og færre pauser under spillet sammenlignet med LZMA, især i WebGL-builds.

Hvis du vil læse andre artikler, der ligner Optimer din Unity WebGL-oplevelse, kan du besøge kategorien Teknologi.

Go up