Im ersten Teil dieses Tutorials haben wir einen Algorithmus programmiert, der ein dreidimensionales zufallbasiertes Labyrinth aus einzelnen Zellen erstellt. Jetzt möchten dieses Labyrinth in unserem Level darstellen. In diesem Tutorial geht es in erster Linie nur um die einfachste Art und Weise der Darstellung ohne irgendwelche Spielmechaniken.
Ein zufällig erstelltes Labyrinth mit der Höhe 1 (also in dem Fall zweidimensional) könnte dann so aussehen:

Wir ergänzen dazu unser Unity Projekt, dass wir bereits im ersten Teil dieses Tutorials erstellt haben um ein Script, ein Prefab und ein Material.
Beginnen wir mit dem Prefab. Erstellt einen neuen Würfel über das Menü GameObject –> 3D Object –> Cube.
Der Würfel sollte dann in eurer Hierarchy erscheinen. Falls er noch nicht ausgewählt ist, wählt ihn aus und macht einen Reset im Transform Compononent. Anschließend setzt ihr die Größe (Scale) auf X:2, Y:2 und Z:0.2.

Wenn das erledigt ist, erstellt ihr ein neues Material über das Menü Assets –> Create –> Material und bearbeitet es wie ihr wollte. Damit das Material besser sichtbar ist empfiehlt es sich eine Textur zu wählen. Zieht das Material auf den Würfel und nennt den Würfel um zu „WallPrefab“.
Danach zieht ihr das Objekt WallPrefab aus der Hierarchy in den Project-Browser wodurch ein neues Prefab erstellt wird. Anschließend löscht den Würfel aus der Hierarchy.
Jetzt muss nur noch das Skript erstellt werden, dass das Labyrinth anzeigt. Erstellt dazu ein neues Skript und nennt es MazeController. Erstellt außerdem in der Hierarchy ein neues „Empty GameObject“ über Create –> Create Empty und nennt das GameObject ebenfalls MazeController. Wenn das GameObject ausgewählt ist, wählt im Inspector unter AddComponent/Scripts euer Script aus und fügt es dem GameObject hinzu.
Da wir ja im ersten Teil dieses Tutorials bereits die meiste Vorarbeit gemacht haben, benötigen wir jetzt lediglich noch die Informationen darüber, wie groß unser Labyrinth werden soll. Dazu erstellen wir drei public Variablen in unserem neuen Script. Wir verwenden public Variablen, damit wir diese im Inspector manuell anpassen können. Außerdem benötigen wir public GameObject, in das wir später ohne erstelltes Prefab ablegen.
public int mazeSizeX = 10;
public int mazeSizeY = 1;
public int mazeSizeZ = 10;
public GameObject wallPrefab;
Der ganze Rest findet nun in der Methode Start() statt, damit das Labyrinth beim Spielstart sofort angezeigt wird.
Bevor wir das Labyrinth nun auf den Bildschirm bringen können, müssen wir es erst erstellen. Das geht dank unserer Vorarbeit sehr schnell:
MazeGenerator3D maze = new MazeGenerator3D(mazeSizeX, mazeSizeY, mazeSizeZ);
maze.generate();
Damit ist das Labyrinth erstellt. Jetzt müssen wir nur noch Zelle für Zelle durchgehen und von jeder Zelle die Wand einfügen, die mit true markiert ist. Die Zellen gehen wir mit einer dreifach verzweigten For-Schleife durch. Wir überprüfen jede einzelne Wand jeder Zelle und wenn Sie existiert erstellen wir eine Kopie unseres Prefabs und drehen die Kopie so hin, wie sie sein muss und zu unserer vorher festgelegten Nummerierung passt.

Die gedrehten Wände müssen jetzt nur noch an die entsprechende Position im Koordinatensystem verschoben werden. Der Einfachheit halber wird hier das Koordinatensystem des Labyrinths einfach mit dem Faktor zwei multipliziert.
Der fertige Code der Klasse MazeController sieht dann so aus:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MazeController : MonoBehaviour {
public int mazeSizeX = 10;
public int mazeSizeY = 1;
public int mazeSizeZ = 10;
public GameObject wallPrefab;
// Use this for initialization
void Start () {
MazeGenerator3D maze = new MazeGenerator3D(mazeSizeX, mazeSizeY, mazeSizeZ);
maze.generate();
for (int x = 0; x < mazeSizeX; x++)
{
for (int y = 0; y < mazeSizeY; y++)
{
for (int z = 0; z < mazeSizeZ; z++)
{
if (maze.cells[x,y,z].walls[0] == true)
{
GameObject wall = Instantiate(wallPrefab);
wall.transform.position = new Vector3(x * 2 - 1, y * 2, z * 2);
wall.transform.Rotate(0, 90, 0);
}
if (maze.cells[x, y, z].walls[5] == true)
{
GameObject wall = Instantiate(wallPrefab);
wall.transform.position = new Vector3(x * 2 + 1, y * 2, z * 2);
wall.transform.Rotate(0, 90, 0);
}
if (maze.cells[x, y, z].walls[2] == true)
{
GameObject wall = Instantiate(wallPrefab);
wall.transform.position = new Vector3(x * 2, y * 2, z * 2 - 1);
}
if (maze.cells[x, y, z].walls[3] == true)
{
GameObject wall = Instantiate(wallPrefab);
wall.transform.position = new Vector3(x * 2, y * 2, z * 2 + 1);
}
if (maze.cells[x, y, z].walls[1] == true)
{
GameObject wall = Instantiate(wallPrefab);
wall.transform.position = new Vector3(x * 2, y * 2 - 1, z * 2);
wall.transform.Rotate(90, 0, 0);
}
if (maze.cells[x, y, z].walls[4] == true)
{
GameObject wall = Instantiate(wallPrefab);
wall.transform.position = new Vector3(x * 2, y * 2 + 1, z * 2);
wall.transform.Rotate(90, 0, 0);
}
}
}
}
}
}