In Teil 2 haben wir gelernt, was die Aufgaben eines XR Rigs sind, und wie uns das XRIT Sample Projekt hier einiges an Arbeit abnehmen kann. Jetzt sorgen wir dafür, dass unsere funktionsfähigen Controller auch irgendwie zum Einsatz kommen.
Asset-Import
Asset-Download
Bevor wir uns weiter mit improvisierten Unity-Cubes herumschlagen, wird es Zeit, dass wir die ausgesuchten Assets zum Einsatz bringen. Falls noch nicht geschehen, lade bitte die folgenden Asset-Packs von Kay Lousberg herunter:
- Halloween Bits Pack
- Skeletons Character Pack
- Adventurers Character Pack
- Dungeon Remastered 3D Asset Pack
Ich verlinke hier Kay Lousbergs Homepage direkt, falls Kay im Laufe der Zeit seinen Distributionskanal ändert. Zum aktuellen Zeitpunkt verlinkt jede seiner Asset-Pack-Seiten zu einer korrespondierenden Seite auf itch.io, einer bekannten Indie-Games-Plattform.
Auf der jeweiligen itch.io Seite findest du oben einen “Download Now” Button. Die Asset Packs werden in verschiedenem Umfang angeboten und die größeren Pakete mit mehr Modellen haben einen Mindestpreis. Das Basispaket ist aber kostenlos herunterladbar. Lass dich von itch.io nicht beirren, wenn es einen Preis vorschlägt: direkt über dem Eingabefeld für einen Preis ist ein Link “No thanks, just take me to the downloads”. Auf der folgenden Seite findest du dann nochmal einen letzten Download-Button, den du klicken musst.
Entpacke die vier heruntergeladenen Archive in ein Verzeichnis außerhalb des Projekts. Wir werden uns nach und nach daraus bedienen, benötigen aber nicht alle Dateien.
Ich freue mich, dass Kay diese Assets kostenlos zur Verfügung stellt, denn damit kann jeder Leser dieser Artikelreihe unabhängig vom Geldbeutel oder den verfügbaren Bezahlmethoden ein ansehnliches Ergebnis erstellen. Falls du ein paar Euro/Dollar erübrigen kannst oder mit mehr Assets kreativ werden willst, freut sich Kay aber sicher, wenn du den vorgeschlagenen Preis annimmst oder erhöhst oder sogar die “Extra” oder “Source Files” Version kaufst.
Alternativ unterhält Kay auch ein Publisher-Profil im Unity Asset Store*, wo du die Assets kostenpflichtig herunterladen kannst.
Projektstruktur, die zweite
Wir folgen dem vorgeschlagenen Schema aus dem zweiten Teil mit weiteren Ordnern. Kay Lousberg’s Assets sind in verschiedenen Dateiformaten verfügbar, für uns relevant sind insbesondere die FBX Dateien. Hierbei handelt es sich um ein populäres Format, das ursprünglich von Autodesk entwickelt wurde. FBX Dateien können allerlei Informationen enthalten, die für 3D Modelle relevant sind, wie z. B. Meshes, Materialien, Texturen, Animationen und Rigs. Lousberg hat gelegentlich auch schon einen speziellen Ordner “fbx(unity)” angelegt, den wir nutzen sollten, sofern er vorhanden ist.
Bitte lege in der Project View unter Assets diese weiteren Ordner an:
020_Prefabs
(sofern im zweiten Teil noch nicht geschehen) – hier speichern wir Prefabs, die wir aus den Modellen erzeugen030_Scripts
– hier speichern wir C# Skripte040_Models
– hier speichern wir die FBX Dateien050_Textures
– hier speichern wir die PNG Dateien060_Materials
– hier speichern wir Materialien ab, die wir für die Texturen erzeugen070_Animation
– hier speichern wir alles rund um Animationen
In 040_Models
werden wir die Original-FBX Dateien ablegen, in 050_Textures
die Original-PNG-Texturen. In 060_Materials
erstellen wir unsere eigene Version der Materialien von Kay, wo wir einige Materialeigenschaften anpassen. Aus all dem gemeinsam erzeugen wir dann Prefabs in 020_Prefabs
, die wir letztendlich im Spiel verwenden werden.
Unser erstes interaktives Objekt
Wir beginnen mit einem Schwert, das der Spieler verwenden kann. Das entsprechende Modell finden wir im Adventurers Asset Pack. Kopiere die Datei KayKit_Adventurers_1.0_FREE/Assets/fbx/sword_1handed.fbx
in den Ordner Assets/040_Models
im Projekt. Kopiere außerdem die Datei KayKit_Adventurers_1.0_FREE/Assets/fbx/knight_texture.png
in den Ordner Assets/050_Textures
.
3D Modell und Material
Da wir jetzt ein neues Objekt anlegen, das uns als Orientierung in der Szene dienen kann, brauchen wir den im zweiten Teil angelegten Cube nicht mehr. Lösche dieses GameObject aus der Szene: klicke rechts darauf und wähle Delete.
Lege jetzt ein neues GameObject an. Klicke mit rechts in einen freien Bereich der Hierarchy und wähle Create Empty im Kontextmenü. Nenne das neue GameObject “Sword” und editiere die Position im Inspector zu (0, 1, 3). Damit befindet es sich vor dem Spieler, genau wie der Cube zuvor, und schwebt etwas über dem Grund.
Ziehe jetzt das Schwert-Modell sword_1handed
aus dem 040_Models
Ordner auf das in der Szene angelegte GameObject “Sword”, so dass es zu einem Child-GO unter dem “Sword” wird.
Wir platzieren das Modell ganz bewusst als Child-GO: so können wir alle nötigen Komponenten auf das Parent-GO oder in weitere Child-GOs platzieren, während das Modell ohne großen Aufwand austauschbar ist. Darüber hinaus wird bei Bedarf nur dieses Objekt skaliert, falls das Modell verkleinert oder vergrößert werden soll. Auf dem Parent werden wir gleich Physik aktivieren und hier führt Skalierung möglicherweise zu unerwünschten Nebeneffekten.

