Verfassen von Szenen und Prefabs mit Schwerpunkt auf der Versionskontrolle

Ziel dieses Leitfadens ist es, Best Practices für die Erstellung von Inhalten in Unity zu vermitteln, die mit Versionskontrolle funktionieren. Weitere Informationen über die Verwendung von Versionskontrolle finden Sie im Unity-Blog Take on version control for stronger collaboration oder in dem ausführlichen E-Book Best practices for version control. Obwohl diese beiden Ressourcen gute allgemeine Informationen für die Arbeit mit der Versionskontrolle enthalten, liegt der Schwerpunkt dieses Blogs auf der Integration von Inhalten in die Versionskontrolle und der Vermeidung von Konflikten bei der Zusammenführung, wenn viele Ersteller gleichzeitig an denselben oder benachbarten Inhalten arbeiten.
Im Internet gibt es viel Verwirrung über .meta-Dateien und Versionskontrolle. .meta-Dateien sollten immer in die Versionskontrolle eingecheckt werden. Sie enthalten wichtige Informationen, wie z. B. die Datei-GUID, die alle Verweise zwischen Assets miteinander verbindet. Sie sollten mit ihren Quelldateien synchronisiert werden (sowohl der Name als auch der Speicherort sollten immer mit der zugehörigen Quelldatei übereinstimmen). Verschieben oder benennen Sie niemals eine Asset-Datei außerhalb des Unity-Editors um, es sei denn, es wurden spezielle Tools für diesen Zweck entwickelt oder Sie haben die Funktionsweise von .meta-Dateien vollständig verstanden.
Der Standardversionskontrollmodus für .meta-Dateien ist Sichtbare Dateien, der die .meta-Dateien auf der Festplatte im Betriebssystem anzeigt, anstatt sie zu verstecken. Wenn Sie Perforce verwenden, wählen Sie den Perforce-Modus.
Das erste, was jedes Team tun sollte, wenn es mit Unity und Versionskontrolle arbeitet, ist Smart Merge einzurichten. Standardmäßig speichert Unity YAML-Dateien als Text, so dass sie in der Versionskontrolle zusammengeführt werden können. Wenn Sie den Asset-Serialisierungsmodus auf binär ändern, können Sie diese Dateien nicht mehr per Versionskontrolle zusammenführen.
Da die YAML-Dateien in Unity textbasiert sind, versuchen viele Versionskontrollprogramme, die Dateien anhand von Text- oder Codierungsregeln zusammenzuführen. Smart Merge wurde von Unity entwickelt, um die YAML-Struktur zu berücksichtigen. Wir empfehlen die Verwendung von Smart Merge als Standard-Zusammenführungswerkzeug für alle YAML-Dateien zu erzwingen.
Smart Merge reduziert den Arbeitsausfall aufgrund von Merge-Konflikten erheblich, aber wenn Ihr Team keine Toleranz für potenzielle Arbeitsausfälle hat, empfehlen wir auch die Verwendung von Dateisperren und die manuelle Auflösung von Merge-Konflikten für alle YAML-Dateien.
Das Sperren von Dateien ist eine gängige Praxis in großen Studios, in denen mehrere Autoren gleichzeitig an der gleichen Binärdatei (oder YAML-Datei) arbeiten können. Die Unity-Versionskontrolle verhindert, dass jemand eine gesperrte Datei auschecken kann. Perforce verhindert, dass jemand eine gesperrte Datei einreichen kann.
Git erfordert, dass Git LFS initialisiert wird, um Dateisperren zu unterstützen. Wir empfehlen die Verwendung von Git LFS für jedes Projekt, das große Inhaltsdateien enthält und Git zur Versionskontrolle verwendet.
Erfolgreiche Teams haben oft strenge Richtlinien bezüglich der Namenskonventionen, der Ordnerstrukturen, der Speicherorte und der Art und Weise der Bearbeitung von Assets. Da jedes Team anders ist, gibt es keine allgemeingültigen Leitlinien. Das Wichtigste ist, dass Sie das richtige System für Ihr Team auswählen und es so lange beibehalten, wie es funktioniert.
Spezifische, strenge Richtlinien machen die Entwicklung von Werkzeugen zur Überprüfung von Inhalten einfacher. Dadurch werden Fehler verhindert, bevor sie überhaupt ins Spiel gelangen. Die Validierung von Inhalten mit Code und Tools wird viel einfacher, wenn Klarheit über den Speicherort und die Benennung von Assets besteht. Sie können dann die Unity-Importstandards über die Asset-Nachbearbeitung und Voreinstellungen leichter durchsetzen.
Bei der Erstellung von Inhalten ist es wichtig, den Grundsatz der Trennung der Interessen zu beachten. Wenn man sich Gedanken darüber macht, wie die Inhalte aufgeteilt werden sollen und wo sie untergebracht werden sollen, bleibt das Projekt sauber und die meisten Ersteller von Inhalten geraten nicht in Konflikte beim Zusammenführen. Es kann auch bei der Auffindbarkeit und dem Onboarding von Feature-Experten helfen, wo einzelne Features in spezifischen Unterszenen oder Prefabs leben. Die wichtigsten Bausteine, die zur Aufteilung von Inhalten in Dateien verwendet werden können, sind Szenen, Prefabs und Subgraphen.


