Die Game En­gine Unity und das Ver­sion­skon­troll­sys­tem Git

Heutzutage benötigt fast jedes Videospiel bestimmte Komponenten, um zu funktionieren. Zum Beispiel muss die physikalische Kollision zwischen dem Spielenden und dem Gegner berechnet oder die Umgebung mit komplexem Licht beleuchtet werden. Umso komplexer die Videospiele werden, desto mehr solcher Features müssen vorhanden sein. Anstatt für jedes einzelne Videospiel diese Umgebung selbst erneut zu programmieren und somit das Rad neu zu erfinden, werden Game Engines verwendet, die Alles für dich bereitstellen, was du brauchst. Eine solche Game Engine ist Unity.

Um gemeinsam in einem Team an einem Unity Projekt zu arbeiten, müssen wir irgendwie unser Projekt miteinander austauschen. Man könnte das Projekt in eine einfache Cloud im Internet zur Verfügung stellen und allen Teammitgliedern den Zugang dazu gewähren. Doch dann kommt es zu dem Problem, dass immer nur eine Person gleichzeitig an dem Projekt arbeiten kann, da ansonsten Dateikonflikte entstehen würden. Zur Lösung dieses Problems wurde das Versionskontrollsystem Git entwickelt.

In­dus­tri­e­nahe Arbeit­s­prozesse lehren

In der Industrie ist Unity bislang noch die meistgenutzte Game Engine und Git das meistgenutzte Versionskontrollsystem. Wir bringen dir einen effektiven Workflow mit Unity und Git bei, der dir auch bei zukünftigen Softwareprojekten helfen wird.

In­teg­ra­tion der produzier­ten As­sets

Nicht jeder aus deinem Team hat den Überblick über Alles, was von Jedem produziert wird. Dementsprechend sollst du die Assets, die du erstellt hast, auch eigenständig in Unity implementieren und über Git hochladen. Damit das klappt, einigen wir uns auf eine gemeinsame Ordnerstruktur und eine Git Branching Strategie.

Kollab­or­a­tion und Team­fer­tigkeiten

Innerhalb eures Teams solltet ihr abklären, welche Branches erstellt werden müssen und welche Personen aktuell an welchen Feature-Branches arbeiten. Wir verwenden GitLab als Plattform für Git, in dem alle Aufgaben innerhalb eines Kanban-Boards eigenständig zugeteilt werden.

Prakt­isches En­twick­eln mit der Game En­gine Unity

Unity teilt alle Features eines Videospiels in Objekte und Komponenten auf: Es gibt Physik-Komponenten, die einem Objekt physikalische Eigenschaften zufügen, Audio-Komponenten, die räumliche Sounds oder Musik auf dem Objekt abspielen, und viele weitere. Zusätzlich wird jedes programmierte Skript (z.B.: „Player Controller“) als Komponente angesehen. Sobald ein Objekt aus allen benötigten Komponenten zusammengestellt worden ist, wird es als Prefab (= Prefabricated) abgespeichert, um später einfach in Spielszenen platziert zu werden. Um deine Assets korrekt einzufügen, musst du den Aufbau des Prefabs verstehen: In welche Komponente gehört das Player-Sprite? Wo ist die Audio-Komponente, die meinen Sound benötigt?

Der Hür­de zum Trotz: Git produkt­iv ver­wenden

Mit Git reicht es nicht mehr aus, deine Änderungen ohne weiteres Nachdenken hochzuladen. Da alle andern Projektteilnehmenden potentiell auch gleichzeitig Änderungen an der gleichen Stelle wie du hochladen könnten, würden sofort Dateikonflikte entstehen. Git implementiert dafür einen eigenen Workflow:

Einerseits werden alle Änderungen am Projekt, sogenannte Commits, abgespeichert. Das bedeutet, dass du zu jeden Zeitpunkt der Arbeit am Projekt, des Repoitories, zurückspringen kannst und somit die Daten des Projekts vollständig gesichert sind. Wenn du ein neues Feature implementierst, erstellst du einen eigenen Branch, auf den du deine Commits hochlädst. Ein Branch ist eine separate Abfolge an Änderungen, die unabhängig vom Hauptprojekt an einer Kopie des Hauptprojekts stattfinden. Damit kommt es zu keinen Dateikonflikten. Sobald dein Feature fertig implementiert ist, musst du deinen Branch wieder mit dem Main-Branch vereinen, bzw. mergen. In dem Prozess musst du einmalig Dateikonflikte lösen. Wenn du dich gut mit deinem Team absprichst, muss es nicht unbedingt zu Konflikten kommen.

Akt­ives En­twick­eln in Unity und kontinu­ier­liche In­teg­ra­tion mit Git macht das Lernen im GamesLab be­son­ders

Verständnis für Entwicklung

Alle Teilnehmer lernen den Git-Workflow kennen, um gemeinsam an einem Projekt mit möglichst wenig Fehlern zu arbeiten. Git mag für viele Teilnehmer zunächst überwältigend erscheinen, aber es macht die Entwicklung in zukünftigen Projekten viel einfacher.

Keine übliche “Gruppenarbeit” sondern “gemeinsames Entwickeln”

