241 lines
8.3 KiB
C#
241 lines
8.3 KiB
C#
|
using UnityEngine;
|
|||
|
using System.Collections;
|
|||
|
using System.Collections.Generic;
|
|||
|
|
|||
|
public class MazeGenerator : MonoBehaviour
|
|||
|
{
|
|||
|
public int mazeWidth = 20; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
public int mazeHeight = 20; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
public float cellSize = 1.5f; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
public float wallThickness = 0f; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
|||
|
public float wallHeight = 1f; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
public GameObject northPrefab; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
public GameObject southPrefab; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
public GameObject eastPrefab; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
public GameObject westPrefab; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
public GameObject floorPrefab1; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
|||
|
public GameObject floorPrefab2; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
|||
|
public GameObject floorPrefab3; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
|||
|
public GameObject floorPrefab4; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
|||
|
public GameObject upperPrefab; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
|||
|
public Transform mazeParent; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
public GameObject LightStick; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
public Vector3 mazeOffset; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>)
|
|||
|
|
|||
|
private Cell[,] grid;
|
|||
|
|
|||
|
void Start()
|
|||
|
{
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
float doorX = 5f;
|
|||
|
float doorZ = 0f;
|
|||
|
float passageWidth = 2f;
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
InitializeMaze();
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
int startX = Random.Range(0, mazeWidth);
|
|||
|
int startZ = Random.Range(0, mazeHeight);
|
|||
|
GenerateMaze(startX, startZ);
|
|||
|
|
|||
|
CreateMazeEntrance();
|
|||
|
CreateMazeExit();
|
|||
|
}
|
|||
|
|
|||
|
void InitializeMaze()
|
|||
|
{
|
|||
|
grid = new Cell[mazeWidth, mazeHeight];
|
|||
|
|
|||
|
for (int x = 0; x < mazeWidth; x++)
|
|||
|
{
|
|||
|
for (int z = 0; z < mazeHeight; z++)
|
|||
|
{
|
|||
|
Cell cell = new Cell();
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
Vector3 cellPos = new Vector3(x * cellSize, 0, z * cellSize) + mazeOffset;
|
|||
|
Vector3 upperPos = new Vector3(x * cellSize, 10, z * cellSize) + mazeOffset;
|
|||
|
Vector3 bottPos = new Vector3(x * cellSize, 0.3f, z * cellSize) + mazeOffset;
|
|||
|
Vector3 backupperPos = new Vector3(x * cellSize, 10.1f, z * cellSize) + mazeOffset;
|
|||
|
Vector3 lightPos = new Vector3(x * cellSize -3, 0, z * cellSize - 3) + mazeOffset;
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
|||
|
int floorType = Random.Range(1, 5);
|
|||
|
switch (floorType)
|
|||
|
{
|
|||
|
case 1:
|
|||
|
cell.floor = Instantiate(floorPrefab1, bottPos, Quaternion.identity, mazeParent);
|
|||
|
break;
|
|||
|
case 2:
|
|||
|
cell.floor = Instantiate(floorPrefab2, bottPos, Quaternion.identity, mazeParent);
|
|||
|
break;
|
|||
|
case 3:
|
|||
|
cell.floor = Instantiate(floorPrefab3, bottPos, Quaternion.identity, mazeParent);
|
|||
|
break;
|
|||
|
case 4:
|
|||
|
cell.floor = Instantiate(floorPrefab4, bottPos, Quaternion.identity, mazeParent);
|
|||
|
break;
|
|||
|
}
|
|||
|
cell.floor.transform.localScale = new Vector3(0.904f, 4f, 0.901f);
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 4-<2D> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
if (((x % 3 == 0 && z % 3 == 0 && Random.value < 0.65f) || (Random.value < 0.1f)) && (x > 2 && z > 2))
|
|||
|
{
|
|||
|
cell.lightstick = Instantiate(LightStick, lightPos, Quaternion.identity, mazeParent);
|
|||
|
}
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
|||
|
cell.upper = Instantiate(upperPrefab, upperPos, Quaternion.identity, mazeParent);
|
|||
|
cell.upper.transform.localScale = new Vector3(1f, -3f, 1f);
|
|||
|
|
|||
|
cell.upper = Instantiate(upperPrefab, backupperPos, Quaternion.identity, mazeParent);
|
|||
|
cell.upper.transform.localScale = new Vector3(1f, 1f, 1f);
|
|||
|
|
|||
|
southPrefab = northPrefab;
|
|||
|
westPrefab = northPrefab;
|
|||
|
eastPrefab = northPrefab;
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
float halfCell = cellSize / 2f;
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
Vector3 northWallPos = cellPos + new Vector3(0, 1, halfCell);
|
|||
|
GameObject northWall = Instantiate(northPrefab, northWallPos, Quaternion.identity, mazeParent);
|
|||
|
northWall.transform.localScale = new Vector3(0.8f, 1, 1);
|
|||
|
cell.northWall = northWall;
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
Vector3 southWallPos = cellPos + new Vector3(0, 1, -halfCell);
|
|||
|
GameObject southWall = Instantiate(southPrefab, southWallPos, Quaternion.identity, mazeParent);
|
|||
|
southWall.transform.localScale = new Vector3(0.8f, 1, 1);
|
|||
|
cell.southWall = southWall;
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
Vector3 eastWallPos = cellPos + new Vector3(halfCell, 1, 0);
|
|||
|
GameObject eastWall = Instantiate(eastPrefab, eastWallPos, Quaternion.identity, mazeParent);
|
|||
|
eastWall.transform.Rotate(0, 90, 0);
|
|||
|
eastWall.transform.localScale = new Vector3(0.8f, 1, 1);
|
|||
|
cell.eastWall = eastWall;
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
Vector3 westWallPos = cellPos + new Vector3(-halfCell, 1, 0);
|
|||
|
GameObject westWall = Instantiate(westPrefab, westWallPos, Quaternion.identity, mazeParent);
|
|||
|
westWall.transform.Rotate(0, 90, 0);
|
|||
|
westWall.transform.localScale = new Vector3(0.8f, 1, 1);
|
|||
|
cell.westWall = westWall;
|
|||
|
|
|||
|
grid[x, z] = cell;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void GenerateMaze(int x, int z)
|
|||
|
{
|
|||
|
grid[x, z].visited = true;
|
|||
|
|
|||
|
List<Vector2Int> neighbors = GetUnvisitedNeighbors(x, z);
|
|||
|
|
|||
|
while (neighbors.Count > 0)
|
|||
|
{
|
|||
|
Vector2Int chosenNeighbor = neighbors[Random.Range(0, neighbors.Count)];
|
|||
|
int nx = chosenNeighbor.x;
|
|||
|
int nz = chosenNeighbor.y;
|
|||
|
|
|||
|
if (!grid[nx, nz].visited)
|
|||
|
{
|
|||
|
RemoveWalls(grid[x, z], grid[nx, nz], x - nx, z - nz);
|
|||
|
GenerateMaze(nx, nz);
|
|||
|
}
|
|||
|
|
|||
|
neighbors = GetUnvisitedNeighbors(x, z);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
List<Vector2Int> GetUnvisitedNeighbors(int x, int z)
|
|||
|
{
|
|||
|
List<Vector2Int> neighbors = new List<Vector2Int>();
|
|||
|
|
|||
|
if (x > 0 && !grid[x - 1, z].visited)
|
|||
|
neighbors.Add(new Vector2Int(x - 1, z));
|
|||
|
if (x < mazeWidth - 1 && !grid[x + 1, z].visited)
|
|||
|
neighbors.Add(new Vector2Int(x + 1, z));
|
|||
|
if (z > 0 && !grid[x, z - 1].visited)
|
|||
|
neighbors.Add(new Vector2Int(x, z - 1));
|
|||
|
if (z < mazeHeight - 1 && !grid[x, z + 1].visited)
|
|||
|
neighbors.Add(new Vector2Int(x, z + 1));
|
|||
|
|
|||
|
return neighbors;
|
|||
|
}
|
|||
|
|
|||
|
void RemoveWalls(Cell current, Cell neighbor, int dx, int dz)
|
|||
|
{
|
|||
|
if (dx == 1)
|
|||
|
{
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
Destroy(current.westWall);
|
|||
|
Destroy(neighbor.eastWall);
|
|||
|
}
|
|||
|
else if (dx == -1)
|
|||
|
{
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
Destroy(current.eastWall);
|
|||
|
Destroy(neighbor.westWall);
|
|||
|
}
|
|||
|
if (dz == 1)
|
|||
|
{
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD>
|
|||
|
Destroy(current.southWall);
|
|||
|
Destroy(neighbor.northWall);
|
|||
|
}
|
|||
|
else if (dz == -1)
|
|||
|
{
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
Destroy(current.northWall);
|
|||
|
Destroy(neighbor.southWall);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void CreateMazeEntrance()
|
|||
|
{
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
float passageWidth = 2f;
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
int entranceXIndex = 0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> x
|
|||
|
int entranceZStart = 0;
|
|||
|
int passageCells = Mathf.CeilToInt(passageWidth / cellSize);
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
for (int i = 0; i < passageCells; i++)
|
|||
|
{
|
|||
|
int z = entranceZStart + i;
|
|||
|
|
|||
|
if (z >= 0 && z < mazeHeight)
|
|||
|
{
|
|||
|
Destroy(grid[entranceXIndex, z].westWall);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void CreateMazeExit()
|
|||
|
{
|
|||
|
int exitXIndex = mazeWidth - 1;
|
|||
|
int exitZIndex = Random.Range(0, mazeHeight);
|
|||
|
|
|||
|
Destroy(grid[exitXIndex, exitZIndex].eastWall);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public class Cell
|
|||
|
{
|
|||
|
public bool visited = false;
|
|||
|
public GameObject northWall, southWall, eastWall, westWall, floor, upper, lightstick;
|
|||
|
}
|