Optimaliseringstips for Unity

Unity er en spillmotor som er populær ikke bare blant indie-utviklere, men også store selskaper.

Den har et brukervennlig grensesnitt, en kraftig gjengivelsespipeline, et brukervennlig komponentsystem, og til slutt støtter det et stort utvalg av plattformer.

Men med et brukervennlig grensesnitt er det enda enklere å overkomplisere spillet ditt (for eksempel ved å plassere mange unødvendige gjenstander osv.), så det er viktig å ha optimering i tankene under hele utviklingsforløpet.

Her er viktige tips for de tre hovedkategoriene (gjengivelse, skript, og lyd) som vil hjelpe du forbedrer ytelsen til spillet ditt:

Gjengivelse

Tips 1: Hold objektene med Renderer-komponenten uskalert

Uskalerte objekter er de som har en skala på (1, 1, 1). I så fall trenger ikke Unity å gjøre ytterligere beregninger for å reskalere objektet i hver ramme.

Eksempel: La oss si at du har en modell av et hus som er for stort eller for lite for ditt nivå. Den naturlige tingen å gjøre er å skalere det slik:

Endre størrelse på bygning

Mesteparten av tiden er det OK å skalere objektet i scenevisningen, men hvis du planlegger å ha mange dupliserte forekomster av det objektet, er det å foretrekke å endre skalaen i importinnstillingene.

Det første du må gjøre er å skalere modellen til den passer dine behov (f.eks. ble bygningen ovenfor skalert fra (1, 1, 1) til (0,49482, 0,49482, 0,49482)), og velg deretter modellen i prosjektet se og i Importinnstillinger merker du skaleringsfaktoren (vanligvis er det enten 1 eller 0.1).

Sett den nye verdien, som skal tilsvare standard skalafaktor multipliser med den nye skalaen (i mitt tilfelle er det 1 x 0,49482 = 0,49482), og trykk deretter på Bruk. Gå nå tilbake til modellen i scenevisningen og sett skalaen tilbake til (1, 1, 1).

Unity 3D-skalafaktorinnstillinger

Objektet er nå skalert slik du trenger, samtidig som standardskalaen (1, 1, 1) bevares.

Dette tipset er spesielt viktig for animerte objekter som bruker SkinnedMeshRenderer, da denne komponenten er dyrere å gjengi, og å ha en skala på (1, 1, 1) forenkler gjengivelsesprosessen.

Tips 2: Bruk så få lys som mulig

Det er 3 typer lys i Unity (retningslys, punktlys og spotlight). Når det gjelder ytelse, er retningsbestemt lys den billigste for gjengivelse, deretter Point, og til slutt Spotlight.

Vanligvis vil du ikke ha mer enn 1 retningslys per scene, og for punkt- og punktlys prøv å ha så få som mulig (eller ingen i det hele tatt).

Når det gjelder sanntidsskygger, mens det forbedrer det visuelle aspektet av spillet, har det en høyytelsesoverhead, så generelt er det bedre å deaktivere dem eller bake dem inn i lightmaps og lyssonder.

Tips 3: Bruk transparente shaders med forsiktighet

Bruk bare transparente eller partikkelskyggeleggere på overflater som må være gjennomsiktige (f.eks. gjerder, røykpartikler osv.)

Objekter med gjennomsiktighet krever et ekstra gjengivelsespass som kan redusere ytelsen, spesielt på plattformer med begrensede ressurser, for eksempel mobil eller nett.

Skripting

Tips 1: Bufre alltid komponentreferanser

Du bør alltid cache komponentreferanser hvis du planlegger å få tilgang til dem hver oppdatering.

Sjekk for eksempel skriptet nedenfor:

Dårlig

using UnityEngine;

public class Script1 : MonoBehaviour
{
    float someValue = 0;

    // Update is called once per frame
    void Update()
    {
        someValue = GetComponent<Script2>().someValue2;
    }
}

Her har vi Script1 som henter variabelen "someValue2" fra Script2 og tilordner den til en lokal variabel.

Nå vil det ikke ha noen innvirkning på ytelsen å kalle én GetComponent hver ramme, men du bør ta en vane med å bufre komponentene som vil bli brukt ofte.

