Optimieren Sie die Leistung Ihres mobilen Spiels: Expertentipps zu Grafiken und Assets

Unser Integrated Success-Team unterstützt Unity-Kunden bei ihren komplexen technischen Problemen. Wir haben uns mit diesem Team erfahrener Software-Ingenieure zusammengesetzt und sie gebeten, uns von ihrem Fachwissen über die Optimierung mobiler Spiele zu berichten.
Unser Accelerate Solutions-Team kennt den Quellcode in- und auswendig und arbeitet mit einer Vielzahl von Unity-Kunden zusammen, um ihnen zu helfen, das Beste aus der Engine herauszuholen. Bei ihrer Arbeit tauchen sie tief in die Projekte der Entwickler ein, um herauszufinden, an welchen Stellen die Leistung optimiert werden kann, um Geschwindigkeit, Stabilität und Effizienz zu verbessern. Als unsere Techniker begannen, ihre Erkenntnisse über die Optimierung von Handyspielen mit uns zu teilen, wurde uns schnell klar, dass es viel zu viele großartige Informationen für einen einzigen Blogbeitrag gab, den wir geplant hatten. Stattdessen haben wir beschlossen, ihren Wissensschatz in ein umfassendes E-Book (das Sie hier herunterladen können) sowie in eine Reihe von Blogbeiträgen zu verwandeln, die einige dieser 75+ umsetzbaren Tipps beleuchten.
Im letzten Teil dieser Optimierungsserie konzentrieren wir uns darauf, wie Sie die Leistung Ihrer Assets, Projektkonfiguration und Grafiken verbessern können. Falls Sie diese verpasst haben, lesen Sie unsere früheren Beiträge über Profilerstellung, Speicher und Code-Architektur sowie Physik, Benutzeroberfläche und Audio, um sich ein vollständigeres Bild von der Optimierung Ihres Spiels zu machen - oder laden Sie das kostenlose E-Book herunter, um einen Überblick über all diese Themen zu erhalten.
Es gibt einige Projekteinstellungen, die sich auf Ihre mobile Leistung auswirken können.
Reduzieren oder Deaktivieren der Beschleunigungsmesserfrequenz
Unity fasst den Beschleunigungsmesser Ihres Handys mehrmals pro Sekunde zusammen. Deaktivieren Sie diese Funktion, wenn sie in Ihrer Anwendung nicht verwendet wird, oder verringern Sie die Häufigkeit, um die Leistung zu verbessern.

