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

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

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

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

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

Q&A

0回答

296閲覧

Unity3Dでグリッドに沿って経路を数珠つなぎに移動してゴールへたどり着きたい

Higawind

総合スコア17

C#

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

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

0グッド

0クリップ

投稿2023/01/15 08:14

前提

Unityでファイアーエムブレムのようなストラテジーを制作しようとしている者です。
下記のYoutubeの動画を元に、経路探索のアルゴリズムを作成いたしましたが、
オブジェクトにその経路を辿らせる手段で行き詰ってしまいました。
https://www.youtube.com/watch?v=fUiNDDcU_I4

是非とも皆様のお知恵をお貸しいただけないでしょうか...?
どうか、よろしくお願いいたします。

実現したいこと

スタート地点からゴール地点までのグリッド上の経路を、グリッドに沿って
オブジェクトを等速で移動させたい。

試したこと

①経路のマス数をループ回数に設定したfor分内で隣接する次の経路のマスへDOTweenのDOMoveを使用して移動させようと
しましたが、斜めに最短距離でゴール地点に向かうだけでした。
(また、DOMoveだとイーズが入っているので、私の求める等速移動には該当していませんでした)

②Youtube上でグリッド状に移動させるMovementの参考動画を元に、上記のfor文とTime.deltatimeなどで移動させようとしましたが、瞬間移動でゴール地点に移動したのみでした。

下記ソースコードの補足

①がメインのスクリプトで、②は数個の数値が入っている参照用のスクリプトです。
①のSetPath()によって、List<GameObject>pathに経路となる複数のマス(GameObject)が全て代入され、経路が割り出されています。
findDistanceをオンにすることで、Update内の処理で経路が割り出されているので、その処理後に経路のマス数をループ回数に設定したfor分内で隣接する次の経路のマスへ移動しようとしましたが上手く行かず...という状態です。

経路となるマスを数珠つなぎに移動していけば上手く行くはず...という考えのもとでしたが、私の技術が甘く、実現には至らずでした。

