Unity Asset-Bündel Tipps und Fallstricke

ATTILIO CAROTENUTO / UNITYTechnical Lead
Apr 16, 2024|8 Min.
Unity Asset-Bündel Tipps und Fallstricke
Diese Website wurde aus praktischen Gründen für Sie maschinell übersetzt. Die Richtigkeit und Zuverlässigkeit des übersetzten Inhalts kann von uns nicht gewährleistet werden. Sollten Sie Zweifel an der Richtigkeit des übersetzten Inhalts haben, schauen Sie sich bitte die offizielle englische Version der Website an.

Asset-Bundles sind Archivdateien, die Assets für Ihr Spiel enthalten. Sie werden verwendet, um Ihr Spiel in logische Blöcke aufzuteilen, die es Ihnen ermöglichen, Inhalte nach Bedarf zu liefern und zu aktualisieren, während Ihr Spielaufbau kleiner wird. Sie werden auch häufig für die Bereitstellung von Patches und DLCs für Ihr Spiel verwendet. Asset-Pakete können alle Arten von Assets enthalten, z. B. Prefabs, Materialien, Texturen, Audioclips, Szenen und vieles mehr, aber sie können keine Skripts enthalten.

Bisher war es erforderlich, Asset-Bündel manuell zu erstellen, jedes Asset entsprechend zu markieren und dann die Abhängigkeiten zur Laufzeit selbst zu verfolgen und aufzulösen. Heutzutage wird all dies vom Addressables-System übernommen, das Asset-Bündel für Sie auf der Grundlage der von Ihnen definierten Asset-Gruppen erstellt und Abhängigkeiten transparent lädt und handhabt.

Es gibt zwar viele Anleitungen zur Funktionsweise von Asset-Bündeln, aber ich möchte hier auf einige weniger bekannte Aspekte des Systems eingehen, wobei der Schwerpunkt auf der Spielleistung, der Speichernutzung zur Laufzeit und der allgemeinen Kompatibilität liegt.

Be- und Entladen von Vermögenswerten

Immer wenn Sie versuchen, ein in einem Bundle enthaltenes Asset zu verwenden, stellt Unity sicher, dass das entsprechende Bundle in den Speicher geladen wird, und lädt dann wiederum das Asset in den Speicher.

Es ist zwar möglich, bestimmte Assets innerhalb eines Asset-Bündels teilweise zu laden, aber das Gegenteil ist nicht erlaubt. Das heißt, sobald ein Asset innerhalb eines Asset-Bündels geladen ist, kann es nur entladen werden, wenn die gesamte Gruppe von Assets nicht mehr benötigt wird.

Wenn Ihre Bundle-Struktur nicht ideal ist, werden Sie im Laufe des Spiels häufig eine zunehmende Nutzung des Laufzeitspeichers feststellen, was zu einer Verschlechterung der Leistung und möglichen Abstürzen führt. Aus diesem Grund ist es am besten, Bündel mit einer großen Menge an Assets zu vermeiden, da sie am Ende viel Laufzeitspeicher beanspruchen und zu einem Engpass für Ihr Spiel werden. Packen Sie stattdessen die Güter danach, wie häufig sie zusammen geladen und verwendet werden.

Kompatibilität der Motorversionen

Asset-Bundles sind in der Regel vorwärtskompatibel, d. h. Bundles, die mit älteren Versionen von Unity erstellt wurden, funktionieren in den meisten Fällen auch in Spielen, die mit neueren Versionen von Unity erstellt wurden (vorausgesetzt, Sie entfernen die TypeTree-Informationen nicht, wie später beschrieben). Das Gegenteil ist der Fall. Daher ist es unwahrscheinlich, dass Bundles, die mit einer neueren Version von Unity erstellt wurden als die, die für die Erstellung Ihres Spiels verwendet wurde, korrekt geladen werden.

Je größer der Versionsunterschied zwischen dem Paket und der für die Erstellung des Spiels verwendeten Engine ist, desto unwahrscheinlicher wird die Kompatibilität. Es gibt auch Fälle, in denen das Bundle zwar geladen wird, aber die darin enthaltenen Objekte in der neuen Version von Unity nicht korrekt geladen werden können, wahrscheinlich aufgrund einer Änderung in der Art und Weise, wie die Objekte serialisiert werden, was zu Problemen führt. In diesem Fall müssen Sie Ihre Pakete neu erstellen, um die Kompatibilität zu gewährleisten.

Auch das Laden von Bundles aus einer anderen Version von Unity ist mit Leistungseinbußen verbunden, wie im Abschnitt TypeTree unten beschrieben.

Aus diesen Gründen wird empfohlen, bei jeder Aktualisierung der Unity-Version Ihres Spiel-Builds mit bestehenden Asset-Bündeln gründlich zu testen und diese nach Möglichkeit ebenfalls zu aktualisieren.

Plattformübergreifende Kompatibilität