Szenen sind die Makro-Bausteine für jede Unity-Anwendung. Jede Szene wird in einer Datei serialisiert (gespeichert), was bedeutet, dass sie verwendet werden kann, um Inhalte in einer Weise zu organisieren, die für die Quellenkontrolle und gleichzeitige Bearbeitung geeignet ist. Das additive Laden von Szenen wird häufig effektiv eingesetzt, um sehr große Szenen, Streaming-Inhalte oder sogar sehr einfache Szenen mit mehreren Komponenten mit unterschiedlichen Anliegen zu erstellen.
Im Allgemeinen wird empfohlen, szenenabhängige Daten in Szenen zu speichern. Bei der gebackenen Beleuchtung zum Beispiel sind Lichter, Lichtkarten und Umgebungseinstellungen davon abhängig, in welcher Szene sie sich befinden. Fast alles andere kann in Prefabs gelagert werden. Wenn eine Szene klein ist und bestimmte Inhalte enthält, die nur innerhalb dieser Szene bearbeitet werden, kann es sinnvoll sein, alle diese Daten in einer einzigen Szene zu speichern. Es ist jedoch wichtig zu beachten, dass bei zwei Spielobjekten in einer Szene jede Änderung an einem dieser Objekte zu Änderungen in der Szenendatei führt.
Während Smart Merge das Szenario handhaben sollte, in dem zwei Inhaltsersteller zwei verschiedene Objekte in der Szene gleichzeitig ändern, können umfangreichere Änderungen zu unlösbaren Konflikten führen. Wir empfehlen den Einsatz von Prefabs, um dieses Problem zu entschärfen.
Was die explizite Szenenstruktur angeht, so enthält die Unity Netcode Demo ein nützliches Flussdiagramm eines Standard-Szenenlayouts für ein einfaches Projekt, das dem ähnelt, das wir in vielen Szenarien gesehen haben.
Vorgefertigte Elemente können verwendet werden, um modulare, separate Inhalte zu erstellen. Weitere Informationen finden Sie in diesem Tutorial über Prefabs und verschachtelte Prefabs. Der wichtigste Abschnitt in diesem Tutorial ist der Abschnitt über bewährte Praktiken. Es gibt keine expliziten Regeln für die Erstellung von Inhalten mit Prefabs. Jedes Team muss selbst entscheiden, was für sein Projekt am besten geeignet ist. Es gibt jedoch einige gute Leitlinien, die zu beachten sind:
- Betrachten Sie Fertighäuser als die Bausteine Ihres Hauses oder Projekts. Im Allgemeinen gibt es eine Wurzel Prefab, die das Fundament des Hauses darstellt. Darin befinden sich die Prefabs für jede wiederverwendbare Komponente, aus denen der Rest des Hauses besteht. Sie können so körnig sein wie eine Fensterbank oder so breit wie eine Wand mit Fenstern. Der erforderliche Grad an Granularität hängt davon ab, wie die Ersteller von Inhalten ihre Prefabs bearbeiten wollen.
- Prefabs können verschachtelt werden. Das bedeutet, dass es in dem obigen Beispiel ein Fertighaus geben könnte, das aus vorgefertigten Wänden, Dächern, Fenstern und Türen besteht, die das Haus bilden. Ein wichtiger Punkt bei der Verschachtelung von Prefabs ist, dass je tiefer die Hierarchie ist, desto wahrscheinlicher wird es, dass das Projekt Leistungsprobleme hat. Wir empfehlen im Allgemeinen, die Tiefe von Voreinstellungshierarchien unter 5-7 Ebenen zu halten.
- Beim Verschachteln von Prefabs ist es im Allgemeinen eine gute Idee, die Prefabs im Prefab-Modus zu bearbeiten. Dadurch wird sichergestellt, dass die Voreinstellungseigenschaften oder Überschreibungen an der richtigen Stelle gesetzt werden. Die Bearbeitung von Prefab-Eigenschaften in der Szenenansicht kann dazu führen, dass Überschreibungen in der falschen Prefab oder in der Szene selbst gespeichert werden. Dies kann unbeabsichtigte Folgen haben und zu Konflikten bei der Zusammenführung führen. Manchmal ist es notwendig, eine untergeordnete Prefab-Eigenschaft in einer übergeordneten Prefab zu überschreiben (auf diese Weise können Variationen erreicht werden, ohne dass jeder Verweis auf eine bestimmte Prefab betroffen ist). Dies ist ein Standardarbeitsablauf, aber es ist wichtig, darauf zu achten, dass Änderungen und Überschreibungen in der richtigen Voreinstellung oder Szene vorgenommen werden.
- Alles in einem Prefab wird zur Laufzeit in den Speicher geladen und instanziiert, wenn ein Prefab geladen und instanziiert wird. Das bedeutet, wenn sich visuelle Effekte oder angehängte Objekte, die nicht immer vorhanden sind, in einem Prefab befinden, werden diese Objekte im Speicher instanziiert. Dies kann zu einer Aufblähung des Speichers führen, da jede instanziierte Prefab alles, was sie enthält, instanziiert. Wenn Objekte gelegentlich mit visuellen Effekten oder Modellen versehen sind, ist es besser, ein Pooling-System und einen Attachment-Manager zu haben, der diese Komponenten zur Laufzeit hinzufügt. Alles, was sich in einem Poolsystem befindet, sollte generell nicht in einem Fertighaus untergebracht werden.
- Es muss nicht alles ein Fertighaus sein. Kleinere Bausteine können GameObjects innerhalb einer Prefab oder sogar einer Szene sein. Wenn ein Objekt nur in einer Szene oder einer Voreinstellung vorkommt, ist es nicht notwendig, eine Voreinstellung dafür zu erstellen.
- Vorgefertigte Varianten sollten mit Vorsicht verwendet werden. Im Allgemeinen ist die beste Verwendung einer vorgefertigten Variante, wenn die Kernbausteine eines Objekts mit nur einfachen Unterschieden identisch sind. So kann es beispielsweise hilfreich sein, eine Prefab-Variante für eine Spielkomponente zu verwenden, die identische Funktionen, aber ein anderes Erscheinungsbild hat. In diesem Szenario wirkt sich eine Änderung der Kernfunktionalität sowohl auf die Funktionalität des Prefab als auch auf die seiner Varianten aus, aber das Erscheinungsbild bleibt überschrieben. Als allgemeine Faustregel gilt, dass so etwas wie ein Charaktervariationssystem oder ein anderes komplexes visuelles Skinning-System nicht auf Prefab-Varianten basieren sollte, es sei denn, das System ist sehr einfach.
Wir empfehlen, eine konsistente Strategie zu entwickeln, um zu bestimmen, was Prefabs und was GameObjects innerhalb von Prefabs oder Szenen sein sollen.
Wenn ein Prefab direkt aus einer FBX-Datei erstellt wird, wird eine spezielle Art von Prefab, eine sogenannte Modell-Prefab, erstellt. Das Ergebnis ist eine Prefab-Variante der FBX-Datei. Alle Ergänzungen oder Änderungen werden als Überschreibungen in der Prefab-Datei gespeichert. Da jedoch die meisten Daten in der FBX-Datei gespeichert sind, können Änderungen und Ergänzungen an der Prefab nicht auf Modell-Prefabs angewendet werden. Wenn Sie das Modell Prefab Variante Workflow verwenden, ist es wichtig, strukturelle Änderungen auf ein Minimum zu beschränken.