Wir unterteilen das Projekt in verschiedene Departments. Jedes Department hat eine leitende Person, die die Kommunikation mit dem Game Designer und den anderen Departments organisiert. Wöchentlich finden Besprechungen innerhalb der Departments und in der gesamten Gruppe statt. Alle Teilnehmenden arbeiten auf gemeinsamen Branches und besitzen Grundkenntnisse über die Verwendung von Unity. Die Arbeit mit Git im GamesLab ermöglicht eine weitaus flexiblere Gruppenarbeit, als sie üblicherweise von Studierenden verlangt wird.

Voka­bel­liste für Unity

Eine Game Engine ist eine Software, die für die Entwicklung von Videospielen bereits Basiswerkzeuge bereit stellt. Sie sorgt dafür, dass zum Beispiel Grafik- oder Physikberechnungen abgenommen werden, ohne dass diese Funktionen komplett neu programmiert werden müssen. 

Eine Engine bietet Components für Game Objects, PlugIns für erweiterte Funktionen oder auch die Möglichkeit erstellte Spiele auf Konsolen zu portieren. Bekannte Game Engines sind zum Beispiel: Unreal, Unity, Godot oder RPG Maker. Im GamesLab der Universität Paderborn nutzen wir die Unity Engine.

Unity hat verschiedene Editor Versionen, die untereinander nicht kompatibel sind. Die Engine bekommt kontinuierlich Updates, sodass unterschiedliche Editor Versionen neue oder veränderte Funktionen und Inhalte haben können. Ein Unity Projekt muss deswegen vor Beginn der Entwicklung auf eine bestimmte Editor Version festgelegt werden und alle Mitarbeitenden müssen die gleiche Version nutzen, um das Projekt zu öffnen.

Unity Hub ist der Desktop-Client, durch die Editor Version eingestellt und das Unity Projekt geöffnet werden kann.

Eine “Scene” ist in Unity die Spielumgebung. In Scenes werden alle GameObjects eingebaut, welche im Spiel zu sehen sind. Eine Scene kann zum Beispiel das Hauptmenü oder Level 1 sein. Eine Scene dient aber auch als Testort, in dem 2D, 3D und Audio Assets, sowie und Effekte und Mechaniken von Coding ausgetestet werden können.

Das Wort “Prefab” ist eine Abkürzung des englischen Wortes “prefabricated” und beschreibt ein vorgefertigtes GameObject. Das kann ein von 2D Asset oder 3D umgewandeltes Asset sein. Ein Prefab speichert Informationen für das Objekt und alle Kopien dessen haben die gleichen Eigenschaften. Der Vorteil: wird eine Eigenschaft am Prefab an einem Ort im Spiel geändert, kann diese Änderung für alle weiteren Instanzen des Objektes aktualisiert werden.

Components werden an GameObjects angehängt, um ihnen Eigenschaften oder Funktionalitäten zuzuschreiben. Jedes GameObject muss ein Transform Component besitzen, welches die Position, Rotation und Skalierung des Objekts in der Scene angibt. Ein Script ist gleichzeitig ein Component.

Asset

Ein Asset sind 2D, 3D oder Audio-Dateien, die für das Spiel optimiert erstellt wurden, aber sich noch nicht im Spiel befinden. Ein Asset muss nach der Produktion in Unity integriert werden und anschließend in ein GameObject umgewandelt werden, um letztendlich im Spiel genutzt werden zu können.

GameObject

Alle Objekte in Unity werden als GameObjects bezeichnet. An diese werden Components angehängt, welche die Eigenschaften des Objekts bestimmen. Die Objekte werden dann in Scenes eingefügt um miteinander zu interagieren.

Voka­bel­liste für Git

Ein Versionskontrollsystem stellt mehr Funktionen als eine einfache Cloud zur Verfügung. Jede Änderung am Projekt wird gespeichert. Es gibt keinen einzigen aktuellen Stand des Projekts, sondern Verschiedene auf mehreren Branches. Zwei Branches können vereint werden, indem sie zusammengefügt, bzw. gemerged werden.

Da wir alle gemeinsam an einem Projekt arbeiten, sollten wir uns auf eine gemeinsame Ordnerstruktur einigen. Zunächst sollte das Unity Projekt komplett von allen anderen Working Files aus anderen Softwares getrennt sein. Die Ordner sollten Dabei komponentenbasiert strukturiert sein: In einem Ordner “Player” befinden sich demnach alle Ordner zum Spieler, wie z.B. “Scripts”, “Materials”.

Wenn du neue Assets integrierst, solltest du die Assets auf den passenden Branch pushen. Ein Asset “Enemy Sprite” gehört idealerweise auf den Branch “feature-enemy”.

Das Projekt ist in mehrere Branches aufgeteilt. Ein Branch besitzt seine eigene Version des Projektes. Auf dem main-Branch ist die aktuellste funktionierende Version des Projektes. Auf dem dev-Branch befindet sich die aktuelle Entwicklungsversion des Projektes. Für jedes neue Feature wird ein feature-Branch erstellt (z.B.: “feature-enemy”). Wenn das Feature fertig ist, wird der Branch auf den dev-Branch gemerged, d.h. der dev-Branch erhält den Inhalt des feature-Branches. Zuletzt kann der dev-Branch in den main-Branch gemerged werden.