該当のソースコード①

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using DG.Tweening; 5using TMPro; 6 7public class GridBehavior : MonoBehaviour 8{ 9 public bool findDistance = false; 10 public int rows = 10; 11 public int columns = 10; 12 public int scale = 1; 13 public GameObject gridPrefab; 14 public Vector3 leftBottomLocation = new Vector3(0, 0, 0); 15 public GameObject[,] gridArray; 16 public int startX = 0; 17 public int startY = 0; 18 public int endX = 2; 19 public int endY = 2; 20 public List<GameObject> path = new List<GameObject>(); 21 22 public GameObject objectToMove; 23 public int speed; 24 public bool move; 25 public int moveStep; 26 Vector3[] pa = 27 { 28 }; 29 // Start is called before the first frame update 30 void Awake() 31 { 32 33 gridArray = new GameObject[columns, rows]; 34 35 if (gridPrefab) 36 { 37 GenerateGrid(); 38 } 39 40 else 41 { 42 print("missing gridPrefab, please assign."); 43 } 44 45 } 46 47 // Update is called once per frame 48 void Update() 49 { 50 if (findDistance) 51 { 52 SetDistance(); 53 SetPath(); 54 findDistance = false; 55 } 56 } 57 58 void GenerateGrid() 59 { 60 for (int i = 0; i < columns; i++) 61 { 62 for(int j = 0; j < rows; j++) 63 { 64 GameObject obj = Instantiate(gridPrefab, new Vector3(leftBottomLocation.x + scale * i, leftBottomLocation.y, leftBottomLocation.z + scale * j),Quaternion.identity); 65 66 obj.transform.SetParent(gameObject.transform); 67 obj.GetComponent<GridStat>().x = i; 68 obj.GetComponent<GridStat>().y = j; 69 gridArray[i, j] = obj; 70 71 } 72 } 73 } 74 void SetDistance() 75 { 76 InitialSetUp(); 77 int x = startX; 78 int y = startY; 79 int[] testArray = new int[rows * columns]; 80 for(int step = 1; step < rows*columns; step++) 81 { 82 foreach(GameObject obj in gridArray) 83 { 84 if(obj && obj.GetComponent<GridStat>().visited == step - 1) 85 { 86 TestFourDirections(obj.GetComponent<GridStat>().x, obj.GetComponent<GridStat>().y, step); 87 } 88 } 89 } 90 } 91 92 void SetPath() 93 { 94 moveStep = 0; 95 int step; 96 int x = endX; 97 int y = endY; 98 List<GameObject> tempList = new List<GameObject>(); 99 path.Clear(); 100 if (gridArray[endX,endY] && gridArray[endX,endY].GetComponent<GridStat>().visited>0) 101 { 102 path.Add(gridArray[x, y]); 103 step = gridArray[x, y].GetComponent<GridStat>().visited - 1; 104 105 } 106 else 107 { 108 print("Can't reach the disired location"); 109 return; 110 } 111 for(int i = step; step > -1; step--) 112 { 113 if (TestDirection(x, y, step, 1)) 114 { 115 tempList.Add(gridArray[x, y + 1]); 116 } 117 if (TestDirection(x, y, step, 2)) 118 { 119 tempList.Add(gridArray[x + 1, y]); 120 } 121 if (TestDirection(x, y, step, 3)) 122 { 123 tempList.Add(gridArray[x, y - 1]); 124 } 125 if (TestDirection(x, y, step, 4)) 126 { 127 tempList.Add(gridArray[x - 1, y]); 128 } 129 GameObject tempobj = FindClosest(gridArray[endX, endY].transform, tempList); 130 path.Add(tempobj); 131 x = tempobj.GetComponent<GridStat>().x; 132 y = tempobj.GetComponent<GridStat>().y; 133 tempList.Clear(); 134 moveStep += 1; 135 136 } 137 } 138 139 void InitialSetUp() 140 { 141 foreach(GameObject obj in gridArray) 142 { 143 if (obj) 144 { 145 obj.GetComponent<GridStat>().visited = -1; 146 } 147 } 148 gridArray[startX, startY].GetComponent<GridStat>().visited = 0; 149 } 150 bool TestDirection(int x, int y, int step, int direction) 151 { 152 //int direction tells which case to use 1 is up, 2 is right, 3 is down, 4 is left 153 switch(direction) 154 { 155 case 1: 156 if (y + 1 < rows && gridArray[x, y + 1] && gridArray[x, y + 1].GetComponent<GridStat>().visited == step) 157 return true; 158 else 159 return false; 160 161 case 2: 162 if (x + 1 < columns && gridArray[x+1, y] && gridArray[x+1, y].GetComponent<GridStat>().visited == step) 163 return true; 164 else 165 return false; 166 167 case 3: 168 if (y - 1 > -1 && gridArray[x, y - 1] && gridArray[x, y - 1].GetComponent<GridStat>().visited == step) 169 return true; 170 else 171 return false; 172 173 case 4: 174 if (x - 1 > -1 && gridArray[x-1, y] && gridArray[x-1, y].GetComponent<GridStat>().visited == step) 175 return true; 176 else 177 return false; 178 179 } 180 return false; 181 } 182 183 void TestFourDirections(int x, int y,int step) 184 { 185 if (TestDirection(x,y,-1,1)) 186 { 187 SetVisited(x, y + 1, step); 188 } 189 if (TestDirection(x,y,-1,2)) 190 { 191 SetVisited(x + 1, y, step); 192 } 193 if (TestDirection(x, y, -1, 3)) 194 { 195 SetVisited(x, y - 1, step); 196 } 197 if (TestDirection(x, y, -1, 4)) 198 { 199 SetVisited(x - 1, y, step); 200 } 201 202 } 203 204 205 void SetVisited (int x, int y, int step) 206 { 207 if (gridArray[x, y]) 208 { 209 gridArray[x, y].GetComponent<GridStat>().visited = step; 210 } 211 } 212 GameObject FindClosest(Transform targetLocation, List<GameObject> list) 213 { 214 float currentDistance = scale * rows * columns; 215 int indexNumber = 0; 216 for (int i = 0; i<list.Count;i++) 217 { 218 if(Vector3.Distance(targetLocation.position,list[i].transform.position) < currentDistance) 219 { 220 currentDistance = Vector3.Distance(targetLocation.position, list[i].transform.position); 221 indexNumber = i; 222 } 223 } 224 return list[indexNumber]; 225 226 } 227} 228

該当のソースコード②

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class GridStat : MonoBehaviour 6{ 7 public int visited = -1; 8 public int x = 0; 9 public int y = 0; 10 11 12 // Start is called before the first frame update 13 void Start() 14 { 15 16 } 17 18 // Update is called once per frame 19 void Update() 20 { 21 22 } 23} 24

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

Unity 2019.4.1f1

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

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

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

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

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

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問