Asset-Bundles bieten im Allgemeinen keine plattformübergreifende Unterstützung. Im Editor können Sie Bundles von einer anderen Zielplattform laden, aber auf dem Gerät wird dies nicht funktionieren.

Dies gilt auch für Pakete, die Assets enthalten, die nicht unbedingt plattformspezifisch sind.

Der Grund für diese Einschränkung ist, dass Daten möglicherweise auf eine Weise optimiert oder komprimiert werden, die nur für die Zielplattform funktioniert. Außerdem können Bundles plattformspezifische Daten enthalten, die nicht zwischen verschiedenen Plattformen ausgetauscht werden sollten, so dass das Durchsickern von Inhalten, die nicht für eine andere Plattform bestimmt sind, verhindert wird.

Cache laden

Der Lade-Cache ist ein gemeinsam genutzter Pool von Seiten, in dem Unity die zuletzt aufgerufenen Daten für Ihre Asset-Bündel speichert. Dieser Wert ist global, d. h. er wird von allen Asset-Bündeln in Ihrem Spiel gemeinsam genutzt.

Dies wurde erst vor kurzem eingeführt, ich glaube mit Unity 2021.3, und dann auf 2019.4 zurückportiert. Zuvor war Unity auf separate Caches für jedes Asset-Bündel angewiesen, was zu einem deutlich höheren Speicherverbrauch zur Laufzeit führte (siehe unten "Serialisierte Dateipuffer").

Standardmäßig ist dieser Wert auf 1 MB festgelegt, er kann jedoch durch die Einstellung AssetBundle.memoryBudgetKB geändert werden.

Die standardmäßige Cache-Größe sollte in den meisten Fällen ausreichen, obwohl es einige Szenarien gibt, in denen eine Änderung der Größe Vorteile für Ihr Spiel bringen könnte. Wenn Sie z. B. Pakete mit vielen kleinen Objekten haben, kann eine Erhöhung der Cache-Größe zu mehr Cache-Treffern führen, was die Leistung Ihres Spiels verbessert.

Zusätzliche interne Daten

Zusammen mit Ihren Spiel-Assets enthalten Asset-Bündel eine Reihe von zusätzlichen Informationen und Headern, die von Unity verwendet werden, um zu wissen, welche Assets wie geladen werden müssen, sowie einen speziellen Cache (abhängig von der verwendeten Unity-Version).

Inhaltsübersicht

Eine Übersicht über die Assets in einem Bundle. Damit können Sie jedes einzelne Asset im Bündel nach seinem Namen suchen und laden. Die Größe des Speichers ist normalerweise kein Problem, es sei denn, Sie haben außergewöhnlich große Asset-Bündel mit Tausenden von Objekten.

Vorspannungstabelle

Die Preload-Tabelle listet die Abhängigkeiten der einzelnen Assets auf, die in Ihrem Bundle enthalten sind. Es wird von Unity verwendet, um Assets korrekt zu laden und zu konstruieren.

Dies kann ziemlich groß werden, wenn die in Ihrem Bundle enthaltenen Assets viele explizite und implizite Abhängigkeiten sowie kaskadierende Abhängigkeiten von anderen Bundles haben. Aus diesem Grund (und aus vielen anderen Gründen) ist es eine gute Idee, Ihre Bundles so zu gestalten, dass die Abhängigkeitskette minimiert wird.

TypeTrees

TypeTrees definieren das serialisierte Layout der in den Asset-Bündeln enthaltenen Objekte.

Ihre Größe hängt davon ab, wie viele verschiedene Arten von Objekten in dem Bündel enthalten sind. Aus diesem Grund ist es ratsam, große Bündel zu vermeiden, in denen Objekte vieler verschiedener Typen zusammengemischt sind.

TypeTrees sind notwendig, um die Kompatibilität aufrechtzuerhalten, wenn Sie die Unity-Version Ihres Spiel-Builds aktualisieren und gleichzeitig versuchen, Asset-Bundles zu laden, die mit älteren Versionen der Engine erstellt wurden. Wenn sich z. B. das Format oder die Struktur des Objekts geändert hat, können Sie ein sicheres binäres Lesen durchführen, damit Unity versuchen kann, das Objekt trotzdem zu laden. Da dies mit Leistungseinbußen verbunden ist, empfiehlt es sich im Allgemeinen, Bundles so oft wie möglich zu aktualisieren, wenn Sie die Engine aktualisieren.

Er kann optional deaktiviert werden, indem die Option BuildAssetBundleOptions.DisableWriteTypeTree setzen, wenn Sie Ihre Bundles erstellen. Dadurch werden Ihre Bundles und der damit verbundene Speicher-Overhead kleiner, aber es bedeutet auch, dass Sie alle Ihre Bundles neu erstellen müssen, wenn Sie die Engine-Version Ihres Spiel-Builds aktualisieren. Dies ist besonders schmerzhaft, wenn Sie sich auf Bundles verlassen, die von Ihren Playern für benutzergenerierte Inhalte erstellt wurden. Wenn Sie also keinen triftigen Grund haben, dies zu tun, sollten Sie TypeTrees aktiviert lassen.