Det er to måter å bufre en komponent i et skript, enten opprette en offentlig variabel og tilordne den i inspektørvisning, eller opprette en privat variabel og tilordne den fra Start eller Awake. Sjekk eksempelet nedenfor:

Flink

using UnityEngine;

public class Script1 : MonoBehaviour
{

    float someValue = 0;

    Script2 script2Cached;

    // Use this for initialization
    void Start()
    {
        script2Cached = GetComponent<Script2>();
    }

    // Update is called once per frame
    void Update()
    {
        someValue = script2Cached.someValue2;
    }
}

Mye bedre, Script2 kan nå få tilgang til hver oppdatering uten ytelsesoverhead.

Gjør det samme for innebygde komponenter, som BoxCollider, Rigidbody, etc. (bortsett fra Transform og GameObject, de er allerede bufret som standard slik at du kan få tilgang til dem med en gang).

Tips 2: Bruk SendMessage med forsiktighet

SendMessage lar deg kalle en spesifikk funksjon (hvis den finnes) på hver MonoBehaviour som er knyttet til et spillobjekt.

For eksempel, når du skyter et våpen i spillet kan du raskt påføre skade når kulen treffer fienden, uten at du trenger å bruke GetComponent og andre ekstra ting.

Denne metoden bør imidlertid ikke kalles for ofte siden den er ganske datakrevende.

Tips 3: Bruk GameObject.Find og GameObject.FindWithTag med forsiktighet

GameObject.Find, GameObject.FindWithTag og GameObject.FindGameObjectsWithTag lar deg raskt søke etter objektene i scenen. Disse metodene er mye tregere enn GetComponent og bør bare brukes under initialisering.

Tips 4: Unngå å bruke OnGUI

Historisk sett var OnGUI den eneste måten å lage menyer i Unity. Men siden den gang ble det lagt til et alternativ kalt UI Canvas som er mye bedre når det gjelder ytelse og tilbyr mye mer funksjonalitet.

Likevel er OnGUI fortsatt en levedyktig måte å lage brukergrensesnitt på i Unity, og hvis du absolutt trenger å bruke det, husk at OnGUI kalles minst to ganger per frame (dobbelt så mye som Update og LateUpdate ) så ikke bruk den til noen beregninger i tillegg til brukergrensesnittet.

En ting du kan gjøre er å ha et eget skript som kun har OnGUI i seg og aktivere/deaktivere det når det trengs.

For eksempel:

UIScript.cs

using UnityEngine;

public class UIScript : MonoBehaviour {

    void OnGUI()
    {
        if(GUI.Button(new Rect(5, 5, 125, 25), "Button 1"))
        {
            //Button 1 was pressed, Do Something
        }
        if (GUI.Button(new Rect(140, 5, 125, 25), "Button 2"))
        {
            //Button 2 was pressed, Do Something
        }
    }
}

Script1.cs

using UnityEngine;

public class Script1 : MonoBehaviour
{

    UIScript uiScript;

    // Use this for initialization
    void Start()
    {
        uiScript = GetComponent<UIScript>();
        uiScript.enabled = false;
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Tab))
        {
            //toggle UIScript when Tab is pressed
            uiScript.enabled = !uiScript.enabled;
        }
    }
}

Både UIScript og Script1 er knyttet til det samme GameObject. Script1 kontrollerer når menyen skal vises.

Når spilleren trykker på Tab, er UIScript aktivert, og viser knappene. Hvis du trykker på Tab igjen, deaktiveres den, og knappene skjules.

Mens UIScript er deaktivert, kalles ikke OnGUI-metoden, noe som igjen forbedrer ytelsen.

Tips 5: Bruk Profiler

Profiler er et av de viktigste verktøyene når det gjelder å identifisere flaskehalser og fps-fall, noe som gjør det lettere å finne den eksakte årsaken til den lave ytelsen.

Lyd

Lydklipp kan optimaliseres ved å sørge for at importinnstillingene deres er riktige.

Optimale Innstillinger for lydimport vil avhenge av lydlengden, avspillingsfrekvensen og målplattformen.