Unnötige Player- oder Qualitätseinstellungen deaktivieren
Deaktivieren Sie in den Player-Einstellungen die automatische Grafik-API für nicht unterstützte Plattformen, um die Erzeugung übermäßiger Shader-Varianten zu verhindern. Deaktivieren Sie Zielarchitekturen für ältere CPUs, wenn Ihre Anwendung diese nicht unterstützt.
Deaktivieren Sie in den Qualitätseinstellungen unnötige Qualitätsstufen.
Unnötige Physik deaktivieren
Wenn Ihr Spiel keine Physik verwendet, deaktivieren Sie Auto Simulation und Auto Sync Transforms. Diese verlangsamen Ihre Anwendung nur, ohne einen erkennbaren Nutzen zu bringen.
Wählen Sie die richtige Bildrate
Bei mobilen Projekten müssen die Bildwiederholraten mit der Akkulaufzeit und der thermischen Drosselung in Einklang gebracht werden. Anstatt mit 60 FPS an die Grenzen Ihres Geräts zu gehen, sollten Sie als Kompromiss 30 FPS verwenden. Unity ist für mobile Geräte standardmäßig auf 30 FPS eingestellt.
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 unter 30 FPS bleiben und höhere FPS-Einstellungen für das Spielen reservieren.
Große Hierarchien sind zu vermeiden
Teilen Sie Ihre Hierarchien auf. Wenn Ihre GameObjects nicht in einer 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 Transformationsberechnungen und mehr Kosten für die Garbage Collection.
Siehe Optimierung der Hierarchie und diesen Unite-Vortrag über bewährte Verfahren mit Transforms.
Einmal umwandeln, nicht zweimal
Außerdem können Sie beim Verschieben von Transformationen mit Transform.SetPositionAndRotation sowohl die Position als auch die Drehung auf einmal aktualisieren. Dadurch wird der Aufwand vermieden, eine Transformation zweimal zu ändern.
Wenn Sie ein GameObjects zur Laufzeit instanziieren müssen, besteht eine einfache Optimierung darin, es während der Instanziierung zu parentieren und neu zu positionieren:
GameObject.Instantiate(prefab, parent);
GameObjects.Instantiate(prefab, parent, position, rotation);
Weitere Einzelheiten zu Object.Instantiate finden Sie in der Scripting API.
Vorausgesetzt, Vsync ist aktiviert
Mobile Plattformen können keine Halbbilder darstellen. Auch wenn Sie Vsync im Editor deaktivieren(Projekteinstellungen > Qualität), ist Vsync auf der Hardware-Ebene aktiviert. Wenn die GPU nicht schnell genug auffrischen kann, wird das aktuelle Bild gehalten, was die FPS effektiv reduziert.
Die Asset-Pipeline kann die Leistung Ihrer Anwendung drastisch beeinflussen. Ein erfahrener technischer Künstler kann Ihr Team bei der Definition und Durchsetzung von Asset-Formaten, Spezifikationen und Importeinstellungen unterstützen, um einen reibungslosen Ablauf zu gewährleisten.
Verlassen Sie sich nicht auf die Standardeinstellungen. Verwenden Sie die plattformspezifische Override-Registerkarte, um Assets wie Texturen und Mesh-Geometrie zu optimieren. Falsche Einstellungen können zu größeren Bauvolumen, längeren Bauzeiten und schlechter Speichernutzung führen. Verwenden Sie die Funktion Voreinstellungen, um die Grundeinstellungen für ein bestimmtes Projekt anzupassen.
Weitere Informationen finden Sie in diesem Leitfaden zu Best Practices für Art-Assets oder in diesem Kurs über 3D Art Optimization for Mobile Applications via Unity Learn.
Texturen korrekt importieren
Der meiste Speicherplatz wird wahrscheinlich für Texturen benötigt, daher sind die Importeinstellungen hier entscheidend. Versuchen Sie im Allgemeinen, diese Leitlinien zu befolgen:
- Verringern Sie die maximale Größe: Verwenden Sie die Mindesteinstellungen, 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 mobile Texturkompressionsformate (PVRCT oder ETC).
- Atlas deine Texturen: Die Platzierung mehrerer Texturen in einer einzigen Textur kann Zeichnungsaufrufe reduzieren und das Rendering beschleunigen. Verwenden Sie den Unity Sprite Atlas oder den TexturePackerteines Drittanbieters , umIhre Texturen zu atasieren.
- 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. In den meisten Fällen sollte diese Funktion deaktiviert bleiben. Wenn Sie Texturen zur Laufzeit generieren, erzwingen Sie dies über Texture2D.Apply, 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 Mip Maps für 3D-Modelle aktiviert, die ihren Abstand zur Kamera verändern).

Texturen komprimieren
Betrachten Sie diese beiden Beispiele mit demselben Modell und derselben Textur. Die Einstellungen auf der linken Seite verbrauchen fast achtmal so viel Speicherplatz wie die auf der rechten Seite, ohne dass sich die Bildqualität wesentlich verbessert.

Verwenden Sie die adaptive skalierbare Texturkomprimierung (ATSC) sowohl für iOS als auch für Android. Die überwiegende Mehrheit der in der Entwicklung befindlichen Spiele zielt auf Minispec-Geräte ab, die die ATSC-Kompression unterstützen.
Die einzigen Ausnahmen sind:
- iOS-Spiele, die auf A7-Geräte oder niedriger ausgerichtet sind (z. B. iPhone 5, 5S usw.) - PVRTC verwenden
- Android-Spiele, die für Geräte vor 2016 bestimmt sind, verwenden ETC2 (Ericsson Texture Compression)
Wenn komprimierte Formate wie PVRTC und ETC keine ausreichende Qualität bieten und ASTC auf Ihrer Zielplattform nicht vollständig unterstützt wird, sollten Sie 16-Bit-Texturen anstelle von 32-Bit-Texturen verwenden.
Weitere Informationen zum empfohlenen Texturkomprimierungsformat je nach Plattform finden Sie im Handbuch.
Einstellungen für den Netzimport anpassen
Ähnlich wie Texturen können auch Meshes zu viel Speicherplatz verbrauchen, wenn sie nicht sorgfältig importiert werden. Um den Speicherverbrauch der Maschen zu minimieren:
- Komprimieren Sie das Netz: Eine aggressive Komprimierung kann den Speicherplatz auf der Festplatte verringern (der Speicher zur Laufzeit ist davon jedoch nicht betroffen). Beachten Sie, dass die Quantisierung des Netzes zu Ungenauigkeiten führen kann. Experimentieren Sie daher mit den Komprimierungsstufen, um zu sehen, was für Ihre Modelle geeignet ist.
- Deaktivieren Lesen/Schreiben: Wenn Sie diese Option aktivieren, wird das Netz im Speicher dupliziert, wodurch eine Kopie des Netzes im Systemspeicher und eine weitere im GPU-Speicher verbleibt. In den meisten Fällen sollten Sie sie deaktivieren (in Unity 2019.2 und früher ist diese Option standardmäßig aktiviert).
- Deaktivieren Sie Rigs und BlendShapes: Wenn Ihr Mesh keine Skelett- oder Blendshape-Animation benötigt, deaktivieren Sie diese Optionen nach Möglichkeit.
- 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.