Ein Fall, in dem TypeTrees normalerweise gefahrlos deaktiviert werden können, sind Bundles, die direkt in den Build des Spiels eingebunden sind. In diesem Fall würde ein Upgrade der Engine ohnehin die Erstellung eines neuen Spielbuilds und neuer Asset-Bündel erfordern, so dass der Aspekt der Rückwärtskompatibilität nicht relevant ist.

Jedes Bundle hat seine eigenen TypeTrees, so dass mehrere kleine Bundles, die denselben Objekttyp enthalten, die Gesamtgröße auf der Festplatte leicht erhöhen. Andererseits werden TypeTrees beim Laden in einem globalen Cache im Speicher abgelegt, so dass keine höheren Laufzeitspeicherkosten entstehen, wenn mehrere Asset-Bundles denselben Objekttyp speichern.

Serialisierte Dateipuffer

Anmerkung: Seit Unity 2019.4 wurde dies durch einen globalen, gemeinsam genutzten Lade-Cache ersetzt, wie oben beschrieben.

Wenn ein Asset-Bundle geladen wird, weist Unity interne Puffer zu, um die serialisierten Dateien im Speicher zu speichern.

Normale Asset-Bündel enthalten eine serialisierte Datei, während Streaming Scene Asset-Bündel bis zu zwei Dateien für jede in diesem Bündel enthaltene Szene enthalten. Die Größe dieser Puffer hängt von der Plattform ab. Auf Switch, PlayStation und Windows RT werden es 128 KB sein, während alle anderen Plattformen 14 KB Puffer haben.

Aus diesem Grund ist es am besten, eine große Anzahl sehr kleiner Asset-Bündel zu vermeiden, da der von diesen Puffern belegte Speicherplatz im Vergleich zu den tatsächlich bereitgestellten Assets erheblich werden kann.

CRC-Integritätsprüfungen

Ein CRC (Cyclic Redundancy Check) wird verwendet, um eine Prüfsummenvalidierung Ihrer Asset-Bündel durchzuführen und sicherzustellen, dass der Inhalt Ihres Spiels genau dem entspricht, was Sie erwarten. CRCs werden auf der Grundlage des unkomprimierten Inhalts des Pakets berechnet.

Auf Konsolen sind Asset-Bundles normalerweise als Teil der Titelinstallation auf dem lokalen Speicher enthalten oder werden als DLCs heruntergeladen, was CRC-Prüfungen unnötig macht. Auf anderen Plattformen, wie z. B. PC oder Mobile, ist es wichtig, CRC-Prüfungen für Bundles durchzuführen, die von einem CDN heruntergeladen wurden. Damit soll sichergestellt werden, dass die Datei nicht beschädigt oder abgeschnitten wird, was zu Abstürzen führen könnte, und um mögliche Manipulationen zu verhindern.

CRC-Prüfungen sind ziemlich kostspielig, was die CPU-Auslastung angeht, insbesondere auf Konsolen und mobilen Geräten. Aus diesen Gründen ist es normalerweise ein guter Kompromiss, CRC-Prüfungen für lokale und zwischengespeicherte Bundles zu deaktivieren und sie nur für nicht zwischengespeicherte Remote-Bundles zu aktivieren.

Geringerer Overhead bei der Suche nach Assets

Standardmäßig bietet Unity drei Möglichkeiten, Assets innerhalb von Bundles zu suchen:

  • Relativer Pfad zum Projekt (Assets/Prefabs/Characters/Hero.prefab)
  • Asset-Dateiname (Held)
  • Asset-Dateiname mit Erweiterung (Hero.prefab)

Das ist zwar praktisch, hat aber auch seinen Preis. Um die beiden letztgenannten Methoden zu unterstützen, muss Unity Nachschlagetabellen erstellen, die bei großen Paketen eine erhebliche Menge an Speicher verbrauchen können.

Darüber hinaus führt das Laden von Assets mit einer anderen Methode als dem relativen Projektpfad zu Leistungseinbußen, wiederum aufgrund des erforderlichen Tabellenabrufs.

Aus diesen Gründen ist es empfehlenswert, diese Methoden nicht zu verwenden. Sie können sie sogar bei der Erstellung der Asset-Bündel deaktivieren, was die Ladeleistung für Ihre Asset-Bündel und die Speichernutzung zur Laufzeit verbessert.

Zu diesem Zweck können Sie bei der Erstellung Ihrer Pakete diese beiden Flags setzen:

Um mehr über Asset Management zu erfahren, Feedback auszutauschen oder sich mit der Community und den Mitarbeitern von Unity auszutauschen, besuchen Sie das Asset Management Forum.