Dies ist der erste Teil einer Reihe von Artikeln, die Tipps zur Optimierung Ihrer Unity-Projekte enthalten. Verwenden Sie sie als Leitfaden für die Ausführung mit höheren Bildraten und weniger Ressourcen. Wenn Sie diese bewährten Verfahren ausprobiert haben, sollten Sie sich die anderen Seiten dieser Reihe ansehen:
- Leistungsoptimierung für High-End-Grafiken
- Verwaltung der GPU-Nutzung für PC- und Konsolenspiele
- Fortgeschrittene Programmierung und Code-Architektur
- Verbesserte Physikleistung für flüssiges Gameplay
Die Asset-Pipeline kann die Produktivität Ihres Teams und die Leistung Ihres Spiels drastisch beeinflussen. Durch die Zusammenarbeit mit einem erfahrenen technischen Künstler wird Ihr Team in die Lage versetzt, Asset-Formate und Spezifikationen für reibungslose Prozesse zu definieren und durchzusetzen.
Verlassen Sie sich nicht auf die Standardeinstellungen. Verwenden Sie die plattformspezifische Registerkarte Override, um Assets wie Texturen und Mesh-Geometrie zu optimieren. Falsche Einstellungen können zu größeren Build-Größen, längeren Build-Zeiten und schlechter GPU-Leistung und Speichernutzung führen. Verwenden Sie die Funktion Voreinstellungen, um die Grundeinstellungen für Ihr Projekt weiter anzupassen.
In diesem Leitfaden finden Sie bewährte Verfahren für die Arbeit mit Kunstwerken. Eine Anleitung speziell für mobile Geräte finden Sie im Unity Learn-Kurs zur Optimierung von 3D-Grafiken für mobile Anwendungen.
Deaktivieren Sie in den Player-Einstellungen die automatische Grafik-API und entfernen Sie zusätzliche Grafik-APIs, die Sie für die einzelnen Zielplattformen nicht unterstützen möchten. Dies kann die Erzeugung von übermäßigen Shader-Varianten verhindern. Deaktivieren Sie die Einstellung Zielarchitekturen für ältere CPUs, wenn Ihre Anwendung diese nicht unterstützt.
Erfahren Sie mehr über die Grafik-API.
Der Wechsel des Skripting-Backends von Mono zu IL2CPP (Intermediate Language to C++) kann zu einer insgesamt besseren Laufzeitleistung führen. Allerdings können sich dadurch auch die Bauzeiten verlängern. Einige Entwickler ziehen es vor, Mono lokal zu verwenden, um schneller zu iterieren, und wechseln dann zu IL2CPP für Buildmaschinen und/oder Release Candidates. Weitere Informationen zur Verkürzung der Erstellungszeiten finden Sie in der Dokumentation Optimizing IL2CPP build times.
Hinweis Mit dieser Option konvertiert Unity ILcode aus Skripten und Assemblies nach C++, bevor eine native Binärdatei (.exe, .apk, .xap) für Ihre Zielplattform erstellt wird.
Wie sich die verschiedenen Compiler-Optionen auf die Laufzeitleistung auswirken, erfahren Sie in der Einführung in die IL2CPP-Interna oder auf der Handbuchseite zu den Compiler-Optionen.
Bei mobilen Projekten müssen die Bildwiederholraten mit der Akkulaufzeit und der thermischen Drosselung in Einklang gebracht werden. Denken Sie an die Bilder pro Sekunde (fps).
Anstatt Ihr Gerät mit 60 fps auszureizen, sollten Sie als Kompromiss 30 fps wählen. Beachten Sie, dass Unity bereits standardmäßig 30 fps für mobile Geräte verwendet.
Sie können die Bildrate auch dynamisch während der Laufzeit mit Application.targetFrameRate anpassen. So können Sie z. B. bei langsamen oder relativ statischen Szenen (z. B. Menüs) unter 30 fps gehen und höhere fps-Einstellungen für das Spiel reservieren.
Mobile Plattformen können keine Halbbilder darstellen. Selbst wenn Sie Vsync im Editor deaktivieren(Projekteinstellungen > Qualität), ist es auf der Hardware-Ebene immer noch aktiviert. Wenn der Grafikprozessor nicht schnell genug aktualisieren kann, wird das aktuelle Bild gehalten, was zu einer Verringerung der Bildrate führt.
Weitere Informationen finden Sie in der Dokumentation.
Unity fragt den Beschleunigungsmesser Ihres Handys mehrmals pro Sekunde ab. Deaktivieren Sie sie, wenn sie in Ihrer Anwendung nicht verwendet wird, oder verringern Sie ihre Häufigkeit, um die Leistung zu verbessern.
Erfahren Sie mehr über den Beschleunigungsmesser.
Teilen Sie Ihre Hierarchien auf. Wenn Ihre GameObjects nicht in der Hierarchie verschachtelt sein müssen, vereinfachen Sie das Parenting.
Kleinere Hierarchien profitieren vom Multithreading, um die Transformationen in Ihrer Szene zu aktualisieren. Komplexe Hierarchien verursachen unnötige Transform-Berechnungen und Kosten für die Garbage Collection (GC).
Siehe Optimierung der Hierarchie und diesen Unite-Vortrag für Tipps zu Transformationen.
Die beiden obigen Beispiele verwenden dasselbe Modell und dieselbe Textur - dennoch verbrauchen die oberen Einstellungen mehr als das Fünffache an Speicherplatz im Vergleich zu den unteren, ohne dass die visuelle Qualität wesentlich besser wäre.
Die Texturkomprimierung bietet bei korrekter Anwendung erhebliche Leistungsvorteile, wie z. B. schnellere Ladezeiten, einen geringeren Speicherbedarf und eine deutlich höhere Rendering-Leistung. Komprimierte Texturen benötigen nur einen Bruchteil der Speicherbandbreite, die für unkomprimierte 32-Bit-RGBA-Texturen benötigt wird.
Siehe diese empfohlene Liste von Texturkompressionsformaten für Zielplattformen.
Texturen können übermäßig viele Ressourcen verbrauchen, daher ist es wichtig, die Importeinstellungen zu optimieren. Versuchen Sie im Allgemeinen, diese Leitlinien zu befolgen:
- Verringern Sie die maximale Größe: Verwenden Sie die minimalen Einstellungen, die zu visuell akzeptablen Ergebnissen führen. Dies ist nicht destruktiv und kann den Texturspeicher schnell reduzieren.
- Verwenden Sie Zweierpotenzen (POT): Unity erfordert POT-Texturabmessungen für Texturkomprimierungsformate.
- Schalten Sie die Option "Lesen/Schreiben aktiviert" aus: Wenn diese Option aktiviert ist, wird eine Kopie sowohl im CPU- als auch im GPU-adressierbaren Speicher erstellt, wodurch sich der Speicherbedarf der Textur verdoppelt. Deaktivieren Sie es in den meisten Fällen und aktivieren Sie es nur, wenn Sie zur Laufzeit eine Textur erzeugen, die Sie überschreiben müssen. Sie können diese Option auch über Texture2D.Apply erzwingen, indem Sie makeNoLongerReadable auf True setzen.
- Deaktivieren Sie unnötige Mip-Maps: Mip-Maps werden nicht für Texturen benötigt, die auf dem Bildschirm eine gleichbleibende Größe haben, wie z. B. 2D-Sprites und UI-Grafiken. Lassen Sie jedoch Mip-Maps für 3D-Modelle aktiviert, deren Abstand zur Kamera variiert.
Erfahren Sie mehr über Texturimport-Einstellungen.
Beim Atlasing werden mehrere kleinere Texturen zu einer einzigen größeren Textur zusammengefasst. Texturatlanten reduzieren die Speichernutzung und erfordern weniger Zeichenaufrufe, wodurch der Aufwand für die GPU sinkt.
- Für 2D-Projekte: Verwenden Sie einen Sprite-Atlas(Asset > Erstellen > 2D > Sprite Atlas), anstatt einzelne Sprites oder Texturen zu rendern.
- Für 3D-Projekte: Sie können ein DCC-Paket ( Digital Content Creation ) Ihrer Wahl verwenden. Verschiedene Tools von Drittanbietern wie MA_TextureAtlasser oder TexturePacker können ebenfalls zur Erstellung von Texturatlanten verwendet werden.
Kombinieren Sie Texturen und remappen Sie UVs für jede 3D-Geometrie, die keine hochauflösenden Maps benötigt. Ein visueller Editor gibt Ihnen die Möglichkeit, die Größen und Positionen im Texturatlas oder Sprite Sheet festzulegen und zu priorisieren.
Der Texture Packer fasst die einzelnen Maps zu einer großen Textur zusammen. Unity kann dann mit einem einzigen Draw-Aufruf auf die gepackten Texturen zugreifen, was zu einem geringeren Performance-Overhead führt.
Lesen Sie hier mehr über Sprite Atlanten.
Hochauflösende Modelle erfordern mehr Speicherplatz und potenziell mehr Arbeit für die GPU. Versuchen Sie daher, die geometrische Komplexität der GameObjects in Ihren Szenen auf ein Minimum zu beschränken. Andernfalls muss Unity erhebliche Vertex-Daten an die Grafikkarte übertragen.
Am besten schneiden Sie die Modelle in Ihrer DCC-Software zurecht und löschen die aus Sicht der Kamera nicht sichtbaren Polygone. Wenn Sie zum Beispiel nie die Rückseite eines Schranks sehen, der an einer Wand steht, sollte das Modell dort keine Flächen haben.
Beachten Sie, dass auf modernen GPUs der Engpass in der Regel mit der Polygondichte und nicht mit der Polygonanzahl zusammenhängt. Versuchen Sie, einen Art-Pass über alle Assets durchzuführen, um die Polygonanzahl von weit entfernten Objekten zu reduzieren. Mikrodreiecke können eine wesentliche Ursache für schlechte GPU-Leistung sein.
Je nach Zielplattform sollten Sie darüber nachdenken, Details über hochauflösende Texturen hinzuzufügen, um die Low-Poly-Geometrie auszugleichen. Verwenden Sie Texturen und Normal Maps, anstatt die Dichte des Meshes zu erhöhen. Reduzieren Sie die Pixelkomplexität, indem Sie so viele Details wie möglich in die Texturen einbauen. So können Sie beispielsweise die Glanzlichter in der Textur selbst erfassen, um die Berechnung der Glanzlichter im Fragment-Shader zu vermeiden.
Seien Sie aufmerksam und denken Sie daran, regelmäßig ein Profil zu erstellen. Schließlich beeinträchtigen diese Techniken die Leistung und sind möglicherweise nicht für Ihre Zielplattform geeignet.
Ähnlich wie Texturen können auch Meshes zu viel Speicherplatz verbrauchen, wenn sie nicht sorgfältig importiert werden. Probieren Sie diese Tipps aus, um den Speicherverbrauch Ihrer Meshes zu minimieren:
- Mesh-Kompression: Die Mesh-Komprimierung kann den Speicherplatz auf der Festplatte verringern (der Speicher zur Laufzeit ist davon jedoch nicht betroffen). Gleichzeitig kann die Quantisierung des Netzes zu Ungenauigkeiten führen. Experimentieren Sie daher mit den Komprimierungsstufen, um herauszufinden, welche für Ihre Modelle geeignet sind.
- Lesen/Schreiben deaktivieren: Wenn Sie diese Option aktivieren, wird das Mesh im Speicher dupliziert, so dass sich eine Kopie des Mesh im Systemspeicher und eine weitere im GPU-Speicher befindet. In den meisten Fällen sollten Sie diese Funktion deaktivieren. In Unity 2019.2 und früher ist diese Option standardmäßig aktiviert.
- Deaktivieren Sie Rigs und Mischformen: Wenn Ihr Netz keine Skelett- oder Blendform-Animation benötigt, deaktivieren Sie diese Optionen.
- Normalen und Tangenten deaktivieren: Wenn Sie absolut sicher sind, dass das Material des Netzes keine Normalen oder Tangenten benötigt, deaktivieren Sie diese Optionen, um zusätzliche Einsparungen zu erzielen.
Weitere Optionen zur Optimierung des Netzes sind in den Player-Einstellungen verfügbar:
- Vertex-Komprimierung stellt die Vertex-Komprimierung für jeden Kanal ein. Sie können zum Beispiel die Komprimierung für alles außer Positionen und Lightmap-UVs aktivieren. Dies kann den Speicherverbrauch Ihrer Meshes während der Laufzeit reduzieren.
- Hinweis Die Einstellung für die Netzkomprimierung in den Importeinstellungen jedes Netzes hat Vorrang vor der Einstellung für die Vertexkomprimierung. In diesem Fall ist die Laufzeitkopie des Netzes unkomprimiert und verbraucht möglicherweise mehr Speicher.
- Mesh-Daten optimieren entfernt alle Daten aus Meshes, die für das auf sie angewendete Material nicht erforderlich sind (z. B. Tangenten, Normalen, Farben und UVs).
Durch die Automatisierung des Prüfungsprozesses können Sie vermeiden, dass Sie versehentlich Asset-Einstellungen ändern. Der AssetPostProcessor kann Ihnen helfen, Ihre Importeinstellungen zu standardisieren oder vorhandene Assets zu analysieren. Sie ermöglicht die Ausführung von Skripten beim Import von Assets und fordert Sie im Wesentlichen auf, die Einstellungen vor und/oder nach dem Import von Modellen, Texturen, Audio und mehr anzupassen.
Lesen Sie mehr über Asset Auditing im Leitfaden Optimierung verstehen.
Unity verwendet einen Ringbuffer, um Texturen an die GPU zu übertragen. Sie können diesen asynchronen Texturpuffer manuell über QualitySettings.asyncUploadBufferSize anpassen.
Wenn entweder die Upload-Rate zu langsam ist oder der Hauptthread beim gleichzeitigen Laden mehrerer Texturen ins Stocken gerät, passen Sie diese Texturpuffer an. In der Regel können Sie den Wert (in MB) auf die Größe der größten Textur einstellen, die Sie in die Szene laden müssen.
Beachten Sie, dass eine Änderung der Standardwerte zu einem hohen Speicherbedarf führen kann. Sie können auch keinen Ringpufferspeicher an das System zurückgeben, nachdem Unity ihn zugewiesen hat. Wenn der GPU-Speicher überlastet ist, entlädt die GPU die jüngste und am wenigsten genutzte Textur und zwingt die CPU, sie beim nächsten Eintritt in den Kameraraum neu zu laden.
Informieren Sie sich über alle Speicherbeschränkungen für Texturpuffer im Tutorial zur Speicherverwaltung und lesen Sie den Abschnitt Optimieren der Ladeleistung, um zu sehen, wie Sie die Ladezeiten verbessern können.
Die Mip Map Streaming System gibt Ihnen die Kontrolle darüber, welche Mip Map Ebenen in den Speicher geladen werden sollen. Aktivieren Sie es, indem Sie die Qualitätseinstellungen von Unity aufrufen(Bearbeiten > Projekteinstellungen > Qualität) und die Option Textur-Streaming aktivieren. Sie können Streaming Mip Maps in den Texturimporteinstellungen unter Erweitert aktivieren.
Dieses System reduziert den Gesamtspeicherbedarf für Texturen, da nur die Mip Maps geladen werden, die für das Rendern der aktuellen Kameraposition erforderlich sind. Ansonsten lädt Unity standardmäßig alle Texturen.
Beim Texture Streaming wird eine geringe Menge an CPU-Ressourcen gegen eine potenziell große Menge an GPU-Speicher eingetauscht. Außerdem werden die Mip-Map-Levels automatisch reduziert, um das benutzerdefinierte Speicherbudget einzuhalten.
Zur weiteren Steuerung können Sie die Mip Map Streaming API verwenden.
Das Adressierbare Asset-System vereinfacht die Verwaltung der Assets, aus denen Ihr Spiel besteht. Jedes Asset, einschließlich Szenen, Prefabs, Text-Assets und so weiter, kann als adressierbar markiert und mit einem eindeutigen Namen versehen werden. Sie können diesen Alias dann von überall aus aufrufen.
Das Hinzufügen dieser zusätzlichen Abstraktionsebene zwischen dem Spiel und seinen Assets kann bestimmte Aufgaben rationalisieren, z. B. die Erstellung eines separaten Pakets mit herunterladbaren Inhalten. Adressierbare Dateien erleichtern auch das Auffinden dieser Asset-Pakete, unabhängig davon, ob sie lokal oder dezentral gespeichert sind.
Installieren Sie das Addressables-Paket über den Paketmanager. Jedes Asset oder Prefab im Projekt hat die Fähigkeit, dadurch "adressierbar" zu werden.
Wenn Sie die Option unter dem Namen eines Assets im Inspektor aktivieren, wird ihm eine eindeutige Standardadresse zugewiesen. Nach der Markierung erscheinen die entsprechenden Assets im Fenster Fenster > Asset Management > Adressierbare Objekte > Gruppen .
Unabhängig davon, ob das Asset an einem anderen Ort gehostet oder lokal gespeichert ist, wird es vom System anhand der Zeichenfolge " Addressable Name" gefunden. Ein adressierbarer Prefab wird erst dann in den Speicher geladen, wenn er benötigt wird, und entlädt dann automatisch die zugehörigen Assets, wenn er nicht mehr verwendet wird. Dieser Blog-Beitrag zum Thema Speicher sparen mit Addressables zeigt, wie Sie Ihre Addressable Groups organisieren können, um effizienter mit dem Speicher umzugehen.
Siehe Adressierbare Daten: Einführung in die Konzepte für einen schnellen Überblick darüber, wie das Addressable Asset System in Ihrem Projekt funktionieren kann.
Einer unserer umfassendsten Leitfäden aller Zeiten enthält über 80 umsetzbare Tipps zur Optimierung Ihrer Spiele für PC und Konsole. Diese ausführlichen Tipps wurden von unseren Experten von Success und Accelerate Solutions erstellt und helfen Ihnen, das Beste aus Unity herauszuholen und die Leistung Ihres Spiels zu steigern.