Es gibt zwei alternative Arbeitsabläufe, die weniger eng gekoppelte Strukturen zwischen dem FBX-Modell und dem Prefab ermöglichen:
Hinzufügen der FBX-Datei direkt in eine Szene und anschließendes Hinzufügen von Komponenten oder strukturellen Änderungen an GameObjects in der Szene. In diesem Szenario werden alle Änderungen nun in der Szenendatei gespeichert. Dies kann zu Konflikten bei der Zusammenführung führen, wenn viele Personen diesen Arbeitsablauf in derselben Szene verwenden. Wir empfehlen diesen Arbeitsablauf nur, wenn die Änderungen in der Szene vorhanden sein müssen und Konflikte kein Thema sind.
Erstellen eines Standard Unity Prefab aus dem explodierten Modell. Bei dieser Methode wird das FBX-Modell in die Szene gezogen und dann vollständig entpackt. Diese wird dann zur Erstellung eines Prefab verwendet. Diese Methode entkoppelt die FBX-Datei vollständig von der Prefab. Dies ist nützlich, wenn eine sehr lose Kopplung zwischen der FBX-Datei und dem Prefab gewünscht ist. Strukturelle Änderungen, die an der ursprünglichen FBX-Datei vorgenommen wurden, werden nicht mehr übernommen. Die Kopplung erfolgt nur zwischen den Namen der Meshes, Materialien und Animationen. Alles andere befindet sich in der Prefab-Datei selbst. Dies kann nützlich sein, um völlig einzigartige Varianten eines FBX-Modells zu erstellen. Wenn beispielsweise zwei Charaktere dasselbe Modell verwenden, aber völlig unterschiedliche Meshes, Materialien oder sogar unterschiedliche Hierarchien benötigen, ist diese Methode möglicherweise besser als die Erstellung mehrerer FBX-Dateien, die zusätzlichen Speicher und Festplattenplatz beanspruchen. Dies kann praktisch sein, wenn extrem komplexe Komponentenaufstellungen erforderlich sind. Anstatt das GameObject verschwinden zu lassen und alle Komponenten zu verlieren, bleibt das Objekt bestehen und die Komponenten können auf das neue Objekt übertragen werden, oder das umbenannte Mesh oder Material kann wieder in das GameObject eingefügt werden, das nun auf ein fehlendes Mesh oder Material verweist.
In den beiden folgenden Bildern werden Änderungen an einer FBX-Datei vorgenommen und anschließend wieder importiert. Der Kreis um das Unity-Logo auf dem Ball wird gelöscht. Der Hauptständer wird umbenannt. Das Material des Hauptballs wurde von schwarz auf grün geändert, und über dem Standlogo wurde ein neues Elternteil eingeführt, das sich durch Transformationen vom Modell abhebt.

