質問編集履歴

2

書式の改善

2021/06/26 07:27

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -472,7 +472,7 @@
472
472
 
473
473
 
474
474
 
475
- ![![イメージ説明](ac0a681f26f67b8e07964a086b803ca8.png)](6cd8d382d3f3084a1fd6e86ede1bce7c.png)
475
+ ![![イメージ説明](ac0a681f26f67b8e07964a086b803ca8.png)
476
476
 
477
477
 
478
478
 
@@ -481,3 +481,5 @@
481
481
  ユニットはランダムに移動しているのですが、ユニットの「不満値」というパラメータが100になると、他のユニットの隣接に移動して、攻撃する、という実装にしようと思っていました。
482
482
 
483
483
  ユニットが移動するスクリプトはUnit_RandomWalk.csというスクリプトです。すべてのユニットにこのスクリプトがアタッチされています。
484
+
485
+ 目的のユニットが移動するたびに経路が再計算されるため、上記の図のように、ぐらぐらと揺れながら移動してしまっています。

1

スクリプトの追加・説明の編集

2021/06/26 07:27

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -18,127 +18,443 @@
18
18
 
19
19
  using UnityEngine;
20
20
 
21
+ using System.Linq;
22
+
23
+
24
+
25
+ namespace UtilityModule
26
+
27
+ {
28
+
29
+ public class Moving_from_PositionA_to_PositionB : MonoBehaviour
30
+
31
+ {
32
+
33
+ private int map_Width = 100;
34
+
35
+ private int map_Height = 100;
36
+
37
+ private ChessboardPathFinder pathFinder;
38
+
39
+ public List<Vector2> moveList = new List<Vector2>();
40
+
41
+ private float speed = 2.5f;
42
+
43
+ public bool stoped_Movement;
44
+
45
+ //始動したコルーチンを覚えておくためのフィールドを追加し...
46
+
47
+ private Coroutine movementAction;
48
+
49
+
50
+
51
+ void Awake()
52
+
53
+ {
54
+
55
+ pathFinder = new ChessboardPathFinder(map_Width, map_Height);
56
+
57
+ }
58
+
59
+
60
+
61
+ public bool Find_Path(Vector2Int startPosition,Vector2Int goalPosition)
62
+
63
+ {
64
+
65
+ bool pathFound = pathFinder.FindPath(startPosition, goalPosition);
66
+
67
+
68
+
69
+ return pathFound;
70
+
71
+ }
72
+
73
+
74
+
75
+ public void Start_MovementAction()
76
+
77
+ {
78
+
79
+ //コルーチン始動時にそれを保存
80
+
81
+ movementAction = StartCoroutine(Move());
82
+
83
+ }
84
+
85
+
86
+
87
+ //そして覚えておいたコルーチンを停止するためのメソッドを用意
88
+
89
+ public void Stop_MovementAction()
90
+
91
+ {
92
+
93
+ if (movementAction != null)
94
+
95
+ {
96
+
97
+ StopCoroutine(movementAction);
98
+
99
+ moveList.Clear();
100
+
101
+ }
102
+
103
+ }
104
+
105
+
106
+
107
+ IEnumerator Move()
108
+
109
+ {
110
+
111
+ foreach (Vector2Int position in pathFinder.Path.Skip(1))
112
+
113
+ {
114
+
115
+ Vector2 pos = new Vector3(position.x, position.y);
116
+
117
+ moveList.Add(pos);
118
+
119
+ }
120
+
121
+
122
+
123
+ Vector2 unitPos = new Vector2(gameObject.transform.position.x, gameObject.transform.position.y);
124
+
125
+ if(moveList.Contains(unitPos))
126
+
127
+ {
128
+
129
+ moveList.Remove(unitPos);
130
+
131
+ }
132
+
133
+
134
+
135
+ int count = 0;
136
+
137
+
138
+
139
+ while (true)
140
+
141
+ {
142
+
143
+ if(stoped_Movement)
144
+
145
+ {
146
+
147
+ break;
148
+
149
+ }
150
+
151
+
152
+
153
+ gameObject.transform.position = Vector2.MoveTowards(gameObject.transform.position, moveList[count], speed * Time.deltaTime);
154
+
155
+
156
+
157
+ if (count < moveList.Count - 1)
158
+
159
+ {
160
+
161
+ count++;
162
+
163
+ }
164
+
165
+
166
+
167
+ if (gameObject.transform.position == (Vector3)moveList[moveList.Count - 1])
168
+
169
+ {
170
+
171
+ break;
172
+
173
+ }
174
+
175
+
176
+
177
+ yield return null;
178
+
179
+ }
180
+
181
+ }
182
+
183
+ }
184
+
185
+ }
186
+
187
+ ```
188
+
189
+ ```C#
190
+
21
- using Module_of_OverWorld;
191
+ using System.Collections;
192
+
193
+ using System.Collections.Generic;
194
+
195
+ using UnityEngine;
22
196
 
23
197
  using Module_of_Unit;
24
198
 
25
-
26
-
27
- namespace UtilityModule
199
+ using UtilityModule;
200
+
201
+
202
+
203
+ namespace Module_of_Berserkermode
28
204
 
29
205
  {
30
206
 
31
- public class Moving_from_PositionA_to_PositionB : MonoBehaviour
207
+ public class Berserkermode : MonoBehaviour
32
208
 
33
209
  {
34
210
 
35
- private int map_Width = 250;
36
-
37
- private int map_Height = 250;
38
-
39
- private ChessboardPathFinder pathFinder;
40
-
41
- public List<Vector2> moveList = new List<Vector2>();
42
-
43
- private float speed = 4;
44
-
45
- public bool stoped_Movement;
46
-
47
-
48
-
49
- void Awake()
50
-
51
- {
52
-
53
- pathFinder = new ChessboardPathFinder(map_Width, map_Height);
54
-
55
- }
56
-
57
-
58
-
59
- public bool Find_Path(Vector2Int startPosition,Vector2Int goalPosition)
60
-
61
- {
62
-
63
- bool pathFound = pathFinder.FindPath(startPosition, goalPosition);
64
-
65
-
66
-
67
- return pathFound;
68
-
69
- }
70
-
71
-
72
-
73
- public void Start_MovementAction()
74
-
75
- {
76
-
77
- StartCoroutine(Move());
78
-
79
- }
80
-
81
-
82
-
83
- IEnumerator Move()
84
-
85
- {
86
-
87
- foreach (Vector2Int position in pathFinder.Path)
88
-
89
- {
90
-
91
- Vector2 pos = new Vector3(position.x, position.y);
92
-
93
- moveList.Add(pos);
94
-
95
- }
96
-
97
-
98
-
99
- int count = 0;
100
-
101
-
102
-
103
- while (true)
104
-
105
- {
106
-
107
- if(stoped_Movement)
211
+ private Unit_RandomWalk unit_RandomWalk;
212
+
213
+ private Unit gameObjectUnit;
214
+
215
+ private Moving_from_PositionA_to_PositionB moving_From_PositionA_To_PositionB;
216
+
217
+ private Unit_RandomWalk unit_RandomWalk_SelectedUnit;
218
+
219
+ private GameObject selectedUnit;
220
+
221
+ private bool get_Distance;
222
+
223
+ private bool switched_Berserkermode;
224
+
225
+ //前回のUpdateで調べたターゲットの位置を保存するためのフィールドを追加
226
+
227
+ private Vector2Int latestTargetPos;
228
+
229
+
230
+
231
+ private void Awake()
232
+
233
+ {
234
+
235
+ unit_RandomWalk = gameObject.GetComponent<Unit_RandomWalk>();
236
+
237
+ gameObjectUnit = gameObject.GetComponent<Unit>();
238
+
239
+ moving_From_PositionA_To_PositionB = gameObject.GetComponent<Moving_from_PositionA_to_PositionB>();
240
+
241
+ }
242
+
243
+
244
+
245
+ public void Action()
246
+
247
+ {
248
+
249
+ //不満値が100%になったら、ランダム移動を停止する
250
+
251
+ unit_RandomWalk.Stop_RandomWalk();
252
+
253
+
254
+
255
+ Invoke("Go", 1);
256
+
257
+ }
258
+
259
+
260
+
261
+ private void Go()
262
+
263
+ {
264
+
265
+ //ランダムに対象を選択する
266
+
267
+ int random = Random.Range(0, gameObjectUnit.playerOwnedUnits_List.Count);
268
+
269
+ selectedUnit = gameObjectUnit.playerOwnedUnits_List[random];
270
+
271
+ unit_RandomWalk_SelectedUnit = selectedUnit.GetComponent<Unit_RandomWalk>();
272
+
273
+ get_Distance = true;
274
+
275
+ switched_Berserkermode = true;
276
+
277
+
278
+
279
+ //対象がいた座標に向かって移動する
280
+
281
+ Go_To_TargetUnit();
282
+
283
+ }
284
+
285
+
286
+
287
+ private void Update()
288
+
289
+ {
290
+
291
+ if(get_Distance)
292
+
293
+ {
294
+
295
+ //このユニットと対象のユニットの距離が、5タイル以内に入ったら、対象のユニットの移動を停止する
296
+
297
+ float distanse = Vector2.Distance(gameObject.transform.position, selectedUnit.transform.position);
298
+
299
+ if (distanse <= 3)
108
300
 
109
301
  {
110
302
 
111
- break;
303
+ unit_RandomWalk_SelectedUnit.Stop_RandomWalk();
304
+
305
+ int x = Mathf.RoundToInt(unit_RandomWalk_SelectedUnit.transform.position.x);
306
+
307
+ int y = Mathf.RoundToInt(unit_RandomWalk_SelectedUnit.transform.position.y);
308
+
309
+ unit_RandomWalk_SelectedUnit.transform.position = new Vector3(x, y, 0);
112
310
 
113
311
  }
114
312
 
115
-
313
+ }
314
+
315
+
316
+
116
-
317
+ //対象のユニットが存在していた座標に到達したら、また移動する
318
+
319
+ /*
320
+
321
+ if (switched_Berserkermode && gameObject.transform.position == (Vector3)moving_From_PositionA_To_PositionB.moveList[moving_From_PositionA_To_PositionB.moveList.Count - 1])
322
+
323
+ {
324
+
325
+ Go_To_TargetUnit();
326
+
327
+ }
328
+
329
+ */
330
+
331
+
332
+
333
+ if (switched_Berserkermode)
334
+
335
+ {
336
+
337
+ //現在のターゲットの位置を調べ...
338
+
117
- gameObject.transform.position = Vector2.MoveTowards(gameObject.transform.position, moveList[count], speed * Time.deltaTime);
339
+ Vector2Int targetPos = new Vector2Int((int)selectedUnit.transform.position.x, (int)selectedUnit.transform.position.y);
340
+
341
+
342
+
118
-
343
+ //敵の位置に変化があったら...
119
-
120
-
344
+
121
- if (count < moveList.Count - 1)
345
+ if (targetPos != latestTargetPos)
122
346
 
123
347
  {
124
348
 
349
+ //現在動作中の移動コルーチンは中止し、目的地への経路を再計算
350
+
351
+ latestTargetPos = targetPos;
352
+
125
- count++;
353
+ Stop_Movement();
354
+
355
+ Go_To_TargetUnit();
126
356
 
127
357
  }
128
358
 
129
-
359
+ }
360
+
130
-
361
+ }
362
+
363
+
364
+
131
- if (gameObject.transform.position == (Vector3)moveList[moveList.Count - 1])
365
+ void Stop_Movement()
132
-
366
+
133
- {
367
+ {
134
-
368
+
135
- break;
369
+ moving_From_PositionA_To_PositionB.Stop_MovementAction();
136
-
370
+
137
- }
371
+ }
372
+
373
+
374
+
138
-
375
+ void Go_To_TargetUnit()
376
+
139
-
377
+ {
378
+
140
-
379
+ //moving_From_PositionA_To_PositionB.moveList.Clear();
380
+
381
+
382
+
383
+ Vector2Int startPos = new Vector2Int((int)gameObject.transform.position.x, (int)gameObject.transform.position.y);
384
+
385
+ Vector2Int goalPos = new Vector2Int((int)selectedUnit.transform.position.x, (int)selectedUnit.transform.position.y);
386
+
387
+
388
+
389
+ Vector2Int up = new Vector2Int(goalPos.x, goalPos.y + 1);
390
+
391
+ Vector2Int down = new Vector2Int(goalPos.x, goalPos.y - 1);
392
+
393
+ Vector2Int right = new Vector2Int(goalPos.x + 1, goalPos.y);
394
+
395
+ Vector2Int left = new Vector2Int(goalPos.x - 1, goalPos.y);
396
+
397
+
398
+
399
+ float up_Distance = Vector2.Distance(startPos, up);
400
+
401
+ float down_Distance = Vector2.Distance(startPos, down);
402
+
403
+ float right_Distance = Vector2.Distance(startPos, right);
404
+
405
+ float left_Distance = Vector2.Distance(startPos, left);
406
+
407
+
408
+
409
+ float min = Mathf.Min(up_Distance, down_Distance, right_Distance, left_Distance);
410
+
411
+
412
+
413
+ if(min == up_Distance)
414
+
415
+ {
416
+
417
+ goalPos = up;
418
+
419
+ }
420
+
421
+
422
+
423
+ if (min == down_Distance)
424
+
425
+ {
426
+
427
+ goalPos = down;
428
+
429
+ }
430
+
431
+
432
+
433
+ if (min == right_Distance)
434
+
435
+ {
436
+
141
- yield return null;
437
+ goalPos = right;
438
+
439
+ }
440
+
441
+
442
+
443
+ if (min == left_Distance)
444
+
445
+ {
446
+
447
+ goalPos = left;
448
+
449
+ }
450
+
451
+
452
+
453
+ if (moving_From_PositionA_To_PositionB.Find_Path(startPos, goalPos))
454
+
455
+ {
456
+
457
+ moving_From_PositionA_To_PositionB.Start_MovementAction();
142
458
 
143
459
  }
144
460
 
@@ -148,258 +464,20 @@
148
464
 
149
465
  }
150
466
 
151
-
152
-
153
467
  ```
154
468
 
155
- ```C#
156
-
157
- using System.Collections;
158
-
159
- using System.Collections.Generic;
160
-
161
- using UnityEngine;
162
-
163
- using Module_of_Unit;
164
-
165
- using UtilityModule;
166
-
167
-
168
-
169
- namespace Module_of_Berserkermode
170
-
171
- {
172
-
173
- public class Berserkermode : MonoBehaviour
174
-
175
- {
176
-
177
- private Unit_RandomWalk unit_RandomWalk;
178
-
179
- private Unit gameObjectUnit;
180
-
181
- private Moving_from_PositionA_to_PositionB moving_From_PositionA_To_PositionB;
182
-
183
-
184
-
185
- private Unit_RandomWalk unit_RandomWalk_SelectedUnit;
186
-
187
- private GameObject selectedUnit;
188
-
189
-
190
-
191
- private bool get_Distance;
192
-
193
-
194
-
195
- private bool switched_Berserkermode;
196
-
197
-
198
-
199
- private void Awake()
200
-
201
- {
202
-
203
- unit_RandomWalk = gameObject.GetComponent<Unit_RandomWalk>();
204
-
205
- gameObjectUnit = gameObject.GetComponent<Unit>();
206
-
207
- moving_From_PositionA_To_PositionB = gameObject.GetComponent<Moving_from_PositionA_to_PositionB>();
208
-
209
- }
210
-
211
-
212
-
213
- public void Action()
214
-
215
- {
216
-
217
- //不満値が100%になったら、ランダム移動を停止する
218
-
219
- unit_RandomWalk.stoped_RandomWalk = true;
220
-
221
-
222
-
223
- Invoke("Go", 1);
224
-
225
- }
226
-
227
-
228
-
229
- private void Go()
230
-
231
- {
232
-
233
- //ランダムに対象を選択する
234
-
235
- int random = Random.Range(0, gameObjectUnit.playerOwnedUnits_List.Count);
236
-
237
- selectedUnit = gameObjectUnit.playerOwnedUnits_List[random];
238
-
239
- unit_RandomWalk_SelectedUnit = selectedUnit.GetComponent<Unit_RandomWalk>();
240
-
241
- get_Distance = true;
242
-
243
- switched_Berserkermode = true;
244
-
245
-
246
-
247
- //対象がいた座標に向かって移動する
248
-
249
- Go_To_TargetUnit();
250
-
251
- }
252
-
253
-
254
-
255
- private void Update()
256
-
257
- {
258
-
259
- if(get_Distance)
260
-
261
- {
262
-
263
- //このユニットと対象のユニットの距離が、5タイル以内に入ったら、対象のユニットの移動を停止する
264
-
265
- float distanse = Vector2.Distance(gameObject.transform.position, selectedUnit.transform.position);
266
-
267
- if (distanse <= 3)
268
-
269
- {
270
-
271
- unit_RandomWalk_SelectedUnit.stoped_RandomWalk = true;
272
-
273
- int x = Mathf.RoundToInt(unit_RandomWalk_SelectedUnit.transform.position.x);
274
-
275
- int y = Mathf.RoundToInt(unit_RandomWalk_SelectedUnit.transform.position.y);
276
-
277
- unit_RandomWalk_SelectedUnit.transform.position = new Vector3(x, y, 0);
278
-
279
- }
280
-
281
- }
282
-
283
-
284
-
285
- //対象のユニットが存在していた座標に到達したら、また移動する
286
-
287
- if (switched_Berserkermode && gameObject.transform.position == (Vector3)moving_From_PositionA_To_PositionB.moveList[moving_From_PositionA_To_PositionB.moveList.Count - 1])
288
-
289
- {
290
-
291
- Go_To_TargetUnit();
292
-
293
- }
294
-
295
- }
296
-
297
-
298
-
299
- void Go_To_TargetUnit()
300
-
301
- {
302
-
303
- moving_From_PositionA_To_PositionB.moveList.Clear();
304
-
305
-
306
-
307
- Vector2Int startPos = new Vector2Int((int)gameObject.transform.position.x, (int)gameObject.transform.position.y);
308
-
309
- Vector2Int goalPos = new Vector2Int((int)selectedUnit.transform.position.x, (int)selectedUnit.transform.position.y);
310
-
311
-
312
-
313
- Vector2Int up = new Vector2Int(goalPos.x, goalPos.y + 1);
314
-
315
- Vector2Int down = new Vector2Int(goalPos.x, goalPos.y - 1);
316
-
317
- Vector2Int right = new Vector2Int(goalPos.x + 1, goalPos.y);
318
-
319
- Vector2Int left = new Vector2Int(goalPos.x - 1, goalPos.y);
320
-
321
-
322
-
323
- float up_Distance = Vector2.Distance(startPos, up);
324
-
325
- float down_Distance = Vector2.Distance(startPos, down);
326
-
327
- float right_Distance = Vector2.Distance(startPos, right);
328
-
329
- float left_Distance = Vector2.Distance(startPos, left);
330
-
331
-
332
-
333
- float min = Mathf.Min(up_Distance, down_Distance, right_Distance, left_Distance);
334
-
335
-
336
-
337
- if(min == up_Distance)
338
-
339
- {
340
-
341
- goalPos = up;
342
-
343
- }
344
-
345
-
346
-
347
- if (min == down_Distance)
348
-
349
- {
350
-
351
- goalPos = down;
352
-
353
- }
354
-
355
-
356
-
357
- if (min == right_Distance)
358
-
359
- {
360
-
361
- goalPos = right;
362
-
363
- }
364
-
365
-
366
-
367
- if (min == left_Distance)
368
-
369
- {
370
-
371
- goalPos = left;
372
-
373
- }
374
-
375
-
376
-
377
- if (moving_From_PositionA_To_PositionB.Find_Path(startPos, goalPos))
378
-
379
- {
380
-
381
- moving_From_PositionA_To_PositionB.Start_MovementAction();
382
-
383
- }
384
-
385
- }
386
-
387
- }
388
-
389
- }
390
-
391
-
392
-
393
- ```
394
-
395
-
396
-
397
469
 
398
470
 
399
471
  ### 試したこと
400
472
 
401
473
 
402
474
 
403
- [Unity A*(A-Star)アルゴリズム](https://teratail.com/questions/283731)を参考にコードを書きました。
475
+ ![![イメージ説明](ac0a681f26f67b8e07964a086b803ca8.png)](6cd8d382d3f3084a1fd6e86ede1bce7c.png)
476
+
477
+
478
+
404
-
479
+ 【回答を追記・編集しました】
480
+
405
- 今のスクリプ、対象が存在していた座標に向かって移動すだけで、移動したあでは対象はそ場所ません。どのように書き換えればいでしょか? 回答よろしくお願ます
481
+ ユニットはランダムに移動しているすがユニットの「不満値」いうパラメータが100になるとユニット隣接移動して、攻撃する、という実装ようと思って
482
+
483
+ ユニットが移動するスクリプトはUnit_RandomWalk.csというスクリプトです。すべてのユニットにこのスクリプトがアタッチされています。