質問編集履歴

7

2021/04/24 11:59

投稿

Um_kok
Um_kok

スコア39

test CHANGED
@@ -1 +1 @@
1
- 内積を使ってプレイヤーがその範囲に入ったらその向きにて追従をしたい「敵AI」
1
+ 答終了ました事お知らせます。
test CHANGED
@@ -1,511 +1,3 @@
1
- こんにちは。現在AIを作り始めたのです詰まてしまっので質問します。
1
+ 同質問ったため回答終了致します。
2
2
 
3
- やりたいことは画像をご覧ください。
4
-
5
- 桃が赤線の範囲外ならばランダムな移動
6
-
7
- 桃がこのゴリラの範囲の中に入ったら桃の向きにゆっくり回転し、追従を始め、桃が範囲外に出たら追従をやめランダムな移動をするというものです。
8
-
9
- ![イメージ説明](c10fea97f8aac3a0c943628e8348ecad.png)
10
-
11
- この画像はコライダです。
12
-
13
- 小さい方はいずれプレイヤーの弾に当たったら、というもので、
14
-
15
- 大きい方は上記の方法(内積のやり方)でやるので消す予定です。
16
-
17
- ![イメージ説明](7cc455015e7a4ac080017b6fabb9419e.png)
18
-
19
- 現在出来ているコードです。
20
-
21
-
22
-
23
- **Enemy_Move **
24
-
25
- ```C#
26
-
27
- using System.Collections;
28
-
29
- using System.Collections.Generic;
30
-
31
- using UnityEngine;
32
-
33
-
34
-
35
- public class Enemy_Move : RandomMove
36
-
37
- {
38
-
39
- [SerializeField] Enemy_Status enemy; // ステータス
40
-
41
- [SerializeField] Enemy_Collision enemyColl; // 探索範囲
42
-
43
-
44
-
45
- Transform my_Vec; // 自身の座標
46
-
47
- Quaternion direction; // 向き
48
-
49
-
50
-
51
- private void Start()
52
-
53
- {
54
-
55
- my_Vec = transform;
56
-
57
- my_Vec.rotation = direction;
58
-
59
- }
60
-
61
- void Update()
62
-
63
- {
64
-
65
-
66
-
67
- if (enemyColl.follow) {// 追従状態
68
-
69
-
70
-
71
- if (NowAct != null) {//NowActの中がnullでない場合、非追従処理が走っている可能性が高い。→非追従処理を止めて、破棄。
72
-
73
-
74
-
75
- StopCoroutine(NowAct);
76
-
77
- NowAct = null;
78
-
79
- }
80
-
81
-
82
-
83
- if(Now_Direction == null) {//プレイヤーの向きに回転開始
84
-
85
-
86
-
87
- Now_Direction = PlayerDirection();
88
-
89
- StartCoroutine(Now_Direction);
90
-
91
- }
92
-
93
-
94
-
95
- my_Vec.position += (Enemy_Collision.playerPos - transform.position) * enemy.enemy_Speed;
96
-
97
- transform.position += my_Vec.position * Time.deltaTime;
98
-
99
- }
100
-
101
- else {// 非捕捉状態
102
-
103
-
104
-
105
- if (NowAct == null) {// ランダムに回転・移動
106
-
107
-
108
-
109
- NowAct = Nolock_Action();
110
-
111
- StartCoroutine(NowAct);
112
-
113
- }
114
-
115
-
116
-
117
- if(Now_Direction != null) {// プレイヤーが離れた時にも動いていたら終了
118
-
119
-
120
-
121
- StopCoroutine(PlayerDirection());
122
-
123
- }
124
-
125
- }
126
-
127
- }
128
-
129
- }
130
-
131
- ```
132
-
133
- **RandomMove  (Enemy_Move の親**
134
-
135
- ```C#
136
-
137
- using System.Collections;
138
-
139
- using System.Collections.Generic;
140
-
141
- using UnityEngine;
142
-
143
-
144
-
145
- public class RandomMove : MonoBehaviour
146
-
147
- {
148
-
149
- protected IEnumerator NowAct;
150
-
151
- protected IEnumerator Now_Direction;
152
-
153
-
154
-
155
- /// <summary>
156
-
157
- /// 非捕捉状態のときの挙動
158
-
159
- /// </summary>
160
-
161
- protected IEnumerator Nolock_Action()
162
-
163
- {
164
-
165
-
166
-
167
- var now_Z = transform.localRotation.eulerAngles.z;//現在角度.z
168
-
169
- var new_Z = now_Z + Random.Range(60f, -60f);//目標角度.z
170
-
171
-
172
-
173
- float rotspeed = 3;//回転速度
174
-
175
-
176
-
177
- float f = 0;//回転進行度
178
-
179
-
180
-
181
- while (f <= 1) {
182
-
183
-
184
-
185
- f += Time.deltaTime * rotspeed;
186
-
187
- gameObject.transform.rotation = Quaternion.Euler(0, 0, Mathf.LerpAngle(now_Z, new_Z, f));
188
-
189
-
190
-
191
- yield return null;
192
-
193
- }
194
-
195
-
196
-
197
- float speed;// 移動スピード
198
-
199
- float speed_Max = 4f;
200
-
201
-
202
-
203
- float time = 0;//移動時間
204
-
205
- float time_Max = 3;
206
-
207
-
208
-
209
- uint move_sens = 0x00000001;
210
-
211
-
212
-
213
- speed = Random.Range(0, speed_Max);
214
-
215
-
216
-
217
- while (time < time_Max)
218
-
219
- {
220
-
221
- var delta = Time.deltaTime;
222
-
223
-
224
-
225
- time += delta;
226
-
227
- var puls = (speed * delta) * move_sens;
228
-
229
- print(puls);
230
-
231
-
232
-
233
- transform.Translate(0, puls, 0);
234
-
235
-
236
-
237
- yield return null;
238
-
239
- }
240
-
241
-
242
-
243
- NowAct = null;
244
-
245
- }
246
-
247
- /// <summary>
248
-
249
- /// プレイヤーの向きに向く
250
-
251
- /// </summary>
252
-
253
- /// <returns></returns>
254
-
255
- protected IEnumerator PlayerDirection() {
256
-
257
-
258
-
259
- var now_rot = transform.localRotation.eulerAngles.z;// 今の角度
260
-
261
- var goal_rot = Enemy_Collision.playerPos.z;     // 変更するまでの角度
262
-
263
-
264
-
265
- float rotSpeed = 2f;
266
-
267
- float f = 0f;
268
-
269
-
270
-
271
-
272
-
273
-
274
-
275
- while (f <= 1) {
276
-
277
-
278
-
279
- f += Time.deltaTime * rotSpeed;
280
-
281
- gameObject.transform.rotation = Quaternion.Euler(0, 0, Mathf.LerpAngle(now_rot, goal_rot, f));
282
-
283
-
284
-
285
- Vector3 target = (Enemy_Collision.playerPos - transform.position).normalized;
286
-
287
- if (Vector3.Dot(target, transform.forward.normalized) < -0.9) {
288
-
289
-
290
-
291
- print("回転終了!");
292
-
293
- break;
294
-
295
- }
296
-
297
- yield return null;
298
-
299
- }
300
-
301
-
302
-
303
- Now_Direction = null;
304
-
305
- }
306
-
307
- }
308
-
309
-
310
-
311
- ```
312
-
313
- **Enemy_Status (スクリプタブルオブジェクト**
314
-
315
- ```C#
316
-
317
- using System;
318
-
319
- using System.Collections;
320
-
321
- using System.Collections.Generic;
322
-
323
- using UnityEngine;
324
-
325
-
326
-
327
- [CreateAssetMenu(fileName = "Enemy", menuName = "ScriptableObjects/CreateAsset")]
328
-
329
- public class Enemy_Status : ScriptableObject
330
-
331
- {
332
-
333
- public float enemy_Speed = 0.1f;// スピード
334
-
335
- }
336
-
337
- ```
338
-
339
- **Enemy_Collision  (大きいコライダについているコード**
340
-
341
- ```C#
342
-
343
- public class Enemy_Collision : MonoBehaviour
344
-
345
- {
346
-
347
- public bool follow { get; private set; } // フォロー中か?
348
-
349
- public static Vector3 playerPos { get; private set; }//プレイヤーの座標
350
-
351
-
352
-
353
- private void OnTriggerStay2D(Collider2D collision) {
354
-
355
-
356
-
357
- if (collision.CompareTag("Player")) {
358
-
359
-
360
-
361
- follow = true;
362
-
363
- playerPos = collision.transform.position;
364
-
365
- }
366
-
367
- }
368
-
369
- private void OnTriggerExit2D(Collider2D collision) {
370
-
371
-
372
-
373
- if (collision.CompareTag("Player")) {
374
-
375
-
376
-
377
- follow = false;
378
-
379
- }
380
-
381
- }
382
-
383
- }
384
-
385
- ```
386
-
387
- ### やった事
388
-
389
- ランダムな移動はコルーチンでできたのですが、**上記の画像のような範囲(赤い範囲のほう)を制限して、桃が入ったらその方向にゆっくり向き(オブジェクトのY軸が正面)を回転し、追従をする**というコードが書けません。
390
-
391
- どうか回答よろしくお願いいたします。
392
-
393
-
394
-
395
-
396
-
397
- ### 追記
398
-
399
-
400
-
401
- 書き直しました。
402
-
403
- ゴリラから桃へのベクトルとゴリラのY軸のベクトルの内積を求め、ACosで角度を貰い、視覚に入っているかを確認しています。
404
-
405
- 視覚に入っていたら桃の方向を確認し、LarpAngleで一定値まで回転、そのあと追従という風にやってみたのですが
406
-
407
-
408
-
409
- 視覚範囲に入っていなくても printの視界に入っているが吐かれます。
410
-
411
- 何処が間違っすでしょうか?
3
+ 皆さんも1回調べから質問しましょう
412
-
413
- ```C#
414
-
415
- var a = transform.up.normalized;
416
-
417
- var b = (playerPos.transform.position - transform.position).normalized;
418
-
419
-
420
-
421
- var dot = Vector3.Dot(a, b);
422
-
423
- var rad = Mathf.Acos(dot);
424
-
425
-
426
-
427
- if(rad <= 60 || rad >= -60) {
428
-
429
-
430
-
431
- print("視界に入っている");
432
-
433
-
434
-
435
- if(rad != 0) {
436
-
437
-
438
-
439
- var now_Z = transform.localRotation.eulerAngles.z;//現在角度.z
440
-
441
- var new_Z = now_Z + (-playerPos.transform.rotation.z);//目標角度.z
442
-
443
-
444
-
445
- float rotspeed = 3;//回転速度
446
-
447
-
448
-
449
- float f = 0;//回転進行度
450
-
451
-
452
-
453
- while (f <= 1) {
454
-
455
-
456
-
457
- f += Time.deltaTime * rotspeed;
458
-
459
- gameObject.transform.rotation = Quaternion.Euler(0, 0, Mathf.LerpAngle(now_Z, new_Z, f));
460
-
461
- }
462
-
463
-
464
-
465
- // 追従
466
-
467
- my_Vec.position += (Enemy_Collision.playerPos - transform.position) * enemy.enemy_Speed;
468
-
469
- transform.position += my_Vec.position * Time.deltaTime;
470
-
471
- }
472
-
473
- return;
474
-
475
- }
476
-
477
- ```
478
-
479
-
480
-
481
- これで視覚判定が取れると思うのですがなかなかうまくいきません。
482
-
483
- ```C#
484
-
485
- var a = transform.up.normalized;
486
-
487
- var b = (playerPos.transform.position - transform.position).normalized;
488
-
489
-      
490
-
491
-     // 内積を求め、角度を求める
492
-
493
- var dot = Vector3.Dot(a, b);
494
-
495
- var rad = Mathf.Acos(dot);
496
-
497
-
498
-
499
-     指定角度内
500
-
501
- if(rad <= 60 || rad >= -60) {
502
-
503
-
504
-
505
- print("視界に入っている");
506
-
507
- }
508
-
509
-
510
-
511
- ```

6

せいや

2021/04/24 11:59

投稿

Um_kok
Um_kok

スコア39

test CHANGED
File without changes
test CHANGED
@@ -398,7 +398,17 @@
398
398
 
399
399
 
400
400
 
401
-
401
+ 書き直しました。
402
+
403
+ ゴリラから桃へのベクトルとゴリラのY軸のベクトルの内積を求め、ACosで角度を貰い、視覚に入っているかを確認しています。
404
+
405
+ 視覚に入っていたら桃の方向を確認し、LarpAngleで一定値まで回転、そのあと追従という風にやってみたのですが
406
+
407
+
408
+
409
+ 視覚範囲に入っていなくても printの視界に入っているが吐かれます。
410
+
411
+ 何処が間違っていますでしょうか?
402
412
 
403
413
  ```C#
404
414
 

5

era-NullReferenceException: Object reference not set to an instance of an object PlayerMove.Update (

2021/04/24 05:21

投稿

Um_kok
Um_kok

スコア39

test CHANGED
File without changes
test CHANGED
@@ -389,3 +389,113 @@
389
389
  ランダムな移動はコルーチンでできたのですが、**上記の画像のような範囲(赤い範囲のほう)を制限して、桃が入ったらその方向にゆっくり向き(オブジェクトのY軸が正面)を回転し、追従をする**というコードが書けません。
390
390
 
391
391
  どうか回答よろしくお願いいたします。
392
+
393
+
394
+
395
+
396
+
397
+ ### 追記
398
+
399
+
400
+
401
+
402
+
403
+ ```C#
404
+
405
+ var a = transform.up.normalized;
406
+
407
+ var b = (playerPos.transform.position - transform.position).normalized;
408
+
409
+
410
+
411
+ var dot = Vector3.Dot(a, b);
412
+
413
+ var rad = Mathf.Acos(dot);
414
+
415
+
416
+
417
+ if(rad <= 60 || rad >= -60) {
418
+
419
+
420
+
421
+ print("視界に入っている");
422
+
423
+
424
+
425
+ if(rad != 0) {
426
+
427
+
428
+
429
+ var now_Z = transform.localRotation.eulerAngles.z;//現在角度.z
430
+
431
+ var new_Z = now_Z + (-playerPos.transform.rotation.z);//目標角度.z
432
+
433
+
434
+
435
+ float rotspeed = 3;//回転速度
436
+
437
+
438
+
439
+ float f = 0;//回転進行度
440
+
441
+
442
+
443
+ while (f <= 1) {
444
+
445
+
446
+
447
+ f += Time.deltaTime * rotspeed;
448
+
449
+ gameObject.transform.rotation = Quaternion.Euler(0, 0, Mathf.LerpAngle(now_Z, new_Z, f));
450
+
451
+ }
452
+
453
+
454
+
455
+ // 追従
456
+
457
+ my_Vec.position += (Enemy_Collision.playerPos - transform.position) * enemy.enemy_Speed;
458
+
459
+ transform.position += my_Vec.position * Time.deltaTime;
460
+
461
+ }
462
+
463
+ return;
464
+
465
+ }
466
+
467
+ ```
468
+
469
+
470
+
471
+ これで視覚判定が取れると思うのですがなかなかうまくいきません。
472
+
473
+ ```C#
474
+
475
+ var a = transform.up.normalized;
476
+
477
+ var b = (playerPos.transform.position - transform.position).normalized;
478
+
479
+      
480
+
481
+     // 内積を求め、角度を求める
482
+
483
+ var dot = Vector3.Dot(a, b);
484
+
485
+ var rad = Mathf.Acos(dot);
486
+
487
+
488
+
489
+     指定角度内
490
+
491
+ if(rad <= 60 || rad >= -60) {
492
+
493
+
494
+
495
+ print("視界に入っている");
496
+
497
+ }
498
+
499
+
500
+
501
+ ```

4

えい

2021/04/24 05:16

投稿

Um_kok
Um_kok

スコア39

test CHANGED
File without changes
test CHANGED
@@ -386,6 +386,6 @@
386
386
 
387
387
  ### やった事
388
388
 
389
- ランダムな移動はコルーチンでできたのですが、**上記の画像のような範囲(赤い範囲のほう)を制限して、桃が入ったらその方向にゆっくり向き追従をする**というコードが書けません。
389
+ ランダムな移動はコルーチンでできたのですが、**上記の画像のような範囲(赤い範囲のほう)を制限して、桃が入ったらその方向にゆっくり向き(オブジェクトのY軸が正面)を回転し、追従をする**というコードが書けません。
390
390
 
391
391
  どうか回答よろしくお願いいたします。

3

おういえす

2021/04/24 01:21

投稿

Um_kok
Um_kok

スコア39

test CHANGED
File without changes
test CHANGED
@@ -8,6 +8,14 @@
8
8
 
9
9
  ![イメージ説明](c10fea97f8aac3a0c943628e8348ecad.png)
10
10
 
11
+ この画像はコライダです。
12
+
13
+ 小さい方はいずれプレイヤーの弾に当たったら、というもので、
14
+
15
+ 大きい方は上記の方法(内積のやり方)でやるので消す予定です。
16
+
17
+ ![イメージ説明](7cc455015e7a4ac080017b6fabb9419e.png)
18
+
11
19
  現在出来ているコードです。
12
20
 
13
21
 
@@ -328,7 +336,7 @@
328
336
 
329
337
  ```
330
338
 
331
-
339
+ **Enemy_Collision  (大きいコライダについているコード**
332
340
 
333
341
  ```C#
334
342
 
@@ -378,6 +386,6 @@
378
386
 
379
387
  ### やった事
380
388
 
381
- ランダムな移動はコルーチンでできたのですが、**上記の画像のような範囲を制限して、桃が入ったらその方向にゆっくり向き追従をする**というコードが書けません。
389
+ ランダムな移動はコルーチンでできたのですが、**上記の画像のような範囲(赤い範囲のほう)を制限して、桃が入ったらその方向にゆっくり向き追従をする**というコードが書けません。
382
390
 
383
391
  どうか回答よろしくお願いいたします。

2

せいや

2021/04/24 01:20

投稿

Um_kok
Um_kok

スコア39

test CHANGED
File without changes
test CHANGED
@@ -328,6 +328,54 @@
328
328
 
329
329
  ```
330
330
 
331
+
332
+
333
+ ```C#
334
+
335
+ public class Enemy_Collision : MonoBehaviour
336
+
337
+ {
338
+
339
+ public bool follow { get; private set; } // フォロー中か?
340
+
341
+ public static Vector3 playerPos { get; private set; }//プレイヤーの座標
342
+
343
+
344
+
345
+ private void OnTriggerStay2D(Collider2D collision) {
346
+
347
+
348
+
349
+ if (collision.CompareTag("Player")) {
350
+
351
+
352
+
353
+ follow = true;
354
+
355
+ playerPos = collision.transform.position;
356
+
357
+ }
358
+
359
+ }
360
+
361
+ private void OnTriggerExit2D(Collider2D collision) {
362
+
363
+
364
+
365
+ if (collision.CompareTag("Player")) {
366
+
367
+
368
+
369
+ follow = false;
370
+
371
+ }
372
+
373
+ }
374
+
375
+ }
376
+
377
+ ```
378
+
331
379
  ### やった事
332
380
 
333
381
  ランダムな移動はコルーチンでできたのですが、**上記の画像のような範囲を制限して、桃が入ったらその方向にゆっくり向き追従をする**というコードが書けません。

1

えい

2021/04/24 01:15

投稿

Um_kok
Um_kok

スコア39

test CHANGED
File without changes
test CHANGED
@@ -330,6 +330,6 @@
330
330
 
331
331
  ### やった事
332
332
 
333
- ランダムな移動はコルーチンでできたのですが、上記の画像のような範囲を制限して、桃が入ったらその方向にゆっくり向き追従をするというコードが書けません。
333
+ ランダムな移動はコルーチンでできたのですが、**上記の画像のような範囲を制限して、桃が入ったらその方向にゆっくり向き追従をする**というコードが書けません。
334
334
 
335
335
  どうか回答よろしくお願いいたします。