Dieses Dokument beinhaltet die technische Dokumentation des Projektes "AR Ranger" von Jona König und David Credo. Es soll einen Überblick über die Systeme und Komponenten des Projektes geben und deren Funktionsweisen erläutern.
Projekttitel: AR Ranger Unity Version: 2022.3.17f1 Verwendete AR/VR Hardware: Open XR, Meta Quest 3 Teammitglieder: Jona König, David Credo
- Einleitung
- Grundlegende Architektur
- Eigenleistungen und 3rd-Party-Assets
- Teilsysteme und Komponenten (UML)
Das gesamte Projekt ist mit C# DocStrings dokumentiert, sodass die Funktionsweise der einzelnen Klassen und Methoden im Code nachvollzogen werden kann. Die technische Dokumentation soll einen Überblick über die Architektur und die Funktionsweise des Projektes geben.
Der Großteil der Ressourcen befindet sich im Assets-Ordner. Dieser ist in mehrere Unterordner unterteilt, die die verschiedenen Arten von Ressourcen enthalten.
Die meisten Ordner sind selbsterklärend, für das technische Verständnis ist der Aufbau des Scripts-Ordners jedoch von Bedeutung. Dieser ist in mehrere Unterordner unterteilt, die die verschiedenen Features des Projektes enthalten.
_Scripts: Enthält alle Skripte, die im Projekt verwendet werden. Die Skripte sind nach Feature (zB. Onboarding, Scanner, etc.) sortiert._Scripts/General: Enthält grundlegende Systeme wie ein leichtgewichtiges Dependency Injection System, das für die Entkopplung von Komponenten verwendet wird. Hier befindet sich ebenfalls ein Event-Bus System, das für die Kommunikation zwischen Komponenten verwendet wird.
Das Event-Bus System stellt das zentrale Kommunikationsmittel zwischen den verschiedenen Komponenten des Projektes dar. Es ermöglicht das Senden und Empfangen von Nachrichten, ohne dass die Komponenten voneinander wissen müssen. Dadurch wird eine starke Entkopplung der Komponenten erreicht, was die Wartbarkeit und Erweiterbarkeit des Projektes erhöht. Eine ausführliche Anleitung zur Implementierung ist auf dem YouTube Kanal https://www.youtube.com/@git-amend zu finden. Beispielhafte Verwendung:
// Senden einer Nachricht, am Beispiel eines Scan-Events des Scanners den der Spieler nutzen kann
EventBus<ScanEvent>.Raise(new ScanEvent());
//Registrierung eines Empfängers, der auf das Scan-Event reagiert soll:
void OnEnable()
{
EventBus<ScanEvent>.Register(OnScan);
}
void OnDisable()
{
EventBus<ScanEvent>.Unregister(OnScan);
}
void OnScan(ScanEvent e)
{
// Reaktion auf das Scan-Event
}- Wie im Beispiel zu sehen, erwartet der EventBus ein EventBinding, welches eine Methode mit einem Parameter des Event-Typs erwartet.
- Der EventBus ist als statische Klasse realisiert, welche mittels Reflection beim Start des Spiels alle Event-Typen in den Assemblies des Projektes sucht und registriert. Dadurch müssen keine Event-Channels manuell initialisiert werden.
- Wichtig: Eigene Assemblies müssen in der Datei
PredefinedAssemblyUtil.cshinzugefügt werden, damit der EventBus auch Events aus diesen Assemblies registriert. - Der EventBus ist generisch, sodass für jeden Event-Typ ein eigener EventBus existiert. Dadurch wird sichergestellt, dass nur Events des richtigen Typs gesendet und empfangen werden können.
- Im Projekt wird vereinzelt Dependency Injection verwendet, um die Abhängigkeiten zwischen den verschiedenen Komponenten zu entkoppeln. Um eine Dependency bereitzustellen, muss man ein MonoBehaviour mit einer Methode erstellen, welche das
Provide-Attribut trägt. Diese Methode wird dann beim Start des Spiels aufgerufen und die bereitgestellte Abhängigkeit wird von einem Injector in die entsprechenden Felder der abhängigen Komponenten injiziert. - Abhängige Komponenten müssen das
Inject-Attribut tragen, um die Abhängigkeit injiziert zu bekommen. Dieses Attribut kann auf Feldern, Properties und Methoden verwendet werden. - Der Injection ist ein Singleton MonoBehaviour, das die Abhängigkeiten verwaltet und die Injektion durchführt. Es muss in jeder Szene vorhanden sein, in der Dependency Injection verwendet wird.
- Scriptable Objects stellen einen zenralen Bestandteil der Architektur dar. Sie werden verwendet, um Konfigurationen, Daten und Zustände zu speichern und zu verwalten.
- Beispielsweise werden die Daten über Lebewesen in Scriptable Objects gespeichert, um sie einfach zu konfigurieren und zu verwalten, sowie deren Zustand (ob der User diese bereits gescannt hat) zu speichern. Durch die globale Zugänglichkeit von Scriptable Objects können sie einfach von verschiedenen Komponenten verwendet werden.
- Scriptable Objects werden auch verwendet, um die Konfiguration von Features zu ermöglichen. Beispielsweise werden die Konfigurationen des Onboarding-Systems in Scriptable Objects gespeichert, um sie einfach zu konfigurieren und zu verwalten.
- Audio-Dateien
- Die Voice-Over-Aufnahmen wurden von uns selbst erstellt und bearbeitet.
- 3D-Modelle
- Scanner
- Sanderling
- Salzmiere
- Sepia/Schulp
- Leuchtturm Interior
- Aquarium
- Texturen
- Progressbar.png
- Tex_Laser_Mask
- Tex_Laser_Beam
- Shader
- Laser
- Haze Shader
- GlassShader
- Audio-Dateien
- Sämtliche Soundeffekte wurden von der Plattform Splice bezogen. Ein Teammitglied hat ein Abonnement und hat die Soundeffekte und Ambience-Sounds für das Projekt ausgewählt und heruntergeladen. Link zu Splice
- 3D-Modelle
- Holzpfähle turbosquid
- Wooden Post sketchfab
- Lautsprecher cgtrader
- Texturen
- Muschel Untergrund (SandyShell_Ground_Mat_1K) cgtrader
- Dunkler Sand (ground_sand_graph_0) adobe substance 3d assets
- Heller Sand (ground_sand_graph_1) siehe Dunkler Sand
- Shader
- Code Packages
- DOTween Animation Library Asset Store
- Helvetica 3D Font Asset Store
- Substance 3D for Unity Asset Store
Hier ist der grobe Ablauf des Spiels dargestellt. Der Spieler startet im Onboarding, in dem er die Steuerung und das Spielkonzept kennenlernt. Anschließend kann er in die Hauptwelt wechseln, in der er die Lebewesen scannen kann. Nachdem er alle Lebewesen gescannt hat, kann er den Leuchtturm betreten um ein Quiz zu absolvieren. Nachdem er das Quiz bestanden hat, ist das Spiel beendet.
Das Onboarding-System besteht aus mehreren Komponenten, die zusammenarbeiten, um dem Spieler das Spielkonzept und die Steuerung zu vermitteln. Das Onboarding-System wird durch den OnboardingProgressController gesteuert, welcher die verschiedenen Onboarding-Phasen verwaltet. Die Onboarding-Phasen sind in als OnboardingStepSOs (ScriptableObjects) implementiert. Das Onboarding-System verwendet das Event-Bus-System, um mit anderen Komponenten zu kommunizieren. Beispielsweise wird ein Event gesendet, wenn ein OnboardingStep erfolgreich absolviert wurde.
Um die Performance zu verbessern, kann der Scanner in einen "disabled" Zustand versetzt werden, in dem er keine RayCasts durchführt. Dieser Zustand wird verwendet, wenn der Spieler den Scanner nicht benutzt. Der Scanner kann ebenfalls in den "Idle" State übergehen, sobald der Spieler seinen Arm korrekt ausgerichtet hat. In diesem Zustand wird der Scanner aktiviert und kann Lebewesen scannen. Sobald ein Lebewesen gescannt wurde, wird der Scanner in den "Scanning" State versetzt, in dem der Scanner die Lebewesen scannt und ScanEvents mit dem aktuellen Fortschritt sowie des gescanntes Lebewesens sendet.
Dieses Konstruk ist dafür zuständig, den Spieler von einer Szene an einen konkreten Ort einer anderen Szene und wieder zurück zu bringen. Hierzu persistieren wir (nur auf dem Hinweg), die Start- und Zielkoordinaten, sowie sowie den Auslöser der Teleportation in einem Stack. Wir speichern auch, von wo der Spieler kommt, da verschachtelte Sprünge möglich sind. Der TeleportationManager gibt dabei aus der Szene heraus die Anweisungen, speichert sie im TeleportationPlacesStack und lädt die neue Szene. Der Spieler fragt nach jedem Laden einer neuen Szene, ob er seine Position nach anggaben des TeleportationPlacesStack verändern muss und berücksichtigt dabei den Auslöser der Teleportation. Ist eine Posisitonsänderung erforderlich, setzt er diese um und löscht den entsprechenden Eintrag aus dem Stack.