Lege jetzt ein neues Material in den Assets an. Klicke im Project View rechts auf den Ordner 060_Materials
und wähle Create → Rendering → Material. Nenne das Material knight_texture
, denn wir werden diese Textur als Grundlage für das Material nutzen.

Während du das neue Material markiert hast, wähle den Ordner 050_Textures
, und ziehe dann die dort zu sehende Texture knight_texture
auf das Rechteck links neben dem Label “Base Map”.
Ziehe außerdem den Slider im Feld “Smoothness” nach links oder setze den Wert auf 0.

Solltest du Schwierigkeiten haben, die Textur in den Material-Inspector zu ziehen, ohne versehentlich die Textur zu markieren und damit die Inspector-Ansicht zu verändern, kannst du auch bei markiertem Material mit dem kleinen Schloss über dem Inspector die aktuelle Ansicht festsetzen. Dann musst du nur daran denken, sie gleich durch erneuten Klick auf das Schloss wieder freizugeben.
Öffne jetzt wieder den 060_Materials
-Ordner im Project View und ziehe das gerade angelegte Material knight_texture
auf das Schwert, das du in der Scene View vor dir siehst. Alternativ kannst du das GO sword_1handed in der Hierarchy View auswählen und das Material in den “Element 0” Slot in der Mesh Renderer Komponente im Inspector ziehen.
Markiere das Schwert in der Szene und drücke “F”, um das Objekt zu fokussieren. Mit dem Material sieht es gleich viel besser aus!

Rigidbody und Collider
Als nächstes fügen wir einen Rigidbody zum Sword-GO hinzu. Damit unterliegt das Objekt den Gesetzen der Physik in Unity und kann von Kräften wie Schwerkraft und Kollisionen beeinflusst werden, wodurch es realistisch bewegt und reagiert. Zudem ermöglicht die Komponente die Nutzung von Physik-Interaktionen wie dynamische Bewegungen und Zusammenstöße.
Wähle das Sword-GO im Hierarchy View und klicke dann rechts im Inspector auf “Add Component”. Tippe “Rigidbody” ins Suchfeld und wähle die Komponente aus den Ergebnissen aus. Die einzige Änderung, die wir an den Attributen dieser Komponente vorerst vornehmen, ist die Erhöhung des Gewichts von 1 auf 10.

Damit das Objekt mit einem Gewicht von 10 und aktivierter Schwerkraft nicht einfach durch den Boden fällt, benötigt es noch einen Collider.
Markiere das “Sword” GO und klicke dann im Inspector erneut auf “Add Component”. Suche nach “Box Collider” und füge ihn hinzu. Die Umrisse des Box Colliders sind erst zu sehen, wenn Gizmos aktiviert sind. Klicke rechts oben in der Scene View auf das Gizmos Icon, um sie zu aktivieren:

Mit aktivierten Gizmos wird klar, dass der Box Collider in seiner initialen Größe viel zu groß ist. Er muss verkleinert werden, damit er sich besser an die Konturen des Schwert-Modells anpasst.
Den Collider kann man über einen Button in der BoxCollider-Komponente editieren (1). Daraufhin können die Seiten des Colliders durch Klicken und Ziehen der grünen Mittelpunkte (2) auf den Seitenflächen verschoben werden.

Es ist einfacher, den Collider genau zu platzieren, wenn man aus der perspektivischen Projektion in die orthografische Projektion wechselt. Klicke dazu auf das “Persp” Label rechts oben im Scene View, beim sogenannten Axis Gizmo:

Dann kannst du durch klicken auf eine der beiden horizontalen Achssymbole das Schwert um die Y-Achse rotieren und so den Box Collider von vorne und hinten sowie von der Seite sehen und die Seiten entsprechend verschieben:
Sobald der Box Collider angepasst ist, kannst du durch erneuten Klick auf die Perspektive unter dem Axis Gizmo wieder zurück in die perspektivische Ansicht wechseln.
Falls du Schwierigkeiten hast, den Collider anzupassen, kannst du im Inspector diese Werte direkt eingeben:
Center: (0.00187932, 0.5243468, -0.001879364)
Size: (0.3121471, 1.763028, 0.06406927)
Würdest du das Schwert etwas zur Seite schieben, so dass es nicht mit dem XR Rig kollidert, und dann das Spiel starten, dann würde das Schwert gerade nach unten auf den Boden fallen und dort aufrecht stehen bleiben. Wenn du willst, kannst du die Form z. B. durch einen zweiten, schmaleren Box Collider für den Griff und einen Sphere Collider am Griffende noch weiter annähern. Für unsere Zwecke reicht allerdings die einfache Variante.
Etwas greifbar machen
Um das Schwert in XR greifen zu können, müssen wir es “greifbar” machen, und zwar im physikalischen wie auch im konzeptionellen Sinne: wir müssen der Anwendung zunächst signalisieren, dass das Schwer ein greifbares Objekt ist, bevor wir diese Handlung in XR ausführen können.
Dazu gibt es im XRIT eine dedizierte Komponente, die man an jedes Objekt mit mindestens einem Collider hängen kann: XRGrabInteractable
. Markiere dein “Sword” GO und klicke dann rechts im Inspector auf “Add Component”, tippe “xrgrab” in den Suchfilter und wähle das Ergebnis aus.
Bilder sagen mehr als tausend Worte, also schauen wir uns einfach an, was diese Komponente leistet. Wenn du das Projekt startest, solltest du das Schwert vor dir sehen:
Was passiert hier?
- Das Schwert fällt wie erwartet zu Boden – die Physik funktioniert…
- …fast, denn am Ende fällt das Schwert durch den Boden.
- Wenn wir mit den Controllern in Richtung des Schwerts zeigen, verlängert sich der Strahl (der sog. Ray Interactor) des Controllers und wir spüren eine Vibration
- Das scheint auch aus weiterer Entfernung zu klappen
- Wenn der Strahl über dem Schwert ist, können wir es mit der Grip-Taste greifen
- Der Griffpunkt entspricht dem Pivot des Schwerts
- Wir können das Schwert hin und her bewegen; es fühlt sich an, als wenn das Schwert tatsächlich einige Meter entfernt an dem Strahl hängt und sich die Bewegung mit Verzögerung überträgt
- Wenn wir das Schwert durch den Grund ziehen, kollidiert es nicht
- Wenn wir es über dem Grund loslassen, kollidiert es wieder ordentlich mit dem Boden
- Wir können das Schwert in bestimmte Richtungen werfen
- Wir können das Schwert durch “Ziehbewegungen” an uns heranziehen
- Die Rotation des Schwerts ist unvorteilhaft und würde schmerzen verursachen, wenn man damit versuchen würde, längere Zeit zu spielen
- Das Schwert ist ganz schön groß!
Im letzten Teil habe ich geschrieben, dass wir uns die einzelnen Bauteile unseres XR Rigs bei Bedarf genauer ansehen werden. Jetzt besteht Bedarf, denn was wir hier am Werk sehen, ist der in XRIT 3 neu eingeführte Near-Far Interactor. Er wurde eingeführt, um die Interaktion mit Objekten in unmittelbarer Nähe und Objekten in der Ferne zu vereinheitlichen – daher der Name.
Interactables sind also die Komponenten für Objekte, mit denen interagiert werden kann. Das Gegenteil dazu sind die Interactors, die i. d. R. an den Controllern hängen.
Den “Near-Far Interactor” finden wir als Child-GO sowohl auf dem “Left Controller” als auch auf dem “Right Controller” im XR Rig.
Er hat mehrere Komponenten, von denen ich ein paar herausgreifen will:
- Der “Interaction Attach Controller” regelt, wie sich das Interactable, mit dem der Interactor interagiert, verhält.
- Der “Sphere Interaction Caster” sucht nach Interactables innerhalb eines konfigurierbaren Radius. Da sich die durch den Radius definierte Kugel mit dem Controller bewegt, ist er für die Interaktion mit Objekten in unmittelbarer Nähe zuständig. Das ist eine ganz reguläre “Grab Interaction”.
- Der “Curve Interaction Caster” ist das Gegenstück dazu: der prüft entlang einer konfigurierbaren Kurve mithilfe von verschiedenen Methoden, ob Interactables auf dem Weg liegen. Das nennt sich dann auch “Remote Grab Interaction”.
- Die “Near-Far Interactor” Komponente orchestriert das Zusammenspiel.
Versuchen wir doch mal eine Sache zu ändern: mit Objekten interagieren zu können, die nicht unmittelbar vor einem liegen, ist ja schon ganz bequem. Aber zum einen ist die Entfernung aktuell sehr großzügig und zum anderen sollte das Objekt dann direkt in die Hand wandern, anstatt in der Ferne zu bleiben.
Markiere zum Ändern beider Seiten beide Near-Far Interactors (unter Left Controller und unter Right Controller) mit gedrückter Ctrl/Cmd Taste oder ändere sie nacheinander wie folgt:
Die Entfernung ist eine Einstellung im Curve Interaction Caster. Hier gibt es ein Feld “Cast Distance” mit aktuellem Wert 10. Ändere den auf 2.

