Im letzten Teil haben wir dafür gesorgt, dass der Spieler das Skelett mit seinem Schwert erledigen kann. Jetzt kümmern wir uns um den Level und die Beleuchtung.
Übersicht
Es wird Zeit, dass wir über das tatsächliche Leveldesign nachdenken. Ich habe mich von der Gruft in Kay Lousberg’s Halloween Bits Pack inspirieren lassen:

Die Gruft ist ja durch das magische Tor verschlossen, wer dort hinein steigt gelangt in das Verlies des Skelettkönigs. Daher stelle ich mir die Gruft als zentrales Objekt auf einem Friedhof vor und gestalte die Umgebung um die Gruft herum.
Rundherum gibt es auf dem ganzen Friedhof natürlich viele Gräber und hier und da sollen unsere Skelette daraus hervorklettern. Die Knochenschlüssel, die zum Öffnen des magischen Tors gebraucht werden, sind dort verstreut.
Rechts der Gruft sieht man auf dem Beispiel eine Säule mit einer Vertiefung. Die könnte ideal zum Platzieren der Skelettschlüssel dienen – wir kommen später dazu.
Zaun und/oder Bäume können als Abgrenzung des begehbaren Bereichs dienen, so dass der Spieler den Friedhof nicht verlassen kann… das Tor ist in unserem Fall also leider zu.
Was uns nun noch fehlt, sind zwei Dinge:
- Ein Terrain. Wir könnten natürlich den Friedhof aus den Steinkacheln zusammensetzen, die man auch oben im Beispiel sieht. Aber dann hätten wir eine ebene Fläche und weniger Variation, was ich optisch weniger ansprechend finde.
- Eine Skybox. Natürlich soll unser Spiel zur Geisterstunde stattfinden, also brauchen wir einen Nachthimmel, gerne mit Mond.
Wir könnten für das Terrain Unity’s eigene Funktionalität nutzen. Aber um etwas schneller vorwärts zu kommen und auch etwas näher an der Low Poly Ästhetik zu bleiben, habe ich mich für ein vorgefertigtes Low Poly Terrain entschieden und bin im LowPoly Environment Pack von k0rveen auf itch.io fündig geworden.
Im Unity Asset Store habe ich das Skyboxes for space free Asset* gefunden, das einen schönen Nachthimmel enthält.
Konfiguration der Skybox
Beginnen wir mit der Skybox! Folge dem Link zum Asset* im Browser, logge dich falls nötig mit deinem Unity Account ein und klicke auf den “Add to my assets” Button.
Dann kannst du zu Unity zurück wechseln und den Package Manager unter Window → Package Manager öffnen. Klicke jetzt links auf “My Assets” (1), das neu hinzugefügte Asset sollte dann direkt oben in der Liste auftauchen (2). Falls nicht, kannst du auch über das Suchfeld danach suchen. Klicke dann auf “Download” (3) und, sobald der Download abgeschlossen ist, auf “Import 1.0.0 to project” (bzw. welche Versionsnummer dann auch immer aktuell ist, wenn du diesen Artikel liest).

Im Import-Fenster kannst du einfach auf “Import” klicken:

Das Package Manager Fenster kannst du nun wieder schließen.
Wenn du nun links unten einen Blick in die Project View wirfst und etwas herunterscrollst, wirst du feststellen, dass das Asset in einen Ordner Assets/AssetProviderForAll/skyboxes
installiert wurde. In diesem Ordner gibt es einen Unterordner materials/1080
, in dem alle Varianten der Skybox als Material gespeichert sind.
Wenn du die Materialien anklickst, kannst du im Inspector rechts ein Preview sehen. Du kannst die Skyboxen aber auch direkt in der Szene ausprobieren, indem du das Material auf den Horizont im Scene View ziehst:

Ich habe mich hier für die Skybox mit Material m22 entschieden. Dir steht es aber frei, eine beliebige andere Skybox zu verwenden.
Importieren eines Low Poly Terrains
Nach Herunterladen und Entpacken des LowPoly Environment Pack von k0rveen findet sich im entpackten Ordner eine Datei Terrain_2
.fbx. Wir wollen diese Datei im Projekt verwenden. Da wir jetzt allerdings einige weitere Modelle importieren, lege ich unterhalb unseres Assets/040_Models
einen neuen Unterordner LowPolyEnvironment
an. Kopiere das Terrain dann in diesen neuen Projektordner.
Ziehe dann das Terrain-Model aus diesem Ordner in die Szene unter das “Static” GO:

Das Terrain ist im Initialzustand noch etwas zu klein. Ändere daher die Skalierung auf (10, 10, 10) und setze im gleichen Zug auch noch das Häkchen bei “Static” im Inspector:

Unsere ursprüngliche Ebene, das “Plane” GO, benötigen wir jetzt nicht mehr. Es kann aus der Hierarchy View gelöscht werden.
Allerdings muss zum Terrain noch ein Mesh Collider hinzugefügt werden, damit Spieler, Skelette und andere physikalische Objekte mit dem Terrain kollidieren. Klicke im Inspector auf “Add Component” und wähle Mesh Collider. Als Mesh wird standardmäßig bereits das Mesh des Mesh Filters eingesetzt, so dass du nichts weiter ändern musst:

Nun wollen wir noch das Material des Terrains anpassen. Es wirkt doch etwas zu grell grün und will so nicht recht in die Nachtszene passen.
Wenn du im Inspector die Mesh Renderer Komponente ansiehst und das Materials Foldout aufklappst, siehst du ein Material “Green.13”. Wenn du das anklickst, wird das Material im Project View hervorgehoben, das Teil des original FBX ist. Aus diesem Grund können wir das Material nicht direkt ändern, aber wir können es duplizieren und dann dem Terrain unser Duplikat zuweisen.
Drücke Strg/Cmd-D, während du das Material in der Project View markiert hast:

Du siehst dann eine neue Instanz des Materials auf oberer Ebene in diesem Ordner. Benenne diese Instanz zu “Terrain” um und ziehe sie in unseren 060_Materials
Ordner.

