前提・実現したいこと
経路探索を正常に動作させたい
該当のソースコード
C#
1using System.Collections; 2using System.Collections.Generic; 3using System.Linq; 4using System.Runtime.ConstrainedExecution; 5using UnityEngine; 6 7public class Astar : MonoBehaviour 8{ 9 public int map_Width = 10; 10 public int map_Height = 10; 11 public GameObject[] walls; 12 public GameObject currenCell; 13 public class Node 14 { 15 public Vector2 pos; 16 //スタートからゴールまでの最短距離。gCost + hCost。 17 public float fCost; 18 //スタートからnノードまでの最短距離 19 public float gCost; 20 //nノードからゴールまでの最短距離 21 public float hCost; 22 public bool walkable; 23 public Node parent; 24 } 25 /// <summary> 26 /// スタートからnノードまでの最短距離 27 /// </summary> 28 public float GetgCost(Node startNode,Node nNode) 29 { 30 float distance = Vector3.Distance(startNode.pos, nNode.pos); 31 return distance; 32 } 33 /// <summary> 34 /// nノードからゴールまでの最短距離 35 /// </summary> 36 public float GethCost(Node nNode,Node goalNode) 37 { 38 float distance = Vector3.Distance(nNode.pos, goalNode.pos); 39 return distance; 40 } 41 public void SetCost(List<Node> nodeList,Node startNode,Node goalNode) 42 { 43 foreach(Node item in nodeList) 44 { 45 item.gCost = GetgCost(startNode, item); 46 item.hCost = GethCost(item, goalNode); 47 item.fCost = item.gCost + item.hCost; 48 } 49 } 50 public Node GetMinNode(List<Node> nodeList) 51 { 52 List<float> floatList = new List<float>(); 53 foreach(Node item in nodeList) 54 { 55 floatList.Add(item.fCost); 56 } 57 float min = floatList.Min(); 58 List<Node> minNodeList = new List<Node>(); 59 foreach(Node item in nodeList) 60 { 61 if(item.fCost == min) 62 { 63 minNodeList.Add(item); 64 } 65 } 66 if(minNodeList.Count == 0) 67 { 68 return minNodeList[0]; 69 } 70 else 71 { 72 List<float> hCostList = new List<float>(); 73 foreach(Node item in minNodeList) 74 { 75 hCostList.Add(item.hCost); 76 } 77 float minhCost = hCostList.Min(); 78 foreach(Node item in minNodeList) 79 { 80 if(item.hCost == minhCost) 81 { 82 return item; 83 } 84 } 85 } 86 return null; 87 } 88 public Node startNode; 89 public Node goalNode; 90 public List<Node> wallNodeList = new List<Node>(); 91 public List<Node> allNodeList = new List<Node>(); 92 public void SetNode() 93 { 94 //すべてのノードをメモリに格納 95 for (int x = 0; x < map_Width; x++) 96 { 97 for (int y = 0; y < map_Height; y++) 98 { 99 Node node = new Node(); 100 node.pos = new Vector2(x, y); 101 node.walkable = true; 102 allNodeList.Add(node); 103 } 104 } 105 } 106 public Node GetNode(int x,int y) 107 { 108 foreach(Node item in allNodeList) 109 { 110 if(item.pos.x == x && item.pos.y == y) 111 { 112 return item; 113 } 114 } 115 return null; 116 } 117 public void SetWall() 118 { 119 List<Vector2> list = new List<Vector2>(); 120 for(int i = 0; i < walls.Length; i++) 121 { 122 list.Add(walls[i].transform.position); 123 } 124 foreach(Vector2 item in list) 125 { 126 Node node = GetNode((int)item.x, (int)item.y); 127 if(node == null) 128 { 129 Debug.Log("OK"); 130 } 131 node.walkable = false; 132 wallNodeList.Add(node); 133 } 134 } 135 136 //OpenリストとCloseリストを設定 137 List<Node> openList = new List<Node>(); 138 List<Node> closeList = new List<Node>(); 139 140 List<Node> parentList = new List<Node>(); 141 142 public void Pathfinding() 143 { 144 SetNode(); 145 SetWall(); 146 //スタート位置とゴール位置を設定 147 startNode = GetNode(0,0); 148 goalNode = GetNode(2,5); 149 openList.Add(startNode); 150 while(openList.Count != 0) 151 { 152 //OpenListが空になったら解なし 153 if(openList == null) 154 { 155 break; 156 } 157 //コストを設定 158 SetCost(openList, startNode, goalNode); 159 //OpenListからfCostが最小のノードnを取得 160 Node n = GetMinNode(openList); 161 openList.Remove(n); 162 closeList.Add(n); 163 if (n == goalNode) 164 { 165 break; 166 } 167 //ノードnの移動可能な方向を調べる 168 foreach(Node neighbour in GetNeighbours(n)) 169 { 170 //隣接するNodeのコストを計算する 171 SetCost(GetNeighbours(n), startNode, goalNode); 172 //検索したNodeをすべてOpenListに追加する 173 openList.Add(neighbour); 174 //すべての隣接するセルの親Nodeを設定する 175 neighbour.parent = n; 176 if (!parentList.Contains(neighbour.parent)) 177 { 178 parentList.Add(neighbour.parent); 179 } 180 } 181 } 182 } 183 public List<Node> GetNeighbours(Node node) 184 { 185 List<Node> neighbours = new List<Node>(); 186 for(int i = (int)node.pos.x - 1;i <= (int)node.pos.x + 1; i++) 187 { 188 for (int j = (int)node.pos.y - 1; j <= (int)node.pos.y + 1; j++) 189 { 190 Node nei = GetNode(i, j); 191 if(nei != null && nei.walkable == true && !openList.Contains(nei) && !closeList.Contains(nei)) 192 { 193 neighbours.Add(nei); 194 } 195 } 196 } 197 return neighbours; 198 } 199 private void Start() 200 { 201 Pathfinding(); 202 parentList.Add(goalNode); 203 StartCoroutine(Move()); 204 } 205 206 IEnumerator Move() 207 { 208 foreach(Node item in parentList) 209 { 210 currenCell.transform.position = item.pos; 211 yield return new WaitForSeconds(0.5f); 212 } 213 } 214} 215
試したこと
Unityで、色々なサイトを参考にしながら、A*アルゴリズムを実装しようとしたのですが、なぜか複雑な形状になると、挙動がおかしくなってしまいます。
どこにおかしくなる原因があるのか、分からなかったため、質問しました。
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2020/08/14 05:13