質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

272閲覧

穴掘り法で迷路を作る際に迷路の壁が削除されず迷路にならない

ptpt

総合スコア22

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2018/09/28 10:05

編集2018/09/28 14:59

前提・実現したいこと

ここを参考にして勉強している。
ランダムな迷路を生成したいが迷路の壁が削除されず迷路にならない。

発生している問題・エラーメッセージ

エラーメッセージは無し

該当のソースコード

c#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class CellScript : MonoBehaviour { 6 7 public GameObject wallL; 8 public GameObject wallR; 9 public GameObject wallU; 10 public GameObject wallD; 11} 12

c#

1 2using System.Collections; 3using System.Collections.Generic; 4using UnityEngine; 5 6public class MazeGenerator : MonoBehaviour { 7 8 9 private void Start() 10 { 11 GenerateMaze(mazeRows, mazeColumns); 12 } 13 14 private void GenerateMaze(int rows, int columns) 15 { 16 if (mazeParent != null) DeleteMaze(); 17 18 mazeRows = rows; 19 mazeColumns = columns; 20 CreateLayout(); 21 } 22 23 // Creates the grid of cells. 24 public void CreateLayout() 25 { 26 InitValues(); 27 28 // Set starting point, set spawn point to start. 29 Vector2 startPos = new Vector2(-(cellSize * (mazeColumns / 2)) + (cellSize / 2), -(cellSize * (mazeRows / 2)) + (cellSize / 2)); 30 Vector2 spawnPos = startPos; 31 32 for (int x = 1; x <= mazeColumns; x++) 33 { 34 for (int y = 1; y <= mazeRows; y++) 35 { 36 GenerateCell(spawnPos, new Vector2(x, y)); 37 38 // Increase spawnPos y. 39 spawnPos.y += cellSize; 40 } 41 42 // Reset spawnPos y and increase spawnPos x. 43 spawnPos.y = startPos.y; 44 spawnPos.x += cellSize; 45 } 46 47 CreateCentre(); 48 RunAlgorithm(); 49 MakeExit(); 50 } 51 52 // This is where the fun stuff happens. 53 public void RunAlgorithm() 54 { 55 // Get start cell, make it visited (i.e. remove from unvisited list). 56 unvisited.Remove(currentCell); 57 58 // While we have unvisited cells. 59 while (unvisited.Count > 0) 60 { 61 List<Cell> unvisitedNeighbours = GetUnvisitedNeighbours(currentCell); 62 if (unvisitedNeighbours.Count > 0) 63 { 64 // Get a random unvisited neighbour. 65 checkCell = unvisitedNeighbours[Random.Range(0, unvisitedNeighbours.Count)]; 66 // Add current cell to stack. 67 stack.Add(currentCell); 68 // Compare and remove walls. 69 CompareWalls(currentCell, checkCell); 70 // Make currentCell the neighbour cell. 71 currentCell = checkCell; 72 // Mark new current cell as visited. 73 unvisited.Remove(currentCell); 74 } 75 else if (stack.Count > 0) 76 { 77 // Make current cell the most recently added Cell from the stack. 78 currentCell = stack[stack.Count - 1]; 79 // Remove it from stack. 80 stack.Remove(currentCell); 81 } 82 } 83 } 84 85 public void MakeExit() 86 { 87 // Create and populate list of all possible edge cells. 88 List<Cell> edgeCells = new List<Cell>(); 89 90 foreach (KeyValuePair<Vector2, Cell> cell in allCells) 91 { 92 if (cell.Key.x == 0 || cell.Key.x == mazeColumns || cell.Key.y == 0 || cell.Key.y == mazeRows) 93 { 94 edgeCells.Add(cell.Value); 95 } 96 } 97 98 // Get edge cell randomly from list. 99 Cell newCell = edgeCells[Random.Range(0, edgeCells.Count)]; 100 101 // Remove appropriate wall for chosen edge cell. 102 if (newCell.gridPos.x == 0) RemoveWall(newCell.cScript, 1); 103 else if (newCell.gridPos.x == mazeColumns) RemoveWall(newCell.cScript, 2); 104 else if (newCell.gridPos.y == mazeRows) RemoveWall(newCell.cScript, 3); 105 else RemoveWall(newCell.cScript, 4); 106 107 Debug.Log("Maze generation finished."); 108 } 109 110 public List<Cell> GetUnvisitedNeighbours(Cell curCell) 111 { 112 // Create a list to return. 113 List<Cell> neighbours = new List<Cell>(); 114 // Create a Cell object. 115 Cell nCell = curCell; 116 // Store current cell grid pos. 117 Vector2 cPos = curCell.gridPos; 118 119 foreach (Vector2 p in neighbourPositions) 120 { 121 // Find position of neighbour on grid, relative to current. 122 Vector2 nPos = cPos + p; 123 // If cell exists. 124 if (allCells.ContainsKey(nPos)) nCell = allCells[nPos]; 125 // If cell is unvisited. 126 if (unvisited.Contains(nCell)) neighbours.Add(nCell); 127 } 128 129 return neighbours; 130 } 131 132 // Compare neighbour with current and remove appropriate walls. 133 public void CompareWalls(Cell cCell, Cell nCell) 134 { 135 // If neighbour is left of current. 136 if (nCell.gridPos.x < cCell.gridPos.x) 137 { 138 RemoveWall(nCell.cScript, 2); 139 RemoveWall(cCell.cScript, 1); 140 } 141 // Else if neighbour is right of current. 142 else if (nCell.gridPos.x > cCell.gridPos.x) 143 { 144 RemoveWall(nCell.cScript, 1); 145 RemoveWall(cCell.cScript, 2); 146 } 147 // Else if neighbour is above current. 148 else if (nCell.gridPos.y > cCell.gridPos.y) 149 { 150 RemoveWall(nCell.cScript, 4); 151 RemoveWall(cCell.cScript, 3); 152 } 153 // Else if neighbour is below current. 154 else if (nCell.gridPos.y < cCell.gridPos.y) 155 { 156 RemoveWall(nCell.cScript, 3); 157 RemoveWall(cCell.cScript, 4); 158 } 159 } 160 161 // Function disables wall of your choosing, pass it the script attached to the desired cell 162 // and an 'ID', where the ID = the wall. 1 = left, 2 = right, 3 = up, 4 = down. 163 public void RemoveWall(CellScript cScript, int wallID) 164 { 165 if (wallID == 1) cScript.wallL.SetActive(false); 166 else if (wallID == 2) cScript.wallR.SetActive(false); 167 else if (wallID == 3) cScript.wallU.SetActive(false); 168 else if (wallID == 4) cScript.wallD.SetActive(false); 169 } 170 171 public void CreateCentre() 172 { 173 // Get the 4 centre cells using the rows and columns variables. 174 // Remove the required walls for each. 175 centreCells[0] = allCells[new Vector2((mazeColumns / 2), (mazeRows / 2) + 1)]; 176 RemoveWall(centreCells[0].cScript, 4); 177 RemoveWall(centreCells[0].cScript, 2); 178 centreCells[1] = allCells[new Vector2((mazeColumns / 2) + 1, (mazeRows / 2) + 1)]; 179 RemoveWall(centreCells[1].cScript, 4); 180 RemoveWall(centreCells[1].cScript, 1); 181 centreCells[2] = allCells[new Vector2((mazeColumns / 2), (mazeRows / 2))]; 182 RemoveWall(centreCells[2].cScript, 3); 183 RemoveWall(centreCells[2].cScript, 2); 184 centreCells[3] = allCells[new Vector2((mazeColumns / 2) + 1, (mazeRows / 2))]; 185 RemoveWall(centreCells[3].cScript, 3); 186 RemoveWall(centreCells[3].cScript, 1); 187 188 // Create a List of ints, using this, select one at random and remove it. 189 // We then use the remaining 3 ints to remove 3 of the centre cells from the 'unvisited' list. 190 // This ensures that one of the centre cells will connect to the maze but the other three won't. 191 // This way, the centre room will only have 1 entry / exit point. 192 List<int> rndList = new List<int> { 0, 1, 2, 3 }; 193 int startCell = rndList[Random.Range(0, rndList.Count)]; 194 rndList.Remove(startCell); 195 currentCell = centreCells[startCell]; 196 foreach(int c in rndList) 197 { 198 unvisited.Remove(centreCells[c]); 199 } 200 } 201 202 public void GenerateCell(Vector2 pos, Vector2 keyPos) 203 { 204 // Create new Cell object. 205 Cell newCell = new Cell(); 206 207 // Store reference to position in grid. 208 newCell.gridPos = keyPos; 209 // Set and instantiate cell GameObject. 210 newCell.cellObject = Instantiate(cellPrefab, pos, cellPrefab.transform.rotation); 211 // Child new cell to parent. 212 if (mazeParent != null) newCell.cellObject.transform.parent = mazeParent.transform; 213 // Set name of cellObject. 214 newCell.cellObject.name = "Cell - X:" + keyPos.x + " Y:" + keyPos.y; 215 // Get reference to attached CellScript. 216 newCell.cScript = newCell.cellObject.GetComponent<CellScript>(); 217 // Disable Cell sprite, if applicable. 218 if (disableCellSprite) newCell.cellObject.GetComponent<SpriteRenderer>().enabled = false; 219 220 // Add to Lists. 221 allCells[keyPos] = newCell; 222 unvisited.Add(newCell); 223 } 224 225 public void DeleteMaze() 226 { 227 if (mazeParent != null) Destroy(mazeParent); 228 } 229 230 public void InitValues() 231 { 232 // Check generation values to prevent generation failing. 233 if (IsOdd(mazeRows)) mazeRows--; 234 if (IsOdd(mazeColumns)) mazeColumns--; 235 236 if (mazeRows <= 3) mazeRows = 4; 237 if (mazeColumns <= 3) mazeColumns = 4; 238 239 // Determine size of cell using localScale. 240 cellSize = cellPrefab.transform.localScale.x; 241 242 // Create an empty parent object to hold the maze in the scene. 243 mazeParent = new GameObject(); 244 mazeParent.transform.position = Vector2.zero; 245 mazeParent.name = "Maze"; 246 } 247 248 public bool IsOdd(int value) 249 { 250 return value % 2 != 0; 251 } 252 253 public class Cell 254 { 255 public Vector2 gridPos; 256 public GameObject cellObject; 257 public CellScript cScript; 258 } 259} 260

試したこと

Google検索

補足情報(FW/ツールのバージョンなど)

unity 2018.2.10

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

ここを参考にしたら迷路を生成できました。

投稿2018/09/28 20:32

ptpt

総合スコア22

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問