Jetzt markieren wir die Kopie in Assets/060_Materials/Terrain
und können rechts im Inspector die Farbe des Terrains anpassen. Ich wähle ein sehr dunkles Braun (Farbcode #1F1608) und setze auch die “Smoothness” auf 0. Zum Ansehen ziehe ich das Material auf das Terrain in der Szene:

Damit das Terrain nun nicht nur visuell, sondern auch logisch ins Spiel eingebunden wird, müssen wir das NavMesh neu berechnen (“baken”). Klicke daher einmal auf das “Static” GO in der Hierarchy und klicke dann im Inspector auf “Bake”.
Außerdem versinken Skelett und Schwert GOs jetzt etwas im Terrain. Ich verschiebe sie etwas nach oben, so dass sie sich wieder überhalb der Oberfläche befinden.
Anpassung der gerichteten Beleuchtung
Sofern du noch keine Änderungen gemacht hast, betrachtest du die Szene höchstwahrscheinlich noch im “Unlit Draw Mode”. Die Einstellung kannst du in dieser kleinen Toolbar im Scene View vornehmen:
Wenn du auf den “Shaded Draw Mode” wechselst, wird die Beleuchtung berücksichtigt und du wirst feststellen, dass dann alles noch etwas heller wirkt.
Als wir die Graveyard-Szene ursprünglich angelegt haben, hat Unity uns direkt ein “Directional Light” GO erzeugt. Wenn du darauf klickst, wirst du im Inspector sehen, dass die Lichtfarbe ein warmes, gelbes Licht ist. Das will nicht recht zu unserer Nachtszene passen, daher ändere ich die Farbe zu einem bläulichen Weiß (#D8E7FF):
Außerdem können wir die Rotation des Lichts etwas ändern, so dass sie besser zum Mond der Skybox passt. Ich wähle (35, -135, 0). Die Position spielt beim Directional Light übrigens keine Rolle!

Aktivieren des Nebels
Nebel gehört natürlich zu einer schaurigen Friedhofsszene dazu! Er ist eine einfache und vergleichsweise kostengünstige Art, Atmosphäre zu erzeugen und die Sichtweite zu beschränken.
Die Einstellungen für den Nebel finden sich im Lighting Tab, das du normalerweise rechts neben dem Inspector Tab findest. Solltest du es nicht sehen, kannst du es auch per Window → Rendering → Lighting öffnen.
Dieses Fenster hat oben einige Tabs, unter “Environment” (1) finden wir unten die Einstellungen für den “Fog”. Mit Klick auf die Checkbox “Fog” aktivieren wir ihn (2). Wenn du nun nicht direkt eine Änderung im Scene View siehst, prüfe bitte, ob du Fog in der Scene View Konfiguration eingeschaltet hast (3):

Die Standardfarbe ist für unsere Nachtszene zu hell. Ich wähle ein fast schwarzes Blau als Nebelfarbe (#0A0B0C) und setze die “Density” auf 0.08. Mit diesen Einstellungen versinkt das Skelett fast im Nebel:

Wir können die Werte später noch anpassen, wenn wir einen besseren Eindruck davon haben, wie der Nebel in Kombination mit der übrigen Geometrie und Beleuchtung wirkt.
Da der Nebel recht heftig ist, empfehle ich dir, ihn in den Scene View Einstellungen wieder zu deaktivieren.
Erstellung von Prefabs am Beispiel der Gruft
Platzieren der Gruft
Wir platzieren nun die Gruft exemplarisch in der Szene. Zuerst legen wir wieder einen Unterordner namens “Halloween” im Assets/040_Models
Ordner an, dann kopieren wir alle Dateien aus KayKit_HalloweenBits_1.0_FREE/Assets/fbx(unity)
in diesen Ordner. Darunter ist auch die Textur, halloweenbits_texture.png
, die wir dann in Unity in den 050_Textures
Ordner verschieben können.
Wie schon bei den letzten importierten Assets erstellen wir außerdem ein eigenes Material. Dazu kann bspw. eines der in die Halloween-Modelle integrierten Materialen dupliziert und dann in den 060_Materials
Ordner verschoben werden. Die Textur des Materials wird dann durch die gerade in 050_Textures
kopierte Textur ersetzt. Wie immer setzen wir im neuen Material die “Smoothness” auf 0.
Jetzt können wir das Gruft-Modell platzieren. Es handelt sich hierbei um das Modell in Assets/040_Models/Halloween/cryp
t. Ich ziehe dieses Modell unter das “Static” GO in der Szene und korrigiere dann die Position zu (-1.27, -0.27, 2.56) und die Rotation zu (-3.309, 153.518, 0). Im Mesh Renderer setze ich unser eigenes Material.
Da es sich bei diesem Objekt um ein statisches Objekt handelt, benötigen wir einen Collider. Je nach Objekt wäge ich dabei ab, ob ich einen Mesh Collider verwende, der vergleichsweise aufwändig ist und sich auf die CPU Auslastung auswirkt, oder die Form mithilfe eines einfacheren Colliders annähern kann. Für die Gruft wähle ich einen Mesh Collider.
Außerdem setze ich das “Static” Flag im Inspector. Damit wird die Gruft sowohl bei der Berechnung des Nav Meshs als auch später beim Generieren der Beleuchtungsinformationen als statisches Objekt betrachtet. Insofern musst du dir auch keine Sorgen machen, dass die Gruft im Moment noch recht heftig aus der Szene hervorsticht – das wird sich bald ändern.
Wenn du jetzt über das “Static” GO das Nav Mesh neu generierst, wirst du feststellen, dass die Wände der Gruft ein Loch im Nav Mesh erzeugen. Du wirst auch feststellen, dass das Dach der Gruft Teil des Nav Meshs ist. Das liegt daran, dass auch dieser Teil der Geometrie den Anforderungen an den begehbaren Bereich genügt. Wir können das ignorieren, denn es gibt keinen Weg, diesen Teil des Nav Meshes zu erreichen, und wir müssen uns keine Sorgen machen, dass ein Skelett auf einmal auf einem Dach auftaucht.
Erzeugung eines Prefabs
Jetzt ist die Gruft für’s Erste vorbereitet. Der letzte Schritt, den wir jetzt für die Gruft und vor allem für folgende Objekte, die mehrfach in der Szene vorkommen können, durchführen, ist die Konvertierung in ein eigenes Prefab. Beim Erstellen eines Prefabs konvertieren wir die Einstellungen der Gruft, die aktuell so nur in der Szene existieren, in ein wiederverwertbares Objekt, das mehrfach mit den gleichen Einstellungen in dieser oder auch in anderen Szenen platziert werden kann oder das per (Visual) Script erzeugt werden kann.
Damit wir nicht den Überblick verlieren, erzeugen wir zur Vorbereitung auch in unserem 020_Prefabs
Ordner einen Unterordner Halloween
. Dann ziehen wir das “crypt” GO aus der Hierarchy in diesen Ordner im Project View. Achte einmal auf das Icon des GO in der Hierarchy: du wirst feststellen, dass es sich verändert. Warum das so ist, erkläre ich jetzt.

Im Laufe dieser Artikelreihe haben wir bereits zwei Arten von Prefabs kennengelernt:
- Das klassische Prefab in Unity ist ein gespeichertes GameObject, das inklusive seiner Komponenten und Hierarchie wiederverwendet werden kann. Das “XR Origin (XR Rig)”, das wir aus den XRIT Starter Assets importiert haben, oder die Vignette sind solche Prefabs. Ein Prefab kann Unity-eigene Komponenten (wie Rigidbody oder Script Machine) und MonoBehaviour-basierte Komponenten enthalten.
- Ein FBX Model Prefab ist eine Unity-kompatible Repräsentation eines importierten 3D-Modells (als Autodesk Maya FBX-Format), oft inklusive seiner Meshes, Animationen und Materialien. Es kann keine darüber hinausgehenden Unity-spezifischen Komponenten enthalten. Das Skelett, Schwert oder die Gruft sind solche Beispiele. Hier wird das FBX Model Prefab erst in der Szene um Unity-spezifische Funktionalität erweitert.
Um die Verwirrung komplett zu machen, gibt es noch eine dritte Variante: Prefab Variants. Das sind Ausprägungen entweder eines Prefabs oder eines FBX Model Prefabs, bei denen Attribute geändert, Komponenten gelöscht oder hinzugefügt, oder deren Hierarchie erweitert wurde.
Sobald wir also die Gruft, deren “Static” Flag, Transform und Material wir verändert und zu der wir einen Mesh Collider hinzugefügt haben, in den Project View ziehen, um daraus ein wiederverwendbares Objekt zu machen, wird aus dem ursprünglich in der Szene erweiterten FBX Prefab Variant ein Prefab Variant, denn als FBX Model Variant könnten wir dieses Objekt nicht mehr speichern: es enthält jetzt Änderungen, die ein FBX Model Variant nicht unterstützt.
Es besteht aber weiterhin eine Verbindung zum FBX Model Variant, aus der wir unser “crypt” Prefab Variant erzeugt haben: Änderungen an den Parametern des Modells in Assets/040_Models/Halloween/crypt.fbx
würden sich z. B. auf das Prefab Variant und auf alle Instanzen dieses Prefab Variants in den Szenen auswirken.
Hinweis zur Wiederholung
Diesen Prozess werden wir nun einige Male wiederholen: wir importieren ein FBX Model Variant (aus dem 040_Models
Ordner) in unsere Szene, machen es “Static” falls angebracht, erweitern es um Collider, ggf. auch Rigidbody und XRGrabInteractable, und speichern es als Prefab Variant (in den 020_Prefabs
Ordner).
Gerade für wiederverwendbare Objekte, wie z. B. ein Stück Zaun oder einen Baum, ist das wichtig: wir arbeiten in der Szene dann in Zukunft nach einmaligem Anlegen nur noch mit den Objekten aus dem Prefabs Ordner! Das ist wesentlich bequemer, als jedes Mal das “nackte” Model wieder um Komponenten zu erweitern. Außerdem können wir die Prefab Variant editieren, wenn wir feststellen, dass z. B. ein Collider nicht genau genug ist, und die Änderung wird dann auf alle Instanzen in der Szene angewandt.
Weitere Objekte
Ich wiederhole diesen Prozess nun also für die verschiedenen Bäume aus dem Halloween Pack (tree_pine_orange_*, tree_pine_yellow_large_*): ich ziehe das Modell in die Hierarchy, setze das “Static” Flag und unser eigenes HalloweenBits Material und füge einen Capsule Collider hinzu. Unity berechnet den Radius des Colliders anhand der Geometrie, weshalb er ohne weitere Änderungen übernommen werden kann. Dann ziehe ich das GO aus der Hierarchy in den Prefabs Ordner. Um jetzt Bäume in der Szene zu platzieren dupliziere ich entweder existierende GOs in der Hierarchy oder ziehe Instanzen der neu angelegten Prefabs in die Szene. Ich arbeite nicht mehr mit den Models direkt.
Bei den toten Bäumen, tree_dead_*, gehe ich ähnlich vor, allerdings betrachte ich hier die Form bei der Auswahl eines Colliders: für tree_dead_large_decorated und tree_dead_small wähle ich aufgrund der komplexeren Geometrie bzw. aufgrund der Höhe einen Mesh Collider. Bei den anderen nutze ich einen Box Collider, den ich so verkleinere, dass er den Baumstamm möglichst eng umschmiegt.
Für den Zaun, der den Friedhof umschließen soll, wähle ich arch_gate als (verschlossenen) Haupteingang, sowie fence_pillar, fence_pillar_broken, fence_seperate und fence_seperate_broken als Objekte für den Zaun. Hier nutze ich jeweils Box Collider.
Mit diesen vorbereiteten Prefab Variants beginne ich, die Umrisse des Friedhofs zu entwerfen.
Bevor ich noch ein paar weitere Hinweise gebe, zeige ich dir, wie das Ergebnis bei mir aussieht:

Es macht Sinn, beim Entwerfen der Szene gelegentlich mal das Spiel im Headset auszuprobieren. So gewinnst du einen guten Eindruck für die Größe des spielbaren Bereichs. Schließlich soll das Ganze auch kein “Walking Simulator” werden, wo der Spieler zum Durchschreiten des Levels von einer Ecke zur anderen Minuten braucht.
Das war ein Grund, warum ich den Zaun relativ eng gezogen habe. So oder so sollte der nicht direkt auf den Kanten des Terrains platziert werden, sondern ein wenig Platz lassen. Schließlich mag es Situationen geben, wo der Spieler direkt am Zaun steht: dann soll er nicht in die Leere blicken.
Der Zaun muss auch nicht durchgehend platziert werden, er kann auch durch ein kleines Wäldchen unterbrochen werden, da ja auch die Bäume nicht passierbar sind.
Das Platzieren von Objekten direkt auf der Oberfläche ist einfacher, wenn du z. B. einen Baum mit aktiviertem Surface Snapping platzierst. Das geht, indem du einen Baum mit der Maus bei gedrückter Strg/Cmd- und Umschalt-Taste greifst. Du erkennst den Modus an der Veränderung am lokalen Ursprung, wie zu Beginn des Videos zu sehen. Beim Bewegen wird er dann automatisch auf der Oberfläche gehalten:
Hier findest du mehr Informationen, wie du das Positionieren von GameObjects einfacher machen kannst.
Zuletzt habe ich dort, wo der Spieler in die Ferne blicken kann, dafür gesorgt, dass an den Kanten der Karte weitere Bäume stehen. Die sieht der Spieler vielleicht nicht direkt, weil sie im Nebel verschwinden, aber sie erzeugen eine schöne Silhouette beim Übergang zur Skybox.
Ich habe zum Editieren übrigens ein Plugin namens Prefab World Builder* verwendet. Damit kannst du dir leicht Paletten von Objekten erstellen, die zufällig auf Mausklick in der Szene platziert werden sollen, inklusive zufälliger Rotation und Skalierung oder konfigurierbarem Abstand. Das ist nur ein kleiner Teil der Funktionalität, aber es ist ideal für etwas wie einen Wald aus verschiedenen Bäumen.
Beim Zaun habe ich mir ein Objekt aus zwei Bauteilen gebaut, indem ich den Zaun selbst zu einem Child der Zaunsäule gemacht habe. So konnte ich einfach die Zaunsäule samt Child duplizieren und die Position und Rotation anpassen, anstatt immer beides einzeln zu machen.
Wenn du deine Welt ausbaust, achte darauf, dass die statischen Objekte zu Prefabs konvertiert werden, wie besprochen, und dass du sie in der Szene alle unterhalb des “Static” GO anlegst, da dort ja unsere Nav Mesh Surface Komponente hängt. Wenn du fertig bist, solltest du dort auch das Nav Mesh noch einmal aktualisieren.
Zuletzt habe ich die Position des Spielers (das “XR Origin (XR Rig)” GO) näher an das Friedhofstor positioniert. Hier kommt der Spieler an und das Spiel beginnt.
In VR sieht das Ganze dann inzwischen so aus:
Obwohl es keine weiteren Lichtquellen mehr gibt, sind zumindest die Objekte in unmittelbarer Nähe immer noch hell erleuchtet. Dem widmen wir uns als Nächstes.
Beleuchtung
In Unity gibt es zwei Arten von Beleuchtung: Echtzeit- (Realtime) und vorberechnete Beleuchtung, sog. Baked Lighting. Echtzeitbeleuchtung wird in jedem Moment berechnet, während das Spiel läuft. Das bedeutet, dass Lichtquellen wie die Sonne oder Lampen die Objekte im Spiel direkt beeinflussen und sofortige Änderungen zeigen, wenn sich etwas bewegt. Das braucht jedoch mehr Rechenleistung und kann die Spielperformance beeinflussen – gerade bei Standalone-VR. Baked Lighting wird einmal vorab berechnet und dann als statische Lichtinformationen auf Oberflächen gespeichert. Das spart Rechenleistung, kostet aber im Gegenzug mehr Speicher und ist weniger flexibel, weil sich vorberechnetes Licht nicht an Objekte anpasst, die sich während des Spiels bewegen.
Mein Ansatz ist, für Standalone-VR möglichst nur ein Directional Light als Echtzeit-Lichtquelle zu verwenden und den Rest statisch vorab zu generieren. Das funktioniert natürlich nur, solange keine flackernden Lichter, Taschenlampen oder ein Tag-/Nacht-Zyklus im Spiel sind.
Baked Lighting
Da wir viele Objekte haben, die sich gar nicht bewegen, sollten wir für diese Baked Lighting verwenden, um die Performance zu schonen.
Zunächst müssen wir die Modelle allerdings dafür vorbereiten. Baked Lighting erzeugt sogenannte Lightmaps, die man sich wie eine zweite Schicht auf der Oberfläche eines Objekts vorstellen kann: dort, wo das Objekt gut beleuchtet ist, ist sie transparent. Dort, wo kein Licht hinkommt, ist sie schwarz und undurchlässig. Und dort, wo ein gelbe Lichtquelle auf das Objekt einwirkt, ist die Lightmap gelb und färbt so das Originalobjekt ein. Damit die Lightmap richtig berechnet werden kann, muss jede Oberfläche eines Models auf eine Oberfläche projiziert werden (sog. Unwrapping) und die daraus entstehenden Koordinaten werden neben den Texturkoordinaten gespeichert. Man spricht hier von einem neuen UV-Channel, konkret UV2. Für die UV-Koordinaten und für die Lightmaps, auf denen oft die Oberflächen mehrerer Objekte nebeneinander platziert werden (sog. Packing). Für den neuen UV-Channel und die generierten Lightmaps wird dann etwas mehr Speicher benötigt.
Markiere im Project View zuerst alle Models im Assets/040_Models/Dungeon
Ordner. Aktiviere dann rechts im Inspector die Checkbox bei “Generate lightmap UVs” und klicke auf “Apply”:

Wiederhole den Prozess für Assets/040_Models/Halloween
und Assets/040_Models/LowPolyEnvironment
. Für die beweglichen Modelle auf oberer Ebene, das Skelett und die Schwerter, müssen wir das nicht machen, da ihre Beleuchtung anders berechnet wird.
Vergewissere dich jetzt noch einmal, dass alle Objekte innerhalb des “Static” Ordners in der Hierarchy auch wirklich als “static” markiert sind. Nur so werden sie in den “Baking”-Prozess eingebunden.
Wechsle dann zum Lighting Tab rechts neben dem Inspector. Falls du es nicht siehst, kannst du es per Window → Rendering → Lighting öffnen.
Mit Blick auf Performance und Möglichkeiten einer Standalone-Anwendung müssen wir die Standard-Einstellungen der Beleuchtung etwas anpassen. Daher klicken wir zuerst auf “New” bei den Lighting Settings. Es wird dann unmittelbar eine neue Einstellungen-Datei im Assets Ordner angelegt, deren Namen du im Project View verändern kannst. Ich benenne meine zu Graveyard
, weil die Lighting-Settings zunächst für diese Szene gedacht sind, und verschiebe die Datei dann auch im Project View in den 000_Scenes
Ordner.

Einer der wesentlichen Parameter bei der Berechnung der Lightmaps ist die “Lightmap Resolution”. Der Parameter regelt, wie viele Textur-Pixel (Texel) auf einer Lightmap für einen Meter Oberfläche im virtuellen Raum verwendet wird. Je höher dieser Wert ist, desto detailreicher wird die Lightmap. Gleichzeitig erhöht sich aber der Speicherbedarf und die Berechnungsdauer. Verringere den Wert von Standard 40 auf 5:

Anmerkung: Bitte speichere jetzt die Szene. In meinen Tests mit dem Unity 6 Preview und auch mit dem LTS Release habe ich die Erfahrung gemacht, dass der nächste Schritt gelegentlich den Editor einfrieren lässt. Es scheint, als wenn jeweils nur die erste Generierung aus dem Editor funktioniert und der Editor für einen weiteren Lauf neu gestartet werden muss.
Anmerkung 2: Mit Version 6000.0.24f1 scheint das Problem behoben worden zu sein.
Ganz unten im Tab findest du einen Button “Generate Lighting”, mit dem du nun die Beleuchtung berechnen kannst – klicke ihn:

Die Szene ist nicht all zu kompliziert und die Beleuchtungseinstellungen sind einfach, daher sollte die Berechnung nicht all zu lange dauern. Nach Abschluss lädt Unity die neu angelegten Lightmaps.
Unterhalb des Buttons findest du nun eine Anzeige über die generierten Lightmaps: “2 backed lightmaps: 2x(1024x1024px) 5.3 MB”. Das ist der zusätzliche Speicherbedarf.
Wenn du im Lighting Tab oben auf das “Baked Lightmaps” Tab klickst, kannst du dir das Ergebnis ansehen. Wenn du dir die erste Lightmap ansiehst, wirst du feststellen, dass über ihr ein zusammenhängendes Gitternetz angezeigt wird: das lässt darauf schließen, dass es sich hier um die Lightmap für das Terrain handelt. Und tatsächlich: wenn du auf das Gitternetz klickst, färbt es sich gelb und im Hintergrund im Scene View wird das Terrain-Objekt markiert. Das Terrain ist so groß, dass es selbst mit einer Lightmap Resolution von nur 5 Texeln eine gesamte Lightmap einnimmt.

In der zweiten Lightmap findest du lauter kleinere Objekte, das sind Zäune, Bäume und Gruft.
Wenn du die Scene im Shaded Draw Mode ansiehst, wirst du feststellen, dass die Objekte nun gemäß der Richtung der einzigen Lichtquelle, dem Directional Light, beleuchtet sind. Die dem Licht abgewandte Seite bleibt dunkel, wie du hier im Screenshot aus dem Editor sehen kannst:

Auf dem Screenshot kommt das nicht so rüber, aber ich finde die Szene noch etwas zu hell!
Daher ändere ich die Farbe des “Directional Light” GO nochmals, diesmal zu einem dunklen grau (#434343).
Kerzen-Partikelsystem
Als nächstes testen wir, wie ein beleuchtetes Objekt in der Szene wirken würde. Ich nutze dazu das Model “shrine_candles” aus dem Halloween Ordner und erzeuge auf dem bereits besprochenen Weg ein Prefab daraus: in die Szene ziehen, als “Static” markieren, Material austauschen, Collider hinzufügen (ich nutze zwei Box Collider für die beiden Ebenen des Steins und ignoriere die Kerzen oben), dann in den Prefabs Ordner ziehen.

Leider haben die Kerzen kein Partikelsystem, um eine Kerzenflamme zu simulieren. Das können wir uns aber vergleichsweise einfach selbst erstellen! Wir benötigen dazu eine Textur, die einer Kerzenflamme gleicht, und lassen einfach ein paar Quads davon mithilfe eines Partikelsystems rotieren und skalieren.
Ich habe eine solche Flamme kurz mit Krita gezeichnet. Ich habe einfach zwei Flächen in Form der Flamme gezeichnet, einmal mit Transparenz 50% für den äußeren Teil und einmal im inneren Transparenz 0%. Das Ergebnis kannst du dir unter dem Bild herunterladen.

Lade diese Datei flame.png herunter und speichere sie im Assets/050_Textures
Ordner:
Wähle die Textur in Unity aus und ändere das Feld “Wrap Mode” von
“Repeat” zu “Clamp”: diese Textur wird sich nicht wiederholen/kacheln.
Lege dann ein neues Material “flame” im Ordner 060_Materials
an. Konfiguriere das Material wie hier zu sehen:
Die “Base Map” Farbe ist (233, 160, 0) (hex #E9A000), die HDR Color für die Emission ist (255, 57, 0).
Positioniere dann leeres GO im “shrine_candles” GO in der Szene, indem du mit rechts darauf klickst und Create Empty auswählst. Nenne dieses Child-GO “flame1_pos”. Wechsle dann in die orthografische Projektion und positioniere “flame1_pos” während du zwischen Seiten- und Vorderansicht wechselst so, dass es genau am Ende eines Kerzendochts liegt, wo eine Kerzenflamme entstehen könne:

Füge dann ein Partikelsystem ein, indem du rechts auf das “flame1_pos” GO klickst und Effects → Particle System auswählst. Nenne das GO “flame”.
Unsere Flammentextur von oben wird nun zu einem Partikel im Partikelsystem. Ändere dazu die folgenden Attribute des Partikelsystems im Inspector:
- In den allgemeinen Einstellungen:
- Prewarm aktivieren – damit werden alle Partikel vorab generiert
- “Start Lifetime” über den kleinen Button an der Seite zu “Random Between Two Constants” ändern und dann 1 und 2 in die Eingabefelder eingeben
- “Start Speed” zu 0 ändern – die Partikel bleiben an Ort und Stelle
- Bei “Start Size” rechts wieder über den Button an der Seite “Random Between Two Constants” aktivieren und 0.2 und 0.4 in die Eingabefelder eingeben
- “3D Start Rotation” aktivieren – ein Partikel soll zufällig um die Y-Achse emittiert platziert werden
- Darunter rechts über den Button “Random Between Two Constants” aktivieren; in die Eingabefelder folgende Werte eingeben:
X: 0, 0
Y: 0, 360
Z: 0, 0 - “Scaling Mode” zu “Shape” ändern
- “Emitter Velocity Mode” zu “Transform” ändern
- “Max Particles” zu 50 ändern
- “Shape” deaktivieren – wir emittieren alle Partikel vom gleichen Punkt
- “Size over lifetime” aktivieren
- Im unteren Teil des Inspectors nach Klick auf “Particle Curve” die Form der Kurve editieren: die beiden äußeren Punkte auf Y=0 ziehen und dann per Doppelklick einen neuen Punkt in der Mitte einfügen und auf Y=1 ziehen (siehe Grafik unten)
- “Rotation over lifetime” aktivieren – ein Partikel darf über die Lebenszeit ruhig etwas um die Y-Achse rotieren
- “Separate Axes” aktivieren, dann folgende Werte eingeben:
X: 0, 0
Y: -50, 50
Z: 0, 0
- “Separate Axes” aktivieren, dann folgende Werte eingeben:
- Bei “Renderer”:
- Wähle als “Material” unser gerade angelegtes “flame” Material
- Setze als “Sort Mode” “Youngest In Front”
- Setze “Max Particle Size” auf 5
So sollte die Kurve für die “Size over lifetime” aussehen:

Wenn du das Partikelsystem in der Hierarchy markierst, sollte die Vorschau im Scene View ungefähr so aussehen:
Wenn du mit dem Ergebnis zufrieden bist, ziehe bitte das “flame” GO aus der Hierarchy in den 020_Prefabs
Ordner im Project View. Damit wird auch aus diesem Partikelsystem ein Prefab und wir können es wiederverwenden.
Wiederhole nun den Prozess zum Anlegen der Flammenposition für die übrigen Kerzen: erzeuge neue Child-GOs “flame2_pos”, “flame3_pos” und “flame4_pos”. Positioniere sie passend zu den übrigen Kerzen und ziehe dann jeweils aus dem 020_Prefabs
Ordner das “flame” Prefab auf das GO. (Alternativ kannst du auch das “flame1_pos” GO duplizieren, den Namen ändern und die Position korrigieren.)
Bisher haben wir natürlich nur Schall und Rauch erzeugt. Die Kerzenflammen sind nur Effekte, wir benötigen noch ein richtiges Licht! Klicke wieder rechts auf das “shrine_candles” GO in der Hierarchy und wähle Light → Point Light.
Positioniere das Licht etwas überhalb der Kerzen und ändere den “Mode” zu “Baked” und die Farbe zu einem zum Partikelsystem passenden Orange: (255, 160, 0). Ändere die “Intensity” zu 5 und aktiviere “Shadow Type” “Soft Shadows”.

Die Einstellung “Baked” sorgt dafür, dass die durch die Kerze erzeugte Beleuchtung samt der konfigurierten Schatten in die Lightmaps aufgenommen wird. Da sich diese Kerzen nicht von ihrem Platz bewegen werden, ist das die richtige Einstellung.
Wir möchten, dass die Kerzenflammen und das Point Light Teil des Prefabs werden, damit auch der nächste platzierte Schrein “funktionierende” Kerzen hat. Klicke dazu auf das “shrine_candles” GO und wähle dann rechts im Inspector im “Overrides” Dropdown “Apply All”. Damit werden die Änderungen am Prefab, die wir in der Szene vorgenommen haben, auf das gespeicherte Asset und auch in alle anderen Instanzen dieses Prefabs angewendet.

Ich habe nun dieses Schrein-Prefab noch ein paar Mal auf dem Friedhofsgelände verteilt, um zu sehen, wie es wirkt, wenn wir uns durch die Szene bewegen.
Jetzt ist es Zeit, die Lightmaps zu aktualisieren. Wechsle wieder zurück auf das Lighting Tab.
Anmerkung: Zur Sicherheit solltest du jetzt wieder speichern. Wie bereits oben geschrieben hat das Generieren der Lightmaps nicht zuverlässig funktioniert und den Editor eingefroren. Wenn das bei dir ebenfalls der Fall ist, versuche einmal, Unity neu zu starten.
Klicke jetzt wieder auf “Generate Lighting”.
Audio
Wir haben bisher noch gar nicht über Musik oder Soundeffekte gesprochen. Die sind in VR ebenfalls unglaublich wichtig.
Durch Umgebungsgeräusche können wir auf sehr einfache Weise Stimmung erzeugen. Wir benötigen eine Geräuschkulisse, die zu unserem nächtlichen Friedhof passt: das Rauschen von Wind, das Knarren von alten Bäumen, eine Eule,…
Ich habe mich wieder auf die Suche gemacht und bin bei der Essential Series von Nox Sound Design auf itch.io fündig geworden. In diesem kostenlosen CC0 Asset finden sich neben Schrittgeräuschen (Footsteps), die wir bald noch verbauen werden, auch Umgebungsgeräusche aus der Natur (Nature Ambience).
Lade das Archiv herunter und kopiere die Datei Essentials_Series_NOX_SOUND/Nature_Essentials_NOX_SOUND/Ambiance_Night_Loop_Stereo.wav
in einen neuen Ordner Assets/080_SFX
.
Erzeuge dann in der Hierarchy per Rechtsklick auf eine freie Stelle eine Audio Source über das Kontextmenü Audio → Audio Source. Nenne das GO “Ambience”. Wähle dann im Inspector in der Audio Source Komponente im Feld “Audio Resource” die Datei “Ambiance_Night_Loop_Stereo”. Setze außerdem das Häkchen bei “Loop”.

Anmerkung: Mit Unity 6 habe ich auf meinem Quest 3 Headset die Erfahrung gemacht, dass sich das WAV in der installierten Version ziemlich merkwürdig anhört. Auch das explizite Umstellen auf Mono (von Stereo) hat keinen Unterschied gebracht. Ich habe daher die Datei mit Audacity von WAV zu einem Mono-MP3 konvertiert, womit es sich dann richtig anhört. Ich habe dieses MP3 hier hochgeladen, damit du es ggf. auch damit probieren kannst:
Mit etwas Beleuchtung und Umgebungsgeräuschen wirkt die Szene nun wirklich unheimlich, oder? Und wie wir die Augen des Skeletts zum leuchten bringen, besprechen wir beim nächsten Mal!
Ausblick
Im nächsten Teil wenden wir uns wieder dem Skelett-Gegner zu und sorgen dafür, dass er dem Spieler Schaden zufügen kann und das Spiel beendet wird, wenn dem Spieler die HP ausgehen.
* Dieser Artikel enthält sogenannte Affiliate-Links. Wenn du sie klickst und im verlinkten Store etwas kaufst, erhalte ich eine kleine Provision. Für dich ändert sich der Preis nicht und ich erhalte keine Informationen über deinen Warenkorb.