-
Notifications
You must be signed in to change notification settings - Fork 0
/
body.tex
1381 lines (1010 loc) · 156 KB
/
body.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
%!TEX root = ./thesis.tex
\chapter{Einführung}\label{chapter:intro}
Zweibeiniges Gehen bietet als Fortbewegungsart durch virtuelle Umgebungen viele Vorteile gegenüber alternativen Fortbewegungsarten. Usoh et al. \cite{usoh-vergleich-1999} beschreiben beispielsweise, ein höheres Präsenzgefühl der Nutzer:innen, wenn sich diese gehend durch die virtuelle Umgebung fortbewegten, als wenn diese per Knopfdruck durch die Szene flogen.
Eine der drei von LaViola \cite{cybersickness} zusammenfassten Theorien, die \textquote{Sensory Conflict Theory} (Sensorische Konflikt Theorie) erklärt die Ursache für so genannte \textquote{Cybersickness} oder auch Simulatorkrankheit: Nutzer:innen erleben in bestimmten, durch virtuelle Umgebungen hervorgerufenen, Situationen teilweise starke Übelkeit, weil Informationen verschiedener Sinnesmodalitäten widersprüchlich sind.
Demnach wäre es also Cybersickness senkend, wenn andere Sinnesmodalitäten, wie der Gleichgewichtssinn oder die Propriozeption zusätzlich zum visuellen Sinn die Eigenbewegung der Nutzer:in wahrnehmen. Und tatsächlich konnten Langbehn et al. \cite{langbehn-vergleich-2018} zeigen, dass Nutzer:innen, die sich in virtuellen Umgebungen fortbewegen signifikant weniger Cybersickness erleben, als bei der Fortbewegung mithilfe von Joysticks.
% erklärt, dass beim Gehen mehr Sinne stimuliert werden als bei künstlichen Alternativen, wie zum Beispiel der Joystick Steuerung. Tiefensensibilität (Propriozeption) und Gleichgewichtssinn (vestibuläre Wahrnehmung) signalisieren, dass er gerade wirklich geht, während diese Information bei alternativen Fortbewegungsart allein vom visuellen Sinn übermittelt wird.
Leider bringt das natürliche Gehen (Real-Walking) auch den großen Nachteil mit sich, dass es in der Regel auf einen einzelnen Raum (den Trackingspace) beschränkt ist.
Dies entsteht zum einen, durch räumlich limitierte Erfassung (auf Englisch: tracking) der Position und Rotation von Headset und Controllern bei einigen Technologien, zum anderen durch die Raumgröße der meisten VR-Setups.
Zwar gibt es dazu auch Ausnahmen, (siehe beispielsweise \cite{microsoft}), jedoch sind diese dann mit großem Aufwand verbunden und nicht für jede Endnutzer:in umzusetzen.
\section{Redirection Methoden}
Eine Herangehensweise an dieses Problem sind so genannte \textquote{Redirection Techniques} (besser bekannt als Redirected Walking. Diese Begriffe werden oft austauschbar verwendet, siehe \cite{redwalk_uebersicht}). Dies ist ein Sammelbegriff für Methoden bei denen die Nutzer:in durch subtile Manipulationen an der Darstellung der virtuellen Umgebung, auf virtuelle Gebiete zugreifen kann, die sonst außerhalb des begehbaren Bereichs wären. Tatsächlich bleibt sie dabei aber nur innerhalb des realen Trackingspaces.
Im Idealfall wird dabei die Illusion aufrecht erhalten sie würde sich unmanipuliert, frei, und in virtueller und echter Umgebung identisch bewegen. Tatsächlich werden bei den meisten dieser Methoden %unterschied zwischen methode und methodik?
gewisse Veränderungen zwischen der Nutzer:in und ihrem virtuellen Avatar etabliert (beispielsweise die Geh-Geschwindigkeit), sodass die Bewegung sich zwischen den beiden Umgebungen unterscheidet.
Bei manchen dieser Methoden sorgt diese Veränderung dafür, dass die Bewegungen der Nutzer:in in gewisser Weise manipuliert werden, beispielsweise indem diese unbewusst versucht die Veränderungen auszugleichen.
Mit diesen Methoden lassen sich also einige Effekte erzielen, wie unter anderem die virtuell begehbare Fläche zu vergrößern.
Im Folgenden werde ich nun zwei dieser Methoden genauer vorstellen.
%%%%%%%%%%%%
\subsection{Rotation-Gains}
Rotation-Gains werden Kopfrotationen hinzugefügt, sodass sich die virtuelle Kamera leicht schneller oder langsamer dreht als der reale
Kopf mit dem VR-Headset.
Wie diese dargestellt werden können findet sich wie folgend bei Steinicke et al. \cite{detection-thresholds}:
Kopfrotationen lassen sich mit der Schreibweise
$$ R_{real} := (pitch_{real}, yaw_{real}, roll_{real}) $$
darstellen, wobei $pitch$, $yaw$ und $roll$ die Eulerschen Winkel der Kopfrotation repräsentieren. Ein Rotation-Gain wird als Quotient des virtuellen Winkels und des realen Winkels einer Rotationsdimension definiert:
$$ gR := \frac{R_{virtual}}{R_{real}} $$
Für alle 3 Winkel kann ein Rotation-Gain angewandt werden.
Statt der eigentlichen Kopfrotation $\alpha$, wird die Multiplikation aus $\alpha$ mit dem Rotation-Gain:
$$ gR * \alpha $$
durchgeführt.
Folglich rotieren virtuelle Kameras mit einem Rotation-Gain von $gR > 1$ schneller in die Richtung der realen Kopfdrehung als der reale Kopf, während solche mit einem Rotation-Gain von $gR < 1$ langsamer die Richtung drehen.
%nochmal peck 11 angucken dazu
Da für jeden Winkel der Kopfrotation ein Rotation-Gain definiert werden kann, können Rotation-Gains folgendermaßen dargestellt werden:
$$(gR_{pitch}, gR_{yaw}, gR_{roll})$$
Nach Steinicke et al. \cite{detection-thresholds} wird generell für Redirection-Zwecke ein Rotation-Gain auf den $yaw_{real}$ Winkel der Kopfrotation angewandt.
Durch Anwenden eines positiven Rotation-Gains auf Yaw-Rotationen nach rechts und eines neutralen oder sogar negativen Rotation-Gains für Rotationen nach links kann der virtuelle Bereich, der dem Trackingspace entspricht um den realen Trackingspace nach rechts rotiert werden, mit dem Drehpunkt der Nutzer:innenposition. Dies gilt auch für die andere Richtung. Indem im vorhinein ein Winkel $\beta$, für die Ziel-Verdrehung der beiden Realitäten definiert wird, lässt sich beim Erreichen dieses Winkels das Anwenden des Rotation-Gains beenden, sodass die Welten sich nun um genau $\beta$ Grad verdreht haben.
Dies ermöglicht Prozesse, bei denen in bestimmten Bereichen der virtuellen Realität ein solcher \textquote{gerichteter} Rotation-Gain bis zu einem bestimmten Ziel-Winkel um einen vorher definierten Drehpunkt\footnote{Es sollte sichergestellt werden, dass sich die Kopfposition der Nutzer:in möglichst nah an diesem Drehpunkt befindet, da sonst nicht der Eindruck entsteht, die Rotation wäre mit der Kopfrotation der Nutzer:in identisch. Außerdem kann es für große Verwirrung sorgen, wenn sich die Welt auf einmal nicht um die eigene Achse dreht, aber dennoch genau dann, wenn der Kopf bewegt wird.} angewendet wird.
In solchen Prozessen ist die Verdrehung zwischen den beiden Realitäten designbar, da sie so deterministisch wird. Da sich nun die Realitäten verdreht haben, liegen nun virtuelle Orte innerhalb des durch den realen Trackingspace begrenzten, für die Nutzer:in begehbaren Bereichs, die es vorher nicht taten.
Für die Nutzer:in kann so die Illusion entstehen, sie würde über die Grenzen des Trackingspaces hinaus schreiten können, ohne dies zu tun.
\subsection{Impossible-Spaces}
Um den begehbaren Bereich eines Trackingspace noch weiter zu vergrößern wurde eine Redirection Methode von Suma et al. \cite{impossible-spaces-suma} vorgestellt, bei der zwei oder mehr Räume in überlappenden Gebieten liegen, allerdings nur einer zur Zeit angezeigt wird. Es gibt dann unterschiedliche Bedingungen, wann welcher der Räume angezeigt wird. Beispielsweise wird Raum $A$ nur angezeigt wenn die Nutzer:in den überlappenden Raum durch Tür $a$ betritt und Raum $B$, wenn sie ihn durch Tür $b$ betritt.
Dafür ist es also notwendig, dass $x$ verschiedene Zustände programmatisch ermöglicht werden, sodass immer einer von $x$ verschiedenen möglichen Räumen angezeigt wird.
Des Weiteren ist es notwendig ein Gebiet in der virtuellen Umgebung bereitzustellen, in dem zwischen den Zuständen gewechselt werden kann, ohne dass die Nutzer:in es merkt.
\section{Generierte Level} %prozedural, oder zufällig? oder pseudozufällig?
Klassischer Weise werden Level in Computerspielen und virtuellen Umgebungen von Leveldesignern gestaltet. Dies erfordert Zeit und Fachwissen.
Der Arbeitsaufwand wächst mit der Größe des Levels. Deshalb ist es unmöglich auf diese Art endlos große Level zu erschaffen. Eine alternative Levelerstellungsweise ist die so genannte \textquote{Prozedurale Generierung}, auch \textquote{Prozedurale Synthese} genannt. Dabei wird das Level von einem Algorithmus erschaffen, und kann somit theoretisch endlos groß werden.
%verschiedene Arten von prozeduraler generiung und dazu beispiel wie minecraft, rogue etc. mit quellen.
Dies ermöglicht mit Hinblick auf die Erweiterung des begehbaren Bereichs durch Redirection Methoden einen weiteren spannenden Effekt. %Endlos generierbare Level können mit Redirection-Maßnahmen, die wiederholt angewendet werden um immer wieder den Begehbaren Bereich durch die virtuelle Umgebung zu transformieren, theoretisch endlos große begehbare virtuelle Umgebungen erschaffen. Eine solche \textquote{Infinite-Walking} Methode wird in dieser Arbeit vorgestellt.
Mit Redirection-Maßnahmen ausgestattet, welche wiederholt angewendet werden können um immer wieder den begehbaren Bereich durch die virtuelle Umgebung zu transformieren, ist es möglich theoretisch endlos große, begehbare virtuelle Umgebungen zu erzeugen. Eine solche \textquote{Infinite-Walking} Methode wird in dieser Arbeit vorgestellt.
\section{Infinite-Walking Methode}
Die in dieser Arbeit vorgestellte Infinite-Walking Methode basiert darauf aufeinander folgende trackingspacegroße Räume zu generieren, die genau so angeordnet sind, dass ein
90\textdegree, gerichteter
Rotation-Gain an einer bestimmten Stelle, in der Nähe einer der Ecken des Raumes, die virtuelle und die reale Umgebungen, so umeinander dreht, dass der reale Trackingspace nach Abschluss des gerichteten Rotation-Gains genau kongruent mit den Außenwänden des nächsten Raumes liegt. Die Nutzer:in kann diesen dann betreten und den gleichen Effekt an einer anderen Ecke des Raumes, in dem die sich nun befindet, wiederholen um den begehbaren Bereich auf den wieder nächsten Raum zu transformieren. Dies kann dann theoretisch endlos so wiederholt werden. Die Räume sind durch Korridore miteinander verbunden. Jeder Raum hat genau einen Korridor. Diese sind so gestaltet, dass der Drehpunkt die Mitte des Korridors kurz vor dessen Ende darstellt. Durch Zufallsfaktoren in der Levelgenerierung, ist es mit dieser Methode möglich, viele unterschiedliche Level, die auf dem eben genannten Prinzip basieren, zu generieren.
Wie die Generierung solcher Level funktioniert, wird in \autoref{chapter:generate} genauer beschrieben.
\section{Information}
Bei allen in dieser Arbeit abgebildeten Grafiken, Bildern, Screenshots und Tabellen handelt es sich um Eigengrafiken, sofern nicht explizit eine Bildquelle dazu angegeben ist.
\chapter{Verwandte Arbeiten}\label{chapter:relatedwork}
In diesem Kapitel werden wissenschaftliche Arbeiten vorgestellt mit denen diese Arbeit zusammenhängt. Dabei werde ich zunächst auf solche Arbeiten eingehen, die sich mit dem Thema Real-Walking in virtuellen Umgebungen beschäftigen, danach verschiedene Redirection-Techniken vorstellen und dann auf das Thema der Level-Generierung eingehen. Zunächst stelle ich generelle Arbeiten zu dem Thema Real-Walking und dann zu Redirection Techniken vor, danach gehe ich konkreter auf die in diesem Projekt sehr im Fokus liegenden Rotation-Gains ein, um danach die auch genutzten Impossible-Spaces vorzustellen. Als nächstes stelle ich der Leser:in Arbeiten zu dem Thema der Prozeduralen Levelgenerierung vor. Dabei werde ich mich sowohl mit Artikeln über die genaue Definition dieses Bereichs beschäftigen, als auch eine Taxonomie zur Einordnung von Prozeduren zur Inhaltsgenerierung zitieren. Die Kombination von generierten Leveln und Redirection-Techniken führen zu dem sogenannten \textquote{Infinite-Walking}. Mit den Arbeiten zu diesem Thema wird das Kapitel abgeschlossen.
\section{Real-Walking}
1995 zeigen Slater et al. \cite{taking-steps}, dass Proband:innen ein höheres Präsenzgefühl angaben, wenn sie die von ihnen vorgestellte Technik \textquote{Walking-In-Place} nutzten, als wenn sie sich per Knopfdruck durch die Welt bewegten. Hierbei handelte es sich um eine Virtual-Walking Technik, bei der die Proband:innen eine Gehbewegung simulierten die dann digital erfasst und in virtuelle Fortbewegung umgewandelt wurde. Dieses Experiment wurde 1999 von Usoh et al. \cite{usoh-vergleich-1999} repliziert, wobei nun die Option wirklich zu gehen (\textquote{Real-Walking}) gegeben war. Dabei hatten die Proband:innen nochmal ein signifikant höheres Präsenzgefühl, als bei den beiden anderen Optionen (Virtual-Walking und Push-Button-Fly).
Des Weiteren zeigen Arbeiten, dass virtuelle Fortbewegungsarten, die anders
als Real-Walking nicht den vestibulären Sinn und die Propriozeption stimulieren, wahrscheinlicher die sogenannte \textquote{Simulatorkrankheit} (simulator sickness) auslösen \cite{locomotion-path-integration} und dass die Nutzer:innen damit weniger effektiv navigieren. \cite{benefits-real-walking}
Wenn Designer eine Real-Walking-Umgebung erstellen, müssen sie dabei schon die Dimensionen des Trackingspaces kennen. Da man aber nicht davon ausgehen kann, dass unterschiedliche Nutzer:innen gleiche Trackingspacedimensionen zur Verfügung haben, entsteht ein Problem. Dies versuchen Marwecki et al. in ihrer Arbeit \cite{scenograph} zu Lösen. Sie stellen dabei das Softwaresystem \textquote{Scenograph} vor, welches große virtuelle Umgebungen in mehrere kleinere, teilweise anders geformte Umgebungen, mit prozedural generierten Verbindungen aufteilt ohne dabei die narrative Struktur der ursprünglichen Umgebung zu verändern.
%Allerdings gibt es auch andere Ansätze um Nutzer:innen mit begrenztem Trackingspaceplatz Real-Walking-Erfahrungen zu ermöglichen. wie beispielsweise den virtuellen Bereich, der von der Nutzer:in begehbar ist, zu vergrößern.
Ein anderer Ansatz um Nutzer:innen mit begrenztem Trackingspaceplatz Real-Walking-Erfahrungen zu ermöglichen ist es den von der Nutzer:in begehbaren Bereich, in der virtuellen Umgebung, zu vergrößern.
Eine vielversprechende Art dies zu erreichen sind Redirection-Techniken.
\section{Redirection Techniken}
Razzaque et al. \cite{rdw-razzaque} stellten 2001 die Methode des \textquote{Redirected-Walking} vor, bei der die Nutzer:innen unwissentlich durch den Trackingspace gelenkt werden, dabei aber die Illusion entsteht, sie würden sich über die Grenzen dessen hinausbewegen. Die Technik basiert darauf, dass der visuelle Sinn dominanter ist als andere Sinne, mit denen man seine Orientierung im Raum bestimmen kann.
Seit dem gibt es zahlreiche weitere Techniken um den selben Effekt zu erzielen oder um ihn weiterzuentwickeln. Der Ansatz, die verschiedenen Manipulationseffekte als \textquote{Gains} zu beschreiben, findet sich bei Steinicke et al. \cite{detection-thresholds}. Dort wird untersucht, wie subtil diese Manipulationen sein müssen um nicht von der Nutzer:in erkannt zu werden.
Es konnte gezeigt werden, dass Proband:innen in virtuellen Umgebungen, welche Redirection-Techniken nutzten um Real-Walking zu ermöglichen, signifikant besser unbewusst räumliches Wissen über diese Umgebungen sammelten, signifikant bessere Navigation und Wegfindung aufwiesen und die Größe der Umgebung signifikant besser einschätzen konnten als in Umgebungen, die andere Fortbewegungsarten nutzen, wie Walking-In-Place, Joystick-Steuerung oder Teleportation \cite{peck-vergleich-2011}, \cite{langbehn-vergleich-2018}.
Eine Taxonomie über die verschiedenen Redirection Techniken stellten 2012 Suma et al. \cite{taxonomy} vor. Die unterschiedlichen Techniken werden in die Kategorien: \textquote{Repositioning} (Repositionierung) oder \textquote{Reorientation} (Reorientierung), \textquote{Subtle} (subtil) oder \textquote{Overt} (unverborgen), und \textquote{Discrete} (diskret) oder \textquote{Continuous} (kontinuierlich) unterteilt.
%curvature games paper?
\subsection{Rotation Gains}
Bei Rotation-Gains handelt es sich nach Sumas Taxonomie \cite{taxonomy} um eine kontinuierliche, subtile Reorientierungstechnik. In der Arbeit \cite{detection-thresholds} untersuchten Steinicke et al. verschiedene subtile Redirection-Techniken darauf, wie stark die Manipulation sein darf, bevor Proband:innen erkennen, ob sie eingesetzt wurde oder nicht. Dazu teilten sie die verschiedenen Elemente, die für Redirected Walking eingesetzt werden, in drei verschiedene Gains ein: \textquote{Translation-Gains}, \textquote{Rotation-Gains} und \textquote{Curvature-Gains}. Es stellte sich heraus, dass Nutzer:innen physisch um bis zu 49\% mehr oder um bis zu 20\% weniger als die wahrgenommene virtuelle Rotation, rotiert werden können, ohne die Diskrepanz zu bemerken, also Rotation-Gains $0,8 < gR < 1,49$ unentdeckt bleiben.
Des Weiteren wurde festgestellt, dass Geh-Distanzen unbemerkt um bis zu 14\% herunter- oder um bis zu 26\% heraufskaliert werden können und dass Nutzer:innen erst bemerken, dass sie in einem kreisförmigem Bogen durch den Trackingspace geleitet werden, wenn dessen Radius 22 Meter oder kleiner ist.
\subsection{Impossible-Spaces}
Bei \textquote{Impossible-Spaces} handelt es sich um eine von
Suma et al. \cite{impossible-spaces-suma} vorgestellte Redirection-Technik, bei der sich die Architektur der virtuellen Umgebung auf nicht-euklidische Weise verändert, sodass solche Gebiete in der Realität nicht existieren könnten.
Die Räume überlappen einander, allerdings wird jeweils nur einer der überlappenden Räume angezeigt. Hierbei handelt es sich nach der schon erwähnten Taxonomie um eine subtile diskrete Redirection-Technik.
In einer Forschungsdemonstration \cite{redirected-spaces} stellten Langbehn et al. eine Weise vor mit der Impossible-Spaces mit traditionelleren Redirected-Walking Methoden kombiniert werden können, sodass beide Methoden ihren Effekt beitragen können.
\section{Prozedural generierte Level}
\subsection{Definition}
Der Artikel \cite{sbpcg} von Togelius et al. definiert prozedurale Generierung von Spiel-Inhalten (procedural (game-)content generation oder auch PCG) als:
\begin{quotation}
\textquote{[...] creating game content automatically, through algorithmic means.}
\end{quotation}
\begin{quotation}
(\textquote{[...] algorithmisch, automatisch, (Computer-)spiel Inhalte erstellen.})
\end{quotation}
In ihrer späteren Arbeit hingegen \cite{what-is-pcg} definieren Togelius et al. PCG folgendermaßen neu:
\begin{quotation}
\textquote{We can therefore tentatively redefine PCG as the algorithmical creation of game content with limited or indirect user input.}
\end{quotation}
\begin{quotation}
(\textquote{Wir können PCG daher versuchsweise als die algorithmische Erstellung von Spielinhalten mit begrenzter oder indirekter Benutzereingabe neu definieren.})
\end{quotation}
\hyphenation{Designer-input}
um unter anderem miteinzubeziehen, dass einige PCG-Algorithmen Nutzer- oder Designerinput miteinbeziehen können und somit nicht mehr \textquote{automatisch} Inhalte generieren. Außerdem wollen sie an der Definition festhalten, dass Nutzerinput typischerweise zumindest indirekt (mindestens durch Druck eines Startknopfes) erforderlich ist, um Inhalte zu generieren.
Mit (Spiel-)Inhalten sind in diesen Definitionen unterschiedlichste Elemente in Videospielen gemeint, unter anderem Texturen und Musik. Auch die Geschichte des Spiels kann prozedural generiert werden. Im Rahmen dieser Arbeit hingegen beschäftige ich mich lediglich mit PCG zur Erstellung von Leveln.
\subsection{Taxonomie}
In ihrer Arbeit \cite{sbpcg} stellen Togelius et al. eine Taxonomie für PCG vor, die aus folgenden Kategorien besteht:
\textquote{Online versus offline} (Zur Laufzeit versus während der Entwicklung),
\textquote{Necessary vs optional} (Müssen die Spieler:innen den generierten Bereich des Spiels absolvieren oder nicht?),
\textquote{Random seeds versus Parameter Vectors} (auch: \textquote{degrees of control}: Wieviel Einfluss hat die Spieler:in auf den generierten Inhalt, wird nur ein zufälliger RNG-Seed (Random-Number-Generator-Seed) als Eingabe in den Zufallsgenerator genutzt oder wird sein bisheriges Spielverhalten analysiert und bei der Generierung beachtet?),
% \textquote{Generic vs adaptive} () irgendwie nur im pcg buch und nicht im paper,
\textquote{Stochastic vs deterministic} (Wird bei gleicher Eingabe (abgesehen vom RNG-Seed) auch der gleiche Inhalt generiert?) und
\textquote{Constructive vs generate-and-test} (Generiert der Algorthmus direkt nur korrekte Ausgaben, oder funktioniert er so, dass er fortlaufend Versuche generiert und dann validiert ob sie korrekt sind und sie dann erst ausgibt.) %und
% \textquote{Automatic generation vs mixed authorship}.
Der in dieser Arbeit beschriebene PCG-Algorithmus lässt sich dementsprechend eher in diese Kategorien der Taxonomie einordnen, als in ihre jeweiligen Alternativen: Online, necessary, random seeds,
%generic,
stochastic and constructive. % and automatic.
\section{Infinite walking}
Viele der Redirection-Techniken simulieren die Vergrößerung des begehbaren Bereichs, doch dennoch bleibt die begehbare Fläche limitiert. Solange die virtuelle Umgebung von menschlichen Designern erschaffen werden muss, ist sie begrenzt. Wenn jedoch PCG genutzt wird um die virtuelle Umgebung zu erschaffen lässt sie sich theoretisch endlos weit durchschreiten, weil die Generierung während der Erkundung der Welt fortgeführt werden kann.
Wenn die virtuelle Umgebung also, mit Hilfe von PCG, theoretisch endlos weit erkundet werden kann, spricht man vom \textquote{Infinite-(Real)-Walking}.
In der Regel lässt sich dieser Zustand %?
erreichen, indem man Redirection-Techniken (um über den Trackingspace hinaus gehen zu können) mit prozeduraler Levelgenerierung (um die Welt während der Laufzeit weiter zu generieren) kombiniert.
Ein Beispiel für eine solche Technik stellen Vasylevska et al. in ihrer Arbeit \cite{flexible-spaces} vor. Ihr Algorithmus generiert fortlaufend Räume, innerhalb des Trackingspaces, die einander überlappen können (Impossible-Spaces) und verbindet sie mit Korridoren, sodass die Nutzer:in von einem Raum zum nächsten gehen kann.
%Praktisch ist diese Technik besonders bei Umgebungen in denen der Inhalt der Räume mehr im Fokus steht als das spezifische Layout der Räume wie beispielsweise einem Museum.
Besonders bei Umgebungen in denen der Inhalt der Räume mehr im Fokus steht als das spezifische Layout der Räume (beispielsweise ein Museeum) ist Technik sehr geeignet.
Einen sehr ähnlichen Ansatz nutzt das VR-Spiel \textquote{Tea for God} \cite{tea-for-god} bei dem die Nutzer:in durch ein endlos groß scheinendes Labyrinth von Korridoren gehen kann. Der Entwickler Jarosław (Void Room) Ciupiński erklärt in seinen Devlogs (beispielsweise \cite{tea-for-god-devlog-a} oder \cite{tea-for-god-devlog-b}) genauer wie der Ansatz funktioniert.
Die Welt besteht aus einem prozedural generierten Netz von verbundenen Zellen, die jeweils einen Raum repräsentieren und mit Korridoren verbunden sind. Auch hier basieren die Räume auf den vorher erwähnten Impossible-Spaces.
%In seinem devlog \cite{tea-for-god-devlog-b} erwähnt der Autor die eben erwähnte Arbeit von Vasylevska et al. \cite{flexible-spaces}, was darauf hindeuten könnte, das Spiel wäre von dem Ansatz der flexible spaces inspiriert.
Einen anderen Ansatz verfolgt das in der Arbeit \cite{microsoft} von Cheng et al. vorgestellte Projekt \textquote{VRoamer}.
Hier erkundet die Nutzer:in eine On-The-Fly generierte virtuelle Umgebung (auch hier besteht diese aus Räumen und Korridoren), während er durch die reale Welt läuft. Die Generierungssoftware erhält einen 3D-Kamera Input und kann so Wände, Säulen, Gegenstände, andere Menschen etc. beachten und dementsprechend die virtuelle Welt anpassen. Dort wird dann ein virtueller Gegenstand platziert, sodass die Nutzer:in nicht mit den Hindernissen der realen Welt kollidiert.
Diese Technik ist nur bei VR-Systemen anwendbar, die nicht auf einen Trackingspace beschränkt sind, sondern (zum Beispiel mit Kameras am HMD (Head-Mounted-Display)) ihre Umgebung, und somit auch ihre eigene Position und Orientierung benötigen. Die Möglichkeiten, die virtuelle Umgebung zu erkunden, sind hier also nur durch den realen Platz, den die Nutzer:in zur freien Begehung zur Verfügung hat, limitiert. Streng genommen gilt die Definition von Infinite-Walking hier also nicht, sie sollte an dieser Stelle aber dennoch Erwähnung finden.
\section{Einordung dieser Arbeit}
Ähnlich zu der Arbeit \cite{flexible-spaces} werde ich in dieser Arbeit eine Methode vorstellen, wie mit verschiedenen Redirection-Techniken und einem PCG-Algorithmus eine virtuelle Umgebung mit Infinite-Walking erstellt werden kann.
Vergleichbar mit den Arbeiten \cite{peck-vergleich-2011} und \cite{langbehn-vergleich-2018} werde ich diese Methode dann in einem Experiment unter Testbedingungen mit alternativen Fortbewegungsarten, die dementsprechend kein Real-Walking ermöglichen, auf verschiedene Faktoren vergleichen.
\chapter{Implementierung}\label{chapter:implementation}
In diesem Kapitel werde ich die technischen Elemente für die Umsetzung des in dieser Arbeit vorgestellten Experimentes vorstellen.
Das Kapitel wird mit einer Übersicht über die Beziehungen zwischen den verschiedenen Scripts und Klassen des Projektes, in Form eines UML-Klassendiagramm beginnen.
% Danach wird jede einzelne Klasse einmal kurz vorgestellt. #
Danach stelle ich jede einzelne Klasse einmal vor.
%Anschließend werden einzelne Bereiche der Implementierung genauer beschrieben.
Anschließend beschreibe ich einzelne Bereiche der Implementierung genauer.
Zuerst die Hierarchie der Unity-Szene, dann das Design der Level, der virtuelle Avatar, die Umsetzungen von Rotation-Gains und Impossible Space, die Umsetzung der für die später vorgestellte Pilotierungsstudie relevanten unterschiedlichen Fortbewegungsarten, der Mechanismus, der die Nutzer:in dazu anreizt, sich für die Rotation-Gains an der richtigen Stelle zu drehen, wie die Türen funktioneren, wie die unterschiedlichen Versuchsbedingungen ausgewählt und geladen werden können und wie die für die Studie gemessenen Daten gemessen und gespeichert werden.
Die gesamte Programmierung für dieses Projekt ist in der Entwicklungsumgebung Unity (Version: 2020.1.17f1) \cite{unity} und folglich mit der Programmiersprache \textquote{C\#} erfolgt. Um die Software während der Entwicklung testen zu können und um damit das Experiment durchführen zu können wurde mir freundlicherweise eine \textquote{Oculus Quest 2} \cite{quest} Datenbrille, vom Arbeitsbereich Mensch-Computer-Interaktion der Universität Hamburg zur Verfügung gestellt. Um mit der Schnittstelle davon zu interagieren nutzt das Projekt das, von Oculus frei zur Nutzung gestellte, \textquote{Oculus Integration SDK} für Unity \cite{integration}. Um die Rotation-Gains zu implementieren wurde mir freundlicherweise die Library \textquote{Space-Extender} von dem Unternehmen \textquote{Curvature-Games} zur Verfügung gestellt, welche diesen Prozess stark vereinfacht. Diese findet sich mittlerweile auch bei GitHub \cite{space-extender-git}.
\section{Klassendiagramm}
Um das Diagramm übersichtlich zu halten beschränkt es sich ausschließlich auf die Relationen zwischen den Klassen, es wird also nicht wie sonst in UML-Klassendiagrammen üblich die gesamte Schnittstelle aller Klassen inklusive ihren Attributen und ihren Methoden aufgelistet.
Aus dem selben Grund wurden auch Grundklassen/-typen mit denen Standardmäßig in Unity gearbeitet wird (zum Beispiel \textquote{Vector3}, \textquote{MonoBehaviour} oder \textquote{GameObject}) weggelassen.
\begin{figure}[H]
\begin{center}
\begin{tikzpicture}
\begin{umlpackage}{Assets/Scripts}
\umlemptyclass[x=4,y=1]{GenerateLevel}
\umlclass[x=10,y=-1]{GeneratorOculusInterface}{}{
}
\umlclass[x=7,y=-5]{RoomGenerator}{}{
}
\umlclass[x=4,y=-1]{RoomAndProgressManager}{}{
}
\umlclass[x=2,y=-5]{RotationGainMechanism}{}{
}
\umlclass[x=10.8,y=-8]{RotationRedirectorCollision}{}{
}
\umlclass[x=4,y=-7]{SceneLoader}{}{
}
\umlinterface[x=5,y=-9.5]{INumberPadListener}{}{
}
\umlclass[x=2,y=-12]{NumberPadScript}{}{
}
\umlclass[x=8,y=-12]{NumberPadButton}{}{
}
\end{umlpackage}
\begin{umlpackage}[x=10,y=5]{SpaceExtender}
\umlclass{RotationRedirector}{}{}
\end{umlpackage}
\begin{umlpackage}[x=2,y=5]{Oculus Integration SDK}
\umlclass{OVRManager}{}{}
\end{umlpackage}
\umldep[geometry=-|, anchors= 5 and -90, align2=left]{GenerateLevel}{RotationRedirector}
\umldep[geometry=-|, anchors= 0 and 85, align2=left]{GenerateLevel}{RoomGenerator}
\umldep[geometry=-|, anchors= -5 and 90, align2=left]{GenerateLevel}{RotationRedirectorCollision}
\umldep[geometry=|-|, weight=0.7, anchors= 160 and -90, align2=left]{GeneratorOculusInterface}{OVRManager}
\umlinherit[geometry=|-, anchors= 160 and 180]{RotationGainMechanism}{INumberPadListener}
\umlinherit[geometry=-|, anchors= 180 and 90]{SceneLoader}{INumberPadListener}
\umluniassoc[geometry=-|-, anchors= 180 and 0]{NumberPadButton}{NumberPadScript}
\umluniassoc[geometry=|-|, anchors= 90 and -90]{NumberPadScript}{INumberPadListener}
\umluniassoc[geometry=-|, anchors= 180 and -90]{RotationRedirectorCollision}{RotationGainMechanism}
\umluniassoc[geometry=|-|, anchors= 110 and -90]{RotationGainMechanism}{RoomAndProgressManager}
\umluniassoc[geometry=|-|, anchors= -50 and 95]{RoomAndProgressManager}{RoomGenerator}
\umluniassoc[geometry=|-|, anchors= -90 and 90]{GenerateLevel}{RoomAndProgressManager}
\umluniassoc[geometry=|-, anchors= 120 and -15]{GeneratorOculusInterface}{GenerateLevel}
\umluniassoc[geometry=|-|, anchors= 150 and -145, align2=left]{RotationGainMechanism}{RotationRedirector}
\umluniassoc[geometry=-|, anchors= 180 and 145, align2=left]{SceneLoader}{NumberPadScript}
\end{tikzpicture}
\end{center}
\caption{Ein Überblick über die Beziehungen der Klassen untereinander in Form eines UML-Klassendiagramms. Für die Übersichtlichkeit wurden Unity-eigene Klassen, wie zum Beispiel $Vector3$ oder $MonoBehaviour$, herausgelassen.}\label{figure:uml}
\end{figure}
\section{Vorstellung der Klassen}
\begin{multicols*}{2}
\paragraph{GeneratorOculusInterface}
Kommuniziert mit der Schnittstelle des \textquote{Oculus Integration SDK} um Informationen, die im Projekt benötigt werden bereitzustellen. Die wichtigsten Informationen, die hier geliefert werden, sind die Koordinaten der Begrenzungsecken des Trackingspaces. Die Nutzer:in der Oculus Quest 2 stellt im Setup der Brille den sogenannten \textquote{Guardian} ein. Dies ist dann eine Begrenzung, die sie um den begehbaren Raum in dem sie sich befindet zieht, und der immer dann in der virtuellen Realität eingeblendet wird, wenn sie dieser Begrenzung mit den Hand-Controllern oder der Datenbrille zu nahe kommt. Diese Begrenzung ist allerdings nicht rechteckig, was für den hier vorgestellten Levelgenerierungsalgorithmus aber notwendig wäre. Doch das Oculus SDK bietet in seiner Schnittstelle an, das größte, in diese Begrenzung passende, Rechteck auszugeben. Dies ist dann die Grundlage für die Raumgenerierung. Zudem ist diese Klasse dafür zuständig, je nach ausgewählter Testbedingung entsprechende Einstellungen an das Oculus SDK zu übergeben.
%Zum Beispiel ist bei der Real-Walking Bedingung erforderlich den \textquote{Tracking Origin Type} der Erfassung auf \textquote{Stage} zu setzen, sodass
\paragraph{RoomGenerator}
\hyphenation{Zusatz-eigenschaften}
Implementiert die Generierung der einzelnen Räume. Dafür liegt in dieser Klasse die zentrale \textquote{Generate}-Methode. Anhand der vier Eckkoordinaten des Raumes, der Richtung, in die der Raum zeigen soll und verschiedener Zusatzeigenschaften wie zum Beispiel, der Tiefe des zu generierenden Korridors, der Höhe der zu generierenden Türen, der Dicke der Wände und der Höhe des zu generierenden Korridors, erzeugt diese Methode das GameObject für den zu generierenden Raum. Außerdem erzeugt er das entsprechende Mesh für den Korridor und platziert die ansonsten nötigen Objekte (zum Beispiel Türen, Tafel, Eingabefeld) an den richtigen Positionen. Um die Tür nicht immer mittig zu platzieren bekommt die \textquote{Generate}-Methode außerdem einen Zufallswert zwischen 0 und 1 übergeben. Dieser bestimmt dann die Position der Tür, die in den Korridor hineinführt. (0 bedeutet ganz links, 1 hingegen ganz rechts).
Des Weiteren bietet diese Klasse mehrere Methoden an, die Berechnungen über den Raum, den sie generiert haben, anstellen. So kann man sich beispielsweise berechnen lassen ob der Korridor des Raumes auf der längeren, oder der kürzeren Kante des Grundrechtecks liegt, wie die Koordinaten des Mittelpunkts eines Raumes inklusive des Korridors sind und wie die Koordinaten des Mittelpunktes des Bereichs vor dem Korridor sind. (An diese Stelle im ersten Raum wird die Proband:in bei den Testbedingungen, in denen kein Real-Walking stattfindet, teleportiert.) Die Klasse besteht aus circa 1000 Zeilen Programmierung und ist somit die längste selbst geschriebene Klasse des Projektes.
\paragraph{GenerateLevel}
Diese Klasse implementiert den Levelgenerierungsalgorithmus der genauer in \autoref{chapter:generate}
beschrieben wird. Sie ist die zentrale Klasse des Projektes. In ihren öffentlichen Attributen können die Einstellungen für die zu generierende Testbedingung verändert werden. In ihrer \textquote{Generate}-Methode implementiert sie den Levelgenerierungsalgorithmus und verbindet darin die restlichen Teilmodule des Projekts. Sie ist also nicht nur dafür verantwortlich die \textquote{Generate}-Methode der \textquote{RoomGenerator}-Klasse mit den richtigen Eingabewerten aufzurufen, sondern platziert auch die Rotation-Gain Funktionalität an die richtige Stelle, und übergibt die generierten Räume an den \textquote{RoomAndProgressManager}, in dem sie in einer Liste gespeichert werden.
\paragraph{RoomAndProgressManager}
\hyphenation{Fire-base-Handler}
Ist dafür zuständig den Fortschritt der Proband:in zu verfolgen und entsprechend zu reagieren wenn es notwendig ist. Beispielsweise öffnet er die entsprechenden Türen, wenn ein Raum abgeschlossen ist.
Des Weiteren hält diese Klasse Instanzen der GameObjects für die Räume, in einer Liste, sodass sie dazu in der Lage ist, an den zugehörigen RoomGenerator-Instanzen Methoden aufzurufen. Diese Klasse ist außerdem dafür verantwortlich, dass nur der Raum in dem die Nutzer:in sich gerade befindet, der Raum davor und 2 Räume danach eingeblendet und sichtbar sind, um sicher zu gehen, dass die Räume nicht von Elementen aus anderen Räumen überlappt werden. Auf ähnliche Weise verwaltet sie auch die Sichtbarkeit der Wände der einzelnen Räume, die für die Real-Walking Bedingung nur angezeigt werden, wenn die Nutzer:in in dem Raum ist.
Um später vergleichen zu können, wie gut die Einschätzung der Proband:innen war misst, diese Klasse außerdem die von der Proband:in zurückgelegte Strecke. Wenn der letzte Raum des aktuellen Versuchs erreicht wurde, übergibt sie die entsprechenden Daten an den FirebaseHandler, der diese dann an eine Cloud-Datenbank verschickt, sodass der Versuchsdurchgang im Nachhinein ausgewertet werden kann.
\paragraph{RotationGainMechanism}
Diese Klasse implementiert den Mechanismus, der in der Real-Walking Bedingung bei den jeweiligen Räumen angewandt wird um den genauen Ablauf des Rotation-Gains zu definieren. Er zeigt die Zahlen auf der Tafel im Korridor an, verwertet die Eingabe des Eingabefelds, startet den Rotation-Gain und beendet ihn auch wieder. Er signalisiert dem RoomAndProgressManager wenn der Rotation-Gain vollständig ist. Dies ist der Fall wenn der Trackingspace um
90\textdegree\
gedreht hat, und die Proband:in dann eine richtige Eingabe tätigt. Dies verursacht, dass sich die Tür in den nächsten Raum öffnet. In den anderen Bedingungen ist er dafür verantwortlich dies nach einer zufälligen, geringen, Anzahl richtiger Eingaben in das Nummerneingabefeld zu tun, sodass die Proband:in auch in diesen Bedingungen den selben Ablauf erlebt. Dieser Mechanismus wird in \autoref{sec:rotgaininc} genauer ausgeführt.
\paragraph{SceneLoader}
Beim Betreten des Levels sieht die Proband:in ein virtuelles Eingabefeld, in dass sie die verschiedenen Testbedingungen eingeben kann, um den Versuch zu starten. Der SceneLoader ist dafür zuständig, auf diese Eingabe entsprechend zu reagieren und die entsprechende Bedingung zu laden. Dazu verändert dieser die Attribute der \textquote{GenerateLevel}-Instanz und ruft dann ihre \textquote{Generate}-Methode auf. Dieser Prozess wird nochmal in \autoref{sec:chooserpad} vertieft.
\paragraph{RotationRedirectorCollision}
Kleine Hilfsklasse, die erkennt ob der Nutzer sich gerade in dem entsprechenden Bereich befindet, indem der Rotation-Gain aktiv sein soll.
\paragraph{Door}
Die Türen nutzen dieses Script. Auf ihm kann die Methode \textquote{OpenDoor} aufgerufen werden, um sie zu öffnen.
\paragraph{Dissolvable}
Wird von der \textquote{Door}-Klasse genutzt, um der Tür die Funktionalität zu geben, fließend zu verschwinden. Dafür nutzt sie einen entsprechend programmierten Shader, der mithilfe einer Wolkentextur die Transparenz des Türmaterials anpasst. %link to image
\paragraph{INumberPadListener}
Die Klassen, die über Eingaben in einem NumberPad informiert werden wollen, können dieses Interface implementieren um zu einem NumberPadListener zu werden. Dies geschieht also nach dem \textquote{Observer Pattern} (siehe \cite{design-patterns})
\paragraph{NumberPadScript}
Dieses Script ist eine Komponente eines Nummerneingabefeldes und ist dafür zuständig die Eingabe zu verarbeiten und dann alle angemeldeten Observer über Änderungen zu informieren.
\paragraph{NumberPadButton}
Verbessert die Knöpfe eines Nummerneingabefeldes, indem es ihnen eine \textquote{CoolDown}-Periode gibt, sodass nicht unbeabsichtigt mehrere Eingaben entstehen und indem es einen Soundeffekt abspielt um der Nutzer:in als Feedback zu bestätigen, dass der Knopf gedrückt wurde.
\paragraph{FireBaseHandler}
Bietet die Methode \textquote{PostResult} an, die die Daten des aktuellen Versuchs an eine Cloud-Datenbank verschickt. So werden dann die Anzahl an Räume des Levels, die gelaufene Strecke in Metern, die Fortbewegungsart, und das Datum, inklusive der genauen Uhrzeit des Abschickens gespeichert. Außerdem wird gespeichert ob das Verschicken im Unity-Editor, also zum Testen, geschehen ist, oder ob es wirklich von der Datenbrille aus versendet wurde.
\end{multicols*}
\section{Hierarchy der Unity-Scene}\label{sec:hierarchy}
\begin{figure}[!h]
\centering
\includegraphics[width=0.5\textwidth]{images/hierarchy.png}
\caption{Die Hierachie der Unity-Szene vor der Laufzeit}\label{figure:hierarchy}
\end{figure}
Der folgende Abschnitt beschreibt die Objekte in der Unity-Szene und ihre Beziehung untereinander.
Das \textquote{Generator}-Objekt existiert um die Scripts, die ihm als Komponenten angehängt sind, in die Szene zu integrieren, sodass diese ausgeführt werden. Darauf folgt das \textquote{RedirectionObject}, welches, als effektiver Parent des \textquote{OVRCameraRig} später dafür genutzt wird, die Rotation-Gains auszuführen. Zwischen diesen beiden Objekten liegt aber noch der PlayerController. Dieser wird in den beiden Kontrollbedingungen für die Fortbewegungsarten genutzt.
Das \textquote{OVRCameraRig} und die hierarchisch untergeordneten Elemente sind ein vom Oculus Integration SDK bereitgestelltes Prefab, es integriert die Funktionalität der virtuellen Umgebung in die Unity-Szene.
\textquote{Floor} und \textquote{Ceiling} repräsentieren Boden und Decke der Szene. Das zuletzt in \autoref{figure:hierarchy} dargestellte Objekt ist das \textquote{ChooserPad}. Dies ist ein, den später beschriebenen Nummerneingabefeldern nachempfundener Mechanismus mit dem die Nutzer:in eingeben kann, welche der Testbedingungen sie ausführen möchte. Dies wird genauer in \autoref{sec:chooserpad} erklärt.
\begin{figure}[!h]
\centering
\includegraphics[width=0.5\textwidth]{images/hierarchy_runtime.png}
\caption{Die Unity-Hierarchie der Objekte, die der Szene erst bei der Levelgenerierung während der Laufzeit hinzugefügt wurden}\label{figure:hierarchy-runtime}
\end{figure}
\autoref{figure:hierarchy-runtime} zeigt die Hierarchie der erst nach Levelgenerierung entstandenen \textquote{Rot-GainCorridor}-Objekte, die nicht nur die, später in \autoref{sec:corridor} beschriebenen, Korridore, und alle Objekte darin repräsentieren, sondern auch die Wände um die zugehörigen Räume, also alle Objekte, die zu dem jeweiligen Raum gehören.
\section{Design der Szene} \label{sec:scene-design}
\begin{figure}[!h]
\centering
\includegraphics[width=0.5\textwidth]{vrscreenshots/rauminnen.jpg}
\caption{Ein Raum von innen}\label{figure:room}
\end{figure}
Im Folgenden werde ich die Designentscheidungen, die die Optik der Szene bestimmen erläutern.
Ein generierter Raum ist in \autoref{figure:room} zu sehen.
Die virtuelle Umgebung, die die Nutzer:in durchschreitet, ist der eines Dungeons nachempfunden. Dies ist in Computerspielen ein häufig eingesetztes Setting, weltbekannte Spiele wie
\textquote{The Elder Scrolls V: Skyrim},
die \textquote{Final Fantasy} Spielreihe,
die \textquote{The Legend of Zelda} Spielreihe,
und besonders sogenannte \textquote{Roguelike}-Spiele, wie
die \textquote{Diablo} Spielreihe,
\textquote{The Binding of Isaac},
oder \textquote{Darkest Dungeon}, beinhalten alle zumindest zum Teil Dungeonartige Level, die den Spieler herausfordern, eine dunkle Umgebung zu erkunden und gegen fiese Gegner zu kämpfen.
Obgleich letztere in den hier erzeugten Leveln nicht vorkommen, ist das Ambiente bewusst ein wenig düster gehalten und erinnert optisch an einen Dungeon. Dafür die aus dem Unity-Asset-Store heruntergeladene Textur \cite{dungeon-material}, die die Wände schmückt und ihnen ein rustikales, dungeonartiges Gefühl verleihen, sehr hilfrich.
\begin{figure}[!h]
\centering
\includegraphics[width=0.5\textwidth]{images/rogue.png}
\caption{
Screenshot des beliebten Computerspiels \textquote{Rogue} (1980)
Bildquelle: \href{https://commons.wikimedia.org/wiki/File:Rogue_Screenshot.png}{https://commons.wikimedia.org/wiki/File:Rogue\_Screenshot.png}
}
\label{figure:rogue}
\end{figure}
Das Spiel \textquote{Rogue}, von 1980, nachdem auch das Genre \textquote{Roguelike} benannt wurde, ist ein Meilenstein in der Prozeduralen Levelgeneration gewesen und hat bis heute großen Einfluss auf die Welt der Computerspiele. Auch dabei geht es darum einen Dungeon zu erkunden, auch wenn dieser verständlicherweise graphisch, noch nicht besonders aufbereitet gewesen ist (siehe \autoref{figure:rogue}).
Abgesehen davon bietet die Umgebung eines Dungeons viele Freiheiten, was den Realismus der Welt angeht. Es wird nicht hinterfragt, wieso ein Gebäude so strukturiert sein sollte, dass man die ganze Zeit um die Ecke geht oder wieso die Türen sich öffnen und schließen, in dem sie magisch erscheinen oder sich auflösen.
Um die Erkundungsstimmung noch ein wenig zu verstärken und eine realistische Lichtquelle in die Welt einzubauen trägt die Nutzer:in eine Kopflampe. Dies ist ein einfacher Spotlight mit leicht bläulichem Licht, dessen Parent die Kamera des Spieler:innenavatars ist.
%MCI mässige quellen wären hier gut
\section{Virtueller Avatar}
\begin{figure}[!h]
\centering
\includegraphics[width=0.5\textwidth]{vrscreenshots/hands.jpg}
\caption{Die Hände des virtuellen Avatars vor einem Nummerneingabefeld}\label{figure:hands}
\end{figure}
Um die Nutzer:in in der Szene zu repräsentieren und ihr die Möglichkeit zu geben mit dieser zu interagieren kann sie über die Tranformation von Datenbrille und Controller einen virtuellen Avatar steuern. Auf diese Weise ist es ihr möglich, mithilfe der Hände dieses virtuellen Avatars die Knöpfe von Nummerneingabefeldern zu bestätigen und in der später beschriebenen Teleportationsbedingung den Ort auszuwählen, zu dem sie sich teleportieren möchte (siehe \autoref{figure:tp-ring}).
Die virtuellen Hände folgen der Bewegung und Drehung der echten Hände sogar der Stellung der Finger, von der Nutzer:in solange sie die Oculus Controller auf die richtige Weise hält. Die Hände sind in \autoref{figure:hands} zu sehen.
Auch mit ihrem Kopf kann die Nutzer:in mit der Szene interagieren und Knöpfe betätigen, wenngleich dies auch eine weniger hilfreiche Funktionalität ist.
Die Funktionalität der virtuellen Avatare wurde vom Oculus SDK bereit gestellt und wurde von mir lediglich in die Szene integriert. %quelle?
Damit virtuelle Objekte innerhalb der Szene dem realen Körper der Nutzer:in folgen wurden diese hierarchisch den dafür bereit gestellten \textquote{Anchor}-Objekten unterstellt (siehe \autoref{figure:hierarchy}). Für die Hände wurden dafür die vom Oculus SDK bereiten gestellten Prefabs genutzt. %name of prefabs
An den \textquote{CenterEyeAnchor} wurde die in \autoref{sec:scene-design} erwähnte Kopflampe angehangen, sodass diese der Blickrichtung der Nutzer:in folgt.
\section{Implementierung der Rotation-Gains}
\begin{figure}[!h]
\centering
\includegraphics[width=1\textwidth]{images/rotationredirector.png}
\caption{Screenshot eines instaziierten \textquote{RotatinRedirector}-Objekts von oben. Der rote Bereich repräsentiert den Trackingspace bevor der Rotation-Gain ausgeführt wurde, der Blaue den danach. Der grün umrandete Quader stellt den Collider dar, in dem die Nutzer:in sich befinden muss, damit der Rotation-Gain angewendet wird. Die grün nach oben steigende Linie repräsentiert den Punkt $\vec{P}$.}\label{figure:rotredirector}
\end{figure}
Die Umsetzung der Rotaiongains erfolgt mithilfe des mir zur Verfügung gestellten Unity-Package \textquote{Space-Extender} \cite{space-extender-git}.
Dieses stellt das Prefab \textquote{RotationRedirector} zur Verfügung. Dieses kann im Code instanziiert werden und ist, nachdem es richtig positioniert wurde und einige Parameter übergeben bekommen hat, dazu in der Lage einen Rotation-Gain auf die Nutzer:in anzuwenden. Dafür benötigt es die Dimensionen des Trackingspaces, den virtuellen Avatar der Nutzer:in und die Koordinaten, des Punktes, um den der Trackingspace rotiert werden soll.
Wie das generierte und konfigurierte RotationRedirector-Objekt im Unity-Editor aussieht ist in \autoref{figure:rotredirector} zu sehen. Der rote Bereich repräsentiert den innerhalb Trackingspaces begehbaren Bereich vor der Anwendung des Rotation-Gains und der Blaue den innerhalb des Trackingspace begehbaren Bereich nach der vollständigen Ausführung des Rotaiongains.
Der RotationRedirector wird, nachdem das alles geschehen ist, für jeden Raum, an die Instanz des RotationGainMechanism, die für eben jenen Raum zuständig ist, übergeben. Sobald das Signal, dass die Nutzer:in sich über dem Rotationspunkt ($\vec{P}$) befindet, vom entsprechenden Collider kommt, wird der Prozess des Rotation-Gains am RotationRedirector aktiviert. (Auch der Collider ist in \autoref{figure:rotredirector} abgebildet.)
Der Rotation-Gain verstärkt oder verringert die Drehung in jeweilige Richtung, um $10\%$. Damit liegt der Rotation-Gain noch innerhalb der in \cite{detection-thresholds} gefundenen Grenzen der Wahrnehmbarkeit (Detection-Thresholds), und sollte somit nicht von Nutzer:innen erkennbar sein.
Des Weiteren sind die Rotation-Gains bei dieser Implementierung abhängig von der Kopf-Drehgeschwindigkeit, bei langsamen Kopfdrehungen wird ein schwächerer Effekt angewandt.
%left: 0.1
%right: -0.1
%use velocity dependet gain: true
%rotation speed upper threshold: 350
\section{Implementierung der Impossible-Spaces}
Die Wände der Räume werden für die Real-Walking Studienbedingung, wie später in \autoref{subsec:realwallgen} ausgeführt, auf eine Weise generiert, die in der realen Welt nicht möglich wäre, die Räume überlagern sich an den Grenzbereichen. Sie werden also zu Impossible-Spaces. Das Ein- und Ausblenden der entsprechenden Wände wird von der \textquote{RoomAndProgressManager}-Klasse übernommen.
\section{Fortbewegungsarten}
Im folgenden werde ich beschreiben wie die unterschiedlichen Fortbewegungsarten implementiert wurden.
\subsection{Joystick-Steuerung} \label{subsec:joystick-implementation}
Der Joystick des rechten Controllers bestimmt bei dieser Fortbewegungsbedingung die Yaw-Rotation des Avatars, während der des linken Controllers die Bewegung ermöglicht. Den linken Joystick nach oben zu schieben beschleunigt den Avatar in die aktuelle Blickrichtung.
Die Joystick-Fortbewegung wurde mithilfe einiger, vom Oculus Integration SDK gelieferter Scripts, hauptsächlich dem \textquote{OVRPlayerController} umgesetzt. Dieser befindet sich dann auf dem in \autoref{sec:hierarchy} beschriebenen PlayerController und steuert so diesen und dessen Kindelemente, so auch den virtuellen Avatar der Nutzer:in.
Um das Aufkommen der Simulatorkrankheit möglichst gering zu halten
werden Drehungen nicht wie bei Joystick-Steuerung, beispielsweise in Konsolenspielen üblich, fließend auf die Kopfdrehungen übersetzt, sondern werden in festen 45\textdegree\--Intervallen angewandt (siehe \cite{cybersickness-yasin}).
Die Beschleunigung des Nutzer:innen-Avatars liegt bei $0,1$. Da die Fortbewegung über den OVRPlayerController geregelt wird, wird hier keine feste Geschwindigkeit, sondern eben nur die Beschleunigung festgelegt.
\subsection{Teleportierung}\label{subsec:teleport-implementation}
\begin{figure}[!h]
\centering
\includegraphics[width=0.5\textwidth]{vrscreenshots/teleportring.jpg}
\caption{Der Teleportationscursor, mit dem die Nutzer:in kurz vor der Teleportation ihr Ziel markieren kann. Der Pfeil innerhalb des Rings repräsentiert die Blickrichtung nach der Teleportation}\label{figure:tp-ring}
\end{figure}
Die Teleportierung funktioniert indem die Nutzer:innen mit der rechten Hand ihres Avatars während sie die $A$-Taste auf dem rechten Controller gedrückt halten, auf die Stelle am Boden zielen, zu der sie sich bewegen möchten. Währenddessen werden ein grüner Laserstrahl, der aus der rechten Hand zielt und der Teleportationscursor eingeblendet (siehe \autoref{figure:tp-ring}). Mit dem Joystick des linken Controllers kann die Blickrichtung nach der Teleportation eingestellt werden, diese wird auch durch den Pfeil im Teleportationscursor repäsentiert. Wenn die Nutzer:in nun den Zeigefinger-Trigger ihres rechten Controller bedient, wird die Teleportation ausgeführt.
Auch diese Fortbewegungsart wird mithilfe einiger, mit dem Oculus Integration SDK gelieferter Scripts, die auf dem extra für diesen Zweck platzierten Kind-Objekt des PlayerControllers \textquote{Teleportation} und auf dem PlayerController-Objekt als Komponenten liegen, implementiert. Diese sind \textquote{PlayerController (Simple Capsule with Stick Movement)}, \textquote{CharacterController}, \textquote{Locomotion Teleport}, \textquote{Teleport Input Handler Touch}, \textquote{Teleport Target Handler Physical}, \textquote{Teleport Aim Handler Laser}, \textquote{Teleport Aim Visual Laser}, \textquote{Teleport Orientation Handler Thumbstick}, und \textquote{Teleport Transition Instant}. Des Weiteren werden zwei Prefabs, nämlich: \textquote{TeleportDestination} und\textquote,{TeleportLaser} benötigt.
\subsection{Real-Walking}\label{subsec:real-walk-implementation}
\hyphenation{OVR-Camera-Rig}
Für die Real-Walking Fortbewegungsart bedarf es keiner besonderen Implementierung, es ist lediglich wichtig, dass die Einstellung \textquote{Tracking Origin Type} im, auf dem \textquote{OVR-CameraRig}-Objekt
liegenden, Script \textquote{OVR Manager}, auf \textquote{Stage} gesetzt wird. Dies unterdrückt den Zentrierungsmechanismus, der standardmäßig ausgeführt wird wenn der \textquote{OculusButton} gehalten wird. Der Zentrierungsmechanismus ist für die anderen beiden Fortbewegungsarten wichtig, um die Position des Nutzer:innen-Avatars wieder mit der wahren Position der Nutzer:in abzugleichen.
\section{Der Rotation-Gain-Anreiz-Mechanismus}
\label{sec:rotgaininc}
Damit der Rotation-Gain zur Wirkung kommt muss sich die Nutzer:in ungefähr auf den Punkt $\vec{P}$ stellen und ihren Kopf um die Yaw-Achse drehen.
Für das intuitivere Gefühl und um die Aufmerksamkeit nicht so konkret auf den Rotation-Gain zu lenken, habe ich mich dagegen entschieden den Punkt $\vec{P}$ zu markieren und die Nutzer:innen zu bitten dort ihren Kopf zu drehen, sondern habe mir einen Vorwand ausgedacht, wieso es zum einen notwendig ist an der Stelle zu stehen und zum anderen, wieso sie ihren Kopf drehen müssen.
\begin{figure}[!h]
\centering
\includegraphics[width=0.5\textwidth]{vrscreenshots/numpad.jpg}
\caption{Ein Nummerneingabefeld. Mit der \# Taste wird eine Eingabe bestätigt, die c-Taste löscht die aktuelle Eingabe}\label{figure:numpad}
\end{figure}
Um diesen Effekt zu erzielen wird ein Nummerneingabefeld (siehe \autoref{figure:numpad}), an der Korridorinnenwand in Richtung des Raumes aus dem die Nutzer:in gerade kommt, genau vor die Position $\vec{P}$ plaziert. In dieses Eingabefeld sollen dann mehrere zweistellige Nummern, die am anderen Ende des Korridors, auf einer digitalen Tafel angezeigt werden, eingegeben werden, bis die Tür sich öffnet. Auf der Tafel wird nur eine zweistellige Nummer zur Zeit angezeigt.
Dies sorgt dann sowohl dafür, dass die Nutzer:in auf den Punkt $\vec{P}$ stellen, um möglichst einfach die Nummern eingeben zu können, als auch dafür, dass die Nutzer:in ihren Kopf wiederholt um die Yaw-Achse dreht, weil sie abwechselnd ablesen muss, welche Zahlen auf der Tafel hinter ihr angezeigt werden und die Zahlen in das Eingabefeld schräg vor ihr eingeben muss. Dies sorgt für einen intuitiven Grund den Kopf zu drehen und somit dafür den Rotation-Gain zu nutzen. Wenn der Fortschritt des Rotation-Gains abgeschlossen ist und ein weiteres Mal die korrekte Nummer in das Eingabefeld eingegeben wurde, öffnet sich die Tür vor der Nutzer:in (also die \textquote{Seitentür}) sodass die Nutzer:in in den nächsten Raum gehen kann. Da nun der Trackingspace genau den nächsten Raum umgibt, ist es wichtig, dass die Nutzer:in nicht versucht, zurück in den vorherigen Raum zu gehen. Aus diesem Grund schließt sich hinter der Nutzer:in eine vorher noch nicht zu erkennenende Tür.
Im Programm-Code findet sich dieser ganze Vorgang in der Klasse \textquote{RotationGainMechanism}. Dieser wird für jeden Raum erstellt und auch dem Objekt des Raumes als Komponente hinzugefügt. Eine Instanz des RotationGainMechanisms ist also immer für den Raum zuständig, auf dem er sich befindet. Mit der \textquote{Init}-Funktion wird das Objekt direkt nach der Erstellung initialisiert, hier meldet sich die Instanz dann auch in der zugehörigen Eingabefeld-Klasse (\textquote{NumPadScript}) als Observer an. Sobald sich die Nutzer:in dann in den um die Position $\vec{P}$ herum platzierten Collider begibt, wird mit der Funktion \textquote{StartMechanism} die Prozedur gestartet. Zunächst wird eine neue zweistellige Zahl mithilfe des (von Unity bereitgestellten) Pseudozufallgenerators erstellt, dann wird diese Zahl auf der dem aktuellen Raum zugehörigen Tafel angezeigt. Sobald die Bestätigungstaste des Eingabefelds gedrückt wurde (\textquote{\#}), wird überprüft ob der Fortschritt des Rotation-Gains schon bei 100\% ist. Falls dem nicht so ist, beginnt der Vorgang von vorne und es wird eine neue Zahl erstellt. Wenn der Rotation-Gain vollständig abgeschlossen ist (also eine 90\textdegree\ Drehung stattgefunden hat) wird dem \textquote{RoomAndProgressManager} mitgeteilt dass der aktuelle Raum abgeschlossen ist und die Tür öffnet sich.
In den Kontrollbedingungen wird kein Rotation-Gain angewandt. Dennoch müssen die Proband:innen auch hier Zahlen in das Eingabefeld eingeben. In diesen Szenarien wird die Türöffnung nicht von der Vervollständigung des Rotation-Gains abhängig gemacht, sondern wird eine Zufallszahl zwischen 4 und 8 bestimmt und mitgezählt, wie oft Zahlen bestätigt wurden. Wenn die Zufallszahl erreicht wird, öffnet sich die Tür. Durch Erfahrungen beim Testen hat sich gezeigt dass es etwa zwischen 4 und 8 Eingaben bedarf, bevor der Rotation-Gain abgeschlossen ist.
\section{Seitentür Mechanismen}
\begin{figure}[!h]
\centering
\includegraphics[width=0.4\textwidth]{vrscreenshots/dissolve.jpg}
\includegraphics[width=0.4\textwidth]{vrscreenshots/reverseddoor.jpg}
\caption{Links: Eine sich gerade mit einem Auflösungseffekt öffnende Seitentür. Rechts: Die nun verschlossene Tür, die verhindert, dass die Nutzer:in nach der Ausführung des Rotation-Gains in den vorherigen Raum zurück geht}\label{figure:doors}
\end{figure}
Um die Nutzer:in daran zu hindern in Bereiche zu gehen, die ihr noch nicht zugänglich sind, weil beispielsweise der Rotation-Gain noch nicht abgeschlossen ist, wird ihr dies durch eine verschlossene Tür suggeriert. Nach abgeschlossenem Rotation-Gain öffnet die Tür sich mit einem auflösenden optischen Effekt (siehe \autoref{figure:doors}, links) und einem Erfolg andeutenden Geräusch. Damit sie nun aber nicht auf die Idee kommt, in den vorherigen Raum zurück zu gehen (dieser läge nun außerhalb des begehbaren Bereichs) wird hinter ihr eine weitere Tür mit dem selben Effekt verschlossen (siehe \autoref{figure:doors} rechts).
Der visuelle Effekt entsteht durch einen Fragmentshader, der auf der Tür liegt. Dieser kontrolliert die Durchsichtigkeit der Bereiche der Tür mithilfe einer animierbaren Variable und einer Wolkentextur. Die dunklen Bereiche der Wolkentextur werden bei ansteigen der Variable zuerst ausgeblendet, bis irgendwann die ganze Tür unsichtbar geworden ist. Bei der schließenden Tür geschieht dies genau umgekehrt.
Um zu verhindern, dass in andere Räume hinragende Korridore betreten werden können, wurden auch die Haupttüren dieser Korridore mit dem selben Effekt verschließbar gemacht. Diese öffnen sich jedoch immer direkt beim Betreten des Raumes, in dem der Korridor steht.
\section{Bedingungsauwahl und Laden der Szene} \label{sec:chooserpad}
\begin{figure}[!h]
\centering
\includegraphics[width=0.5\textwidth]{vrscreenshots/better_chooserpad.jpg}
\caption{Das Eingabefeld, mit dem die verschiedenen Versuchsbedingungen ausgewählt werden können. Die c-Taste löscht die aktuelle Eingabe, mit der \#-Taste wird das aktuell ausgewählte Level gestartet}\label{figure:chooserpad-menu}
\end{figure}
Damit die Versuchspersonen der später vorgestellten Studie die Level mit den unterschiedlichen Bedingungen ausführen können, gibt es ein Menü, in dem diese ausgewählt werden können. Darin befindet sich nur der Boden, die Decke und das Bedingungsauswahlfeld (siehe \autoref{figure:chooserpad-menu}). Auf diesem kann die Nutzer:in auf einem $3 \times 3$ Eingabefeld auswählen, welche Versuchsbedingung sie starten möchte. In der späteren Studie wird vorgegeben, welche die Proband:in auswählen soll. Die einzelnen Bedingungen sind folgendermaßen kodiert. $A$ steht für die Real-Walking Fortbewegungsart-Bedingungen, $B$ für Joystick-Steuerung, $C$ für Teleportation, $1$ für eine Raumanzahl von 3 Räumen, $2$ für 6 und $3$ für 9 Räume. Die Auswahl erfolgt per Tastendruck, allerdings wird das Level erst generiert und gestartet, sobald anschließend die Bestätigungstaste \# gedrückt wird. Diese Kodierung ist den Versuchspersonen nicht bekannt.
Das ganze funktioniert dann so, dass die Instanz der \textquote{SceneLoader}-Klasse, die auf dem \textquote{Generator}-Objekt liegt, eine Instanz auf das Auswahlfeld und auf die \textquote{GenerateLevel}-Instanz hält. Sobald die Bestätigungstaste gedrückt wurde, werden die entsprechenden Einstellungen daran vorgenommen, einige VR-Einstellungen getätigt (beispielsweise das Deaktivieren der Reset-Möglichkeit, die bei der Real-Walking Bedingung zu Problemen führen könnte), die Fortbewegungsart festgelegt, indem die entsprechenden Unity-Komponenten, die die Joysticksteuerung oder die Teleportation ermöglichen aktiviert, oder deaktiviert werden und zu guter letzt die Teleportierung der Nutzer:in in den ersten Raum des Levels getätigt.
\section{Messmechanismen und Datenspeicherung} \label{sec:measure-distance}
Um an späterer Stelle einschätzen zu können, wie gut die Proband:innen die zurückgelegte Strecke geschätzt haben, ist es erforderlich diese zu messen. Zusätzlich dazu ist es auch notwendig diese Daten zu speichern. Im Folgenden werde ich erläutern, wie dies implementiert ist.
Da es nicht darum geht, die Luftlinie zwischen Start und Ende des Levels zu messen, sondern ihre konkret zurückgelegte Distanz zu messen, ist diese Aufgabe nicht gänzlich trivial. Würde man einfach in jedem Tick die Kopfposition des virtuellen Avatars der Proband:in speichern, die Distanz zum vorherigen Punkt berechnen und aufsummieren, wäre das Ergebnis unerwartet groß, und insoweit inkorrekt, als dass damit dann nicht mehr die zurückgelegte Distanz, wie sie wahrscheinlich intuitiv interpretiert werden würde gemeint wäre.
Da nun jede Millimeterbewegung des Kopfes aufsummiert werden würde, würde eine einfache Kopfdrehung die zurückgelegte Strecke schon um einen großen Teil erhöhen. Dies würde dazu führen, dass die Messung der zurückgelegten Distanz nicht mehr intuitiv einzuschätzen wäre.
Um dem entgegenzuwirken habe ich die Auflösung dieser Messung deutlich veringert, indem nicht mehr jeder Tick, diesen Prozess durchläuft, sondern nur ein Tick etwa alle 2 Sekunden. So werden deutlich grobere Bewegungen gemessen und die gemessenen Ergebnisse passen deutlich besser zu der intuitiven Einschätzung der Entfernung. Es ist aber dennoch zu erwähnen, dass durch die verlorenen Details auch eine gewisse Strecke verloren geht, beispielsweise wenn die Nutzer:in zwischen den zwei Ticks eine Kurve gegangen ist.
Es ist dennoch unumgänglich eine solche, oder ähnliche Messauflösungsveringerung vorzunehmen. Andernfalls wäre zusätzlich davon auszugehen, dass die Real-Walking Bedingung aufgrund von natürlichen Schwankungen beim Gehen deutlich längere gemessene Strecken produzieren würde, als die virtuellen Fortbewegungsarten.
All dies ist im \textquote{RoomAndProgressManager} implementiert. Hier gibt es eine \textquote{StartTime-Measure}-Methode, die zum Start der Bedingung vom \textquote{SceneLoader} aufgerufen wird und eine \textquote{AddDistance}-Methode, die in der von der \textquote{Update}-Methode alle 150 Frames einmal aufgerufen wird. Diese bestimmt dann euklidisch die Distanz zwischen der aktuellen Position der Nutzer:in und der zuletzt gemessenen und addiert diese auf eine Kummulationsvariable.
Sobald das Level der Versuchsbedingung abgeschlossen ist, wird diese Kummulationsvariable an den \textquote{FirebaseHandler} weitergeleitet, der nun die Daten der aktuellen Versuchsbedingung an die private Datenbank sendet um die Daten für die spätere Auswertung zu speichern.
\chapter{Levelgenerierung}
\label{chapter:generate}
Dieses Kapitel beschreibt, wie genau die Generierung eines mit der Methode, die diese Arbeit vorstellt, generierten Levels funktioniert. Nacheinander werde ich die grundlegenden Ideen hinter der Levelgenerierung erörtern und dabei jeweils genauer auf ihre Implementierung eingehen. Anschließend werde ich den Algorithmus, der die unterschiedlichen Codeblöcke nutzt um die Levelstruktur zu generieren beschreiben und vorstellen.
Zuerst bespreche ich, wie die Räume angeordnet werden müssen damit, sie durch den Rotation-Gain verbunden werden können. Dann stell ich vor, wie die Korridore, die in den Räumen generiert werden um der Nutzer:in einen klaren Weg voran zu präsentieren und den Übergang zwischen den Räumen intuitiver zu gestalten, erstellt werden. Als nächstes beschreibe ich die Vorgänge, die für die Generierung der Wände der Räume verantwortlich sind und erkläre wie die entsprechenden Berechnungen stattfinden.
Anschließend werde ich beschreiben, an welchen Stellschrauben manipuliert werden kann um heterogene Ergebnisse bei der Levelgenerierung zu bekommen, erst hier können (Pseudo-)Zufallsfaktoren eine Rolle spielen.
Mit der Erklärung der Zusammensetzung des Algorithmus schließe ich dieses Kapitel ab.
\section{Raumplatzierung}
Um zu verstehen, wie die Ecken eines Raumes berrechnet werden, ist es zunächst essentiell, die Grundidee hinter der Raumanordnung zu verstehen.
\begin{figure}[H]
\ctikzfig{2rooms_a}
\caption{Darstellung davon, wie die Räume für den antizipierten Effekt angeordnet sein müssen. Wenn an Punkt $\vec{P}$ ein Rotation-Gain über 90\textdegree\ ausgeführt wird liegt der Trackingspace vor der Ausführung des Rotation-Gains über dem Bereich $A$ und danach über dem Bereich $B$. $O$ bezeichnet den Bereich, bei dem sich die beiden Räume überlagern}\label{figure:two_rooms}
%TODO: P Point size in tikz
\end{figure}
%paragraph Erklärung
\subsection{Grundidee}
\label{subsec:roomplaceidea}
%Um die durchgehende Weiterführung des Levels zu ermöglichen werden zwei Räume immer genau so angeordnet, dass ein Rotation-Gain, der genau bis zu einer Verdrehung der beiden Realitäten von 90\textdegree\ angewandt wird, während die Nutzer:in an einem bestimmten Punkt in der Ecke des Raumes steht,
Wenn ein Rotation-Gain angewandt wird, verdrehen sich virtuelle und reale Realität umeinander, um einen konkreten Drehpunkt. In der Regel stellt dieser die Position der Nutzer:in dar, damit der Effekt allerdings genau plan- und vorhersagbar ist, findet die Drehung der Umgebung nicht um den Kopf der Nutzer:in, sondern um einen bestimmten vordefinierten Punkt $\vec{P}$ statt.
Wenn diese Position $\vec{P}$ sich in einer Ecke des (rechteckigen) Trackingspace-Raumes befindet, zudem genau gleich weit von beiden Wänden, die diese Ecke bilden, entfernt ist und dann ein gerichteter Rotation-Gain angewandt wird,
bis genau 90\textdegree\ Verdrehung erreicht sind, dann steht der aktuelle begehbare Bereich in der virtuellen Umgebung $B$, dem vorherigen begehbaren virtuellen Bereich, der ebenfalls durch den Trackingspace definiert war $A$, genau orthogonal gegenüber.
Vorher hat der Bereich $A$ genau den virtuellen Bereich innerhalb des Trackingspaces dargestellt. Die beiden Areale $A$ und $B$ überlappen sich zwar in einem gewissen Bereich, in dem die Nutzer:in nach Beendigung des Rotation-Gains dann auch gerade steht $O$, aber ein Großteil von $A$ ist nun Teil des Bereiches der virtuellen Umgebung geworden, der, begrenzt durch den Trackingspace, nicht zugänglich ist. Auf diese Weise ist also für die Nutzer:in ein neuer Bereich der virtuellen Umgebung begehbar geworden.
Wenn der Rotation-Gain subtil genug angewandt wurde hat die Nutzer:in (idealerweise) nicht bewusst wahrgenommen, dass die Welten sich verdreht haben. Wenn sie anschließend geradeaus geht, entsteht der Eindruck, dass nun ein weiterer Teil der Welt zugänglich geworden ist.
Ziel des Algorithmus ist es eine Reihe von aufeinander folgenden Räumen zu generieren, sodass die Nutzer:in sich durch ein Dungeon-artiges Level bewegen kann um vom ersten zum letzten Raum zu gelangen.
Die Grundidee hinter der Raumgenerierung ist es also, dass genau die beiden Areale $A$ und $B$ von Wänden umgeben werden. %TODO: formulierung
In \autoref{figure:two_rooms} wird ersichtlich, wie die beiden Räume zueinander stehen müssen, um diesen Effekt zu ermöglichen.
Um dann also von Raum $A$ zu Raum $B$ zu gelangen, muss die Nutzer:in sich an der Position $\vec{P}$ oft genug drehen und dann muss ein Rotation-Gain bis zu 90\textdegree\ in die jeweilige Richtung angewandt werden. Bei dem Beispiel in \autoref{figure:two_rooms} muss der Rotation-Gain bei Yaw-Kopfdrehungen nach links positiv und nach rechts negativ verlaufen um den gewünschten Effekt möglichst effizient zu erzielen.
% Andersherum wäre auch möglich, dann müssten sich die Welten aber nicht um
% 90 \textdegree sondern um 270 \textdegree
% drehen.
%Danach kann sie mit der Illusion geradeaus zu gehen einen neuen Raum erkunden während sie sich eigentlich nur weiter innerhalb des realen Trackingspaces bewegt.
Die Nutzer:in kann nun geradeaus gehen, da sie sich innerhalb des realen Trackingspaces um 90\textdegree\ gedreht hat, also nicht mehr so steht, dass sie aus dem Trackingspace hinaus gehen würde, würde sie geradeaus gehen. Wenn sie diese Drehung aber nicht wahrgenommen hat, entsteht die Illusion sie könnte geradeaus, über die Grenzen des Trackingspaces hinaus gehen.
Der reale Trackingspace umschließt bei der hier vorgestellten Methode also immer genau den Raum, in dem sich die Nutzer:in gerade befindet.
\subsection{Berechnung der Ecken}
\label{subsection:calccorners}
\begin{figure}[H]
\centering
\input{calculateCorners.tikz}
\caption{Die Pfeile repräsentieren die zur Eckenberechnung genutzten Vektoren. Mit $\vec{C_0}, ..., \vec{C_3}$ werden die Ecken bezeichnet, mit $S_{0}, ..., S_3$ die Seiten des Raumes}
\label{figure:calculateCornersFig}
\end{figure}
Der Effekt, dass die Räume in denen sich die Nutzer:innen gerade befinden, immer genau den Trackingspace darstellen, wird zu großen Teilen durch die besondere Art der Raumgenerierung ermöglicht. Diese möchte ich im Folgenden vorstellen.
Zunächst müssen die Koordinaten der Ecken innerhalb der virtuellen Umgebung bestimmt werden. Für den ersten Raum ist es nicht schwierig, die virtuellen Koordinaten der Ecken der Trackingspace-Boundaries werden vom Oculus Integration SDK geliefert.
In der \textquote{GeneratorOculusInterface} Klasse werden diese zu Beginn der Levelgenerierung abgefragt und der \textquote{GenerateLevel}-Klasse zur Verfügung gestellt. Um allerdings die Raumecken der folgenden Räume zu bestimmen, müssen einige Punkte, Längen und Vektoren bereits definiert oder errechnet worden sein. Wie diese zustande kommen, wird im darauf folgenden Absatz erläutert. Für alle Räume, außer dem ersten berechnen, sich die Eckkoordinaten dann folgendermaßen.
% $$ cP = P + (-1) * sDD * dP $$
% $$ C_a = cP + (-1) * btF * dP $$
% $$ C_b = C_a + sDD * length $$
% $$ C_c = C_d + sDD * length $$
% $$ C_d = cP + btF * (width - dP) $$
%TODO: nochmal checken
\begin{align}
\begin{split}\label{eq:1}
\vec{cP} ={}& \vec{P} + (-1) * \hat{sDD} * dP
\end{split}\\ \\
\begin{split}\label{eq:2}
\vec{C_0} ={}& \vec{cP} + (-1) * \hat{btF} * dP
\end{split}\\
\begin{split}\label{eq:3}
\vec{C_1} ={}& \vec{C_0} + \hat{sDD} * length
\end{split}\\
\begin{split}\label{eq:4}
\vec{C_2} ={}& \vec{C_3} + \hat{sDD} * length
\end{split}\\
\vec{C_3} ={}& \vec{cP} + \hat{btF} * (width - dP)\label{eq:5}
\end{align}
% \begin{align}
% \begin{split}\label{eq:1}
% a ={}& b + c + d\\
% & + e + f + g
% \end{split}\\
% \begin{split}\label{eq:2}
% k ={}& l + m + n + m + n + m + n\\
% & + o + p + q
% \end{split}\\
% r ={}& s + t (u + v + w)\label{eq:3}
% \end{align}
Auch zu sehen ist diese Berechnung in dem in der \autoref{figure:calculateNewCornersScript} gezeigen Quelltext.
Wie die hier genutzen Variablen
$\vec{cP}$,
%$\hat{sDD}$, $\hat{btF}$,
$width$ und $length$ definiert sind wird aus \autoref{figure:calculateCornersFig} ersichtlich. %TODO: figure erweitern
%weiteres dP nach rechts
%sDD
%btF
$\vec{cP}$ steht dabei für den Punkt hinter $\vec{P}$, der genau eine $dP$-Länge in Richtung des alten Raumes liegt. $\hat{sDD}$ (sideDoorDirection) ist ein normalisierter Richtungsvektor,
der die Richtung des Korridors des letzen Raumes erweitert. %TODO: formulierung erweitert?
Also aus dem vorherigen in den aktuellen Raum hineinzeigt.
$\hat{btF}$ (backToFront) ist auch ein normalisierter Richtungsvektor, der orthogonal zu $\hat{sDD}$ steht.
Er zeigt von der hinteren Wand des Korridors des vorherigen Raumes zur vorderen Wand.
Diese Richtungsvektoren werden vor der Eckenberechnung errechnet indem die Vektoren, die die entsprechenden Ecken des schon bestehenden Raumes darstellen, voneinander subtrahiert werden um die gemeinten Richtungen in Form von Vektoren zu errechnen, bevor sie dann normalisiert werden.
$width$ beschreibt die Breite der Räume, während $length$ die Länge beschreibt. Diese beiden Variablen hängen von den Maßen des ersten Raumes ab, bei dem die Eckkoordinaten ja den Trackingspace der Nutzer:in abbilden. Es ist noch wichtig zu erwähnen, dass die in der eben erwähnten Abbildung gezeigte Folge von Ecken und Seiten nicht genau spiegelverkehrt ist, wenn der Raum in die andere Richtung generiert würde (siehe \autoref{sec:random}), sondern die Reihenfolge der Ecken genau invertiert läuft. Das Ganze ist also nicht nur vertikal, sondern auch horizontal gespiegelt zu der Darstellung in \autoref{figure:calculateCornersFig}.
\begin{figure}[H]%TODO: frisieren und kommentieren
\centering
\sourcecode{calculateNewCorners.cs}
\caption{Funktion zur Berechnung der virtuellen Eckkoordinaten des nächsten Raumes}
\label{figure:calculateNewCornersScript}
\end{figure}
\section{Korridore}
\label{sec:corridor}
%paragraph Erklärung
\begin{figure}[!h]
\centering
\includegraphics[width=0.5\textwidth]{vrscreenshots/korridorheraus.jpg}
\caption{Ein Korridor von innen. Links im Bild, am Ende des Ganges befindet sich die Seitentür, an der Wand daneben das Nummerneingabefeld. Rechts im Bild lässt sich aus der Tür hinaus in den Raum blicken}\label{figure:corridor-out}
\end{figure}
Damit die Nutzer:in versteht, wie sie in den nächsten Raum kommt, sind die Räume so gestaltet, dass es einen offensichtlichen Weg voran gibt. Um dies zu erreichen, wird in die Räume jeweils ein Korridor, also ein kleiner Flur, der auf die Tür zum nächsten Raum zuläuft, generiert. Wie ein solcher Korridor von innen aussieht ist in \autoref{figure:corridor-out} zu sehen. In der hier vorgestellten Implementierung der Levelgenerierungmethode wird der Korridor für jeden Raum generiert, bevor mit der Eckenberechnung für den nächsten Raum begonnen wird, und wie in \autoref{sec:random} beschrieben wird, hängt diese sogar von dem Korridor ab. Sie sind also wichtiger Bestandteil dieser Implementierung, die Levelgenerierungmethode ließe sich aber auch ohne sie realisieren. In diesem Abschnitt wird die Generierung dieser Korridore für ihre jeweiligen Räume erläutert.
Zunächst wird eine Kante des Grundecks des Raumes ausgewählt, an der ein Korridor erstellt wird (diese wird pseudozufällig ausgewählt, siehe \autoref{sec:random}). Er kann sowohl an einer kürzeren Kante, als auch an einer längeren Kante des Grundecks des Raumes erstellt werden, nur nicht an der Seite aus der das Ende des Korridors des vorherigen Raums herausragt, da sich die beiden Korridore sonst kreuzen würden.
Der Korridor hat zwei Türen: Eine \textquote{Haupttür}, durch die die Nutzer:in in den Korridor hineinkommt und eine \textquote{Seitentür}, die anfangs noch verschlossen ist und in den nächsten Raum führt. %optional todo: figure mit korridor aus topansicht
In diesem Korridor werden dann Elemente platziert, die gemeinsam für einen Mechanismus sorgen, der es der Nutzer:in nahelegt, sich genug um die Yaw-Achse zu drehen, dass die wirkliche und die virtuelle Realität sich dank des Rotation-Gains genug umeinander drehen, dass der nächste Raum nun mit dem realen Tracking-Space übereinstimmt. Dieser Mechanismus wurde in
\autoref{sec:rotgaininc}
genauer beschrieben.
\subsection{Korridor-Meshgenerierung}
\label{subsec:corridormesh}
Um einen solchen Korridor zu generieren, müssen zunächst die Koordinaten der für das Korridor-Mesh genutzten Knotenpunkte (Vertices) bestimmt werden. Zudem müssen dann entsprechende Flächen (Faces) gespannt und für jeden Knotenpunkt dann auch die UV-Koordinaten errechnet werden, sodass die Korridore texturiert werden können. All dies geschieht in der \textquote{RoomGenerator}-Klasse.
Ein Korridor besteht aus einem Boden, einer Frontalwand, zwei Seitenwänden und einer Rückwand. Zudem sind in der Frontalwand und einer der Seitenwände Türen eingelassen.
Bevor die Meshgenerierung stattfinden kann, muss zunächst die Türposition auf der Frontalachse, $D$, bestimmt werden. Dabei handelt es sich um einen Wert zwischen $0$ und $1$, der für jeden Raum pseudo-zufällig generiert wird (siehe \autoref{sec:random}). Mit diesem Wert wird die Frontal-Türposition bestimmt. Je geringer er ist desto weiter links liegt die Haupttür in der Frontalwand. Ist der Wert geringer als 0,5, befindet sich die Seitentür in der rechten Seitenwand, sonst in der linken, sodass diese immer auf der gegenüberliegenden Seite der Haupttür liegt.
\begin{figure}[H]
\centering
\input{doorCalc.tikz}
\caption{Frontalansicht von der Struktur der Vorderseite eines Korridors}
\label{figure:doorCalcFig}
\end{figure}
Es gibt zwei Möglichkeiten der Struktur einer Wand, abhängig davon, ob in ihr eine Tür eingelassen ist oder nicht. Der simplere Fall trifft zu, wenn in der Wand keine Tür liegt, dann besteht die Wand aus einem Quader, also aus 8 Vertices.
Die Wandstruktur der Tür-beinhaltenden Alternative wird in \autoref{figure:doorCalcFig}
veranschaulicht. Dabei ist allerdings zu beachten, dass nur die Frontalansicht auf eine solche Wand gezeigt ist. Die Innenseite derselben Wand hat die selbe Struktur. Zudem sind die frontalen Vertices der Tür jeweils mit ihren inneren Gegenspielern durch Faces verbunden, sodass man beim d
Durchschreiten der Tür nicht ins Innere der Wand blicken kann.
\paragraph*{Vertices}
Das Generieren eines solchen Korridors beschreibe ich im Folgenden. Gegeben sind die Eckkoordinaten des Raumes, in den der Korridor platziert werden soll ($\vec{C_0}, ..., \vec{C_3}$, diese werden wie in \autoref{subsection:calccorners} berechnet), die Seite des Raumes, an der der Korridor liegen soll ($S_s$) und die Türposition $D$, welche mithilfe eines Pseudo-Zufallsalgorithmus ermittelt werden (siehe \autoref{sec:random}). Dazu noch einige Werte, die im vorhinein von der Gestalter:in der Level vordefiniert werden: Die Tiefe des Korridors $d$, durch die sich auch der in \autoref{subsection:calccorners} besprochene Wert $dP$, also der Abstand des Punktes $\vec{P}$ zu den Wänden der Ecke des Raumes ergibt: $dP = \frac{d}{2}$, die Höhe $h$ und Dicke der Wände $w$ sowie die Höhe ($dh$) und Breite ($dw$) der Tür.
Als erstes werden die unteren, äußeren Punkte berechnet. ($\vec{F_0}, ..., \vec{F_3}$)
Dabei wird mit den beiden hinteren, äußeren Punkten des Korridors begonnen. Da die Ecken eines Raumes immer im Uhrzeigersinn gespeichert werden, lassen sich diese Punkte heraussuchen, indem die $s$'te Ecke des Raumes und die im Uhrzeigersinn darauf Folgendel, auswählt werden.
$$ \vec{F_0} = \vec{C_s} $$
$$ \vec{F_1} = \vec{C_{((s+1)\pmod 4)}} $$
Damit wird der Richtungsvektor $\hat{rTL}$ (rightToLeft) errechnet, indem die rechte Ecke von der linken Ecke subtrahiert wird und das Ergebnis dann normalisiert wird.
$$ \vec{rTL} = \vec{F_0} - \vec{F_1} $$
$$ \hat{rTL}=\frac{\vec{rTL}}{\left | \vec{rTL} \right |} $$
Um die beiden vorderen äußeren Ecken zu bestimmen, muss nun ein Richtungsvektor $\hat{tF}$ (toFrontWall) berechnet werden, der von der Seite $S_s$ in Richtung der gegenüber liegenden Seite des Raumes zeigt. Hierfür wird das Kreuzprodukt von $\hat{rTL}$ und dem nach oben gerichteten Einheitsvektor berechnet und das Ergebnis normalisiert.
$$ \hat{up} = \begin{pmatrix} 0 \\ 1 \\ 0 \\ \end{pmatrix} $$
$$ \vec{tF} = \hat{rTL} \times \hat{up} $$
$$ \hat{tF} = \frac{\vec{tF}}{\left | \vec{tF} \right |} $$
Um nun die vorderen Punkte zu bestimmen, wird einfach der neue Richtungsvektor $\hat{tF}$ mit $2 * dP$ multipliziert und auf die hinteren Punkte addiert.
$$ \vec{F_2} = \vec{F_0} + \hat{tF} * dP $$
$$ \vec{F_3} = \vec{F_1} + \hat{tF} * dP $$
Nach dem nun klar gewordenen Prinzip, die Knotenpunkte zu berechnen, indem schon errechnete Knotenpunkte mit den entprechenden Richtungsvektoren multipliziert werden, lassen sich nun die äußeren oberen Ecken des Korridors bestimmen. Hierfür werden die unteren Ecken mit dem Vektor $\vec{T}$ addiert, der sich wie folgt berechnet:
$$\vec{T} = \hat{up} * h $$
$$ \vec{F_4}, ..., \vec{F_7} = \vec{F_0} * \vec{T}, ..., \vec{F_3} * \vec{T} $$
Um die inneren Punkte zu berechnen, werden die äußeren Ecken nach dem selben Prinzip, jeweils mit den entsprechenden Richtungsvektoren, die dann mit $w$ multipliziert werden, addiert. Die inneren Punkte liegen mit den äußeren Punkten auf einer Höhe. Die linken Ecken werden also jeweils nach rechts addiert, die rechten nach links, die hinteren nach vorne, die vorderen nach hinten, sodass jede innere Ecke mit zwei $w$-langen Vektoren von den äußeren Punkten in Richtung der Mitte verschoben wurde. Für die Richtung nach links wird $\hat{rTL}$ verwendet, nach rechts $\hat{rTL} * (-1)$, nach vorne $\hat{tF}$ und nach hinten $\hat{tF} * (-1)$.
In der folgenden Erklärung wird davon ausgegangen, dass $D <= 0.5$ ist und somit die Haupttür links und die Seitentür rechts erzeugt wird, andernfalls wären natürlich $\hat{rTL}$ und $\hat{rTL} * (-1)$ vertauscht. Genauso verhält es sich mit den beiden äußeren, unteren, vorderen Ecken $F_2$ (links vorne) und $F_3$ (rechts vorne), die Nutzung in den folgenden Formeln wäre vertauscht, wenn $D > 0.5$.
Für die Tür-Vertices wird zunächst der untere Mittelpunkt der Tür ($\vec{mD}$) berechnet.
Hierfür ist es zunächst wichtig die entsprechende Achse $\vec{mDX}$ zu berechnen, auf der die Tür dann erzeugt wird (siehe \autoref{figure:doorCalcFig})
Dafür wird erstmal der Punkt $\vec{dP}$, an der Frontalseite des Korridors, diagonal hinter $\vec{P}$ berechnet.
$$\vec{xP} = \vec{P} + \hat{tF} * dP + \hat{rTL} * dP$$
Von da aus spannt sich die Achse $\vec{mDX}$ dann bis zur anderen Seite des Korridors. Da $\vec{mD}$ ja den Mittelpunkt der Haupttür darstellen soll, muss an beiden Seiten der Achse $\frac{dw}{2}$ als Padding eingesetzt werden, damit die Tür nicht weiter links oder rechts übersteht, falls $D$ einen Extremwert annimmt.
$$ \vec{mDX} = (F_2 + \hat{rTL} * (-1) * \frac{dw}{2}) -
(\vec{xP} + \hat{rTL} * \frac{dw}{2})$$
$\vec{mD}$ berechnet sich dann folgendermaßen:
$$ \vec{mD} = \vec{xP} + \vec{mDX} * D$$
Die Berechnung und $\vec{mDX}$ wird auch aus dem in \autoref{figure:calcMainDoorCode}
dargestellten Quelltext ersichtlich. %TODO: kommentare, variablen übersetzen etc.
Die Berechnung der Vertices, in der Haupttür ist nun trivial, erfolgt mit der bekannten Methode und wird auch in \autoref{figure:doorCalcFig} ersichtlich. Türhöhe ($dh$), Türbreite ($dw$) und Wandbreite ($w$) werden mit den entsprechenden Richtungsvektoren multipliziert und auf $mD$ addiert.
\begin{figure}[H]
\centering
\sourcecode{calcMainDoor.cs}
\caption{Der Quelltext, der für die Errechnung des Mittelpunktes der Haupttür eines Korridors verantwortlich ist}
\label{figure:calcMainDoorCode}
\end{figure}
\paragraph*{Faces}
Der nächste Schritt, der für die Meshgenerierung erforderlich ist, ist das Spannen der verschiedenen Faces (Triangles). Die meisten für den Korridor erforderlichen Flächen bestehen nur aus zwei aneinanderliegenden Triangles, die somit gemeinsam die viereckige Fläche bilden. Die Ausnahmen sind die Frontalfläche und die Seitenfläche, in die die Seitentür generiert wurde (jeweils mit der zugehörigen Innenseite). Die Struktur dieser Ausnahmen wird auch in \autoref{figure:doorCalcFig} ersichtlich.
Auch hier werden die benötigten Vertices jeweils durch Multiplizieren mit den entsprechenden Richtungsvektoren und der anschließenden Addierung auf bestehende Vertices errechnet. \footnote{Bei der Seitentür verläuft die Berechnung des Türmittelpunkts deutlich simpler, es handelt sich einfach um die Mitte des Korridors.}
Um die späteren UV Berechnungen nicht zu verunreinigen, wird jeder Vertex dem Buffer pro Face einmal hinzugefügt. Die Faces werden dann gespannt, indem die jeweiligen Indizes der Vertices im Buffer aufgelistet werden. Dies beides wird dann in Listenform dem neu erzeugten $MeshFilter$ Objekt übergeben.
\paragraph*{UV}
Die Berechnung der UV-Koordinaten erfolgt für jeden Knotenpunkt einzeln und wird nach Triangles geordnet iterativ durchgeführt. Der Quelltext dazu findet sich in der GenerateUV Methode, die im folgenden Quelltext abgebildet ist.
Die Berechnung besteht daraus die Normale des Triangles zu berechnen, diese mit den Richtungsvektoren abzugleichen und die UV-Vektoren der Vertices dann entsprechend zu Rotieren.
\sourcecode{uvCode.cs}
\section{Wandgenerierung}
\label{sec:genwalls}
%paragraph Erklärung
Natürlich reichen die Meshs der Korridore noch nicht aus, um das Gefühl eines Raumes zu vermitteln, zumal diese ja auch nur an einer Seite des Raumes statuiert sind.
Wie in \autoref{subsec:roomplaceidea} besprochen, sollen die Räume von Wänden umgeben sein.
\begin{figure}[H]
\centering
\scalebox{0.4}{\input{wallCompare.tikz}}
\caption{Vergleich der zwei Wandgenerierungsvarianten. Oben: Die \textquote{realistische} Variante, die in Joystick- und Teleportationsbedingung eingesetzt wird. Unten: \textquote{unmögliche} Variante, die in der Real-Walking Bedingung die Wände generiert. Gestrichelte Linien repräsentieren Wände, die erst unter bestimmten Umständen sichtbar werden}
\label{figure:wallCompare}
\end{figure}
Die Wandgenerierung erfolgt über ein Prefab, dass instanziiert und dann gestreckt, positioniert und rotiert wird. Es besteht aus einem Würfel mit der entsprechenden Textur, der Höhe der Wandhöhe $h$, und der Breite und Tiefe der Wände $w$.
Dies geschieht in der Methode \textquote{GenerateWall}. Diese bekommt als Eingabe zwei Punkte, und instanziiert dann eine Wand, die von dem einen dieser Punkte zum anderen reicht.
Außerdem müssen für jeden Raum, für jede Wand, jeweils die zwei Endpunkte der Wand berechnet werden.
%Abgesehen davon besteht der Prozess der Wandgenerierung also noch daraus für jeden Raum, für jede Wand, jeweils die zwei Endpunkte der Wand zu berechnen.
In dem hier vorgestellten Projekt werden die Wände auf zwei verschiedene Arten generiert. In der \autoref{figure:wallCompare} werden die beiden Varianten miteinander verglichen.
%bedingung a (JS, TP)
\subsection{Realistische Wandgenerierung}\label{subsec:realwallgen}
Die erste Art, fortlaufend \textquote{realistische} Variante genannt, generiert die Wände zwischen den Räumen so, wie sie auch real existieren könnten.
Dazu gibt es einen ausgefeilten Algorithmus, der alle Eventualitäten der Raumgenerierung kennt und die Wände so zwischen den Räumen platziert, dass die Räume noch möglichst viel Platz bieten, aber auch rundherum von Wänden umgeben sind. Der Code für diese Generierung wird in der \textquote{RoomGenerator}-Klasse in den beiden \textquote{GenerateWallsLegacy}-Methoden ausgeführt. Diese Variante wird in den beiden Kontrollbedingungen \textquote{Teleport} und \textquote{Joystick} verwendet, weil Versuchsbedingungen mit ihnen keine Impossible-Spaces beinhalten.
Bei der realistischen Wandgenerierung ist die Idee, dass die Wände genau so zwischen die Korridore platziert werden, dass der nachfolgende Raum die Priotität über den Platz hat. Der Bereich $O$, der in der \autoref{figure:two_rooms} zu sehen war, gehört bei dieser Variante also immer zu dem Raum $B$ und nicht zu dem Raum $A$.
Davon, ob der Korridor des Raumes an der längeren, oder der kürzeren Seite des Rechtecks generiert wurde, hängt ab, wieviele Wände generiert werden. Ist der Korridor an der längeren Seite des Raumes, werden ausgehend vom Korridor des letzten Raumes zwei Wände generiert, da die breite Seite des nächsten Raumes als Wand genutzt werden kann. Ist jedoch der Korridor des aktuellen Raumes an der kürzeren Seite des Rechtecks, so muss eine dritte Wand generiert werden, die verhindert, dass eine offene Stelle zwischen dem aktuellen und dem nächsten Raum entsteht.
Um die Wände generieren zu können, ist es wichtig, die Punkte diagnonal vor und hinter dem Punkt $\vec{P}$ des vorherigen Raumes zu kennen. Dazu werden diese nach der Generierung als Iterationsübergreifende Variablen gespeichert und somit an den jeweils nächsten Raum übergeben, siehe \autoref{subsec:iteration}.
%bedingung b (RDW)
\subsection{Unmögliche Wandgenerierung}
Die andere Variante der Levelgenerierung, hier \textquote{unmögliche} Variante genannt, umschließt alle Räume mit drei Wänden, zeigt aber immer nur die Wände des Raums, in dem sich die Nutzer:in gerade befindet an und hat dementsprechend die Freiheit, die gesamte Raumgröße zu umschließen, weil keine Kompromisse für den sich überlappenden Bereich $O$ gemacht werden müssen (siehe \autoref{figure:two_rooms}). Der Code für diese Generierung wird in der \textquote{RoomGenerator}-Klasse in den beiden \textquote{GenerateWalls}-Methoden ausgeführt. Im Experiment wird diese Variante ausschließlich in der Real-Walking Bedingung eingesetzt. Durch sie werden die Räume erst zu Impossible-Spaces, da die Räume sich nun überlappen.
Die Umsetzung der unmöglichen Wandgenerierung erfolgt recht ähnlich, wenn auch um einiges minimalistischer als die der realistischen. Anstatt die Wandgenerierung auf die verschiedenen Räume aufzuteilen, werden die Wände so generiert, dass sie abgesehen von den Korridoren, des aktuellen, und des vorherigen Raumes den ganzen Raum umschließen. Das Ein- und Ausblenden, der Wände wird dann vom \textquote{RoomAndProgressManager}, der ja Überblick darüber hat, wo die Nutzer:in sich gerade befindet, geregelt. Es werden immer nur die Wände des aktuellen Raumes, angezeigt.
\section{Zufallsfaktoren in der Levelgenerierung}
\label{sec:random}
%paragraph Erklärungen
Der hier beschriebene Levelgenerierungsalgorithmus nutzt das Element des Pseudozufalls um durch Verändern verschiedener Variablen das Ergebnis zu beeinflussen. So ist es möglich viele unterschiedliche Level zu generieren. Welche Variablen sich dafür unterscheiden können, werde ich an dieser Stelle vorstellen.
\subsection{Korridorrichtung}
\begin{figure}[h!]
\sourcecode{RandomDirectionBlocked.cs}
\caption{}\label{figure:randomdirection}
\end{figure}
Zu Beginn der Korridorgenerierung wird eine Seite des Raumes als Korridorseite $S_s$ bestimmt. Diese wird pseudozufällig ausgewählt. Im ersten Raum ist es noch vollkommen beliebig, welche Seite ausgewählt wird\footnote{Im Versuchsaufbau wird dabei aber immer die selbe Seite ausgesucht um das Erscheinen im Raum einheitlicher zu gestalten. (Die Nutzer:in guckt nach dem Start des Versuchs in Richtung des Korridors).}.
Bei den weiteren Räumen hingegen können bestimmte Seiten nicht ausgewählt werden, weil der Korridor nach der Generierung sonst mit dem Ausgang des Korridors des vorherigen Raumes überlappt.
Durch die Art und Weise, wie die Eckenberechnung der Räume funktioniert, lässt sich feststellen, dass $S_3$ in allen Umständen immer die Seite ist, aus der der Korridor des letzten Raumes herauszeigt (siehe \autoref{subsection:calccorners}). $S_3$ kann also zur Korridorgenerierung nicht ausgewählt werden.
Falls die Seitentür des vorherigen Raumes auf der rechten Seite liegt (wie in der \autoref{figure:calculateCornersFig}), muss außerdem $S_0$ blockiert werden, da die Nutzer:in sonst von einem Korridor direkt in den nächsten läuft. Ist die Seitentür aber auf der linken Seite ist die Ecken- und Seitenbelegung, wie in \autoref{subsection:calccorners} beschrieben, nicht nur horizontal, sondern auch vertikal spiegelverkehrt. Deshalb muss in dem Fall die Seite $S_2$ blockiert werden.
Damit diese Seiten bei der zufälligen Auswahl ignoriert werden, funktioniert die Methode dafür (\textquote{RandomDirectionBlocked}, siehe \autoref{figure:randomdirection})
folgendermaßen: Als Eingabe wird eine Liste $LB$ mit den blockierten Richtungen übergeben. Alle Richtungen (repräsentiert von Zahlen von 0-3), die darin vorkommen, werden aus der Liste aller möglichen Richtungen entfernt.
Mit dem Unity-Objekt $Random$ lässt sich durch Abrufen der Eigenschaft $value$ eine zufällige Zahl zwischen 0 und 1 generieren\footnote{Falls tatsächlich eine volle 1 ausgewählt wird, würde dies dazu führen, dass eine zu hohe Zahl ausgewählt werden würde. Deshalb wird im Code mithilfe der $Min$-Funktion dafür gesorgt, dass dieser Fall nicht eintreten kann, siehe \autoref{figure:randomdirection}}.
Um nun die Zahl aus der Liste verbleibender Richtungen $LD$ auszuwählen, wird das Ergebnis nun mit $4 - length(LB)$ multipliziert, um den Index zu berechnen.
\subsection{Türposition}
Die Frage, in welche Richtung der jeweils nächste Raum generiert wird, hängt gänzlich davon ab, wie die Haupttür des Korridors positioniert ist. In \autoref{subsec:corridormesh} wird erklärt, wie die Haupttür auf der Frontalwand des Korridors generiert wird und abhängig von dem Wert $D$ auf der links-rechts Achse positioniert wird.
Falls $D$ einen Wert von $0$ hat, wird die Tür ganz links positioniert, bei einem Wert von $1$ ganz rechts. Davon ist dann auch die Positionierung der Seitentür abhängig. Ist $D <= 0.5$, wird die Seitentür in die rechte Seitenwand des Korridors generiert, sonst in die Linke.
Davon ist dann natürlich auch wieder abhängig, in welche Richtung der folgende Raum generiert wird, denn die Nutzer:in soll ja aus der Seitentür heraus-, in den Raum hineintreten.
Man kann den Wert $D$ also sowohl als einen verstehen, der feinere Unterschiede
der Position auf der Frontalwand bestimmt, damit nicht jeder Raum genau gleich wirkt, als auch als einen wichigen Wert, der die Richtung des folgenden Raumes vorherbestimmt.
Auch hier müssen wieder einige Varianten ausgeschlossen werden, um die Begehbarkeit der erzeugten Level zu garantieren.
%figures?
$S_1$ stellt - unabhängig der Richtung - immer die Seite gegenüber der Seite dar, aus der man kommt, wenn man aus dem vorherigen Raum in den aktuellen Raum tritt.
Wenn der Korridor an diese Seite generiert wurde, kann die Türposition nicht mehr so sein, dass der als nächstes generierte Raum Überschneidungen mit der Seite des aktuellen Raumes hat, aus der der Korridor des vorherigen Raumes kommt, da sonst der Weg aus dem Korridor des vorherigen Raumes nicht frei ist, weil der nachfolgende Raum darüber generiert wurde. Je nach Raumdimensionen würden sich dann sogar potentiell 3 Räume überlappen.
Genauso wichtig ist, dass das Ende des Korridors des aktuellen Raumes, nicht in Richtung des vorherigen Raumes zeigt.
Diese Varianten werden bei der Levelgenerierung durch Fallunterscheidungen ausgeschlossen. %TODO: zeigen?
Dazu hat die Methode \textquote{GenerateRandomDoorPosition} in der \textquote{GenerateLevel}-Klasse, die für die Berechnung von $D$ verantwortlich ist zwei Parameter, $forceLeftSideDoor$ und $forceRightSideDoor$, die zwar beide $false$ sein dürfen, (dann wird nichts verhindert), aber nicht beide $true$ sein dürfen.
Die Berechnung von $D$ erfolgt nun wieder über das Aufrufen von Unitys $Random.value$ Attribut, welches einen pseudozufälligen Wert der, zurückgibt.
Soll die rechte Seite forciert werden, wird der Wert durch $2$ geteilt. Falls die linke Seite forciert werden soll, wird nach der Division durch $2$, nochmal $0,5$ addiert. Falls nichts blockiert werden soll, wird der Wert direkt zurückgegeben.
\section{Umsetzung der Levelgenerierung}
Nachdem ich nun nacheinander die einzelnen Komponenten der Levelgenerierung erklärt habe, werde ich nun erklären, wie diese zusammenspielen um den Levelgenerierungsalgorithmus zu bilden. Diesen werde ich zunächst in seiner Vorgehensweise erläutern und anschließend die Grundstruktur des Quelltextes darstellen.
\subsection{Funktionsweise des Levelgenerierungsalgorithmus}
Im Rahmen des in dieser Arbeit vorgestellten Experiments war es notwendig, Level zu generieren, bei denen im vorhinein die Anzahl der Räume $L$ definiert werden konnte, und die dementsprechend nicht unendlich lang waren. Jedoch ist es durchaus trivial den folgend vorgestellten Algorithmus leicht zu verändern, sodass er die Räume fortlaufend generiert, während die Nutzer:in bereits dabei ist, das Level zu erkunden.
Nachdem $L$ ausgewählt wurde (in diesem Fall indem die Proband:in eine der Versuchsbedingungen auswählt, siehe \autoref{sec:chooserpad})
kann das Level generiert werden.
% An dieser Stelle möchte ich noch einmal die Werte auflisten, die vorher von der Designer:in festgelegt werden sollen und kurz zusammenfassen was sie bedeuten.
% %wo werden sie definiert
% %TODO: überarbeiten
% \begin{align*}
% d &: \text{Tiefe der zu generierenden Korridore} \\
% h &: \text{Höhe der Wände, und des Korridors} \\
% w &: \text{Die Dicke der Wände und der Wände des Korridors} \\
% dw &: \text{Die Breite der zu generierenden Türen} \\
% dh &: \text{Die Höhe der zu generierenden Türen}
% \end{align*}
Grundlegend besteht der Algorithmus aus der Deklarierung einiger Variablen, die den Zustand über die Iterationen hinweg speichern, und einer Schleife, die pro Iteration einen neuen Raum generiert. In der hier vorgestellten Form des Algorithmus wird diese Schleife zu Beginn der Versuchsbedingung ganz ausgeführt, sodass das Level fertig generiert wurde, bevor die Proband:in angefangen hat, es zu erkunden.
Um den Prozess so umzubauen, dass das Level fortlaufend weiter generiert wird, ist es lediglich notwendig, den Quellcode, der innerhalb der Schleife steht, in eine Funktion auszuverlagern, die immer dann, wenn die Nutzer:in einen Raum betritt, einen weiteren erzeugt. Damit dies nicht bemerkt wird, ist es an dieser Stelle ratsam, einen kleinen Puffer von etwa 2 oder 3 Räumen einzubauen, sodass die neu erzeugten Räume nicht direkt vor den Augen der Nutzer:in auftauchen. Dies lässt sich einfach erzielen, indem man zu Beginn des Levels einige wenige Räume erzeugt und die neuen Räume erst hinter diesen generiert werden.
\subsection{Inhalt einer Iteration}\label{subsec:iteration}
Eine Iteration besteht aus zwei Bereichen. Im ersten wird zunächst der Raum anhand des aktuellen Zustands der Iterationsübergreifenden Variablen generiert, indem die \textquote{Generate} Methode der \textquote{RoomGenerator} Klasse aufgerufen wird. Der zweite Teil ist dann dafür verantwortlich, die nächste Iteration vorzubereiten. Dies hat den Zweck, dass der erste Teil der ersten Iteration, den Ursprungszustand der Variablen nutzen kann. Ein Beispiel dafür sind die vom Oculus Integration SDK übergebenen Eckkoordinaten des realen Trackingspaces oder die, vom Designer ausgewählte, erste Korridorrichtung, die das Erscheinen im ersten Raum vereinheitlichen soll.
\paragraph*{Generierungs-Teil}
Darin werden dann zunächst die Meshs des Korridors erzeugt (siehe \autoref{subsec:corridormesh}) und als GameObjects instanziiert. Zudem werden diese mit den entprechenden Materialien für die Optik und den entsprechenden Scripts versehen.
Dann werden die für den Rotation-Gain erforderlichen Objekte instanziiert, positioniert und die entsprechenden Mechanismen in die Wege geleitet, indem die Eigenschaften des zuständigen \textquote{RotationRedirector} gesetzt werden.
Zudem wird die Innenausstattung des Korridors instanziiert, positioniert, mit den entsprechenden Scripts ausgestattet und mit den eben erzeugten Mechanismen, die den Rotation-Gain überwachen, verknüpft.
Die Generierung der Wände wird als nächstes in die Wege geleitet, je nach Variante wird zwischen den verschiedenen Methoden unterschieden, die danach aufgerufen werden, um die Wandpunkte zu berechnen und dann Wandobjekte zu initialisieren. Hierfür ist zudem erforderlich, das in \autoref{sec:genwalls} besprochene Prefab zur Verfügung zu stellen, das vorher von der Designer:in erstellt werden muss.
\paragraph*{Berechnungsteil}
Der zweite Teil einer Iteration ist dann für die Berechnung der Zustandsvariablen zuständig. Diese müssen berechnet werden, weil der erste Teil der nächsten Iteration keinen Zugriff mehr auf die Objekte der aktuellen Iteration hat. Hier findet die in \autoref{subsection:calccorners} erklärte Eckenberechnung statt. So können die Richtungsvektoren und andere Informationen von dem Raum, der in der aktuellen Iteration generiert wurde, genutzt werden, um die Generation des nächsten Raumes vorzubereiten. Auch die in \autoref{sec:random} besprochenene Pseudozufallsvariablen und die in \autoref{subsec:realwallgen} besprochenen Punkte diagonal vor und hinter dem Punkt $\vec{P}$ des vorherigen Raumes werden hier berechnet, sodass sie in der nächsten Iteration schon feststehen und genutzt werden können.
\chapter{Konzipierung der Pilotierungsstudie}\label{chapter:experiment}
Im folgenden Kapitel möchte ich das für diese Arbeit konzipierte Experiment vorstellen. Dabei handelt es sich um eine informelle Pilotierungsstudie zum Vergleich von Fortbewegungsarten für das Raumverständnis und das Präsenzgefühl in der generierten virtuellen Umgebung. Dabei soll konkreter untersucht werden, ob die Fortbewegungsart \textquote{Real-Walking} in diesen Punkten bessere Effekte erzielt als vergleichbare alternative Fortbewegungsarten.
Um das Experiment vorzustellen, werde ich zunächst die Hypothesen, denen ich mit dieser Arbeit auf den Grund gehen will, aufstellen um deutlich zu machen, was das Ziel des Experiments ist.
Im darauf folgenden Teil werde ich dann beschreiben wie die statistische Versuchsplanung der konzipierten Pilotierungsstudie aussieht. Dabei werde ich genauer auf die drei verschiedenen Fortbewegungsbedingungen eingehen, die untersucht werden sollten und beschreiben, wie diese für die Studie implementiert wurden.
\section{Hypothesen und Messvariablen}
An dieser Stelle möchste ich die in dem Experiment zu überprüfenden Hypothesen vorstellen.
\begin{enumerate}
%\item Nach dem, mit der \textquote{Real-Walking} Fortbewegungsart absolvieren eines, mit der, in dieser Arbeit vorgestellten Levelgenerierungmethode, generierten Levels, ist die Schätzungsfähigkeit der zurückgelegten Strecke im Vergleich zu den beiden alternativen \textquote{Joystick} und \textquote{Teleportation} signifikant besser.
\item Nachdem ein mit der hier vorgestellten Levelgenerierungmethode erstelltes Level mit der Fortbewegungsart \textquote{Real-Walking} durchquert wurde, ist die Fähigkeit, die darin zurückgelegte Strecke einzuschätzen, besser als wenn es mit den alternativen Fortbewegungsarten \textquote{Joystick} und \textquote{Teleportation} durchquert wurde.
\item Beim Durchqueren der mit der hier vorgestellten Levelgenerierungmethode erstellten Level mit der \textquote{Real-Walking} Fortbewegungsart haben Nutzer:innen ein größeres Präsenzgefühl als mit den beiden Alternativen \textquote{Joystick} und \textquote{Teleportation}.
\end{enumerate}
\subsection{Distanzschätzung}
Mehrere Forschungsergebnisse deuten darauf hin, dass natürliches Gehen das Raumverständnis im Vergleich zu anderen Fortbewegungsarten verbessert. \cite{langbehn-vergleich-2018,peck-vergleich-2011, walking-improves-map-building} %TODO: mehr?
Die hier vorgestellte Hypothese basiert zum Teil auf der Annahme, dass ein besseres Raumverständnis dazu führt, dass Nutzer:innen bereits gegangene oder anderweitig zurückgelegte Distanzen besser schätzen können. Dafür spricht die von Peck et al. \cite{peck-vergleich-2011} gefundene Untersuchung, dass Proband:innen in Real-Walking Fortbewegungsbedingungen die größe der virtuellen Umgebung nach dem Versuch siginifikant besser einschätzen konnten, als mit anderen virtuellen Fortbewegungsarten.
%gemessen ob es auch in generierten leveln gilt?
Wie gut die Nutzer:innen die zurückgelegte Distanz schätzen, wird hier gemessen, indem die Proband:innen nach jedem Durchlauf einer Versuchsbedingung schätzen sollen, wieviele Meter sie sich gerade fortbewegt haben.\footnote{Dabei ist zu spezifizieren, dass es nicht um die euklidische Entfernung von Start und Ziel ging (die \textquote{Luftlinie}), sondern um die gesamte zurückgelegte Strecke.}
Neben der Schätzung wurde auch die vom virtuellen Avatar zurückgelegte Strecke gemessen (siehe \autoref{sec:measure-distance}), sodass die absolute Differenz von Schätzung und Messung widerspiegelt, wie gut die Proband:innen die zurückgelegte Strecke einschätzen konnten.
Diese Art von Messung bietet sich für Level an, die mit der hier vorgestellten Methode generiert werden, weil diese sehr linear sind. Ein Raum folgt auf den nächsten, ohne dass die Nutzer:in Richtungsentscheidungen tätigt oder Abzweigungen geht.
Zwar gibt es in der Literatur viele Hinweise darauf, dass Menschen in virtuellen Umgebungen die Entfernung zwischen ihnen und Objekten in der Umgebung, verglichen mit der realen Umgebung, nicht besonders gut einschätzen können \cite{meta-distance-perception, bruder-distance}, % TODO: \cite, RVH 13 and others TODO: all?
%schlechter, jeh schlechter die qualität
allerdings werden in der hier vorgestellten Studie alle drei Fortbewegungsarten in einer (sich auch nicht grundlegend zwischen den Versuchsbedingungen unterscheidenden) virtuellen Umgebung durchgeführt, sodass dieser Effekt ausgeglichen wird.
\subsection{Präsenzgefühl}
In dem Paper \cite{presence-questionaire} geben Usoh et al. eine Zusammenfassung über die bis dahin diskutierten Ideen darüber, wie die Stärke der Präsenz in virtuellen Umgebungen stark erhöht wird. Diese wird in 5 Punkte aufgeteilt, die übersetzt und zusammengefasst so lauten:
\begin{enumerate}
%übersetzungen und original, also beides?
% \item High resolution information displayed to the participant, in a manner that does not indicate the existence of the display devices. This includes Steuer’s notion of vividness, ‘the ability of a technology to produce a sensorially rich mediated environment’.
\item Informationen werden den Proband:innen in hoher Auflösung angezeigt, in einer Weise, die die Existenz des Displays nicht erkennen lässt.
% \item Consistency of the displayed environment across all sensory modalities.
\item Die dargestellte Realität ist über alle Sinnesmodalitäten hinweg konsistent.
% \item The possibility of the individual being able to navigate through and interact with objects in the environment, including interaction with other actors which may spontaneously react to the indi- vidual.
\item Die Möglichkeit der Nutzer:in durch die Umgebung zu navigieren und mit Objekten oder anderen Agenten zu interagieren.
% \item Theindividual’svirtualbody,theirself-representationwithintheenvironment,shouldbesimi- lar in appearance or functionality to the individual’s own body, and respond appropriately to the movements of their head, eyes, and limbs.
\item Der virtuelle Avatar der Nutzer:in sollte sich äußerlich oder funktionell dem echten Körper dieser ähneln und angemessen auf Kopf-, Augen- und Gliedmaßenbewegungen reagieren.
% \item Theconnectionbetweenindividual’sactionsandeffectsofthoseactionsshouldbesimple enough for the individual to quickly learn.
\item Die Verbindung zwischen den Aktionen und ihren Effekten sollte unkompliziert genug sein, sodass sie leicht zu erlernen ist.
\end{enumerate}
Besonders interessant für dieses Projekt sind hier die Punkte 2 und 3, da diese sich zwischen den verschiedenen Fortbewegungsarten unterscheiden. So ist zum Beispiel davon auszugehen, dass die Real-Walking-Fortbewegungsart in mehr Sinnesmodalitäten Konsistenz bietet, da die Nutzer:in ihre Stellung im Raum auch durch ihre Propriozeption und ihren Gleichgewichtssinn wahrnehmen kann.
Nicht außer Acht zu lassen ist natürlich auch, dass natürliches Gehen durch dessen Alltagsnähe eine deutlich intuitivere Fortbewegungsmethode darstellt und dementsprechend anzunehmen ist, dass es als solche einem Präsenzgefühl weniger im Weg steht als die ungewohntere Navigation mit den Alternativen.
Um diesen Effekt zu erfassen, wurde mit den Teilnehmer:innen nach jeder Bedingung ein Slater-Usoh-Steed-Präsenz-Questionaire \cite{presence-questionaire} durchgeführt. (Fortlaufend SUS-Questionaire genannt.) Dieser ist im \nameref{anhang:durchlauf} enthalten (P1-P7) und ist im Anhang abgebildet. Der SUS-Questionaire besteht aus 6 Fragen, die auf einer Skala von 1-7 beantwortet werden, wobei 7 immer für die höchste und 1 für die geringste wahrgenommene Präsenz in der Umgebung steht. Die letze Frage des SUS-Questionaires ermöglicht den Proband:innen noch etwas dazu hinzuzufügen.
%wer hat da was zu rausgefunden
Usoh et al. überprüfen in ihrer Arbeit \cite{usoh-vergleich-1999}, inwieweit sich das Präsenzgefühl zwischen natürlichem Gehen, virtuellem Gehen und Fortbewegung durch Fliegen unterscheidet. Die Ergebnisse deuten darauf hin, dass die beiden Geh-Fortbewegungsarten zu einem signifikant höhreren Präsenzgefühl führen und sie konkludieren, dass dies mit der stärkeren Assoziation mit dem virtuellen Avatar zu tun haben könnte. Dies ist die Grundlage für die zweite, in dieser Thesis überprüfte, Hypothese.
%TODO:at related work einen presence teil?
\section{Versuchsplanung}\label{sec:setup}
Im Folgenden werde ich den Aufbau des Experiments beschreiben.
Um aus der geringen Teilnehmerzahl der Studie (siehe \autoref{sec:circumstances})
dennoch möglichst viele Daten zu sammeln und weil nicht davon auszugehen ist, dass die Bedingungen der Fortbewegungsarten sich gegenseitig beeinflussen, habe ich mich für ein \textquote{Within-Subjects Design} entschieden. Folglich haben alle Teilnehmenden alle 3 Konditionen durchlaufen. Um dabei zu vermeiden, dass die Reihenfolge der Konditionen die Ergebnisse beeinflusst (beispielsweise indem alle zuerst die Real-Walking Bedingung durchlaufen und zu diesem Zeitpunkt noch am besten einschätzen können, wie weit sie gegangen sind, weil die Schätzungsfähigkeit mit der Zeit abnimmt), wurden die Teilnehmenden in 3 Gruppen eingeteilt, die die 3 möglichen unterschiedlichen Reihenfolgen der 3 Bedingungen abbilden.
Um die Schätzung der zurückgelegten Strecke im Generellen, sowohl bei mehr als auch bei weniger vielen Räumen zwischen Start und Ziel (also bei längeren und kürzeren Leveln) in die Daten einfließen zu lassen, wurden die Bedingungen in unterschiedlichen Raumlängen durchgeführt. Um diesen Effekt gleichmäßig auf alle Messergebnisse zu verteilen, wurden die Raumlängen alternierend den unterschiedlichen Gruppen und den unterschiedlichen Fortbewegungsbedingungen zugewiesen, sodass jede Teilnehmer:in einmal jede der 3 Fortbewegungsarten und einmal jede der drei Raumlängen 3, 6 und 9 durchlief. Es wurde auch darauf geachtet, dass sich für jede Gruppe die Kombination aus Fortbewegungsart und Raumlänge bei allen drei durchgeführten Bedingungen unterschied.
\begin{figure}[!h]
\centering
\input{graeco-latin-square.tex}
\caption{Das Griechisch-Lateinische Quadrat, das die Reihenfolge der Versuchsbedingungen (Schritt 1-3) der verschiedenen Gruppen (G1-3) darstellt. $A$ steht dabei für Real-Walking, $B$ für Joystick Steuerung und $C$ für Teleportation. $1-3$ repräsentieren die verschiedenen Raumlängen $3$, $6$ und $9$}\label{figure:graecolatin}
\end{figure}
Dementsprechend bot sich als Versuchsplan ein Griechisch-Lateinisches Quadrat in der Größe $3 \times 3$ an. \autoref{figure:graecolatin} stellt das für die Studie genutzte Griechisch-Lateinische Quadrat dar, wobei $A$ für die Versuchsbedingung \textquote{Real-Walking}, $B$ für die Versuchsbedingung \textquote{Joystick} und $C$ für die Bedingung \textquote{Teleportation} steht, während $1$ für eine Raumlänge von 3 Räumen, $2$ von 6, und $3$ für eine Raumlänge von 9 Räumen steht.
Die abhängige Variable ist die jeweilige Messvariable der Bedingung, also die absolute Differenz von Messung und Schätzung des zurückgelegten Wegs, oder das mit dem SUS-Präsenz Questionaire gemessene Präsenzgefühl. Die unabhängige Variable ist die Fortbewegungsart ($A-C$).
\section{Fortbewegungsbedingungen}\label{sec:conditions}
Im Folgenden werde ich die drei verschiedenen Fortbewegungsbedingungen vorstellen, diese stellen die unterschiedlichen Fortbewegungsarten dar. Zunächst beschreibe ich die beiden virtuellen Fortbewegungsarten: Joystick und Teleportation. Diese repräsentieren klassische Fortbewegungsarten in VR. Im Kontrast dazu steht dann die Fortbewegungsart des natürlichen Gehens.
\subsection{Kontrollbedingung I Joystick}\label{subsec:joystick}
In der Joystick-Kontrollbedingung ($B$) bewegen sich die Proband:innen virtuell mithilfe der sich an ihren Oclus Quest 2 Controllern befindenden Joysticks fort. %abbildung der Controller?
Der sich auf dem Controller für die linke Hand befindende Joystick (von nun an \textquote{linker Joystick} genannt) ist dabei für die Fortbewegung zuständig. Der sich auf dem rechten Controller befindende Joystick (\textquote{rechter Joystick}) gibt der Nutzer:in die Möglichkeit sich umzuschauen. Diese unterscheidet sich leicht von der Steuerung der meisten Joystick basierten Videospiele, indem ausschließlich die Yaw-Achsen Kopfdrehung von dem Joystick beeinflusst wird, nicht zusätzlich auch die Pitch-Achsen Kopfdrehung und indem die Kopfdrehung in gleichmäßigen Intervallen von
45\textdegree\
verändert wird. %TODO: hci quelle finden wieso
Wie in \autoref{subsec:realwallgen} erklärt, nutzt diese Bedingung die realistische Wandgenerierung.
Die Implementierung der Joysticksteuerung wurde bereits in \autoref{subsec:joystick-implementation} beschrieben. Dort sind auch die technischen Details beschrieben.
\subsection{Kontrollbedingung II Teleportation}\label{subsec:teleport}
Auch in dieser Bedingung $C$ haben die Proband:innen die Möglichkeit, sich ähnlich wie in Bedingung $B$ mithilfe des rechten Joysticks in Intervallen von 45\textdegree\% umzusehen. Die eigentliche Fortbewegung funktioniert hier allerdings auf anderem Wege. Wenn die Proband:innen die sich auf dem rechten Controller befindliche %TODO:komma?
A-Taste gedrückt halten, sehen sie einen grünen Laserstrahl, der aus ihrer rechten Hand gestrahlt wird.
Wenn dieser Strahl auf den Boden trifft, wird an dieser Stelle ein Teleportationscursor angezeigt. Dieser ist in \autoref{figure:tp-ring}
abgebildet und dient sowohl dazu, der Proband:in anzuzeigen, wohin sie sich aktuell teleportieren würde, als auch dazu, die Blickrichtung nach der Teleportierung mithilfe eines Pfeils in der Mitte anzuzeigen. Währenddessen lässt sich mit dem linken Joystick diese Blickrichtung verändern, sodass schon vor dem Teleportieren entschieden werden kann, wohin danach geguckt wird. Um die Teleportierung zu dem ausgewählten Punkt mit der ausgewählten Blickrichtung durchzuführen, muss die Proband:in den Zeigefingertrigger des rechten Controllers bestätigen.
Anschließend wird sie augenblicklich an die Stelle teleportiert, auf der kurz zuvor noch der Teleportationscursor zu sehen war. Dabei blickt sie dann auch in die Richtung, in die eben noch der Pfeil des Cursors gezeigt hat.
Auch bei dieser Bedingung wird die realistische Wandgenerierung genutzt.
\subsection{Versuchsbedingung Real-Walking}\label{subsec:realwalk}
In der Versuchsbedingung Real-Walking können die Proband:innen sich durch natürliches Gehen im Raum bewegen. Nur in dieser Bedingung wird ein Rotation-Gain angewandt.
Des Weiteren wird in dieser Bedingung die in \autoref{subsec:realwallgen} besprochene unmögliche Wandgenerierung verwendet, sodass die Proband:innen mehr Platz innerhalb der Räume haben. Dafür eine Raumstruktur genutzt wird, die darauf basiert, dass Wände von Räumen, in denen sich die Nutzer:in gerade nicht befindet, ausgeblendet werden. Die Räume sich also überlagern sich folglich werden und somit zu Impossible-Spaces.
\chapter{Durchführung und Ergebnisse}\label{}
Nachdem das vorherige Kapitel die Versuchsplanung zur Pilotierungsstudie beschrieben hat, wird dieses davon handeln, wie die Studie durchgeführt und die Datenevaluation mitsamt der Berechnung der statistischen Tests verlaufen ist. Dementsprechend werden zunächst Umstände und Teilnehmer:innen des Experiments vorgestellt, dann der genaue Ablauf der Studie beschrieben, um danach die Methoden der Datenevaluation vorzustellen und diese, zu guter letzt, durchzuführen. Die Fragebögen wurden mit \textquote{Google-Forms} implementiert und sind im \textquote{\nameref{anhang}} mitsamt allen Daten und Antworten zu finden.
\section{Umstände}\label{sec:circumstances}
Aufgrund der anhaltenden Covid-19 Situation wurde die hier vorgestellte Studie nicht, wie sonst bei vergleichbaren Arbeiten üblich, im offiziellen Rahmen der Universität durchgeführt, sondern unter meiner privaten Verantwortung. Es wurden ausreichend Sicherheitsmaßnahmen durchgeführt, um die Gefahr einer Infektion durch die Umstände des Experiments so gering wie möglich zu halten. Abgesehen von einer teilnehmenden Person, hatten alle Proband:innen zum Zeitpunkt der Durchführung bereits vollen Impfschutz.
Alle Teilnehmenden wurden vor der Durchführung des Experiments mit einem Schnelltest auf Covid-19 getestet und ihre Kontaktdaten wurden festgehalten, um sie zu informieren, falls dennoch erforderlich. Außerdem wurden die genutzen Materialen nach jedem Versuchsdurchlauf desinfiziert.
Alle Teilnehmenden wurden gebeten, während der Durchführung des Experiments einen Mund- und Nasenschutz zu tragen sowie sich vorher die Hände mit Handdesinfektionsmittel zu desinfizieren.
Aufgrund dieser Umstände war es leider nicht möglich, dem Standard einer solchen Arbeit entsprechend viele Proband:innen zu finden. Deshalb musste ich mich dafür entscheiden, eine Pilotierungsstudie statt einer vollwertigen Studie durchzuführen. Deshalb möchte ich an dieser Stelle betonen, dass die statistische Aussagekraft der hier erhobenen Ergebnisse nicht so groß wie gewünscht ist. Dies werde ich natürlich in der Auswertung und Einordnung der Ergebnisse berücksichtigen. Ich hoffe dennoch, dass zukünftige Studien mit mehr Teilnehmer:innen von meiner hier geleisteten Vorarbeit profitieren können.
\section{Teilnehmende}\label{sec:participants}
An der Studie nahmen 10 Proband:innen im Alter zwischen 20 und 69 (Median: 23), davon 8 männlich und 2 weiblich, teil. Die Teilnehmenden waren ausnahmlos private Bekannte von mir und haben keinerlei Entschädigung für die freundliche Teilnahme erhalten. Alle Teilnehmer:innen gaben ihre mündliche Zustimmung zur Teilnahme an der Studie und der Verwertung und anonymen Veröffentlichung der darin erhobenen Daten ab. Da alle Teilnehmer:innen aus meinem engen persöhnlichen Umfeld kommen, wurde mir dieses Vorgehen von dem Zweitgutachter dieser Arbeit als ausreichend bestätigt.
Die Teilnehmer:innen waren zwischen 1,62m und 1,89m groß (durschnittlich 1,80m).
5 der 10 Teilnehmer:innen gaben an, nicht an einer diagnostizierten Sehschwäche zu leiden, 3 trugen eine Brille oder Kontaktlinsen und 2 der Proband:innen gaben an, zwar unter einer Sehschwäche zu leiden, aber keine Korrigierung dafür zu nutzen. Ansonsten gaben die Teilnehmer:innen keine Vorerkrankungen an, mit Ausnahme einer Person, die äußerte unter einer Rot-Grün-Schwäche zu leiden.
70\% der Proband:innen hatten schon einmal eine virtuelle Realitätserfahrung mithilfe einer Datenbrille erlebt. Die angegebene Erfahrung mit stereoskopischem 3D und Computerspielen ist aus \autoref{figure:videogames} ersichtlich.
\begin{figure}[H]
\centering
\includegraphics[width=0.99\textwidth]{images/erfahrungpc.png}
\includegraphics[width=0.99\textwidth]{images/pcstundenprowoche.png}
\includegraphics[width=0.99\textwidth]{images/3derfahrung.png}
\caption{Angaben der Teilnehmenden zur Erfahrung mit Computerspielen und stereoskopischem 3D. Bei allen drei Diagrammen gilt:
X-Achse: Antworten der Teilnehmenden. Y-Achse: Häufigkeit der Antworten.}\label{figure:videogames}
\end{figure}
\section{Ablauf der Studie}
An dieser Stelle werde ich den genauen Ablauf der Studie beschreiben.
Die Studie wurde zwischen dem 12.08.2021 und dem 20.08.2021 in einer geräumigen Wohnung in Hamburg/Stellingen ausgeführt. Nach Ankunft der Teilnehmer:innen wurden zunächst die notwendigen Covid-Sicherheitsmaßnahmen thematisiert.
Anschließend haben diese sich ihre Hände desinfiziert, danach führten sie einen Antigen-Schnelltest an sich aus. Bis zur Feststellung des Testergebnisses wurden den Proband:innen in die Steuerung von der Joystick- und Teleportationsbedingung eingewiesen.
Zudem wurde ihnen erklärt, dass ihre Aufgabe während des Experiments darin bestünde, die zurückgelegte Entfernung in jeder Bedingung einzuschätzen. Dabei wurde betont, dass es nicht um die Luftlinie zwischen Start und Ziel ging, sondern um die Strecke, die sie insgesamt zurücklegten. Zudem sollten sie von Raum zu Raum gelangen, indem sie an der Tür zum nächsten Raum die erforderlichen Zahlencodes eingeben, bis die Tür sich öffnet.
Nachdem das negative Testergebnis abzulesen war (bei keiner Teilnehmer:in gab es ein positives Testergebnis), wurden die Proband:innen einer der Gruppen zugeteilt. Ihnen wurde der erste Abschnitt des im Anhang abgebildeten \nameref{anhang:demo}s auf einem Laptop bereit gestellt. Nachdem dieser ausgefüllt war, durften die Proband:innen das erste Mal die für die Durchführung der Studie genutzte Oculus Quest 2 Datenbrille aufsetzen, um sich kurz damit vertraut zu machen. Nebenbei wurde das Bild der Brille über einen Google-Chromecast angezeigt, sodass es von außen möglich war zu sehen, was in der Datenbrille dargestellt wurde. Den Teilnehmer:innen wurde erklärt, wie sie innerhalb des Oculus Startbildschirm navigieren können, sodass diese selbst die APK für die Studie öffnen konnten (siehe \autoref{figure:oculus-menu}).