Überprüfen Sie Ihre Polygonzahlen
Höher aufgelöste Modelle bedeuten mehr Speicherbedarf und möglicherweise längere GPU-Zeiten. Benötigt Ihre Hintergrundgeometrie eine halbe Million Polygone? Ziehen Sie in Erwägung, die Modelle im DCC-Paket Ihrer Wahl zu kürzen. Löschen Sie unsichtbare Polygone aus der Sicht der Kamera und verwenden Sie Texturen und Normal Maps für feine Details anstelle von Meshes mit hoher Dichte.
Automatisieren Sie Ihre Importeinstellungen mit dem AssetPostprocessor
Mit dem AssetPostprozessor können Sie beim Importieren von Assets Skripte ausführen. Dies fordert Sie auf, die Einstellungen vor und/oder nach dem Import von Modellen, Texturen, Audio usw. anzupassen.
Verwenden Sie das Addressable Asset System
Das Addressables Asset System bietet eine vereinfachte Möglichkeit, Ihre Inhalte zu verwalten. Dieses einheitliche System lädt AssetBundles nach "Adresse" oder Alias asynchron entweder von einem lokalen Pfad oder einem entfernten Content Delivery Network (CDN).

Wenn Sie Ihre Nicht-Code-Assets (Modelle, Texturen, Prefabs, Audio und sogar ganze Szenen) in ein AssetBundle aufteilen, können Sie sie als herunterladbaren Inhalt (DLC) abtrennen.
Verwenden Sie dann Addressables, um einen kleineren ersten Build für Ihre mobile Anwendung zu erstellen. Mit Cloud Content Delivery können Sie Ihre Spielinhalte hosten und den Spielern zur Verfügung stellen, während sie das Spiel durchlaufen.

Klicken Sie hier, um zu erfahren, wie das Addressable Asset System die Verwaltung von Vermögenswerten vereinfachen kann.
Bei jedem Frame bestimmt Unity die Objekte, die gerendert werden müssen, und erstellt dann Zeichenaufrufe. Ein Zeichenaufruf ist ein Aufruf an die Grafik-API, um Objekte (z. B. ein Dreieck) zu zeichnen, während ein Stapel eine Gruppe von Zeichenaufrufen ist, die zusammen ausgeführt werden.
Je komplexer Ihre Projekte werden, desto mehr benötigen Sie eine Pipeline, die die Arbeitslast auf Ihrer GPU optimiert. DieUniversal Render Pipeline (URP) verwendet derzeit einen Single-Pass-Forward-Renderer, um hochwertige Grafiken auf Ihre mobile Plattform zu bringen (Deferred Rendering wird in zukünftigen Versionen verfügbar sein). Die gleiche physikalisch basierte Beleuchtung und die Materialien von Konsolen und PCs können auch auf Ihr Handy oder Tablet übertragen werden.
Die folgenden Hinweise können Ihnen helfen, Ihre Grafiken zu beschleunigen.
Stapeln Sie Ihre Ziehungsaufrufe
Die Zusammenfassung von Objekten, die zusammen gezeichnet werden sollen, minimiert die Zustandsänderungen, die erforderlich sind, um jedes Objekt in einem Stapel zu zeichnen. Dies führt zu einer verbesserten Leistung, da die CPU-Kosten für das Rendern von Objekten reduziert werden. Unity kann mehrere Objekte mit Hilfe verschiedener Techniken zu weniger Stapeln zusammenfassen:
- Dynamische Dosierung: Bei kleinen Meshes kann Unity Scheitelpunkte auf der CPU gruppieren und transformieren und sie dann in einem Durchgang zeichnen. Anmerkung: Benutzen Sie dies nur, wenn Sie genügend Low-Poly-Meshes haben (weniger als 900 Vertex-Attribute und nicht mehr als 300 Scheitelpunkte). Der Dynamic Batcher verarbeitet keine Meshes, die größer sind als dieser Wert, so dass bei seiner Aktivierung CPU-Zeit für die Suche nach kleinen Meshes verschwendet wird, die in jedem Frame verarbeitet werden.
- Statische Dosierung: Bei nicht bewegter Geometrie kann Unity Zeichnungsaufrufe für Meshes, die das gleiche Material verwenden, reduzieren. Sie ist zwar effizienter als die dynamische Stapelverarbeitung, verbraucht aber mehr Speicher.
- GPU-Instanzierung: Wenn Sie eine große Anzahl identischer Objekte haben, können Sie sie mit dieser Technik durch den Einsatz von Grafikhardware effizienter zusammenfassen.
- SRP Batching: Aktivieren Sie den SRP-Batcher in Ihrem Universal Render Pipeline Asset unter Erweitert. Dies kann die CPU-Rendering-Zeiten je nach Szene erheblich beschleunigen.