Das Verhalten bei Far-Grab wird im Near-Far Interactor konfiguriert. Ändere das Feld “Far Attach Mode” von “Far” auf “Near”.

Mit diesen Änderungen verhält sich das Schwert so: aus größerer Entfernung kann nicht mehr damit interagiert werden und wenn es gegriffen wird, wandert es direkt in die Hand.
Die Position des Schwerts in der Hand bzw. im Controller fühlt sich aber noch nicht gut an. Zum einen sollte die Schneide des Schwerts nach vorne zeigen, zum anderen sollte das Schwert etwas nach vorne geneigt werden.
Hier kommt ein Attribut der XR Grab Interactable Komponente, die an unserem Schwert hängt, zum Tragen. Dort gibt es nämlich das “Attach Transform” Feld, mit dem ich den Standard-Pivot-Punkt des Root-GOs überschreiben kann.
Markiere das Schwert in der Hierarchy und lege per Rechtsklick → Create Empty ein leeres Child-GO an. Nenne es “AttachPoint”. Die Position ist schon in Ordnung – der Autor des 3D Modells, Kay Lousberg, hat ja glücklicherweise den Ursprung des Schwerts mitten auf den Griff gelegt. Aber die Rotation können wir so anpassen: markiere das neue “AttachPoint” GO und setze die Y-Rotation auf 90 oder -90. Damit rotieren wir die Schneide des Schwerts so, dass sie nach “vorne” zeigt und wir Gegner nicht mit der flachen Seite erschlagen müssen. Setze dann die X-Rotation auf -45. Damit neigen wir das Schwert etwas nach vorne.

Markiere jetzt wieder das Schwert und ziehe jetzt das neu angelegte AttachPoint GO in das “Attach Transform” Feld:

Damit sieht das dann so aus:
Interaktion mit der Spielwelt
Nur das Schwert greifen zu können macht aber noch keinen Schwertkämpfer aus uns! Solange wir das Schwert durch den Boden ziehen können oder es beim Loslassen sogar gelegentlich in die Tiefe fällt, werden wir im Kampf gegen Skelette nicht weit kommen. Diese beiden Probleme lassen sich wieder durch Änderungen auf dem “Sword” GO lösen.
Ursache für das Fallen durch den Boden ist die standardmäßige Einstellung der Collision Detection des Rigidbodies: die steht auf “Discrete” und muss zu “Continuous Dynamic” geändert werden. Das ist ein häufig auftretendes Problem mit Objekten, die sich zu schnell durch die Welt bewegen: in dem Fall muss der Physik in Form der angepassten Kollisionserkennungsmethode ein Hinweis gegeben werden.

Die Kollision des Schwerts mit dem Boden, während wir das Schwert in der Hand halten, kann auf mehreren Wegen bewerkstelligt werden. Wir bleiben aber erstmal im Sword-GO und schauen, welche Möglichkeiten es dort gibt. Die relevante Einstellung findet sich diesmal im XR Grab Interactable des Schwerts. Das Attribut “Movement Type” muss von “Instantaneous” zu “Velocity Tracking” geändert werden.

Das Verhalten des Schwerts in der Hand wird sich damit vorerst etwas verändern: es gleitet nicht mehr ganz so butterweich beim Bewegen.
Um zu erklären, warum das so ist, warum das dennoch erstmal die beste Option bleibt und wie wir die Situation verbessern können, schauen wir uns am besten mal die Optionen des “Movement Type” Attributs an:
- Instantaneous: Das war die Standard-Einstellung. Das Schwert folgte hier 1:1 der Bewegung des Controllers, ohne dass die eigene Physik, d.h. der Einfluss des Rigidbodies des Schwerts, zum Tragen kam. Bei dieser Bewegung wird nämlich direkt die “Transform” Komponente des Schwerts aktualisiert. Das Schwert könnte noch auf andere Rigidbodies Einfluss nehmen, aber der Boden hat keinen solchen und es macht für statische Geometrie auch keinen Sinn, einen Rigidbody hinzuzufügen.
- Kinematic: jetzt wird die Bewegung über die “Rigidbody” Komponente des Schwerts gesteuert, aber während das “Is Kinematic” Flag des Rigidbodies aktiviert wird. Das bedeutet, dass auch hier die eigene Physik des Schwerts nicht zum Tragen kommt. Dadurch kann die Interaktion mit anderen physikalischen Objekten schnell unrealistisch wirken. Auch mit dieser Option geht das Schwert einfach durch Objekte ohne eigenen Rigidbody durch.
- Velocity Tracking: hier wird die Bewegung wieder über die “Rigidbody” Komponente gesteuert und die Physik des Schwerts kommt zum Tragen, d.h. Trägheit oder Gravitation wirken jetzt auf das Schwert, während wir es mit dem Controller bewegen. Dadurch, dass die Physik in festen und i. d. R. längeren Intervallen als das Rendern eines Frames berechnet wird, merkt man aber jetzt die Verzögerung sehr deutlich.
Welche Option die richtige ist, hängt also am Anwendungsfall genau so wie den Kompromissen, die man eingehen kann, oder am Aufwand, den man treiben möchte. Die Verzögerung beim Velocity Tracking lässt sich z. B. durch Reduzierung des Gewichts der Objekte mindern, was sich aber wieder auf andere Interaktionen auswirkt, oder durch Verringerung des Intervalls der Physikberechnungen reduzieren, allerdings zu Lasten der CPU Auslastung. Die Wahrnehmung der Verzögerung lässt sich ebenfalls reduzieren, indem man den Controller bzw. dann später ein Handmodell direkt an das Objekt hängt.
Aber es gibt auch noch einen vergleichsweise einfachen Trick: Reparenting des Sword-GO! Während das Schwert gehalten wird, können wir es unter den Interactor hängen. Damit wird es mit diesem bewegt und der Ausgleich, den das Velocity Tracking durchführen muss, ist gleich Null. Dennoch profitieren wir von der vollen Interaktion mit der Welt.
Wie genau dieses Reparenting funktioniert, schauen wir uns im nächsten Teil an.
Ausblick
Um das Schwert in der Scene Hierarchy zu verschieben und es zu einem Child-GO des Interactors zu machen, müssen wir auf Events reagieren, die uns das XRGrabInteractable
zur Verfügung stellt. Und dazu kommen wir im nächsten Teil nicht um (visuelle) Programmierung herum!
* 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.