Dies alles ist sowohl in der FBX-Datei als auch in der Modellvorlage genau aufeinander abgestimmt. Im Nicht-Modell Prefab werden die ursprüngliche Hierarchie, Namen und Materialien beibehalten. Das gelöschte Mesh ist nun ein fehlendes Mesh, aber das GameObject ist noch vorhanden. Das umbenannte Netz ist auch nicht sichtbar, weil es auf einen Netznamen verweist, der im Modell nicht mehr existiert. Das geänderte Material wird nicht aktualisiert, da das GameObject immer noch auf das ursprüngliche Material verweist. Außerdem wird die Änderung der Hierarchie nicht beachtet, und das Netz bleibt an der gleichen Stelle, da sich sein übergeordnetes Element nicht geändert hat.

In den folgenden Vorher- und Nachher-Bildern sind die Ergebnisse der oben vorgenommenen Änderungen in der Szenenhierarchie zu sehen. Die FBX-Datei, die direkt in der Szene referenziert wird, und das Standardmodell Prefab reagieren auf alle Änderungen, die an der ursprünglichen FBX-Datei vorgenommen werden. Die entpackte Voreinstellung behält ihre ursprüngliche Hierarchie bei und reagiert nicht auf Löschungen oder Namensänderungen.

Es ist wichtig, sorgfältig zu entscheiden, welche Methodik in einem bestimmten Szenario angewendet wird. Wenn eine enge Kopplung zwischen dem Editor und den FBX-Dateien erwünscht ist, dann ist das Standardmodell Prefab wahrscheinlich die beste Wahl. Wenn eine sehr lose Kopplung erwünscht ist (z. B. bei einem sehr flexiblen Charaktersystem, bei dem Meshes oder Materialien häufig ausgetauscht werden können), dann ist es besser, Nicht-Modell-Prefabs mit weichen Referenzen auf die Komponenten der FBX-Datei zu erstellen.
Im Falle von Graphwerkzeugen wie Shader Graph oder Visual Effect Graph können Shader Graph Subgraphs und Visual Effect Graph Subgraphs verwendet werden, um wiederverwendbare funktionale Knoten zu erstellen, die in einer separaten Datei gespeichert sind und bearbeitet werden können, ohne Konflikte in jedem Shader Graph oder Visual Effect Graph zu verursachen. Dies ermöglicht es den Nutzern, Belange in ähnlicher Weise wie bei Prefabs und Szenen zu trennen. Wir empfehlen, eine Strategie für die Wiederverwendbarkeit zu entwickeln, indem wir Teilgraphen dort nutzen, wo es am sinnvollsten ist.

