Optimeringstips för enhet

Unity är en spelmotor som är populär inte bara bland indieutvecklare utan även hos stora företag.

Den har ett användarvänligt gränssnitt, en kraftfull renderingspipeline, ett lättanvänt komponentsystem, och slutligen stöder det ett stort antal plattformar.

Men med ett lättanvänt gränssnitt är det ännu lättare att överkomplicera ditt spel (till exempel genom att placera en massa onödiga föremål etc.), så det är viktigt att ha optimering i åtanke under hela utvecklingsförloppet.

Här är viktiga tips för de tre huvudkategorierna (Rendering, Scripting, och Audio) som hjälper dig att förbättra ditt spels prestanda:

Tolkning

Tips 1: Behåll objekten med Renderer-komponenten oskalade

Oskalade objekt är de som har en skala på (1, 1, 1). I så fall behöver Unity inte göra ytterligare beräkningar för att skala om objektet i varje bildruta.

Exempel: Låt oss säga att du har en modell av ett hus som är för stort eller för litet för din nivå. Det naturliga att göra är att skala det så här:

Ändra storlek på byggnad

För det mesta är det ok att skala objektet i scenvyn, men om du planerar att ha många duplicerade instanser av det objektet är det bättre att ändra skalan i importinställningarna.

Det första du behöver göra är att skala modellen tills den passar dina behov (t.ex. byggnaden ovan skalades från (1, 1, 1) till (0,49482, 0,49482, 0,49482)), välj sedan modellen i projektet visa och i importinställningarna notera skalfaktorn (vanligtvis är det antingen 1 eller 0,1).

Ställ in det nya värdet, som ska vara lika med standardskalfaktorn multiplicera med den nya skalan (i mitt fall är det 1 x 0,49482 = 0,49482), tryck sedan på Använd. Gå nu tillbaka till modellen i scenvyn och ställ tillbaka skalan till (1, 1, 1).

Unity 3D Skalfaktorinställningar

Objektet skalas nu som du behöver samtidigt som standardskalan (1, 1, 1) bevaras.

Det här tipset är särskilt viktigt för animerade objekt som använder SkinnedMeshRenderer eftersom denna komponent är dyrare att rendera och att ha en skala på (1, 1, 1) förenklar renderingsprocessen.

Tips 2: Använd så få lampor som möjligt

Det finns 3 typer av ljus i Unity (Riktningsljus, Punktljus och Spotlight). När det gäller prestanda Riktningsljus är det billigaste för rendering, sedan Point och slutligen Spotlight.

Generellt sett vill du inte ha mer än 1 riktat ljus per scen, och för punkt- och punktljus försök att ha så få som möjligt (eller inga alls).

När det gäller skuggor i realtid, medan det förbättrar den visuella aspekten av spelet, har det en högpresterande overhead så generellt är det bättre att inaktivera dem eller baka in dem i lightmaps och light sonder.

Tips 3: Använd Transparent Shaders med försiktighet

Använd endast transparenta eller partikelskuggare på ytor som behöver vara genomskinliga (t.ex. staket, rökpartiklar, etc.)

Objekt med transparens kräver ett extra renderingspass som kan minska prestandan, särskilt på plattformar med begränsade resurser, som mobil eller webb.

Skript

Tips 1: Cache alltid komponentreferenser

Du bör alltid cache komponentreferenser om du planerar att komma åt dem varje uppdatering.

Kontrollera till exempel skriptet nedan:

Dålig

using UnityEngine;

public class Script1 : MonoBehaviour
{
    float someValue = 0;

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

Här har vi Script1 som får variabeln "someValue2" från Script2 och tilldelar den till en lokal variabel.

Att anropa bara en GetComponent varje bildruta kommer nu inte att ha någon inverkan på prestandan, men du bör ta för vana att cachelagra komponenterna som kommer att användas ofta.

Det finns två sätt att cachelagra en komponent i ett skript, antingen skapa en offentlig variabel och tilldela den i inspektörsvyn, eller skapa en privat variabel och tilldela den från Start eller Awake. Kontrollera exemplet nedan:

Bra

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;
    }
}

Mycket bättre, Script2 kan nu nås varje uppdatering utan prestandakostnader.

Gör samma sak för inbyggda komponenter, som BoxCollider, Rigidbody, etc. (förutom Transform och GameObject, de är redan cachade som standard så att du kan komma åt dem direkt).

Tips 2: Använd SendMessage med försiktighet

SendMessage låter dig anropa en specifik funktion (om det finns) på varje MonoBehaviour som är kopplad till ett spelobjekt.

Till exempel, när du skjuter ett vapen i spelet kan du snabbt orsaka skada när kulan träffar fienden, utan att behöva använda GetComponent och andra extra grejer.

Den här metoden bör dock inte anropas för ofta eftersom den är ganska beräkningskrävande.

Tips 3: Använd GameObject.Find och GameObject.FindWithTag med försiktighet

GameObject.Find, GameObject.FindWithTag och GameObject.FindGameObjectsWithTag låter dig snabbt söka efter objekten i scenen. Dessa metoder är mycket långsammare än GetComponent och bör endast användas under initiering.

Tips 4: Undvik att använda OnGUI

Historiskt sett var OnGUI det enda sättet att skapa menyer i Unity. Men sedan dess har ett alternativ lagts till som heter UI Canvas som är mycket bättre när det gäller prestanda och erbjuder mycket mer funktionalitet.

Trots det är OnGUI fortfarande ett gångbart sätt att göra UI i Unity och om du absolut behöver använda det, kom ihåg att OnGUI anropas minst två gånger per bildruta (dubbelt så mycket som Update och LateUpdate) så gör inte det använd den för alla beräkningar förutom UI.

En sak du kan göra är att ha ett separat skript som bara har OnGUI i sig och aktivera/inaktivera det när det behövs.

Till exempel:

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 och Script1 är kopplade till samma GameObject. Script1 styr när menyn ska visas.

När spelaren trycker på Tab är UIScript aktiverat och visar knapparna. Om du trycker på Tab igen avaktiveras den, och knapparna döljs.

Medan UIScript är inaktiverat anropas inte OnGUI-metoden vilket i sin tur förbättrar prestandan.

Tips 5: Använd Profiler

Profiler är ett av de viktigaste verktygen när det gäller att identifiera flaskhalsar och fps-fall, vilket gör det lättare att hitta den exakta orsaken till den låga prestandan.

Audio

Ljudklipp kan optimeras genom att se till att deras importinställningar är korrekta.

Optimala Ljudimportinställningar beror på ljudlängden, uppspelningsfrekvensen och målplattformen.