Verwenden Sie den Frame-Debugger
Der Frame-Debugger zeigt, wie jeder Frame aus einzelnen Zeichenaufrufen aufgebaut ist. Dies ist ein unschätzbares Werkzeug für die Fehlersuche bei Ihren Shader-Eigenschaften, mit dem Sie analysieren können, wie das Spiel gerendert wird.

Neu im Frame Debugger? Schauen Sie sich diesen einführenden Lehrgang hier an.
Vermeiden Sie zu viele dynamische Lichter
Es ist wichtig, dass Sie Ihrer mobilen Anwendung nicht zu viele dynamische Lichter hinzufügen. Erwägen Sie Alternativen wie benutzerdefinierte Shader-Effekte und Lichtsonden für dynamische Meshes sowie gebackene Beleuchtung für statische Meshes.
In dieser Vergleichstabelle finden Sie die spezifischen Grenzen von URP und integrierten Pipeline-Echtzeitlichtern.
Schatten deaktivieren
Schattenwurf kann pro MeshRenderer und Licht deaktiviert werden. Deaktivieren Sie Schatten, wann immer es möglich ist, um die Anzahl der Zeichenaufrufe zu reduzieren.
Sie können auch falsche Schatten erzeugen, indem Sie eine unscharfe Textur auf ein einfaches Mesh oder ein Quad unter Ihren Figuren anwenden. Ansonsten können Sie Blob-Schatten mit benutzerdefinierten Shadern erstellen.

Backen Sie Ihre Beleuchtung in Lightmaps
Fügen Sie Ihrer statischen Geometrie mit Global Illumination (GI) eine dramatische Beleuchtung hinzu. Markieren Sie Objekte mit Contribute GI, damit Sie hochwertige Beleuchtungen in Form von Lightmaps speichern können.
Die gebackenen Schatten und Beleuchtungen können dann ohne Leistungseinbußen zur Laufzeit gerendert werden. Der Progressive CPU und GPU Lightmapper kann das Backen von Global Illumination beschleunigen.

Folgen Sie dem Handbuch und diesem Artikel über die Optimierung der Beleuchtung, um den Einstieg in das Lightmapping in Unity zu erleichtern.
Leichte Schichten verwenden
Bei komplexen Szenen mit mehreren Lichtern trennen Sie Ihre Objekte mit Hilfe von Ebenen und beschränken dann den Einfluss jedes Lichts auf eine bestimmte Ausblendmaske.

Lichtsonden für bewegte Objekte verwenden
Lichtsonden speichern gebackene Beleuchtungsinformationen über den leeren Raum in Ihrer Szene und bieten gleichzeitig eine hochwertige Beleuchtung (sowohl direkt als auch indirekt). Sie verwenden Spherical Harmonics, die im Vergleich zu dynamischen Lichtern sehr schnell berechnen.

Verwenden Sie Level of Detail (LOD)
Wenn sich Objekte in die Ferne bewegen, kann Level of Detail sie anpassen oder umschalten, um einfachere Meshes mit einfacheren Materialien und Shadern zu verwenden, um die GPU-Leistung zu verbessern.