Die Vermeidung tiefer Hierarchien ist eine allgemeingültige Aussage für Inhalte, die sich auf Scenes, Prefabs, GameObjects, Animationen, UI und alles andere beziehen. Im Allgemeinen führen tiefe Hierarchien jeglicher Art zu Leistungsproblemen. Tiefe Animationshierarchien in Zeichen führen dazu, dass aus Gründen der CPU-Leistung weniger Zeichen auf dem Bildschirm gezeichnet werden können. Aus diesem Grund empfehlen wir, alle animierten Hierarchien auf dem Wurzelknoten der Szene zu platzieren, um die Leistung zu verbessern. Die Entscheidung für flache Hierarchien bei der Verwendung von UGUI und Canvases führt zu einer besseren Leistung, da weniger kaskadierende Layout-Updates erforderlich sind. Tief verschachtelte Prefabs können Leistungsprobleme verursachen und auch zu Verwirrung führen, wenn Überschreibungen nicht sorgfältig verwaltet werden.
Wir beobachten häufig, dass Teams Quellinhalte an verschiedenen Orten speichern, von Netzlaufwerken bis hin zu lokalen Rechnern. Wir empfehlen, alle wichtigen Quellinhalte auf die eine oder andere Weise in die Versionskontrolle aufzunehmen.
Die häufigste Methode, die wir kennen, besteht darin, den Quellinhalt in einem Ordner der Versionskontrolle abzulegen, der sich außerhalb des Ordners Assets befindet. Dadurch wird sichergestellt, dass Unity nicht versucht, Inhalte direkt aus den Quelldateien zu importieren. Maya-, 3ds Max-, Blender- und Photoshop-Dateien werden automatisch in Modelle und Texturen importiert, wenn sie irgendwo im Ordner "Assets" abgelegt sind. Obwohl Unity dies unterstützt, raten wir von dieser Praxis ab. Außerdem empfehlen wir, das Quellverzeichnis mit dem Inhalt im Assets-Verzeichnis zu spiegeln, damit die Nachverfolgung von Assets relativ einfach ist.
Der Quellinhalt sollte für die Benutzer maskierbar sein, da die meisten Benutzer nicht alles benötigen und der Quellinhalt auf der Festplatte extrem groß sein kann (man denke an Terabytes). In einigen Versionskontrollprogrammen ist das Erstellen von Inhaltsmasken recht einfach. In der Unity-Versionskontrolle wird dies mit getarnten Dateien erreicht. In Perforce werden Ansichten verwendet, um Inhalte vor dem Client zu verbergen. Git ist jedoch nicht dafür ausgelegt, auf diese Weise zu arbeiten. Aus diesem Grund empfehlen wir, ein separates Git-Repository für Quellinhalte oder ein separates Repository für jede Art von Inhalt zu erstellen (z. B. müssen 3D-Künstler möglicherweise nie die gesamte Audioquelle synchronisieren und umgekehrt).
Die Erstellung von Inhalten, die mit Versionskontrolle funktionieren und mehrere Benutzer unterstützen, die in denselben Bereichen arbeiten, ist eine schwierige Aufgabe. Unity bietet jedoch Bausteine, die bei sorgfältiger Überlegung und Planung verwendet werden können, um umfangreiche Inhalte zu erstellen, ohne dass es zu unlösbaren Konflikten bei der Zusammenführung oder zu Arbeitsausfällen kommt.