Verwenden Sie Occlusion Culling, um verdeckte Objekte zu entfernen
Objekte, die hinter anderen Objekten verborgen sind, können möglicherweise noch gerendert werden und Ressourcen kosten. Verwenden Sie Occlusion Culling, um sie zu verwerfen.
Während die Ausblendung außerhalb der Kameraperspektive automatisch erfolgt, ist die Ausblendung der Okklusion ein gebackener Prozess. Markieren Sie Ihre Objekte einfach als statische Occluder oder Occludees und backen Sie sie dann über den Dialog Fenster > Rendering > Occlusion Culling . Auch wenn dies nicht für jede Szene notwendig ist, kann das Culling in vielen Fällen die Leistung verbessern.
Weitere Informationen finden Sie im Tutorial " Arbeiten mit Occlusion Culling".
Vermeiden Sie eine mobile native Auflösung
Da Handys und Tablets immer fortschrittlicher werden, haben neuere Geräte in der Regel eine sehr hohe Auflösung.
Verwenden Sie Screen.SetResolution(width, height, false), um die Ausgabeauflösung zu verringern und etwas Leistung zurückzugewinnen. Profilieren Sie mehrere Auflösungen, um das beste Gleichgewicht zwischen Qualität und Geschwindigkeit zu finden.
Beschränkung der Verwendung von Kameras
Jede Kamera verursacht einen gewissen Overhead, unabhängig davon, ob sie sinnvolle Arbeit leistet oder nicht. Verwenden Sie nur Kamerakomponenten, die für das Rendering erforderlich sind. Auf weniger leistungsfähigen mobilen Plattformen kann jede Kamera bis zu 1 ms CPU-Zeit in Anspruch nehmen.
Shader einfach halten
Die Universal Render Pipeline enthält mehrere leichtgewichtige Lit- und Unlit-Shader, die bereits für mobile Plattformen optimiert sind. Versuchen Sie, Ihre Shader-Variationen so gering wie möglich zu halten, da sie sich drastisch auf die Speichernutzung zur Laufzeit auswirken können. Wenn die standardmäßigen URP-Shader nicht Ihren Anforderungen entsprechen, können Sie das Aussehen Ihrer Materialien mit Shader Graph anpassen. Hier erfahren Sie, wie Sie Ihre Shader mit Shader Graph visuell erstellen können.

Überzeichnen und Alpha-Blending minimieren
Vermeiden Sie das Zeichnen unnötiger transparenter oder halbtransparenter Bilder. Mobile Plattformen werden durch die daraus resultierende Überzeichnung und Alpha-Blending stark beeinträchtigt. Überlagern Sie kaum sichtbare Bilder oder Effekte nicht. Sie können die Überzeichnung mit dem RenderDoc-Grafikdebugger überprüfen.
Post Processing-Effekte begrenzen
Post Processing-Effekte im Vollbildmodus, wie z. B. Glow-Effekte, können die Leistung drastisch verringern. Verwenden Sie sie mit Bedacht in der künstlerischen Gestaltung Ihres Titels.

Seien Sie vorsichtig mit Renderer.material
Der Zugriff auf Renderer.material in Skripten dupliziert das Material und gibt einen Verweis auf die neue Kopie zurück. Dadurch wird eine bestehende Charge, die das Material bereits enthält, unterbrochen. Wenn Sie auf das Material des gepackten Objekts zugreifen möchten, verwenden Sie Renderer.sharedMaterial stattdessen.
Optimieren von SkinnedMeshRenderern
Das Rendern von Meshes mit Skins ist teuer. Stellen Sie sicher, dass jedes Objekt, das einen SkinnedMeshRenderer verwendet, diesen benötigt. Wenn ein GameObject nur zeitweise animiert werden muss, verwenden Sie die Funktion BakeMesh, um das gehäutete Mesh in einer statischen Pose einzufrieren, und wechseln Sie dann zur Laufzeit zu einem einfacheren MeshRenderer.
Reflektionssonden minimieren
Eine Reflexionssonde kann realistische Reflexionen erzeugen, ist aber sehr kostspielig, was die Stückzahlen angeht. Verwenden Sie Cubemaps mit niedriger Auflösung, Culling-Masken und Texturkompression, um die Laufzeitleistung zu verbessern.
Dies war der letzte Blog-Beitrag in der Serie zur Optimierung der mobilen Leistung. Wenn Sie jedoch Zugriff auf die vollständige Liste der Tipps und Tricks des Teams haben möchten, haben wir auch ein 52-seitiges E-Book veröffentlicht, das hier erhältlich ist.

Wenn Sie mehr über integrierte Support-Services erfahren möchten und Ihrem Team direkten Zugang zu Ingenieuren, Expertenrat und Best-Practice-Anleitungen für Ihre Projekte geben wollen, dann sehen Sie sich hier die Erfolgspläne von Unity an.
Haben Sie nicht gefunden, wonach Sie gesucht haben?
Wir möchten Ihnen helfen, Ihre Unity-Anwendungen so leistungsfähig wie möglich zu machen. Wenn Sie mehr über ein bestimmtes Optimierungsthema wissen möchten, lassen Sie es uns bitte in den Kommentaren wissen.