回答編集履歴

4

実装方法の定義

2023/11/02 04:16

投稿

blanket
blanket

スコア295

test CHANGED
@@ -1,6 +1,8 @@
1
1
  ![円とその他の当たり判定](https://ddjkaamml8q8x.cloudfront.net/questions/2023-11-01/a31debc5-774e-4e01-a4ef-e79c97301ca2.png)
2
2
  > 追記
3
3
  [LayerMaskで特定のLayerと当たり判定をとる](https://www.youtube.com/watch?v=vH5iH2y-4jI)
4
+ [扇状の当たり判定の取り方](https://www.youtube.com/watch?v=sM5eB4I1JwA)
5
+ 扇状に当たり判定を取れば3枚目の画像でも判定を取ることができるのではないでしょうか?
4
6
  ↓プレイヤーにつける疑似的なコード
5
7
  ```C#
6
8
  public class Player : MonoBehaviour

3

回答の修正

2023/11/01 10:50

投稿

blanket
blanket

スコア295

test CHANGED
@@ -1,51 +1,22 @@
1
1
  ![円とその他の当たり判定](https://ddjkaamml8q8x.cloudfront.net/questions/2023-11-01/a31debc5-774e-4e01-a4ef-e79c97301ca2.png)
2
2
  > 追記
3
+ [LayerMaskで特定のLayerと当たり判定をとる](https://www.youtube.com/watch?v=vH5iH2y-4jI)
3
4
  ↓プレイヤーにつける疑似的なコード
4
5
  ```C#
5
6
  public class Player : MonoBehaviour
6
7
  {
7
- Explosion explosion;
8
-
9
- bool isTrigger = false;
10
-
11
- // プレイヤーを視認する範囲
12
- private float visualRange = 5.0f;
13
-
14
- Transform thistrans;
15
-
16
8
  private void Start()
17
9
  {
18
- isTrigger = false;
19
- explosion = GameObject.Find("Sphere").GetComponent<Explosion>();
10
+ LayerMask layerMask = 1 << LayerMask.NameToLayer("ObstacleLayer");
20
- }
21
11
 
22
- private void Update()
12
+ if(Physics.Raycast(
23
- {
24
- // 座標取得
25
- thistrans = this.transform;
13
+ transform.position,
26
-
27
- // プレイヤーが視認距離より遠くに行くか敵の後ろに行ったとき
14
+ new Vector3(-1f,0,0),
28
- if (thistrans.position.x + visualRange < explosion.transform.position.x ||
29
- thistrans.position.x - visualRange > explosion.transform.position.x)
15
+ out RaycastHit hit,
16
+ Mathf.Infinity,
17
+ layerMask))
30
18
  {
31
- Debug.Log("1:逃げ切った");
32
- }
33
- else if (isTrigger)
34
- {
35
- // 障害物がない場合、プレイヤーと爆風の間に障害物はなく、当たっていると判断
36
- Debug.Log("2:NONE Hit");
37
- }
38
- else
39
- {
40
- Debug.Log("3:範囲内");
19
+ Debug.Log("視認");
41
- }
42
- }
43
-
44
- private void OnTriggerEnter(Collider other)
45
- {
46
- if (other.gameObject.CompareTag("Explosion"))
47
- {
48
- isTrigger = true;
49
20
  }
50
21
  }
51
22
  }

2

説明の補正

2023/11/01 01:23

投稿

blanket
blanket

スコア295

test CHANGED
@@ -1,5 +1,4 @@
1
- プレイヤーと当たり判定をとるオブジェクトにSphereColliderを2つ用意して、IsTriggerにチェックを入れたのと入れていないのを用意します。IsTriggerにチェックを入れていないほうに細工をします。Radiusを0.1にして壁の隙間よりも小さくします。Physics.Raycastの判定をスクリプトで行えば、Collisionの方は当たり判定が小さいのでrayの太さも小さくなり壁の隙間に通すことができます。Triggerの方はそのままの大きさなのでプレイヤーと当たり判定をとるオブジェクトの円の中に入っているため当たり判定を取ることができます。
2
-
1
+ ![円その他の当たり判定](https://ddjkaamml8q8x.cloudfront.net/questions/2023-11-01/a31debc5-774e-4e01-a4ef-e79c97301ca2.png)
3
2
  > 追記
4
3
  ↓プレイヤーにつける疑似的なコード
5
4
  ```C#
@@ -7,32 +6,38 @@
7
6
  {
8
7
  Explosion explosion;
9
8
 
10
- // 壁や障害物のレイヤーマスク
11
- private LayerMask obstacleLayer;
9
+ bool isTrigger = false;
12
10
 
13
- // Debug
11
+ // プレイヤーを視認する範囲
14
- bool isDebugOK;
12
+ private float visualRange = 5.0f;
15
13
 
16
- bool isWall = false;
17
- bool isTrigger = false;
14
+ Transform thistrans;
18
15
 
19
16
  private void Start()
20
17
  {
21
18
  isTrigger = false;
22
- isWall = false;
23
- isDebugOK = false;
24
19
  explosion = GameObject.Find("Sphere").GetComponent<Explosion>();
25
- obstacleLayer = LayerMask.GetMask("ObstacleLayer"); // 障害物のレイヤーマスクを設定
26
20
  }
27
21
 
28
22
  private void Update()
29
23
  {
24
+ // 座標取得
30
- if (isDebugOK == false)
25
+ thistrans = this.transform;
26
+
27
+ // プレイヤーが視認距離より遠くに行くか敵の後ろに行ったとき
28
+ if (thistrans.position.x + visualRange < explosion.transform.position.x ||
29
+ thistrans.position.x - visualRange > explosion.transform.position.x)
31
30
  {
31
+ Debug.Log("1:逃げ切った");
32
+ }
33
+ else if (isTrigger)
34
+ {
32
- // プレイヤーが視認範囲にいる
35
+ // 障害物がない場合、プレイヤーと爆風の間障害物はなく、当たっていると判断
33
- ExpSearch();
36
+ Debug.Log("2:NONE Hit");
34
-
37
+ }
38
+ else
39
+ {
35
- isDebugOK = true;
40
+ Debug.Log("3:範囲内");
36
41
  }
37
42
  }
38
43
 
@@ -40,30 +45,8 @@
40
45
  {
41
46
  if (other.gameObject.CompareTag("Explosion"))
42
47
  {
43
- if (isWall) return;
44
- Debug.Log("トリガー");
45
48
  isTrigger = true;
46
- }
47
- }
48
-
49
- public void ExpSearch()
50
- {
51
- // プレイヤーから爆風に向かう方向のベクトルを計算
52
- Vector3 direction = explosion.transform.position - transform.position;
53
-
54
- // プレイヤーから爆風へのレイを飛ばし、障害物があるかどうかを判定
55
- if (Physics.Raycast(transform.position, direction, out RaycastHit hit, 5f, obstacleLayer))
56
- {
57
- // レイが障害物に当たった場合、障害物が存在するため当たっていないと判断
58
- Debug.Log("Blocked by an obstacle");
59
- isWall = true;
60
- }
61
- else if(isTrigger)
62
- {
63
- // 障害物がない場合、プレイヤーと爆風の間に障害物はなく、当たっていると判断
64
- Debug.Log("Hit");
65
49
  }
66
50
  }
67
51
  }
68
52
  ```
69
- Physics.Raycastを実装して、もしTriggerの中にいて遮るものがある場合bool型でTrigger内にいる事であれば当たったことにしてしまおうというものです。

1

文法の修正、疑似的なコード追加

2023/11/01 00:01

投稿

blanket
blanket

スコア295

test CHANGED
@@ -1 +1,69 @@
1
1
  プレイヤーと当たり判定をとるオブジェクトにSphereColliderを2つ用意して、IsTriggerにチェックを入れたのと入れていないのを用意します。IsTriggerにチェックを入れていないほうに細工をします。Radiusを0.1にして壁の隙間よりも小さくします。Physics.Raycastの判定をスクリプトで行えば、Collisionの方は当たり判定が小さいのでrayの太さも小さくなり壁の隙間に通すことができます。Triggerの方はそのままの大きさなのでプレイヤーと当たり判定をとるオブジェクトの円の中に入っているため当たり判定を取ることができます。
2
+
3
+ > 追記
4
+ ↓プレイヤーにつける疑似的なコード
5
+ ```C#
6
+ public class Player : MonoBehaviour
7
+ {
8
+ Explosion explosion;
9
+
10
+ // 壁や障害物のレイヤーマスク
11
+ private LayerMask obstacleLayer;
12
+
13
+ // Debug
14
+ bool isDebugOK;
15
+
16
+ bool isWall = false;
17
+ bool isTrigger = false;
18
+
19
+ private void Start()
20
+ {
21
+ isTrigger = false;
22
+ isWall = false;
23
+ isDebugOK = false;
24
+ explosion = GameObject.Find("Sphere").GetComponent<Explosion>();
25
+ obstacleLayer = LayerMask.GetMask("ObstacleLayer"); // 障害物のレイヤーマスクを設定
26
+ }
27
+
28
+ private void Update()
29
+ {
30
+ if (isDebugOK == false)
31
+ {
32
+ // プレイヤーが視認範囲にいるか
33
+ ExpSearch();
34
+
35
+ isDebugOK = true;
36
+ }
37
+ }
38
+
39
+ private void OnTriggerEnter(Collider other)
40
+ {
41
+ if (other.gameObject.CompareTag("Explosion"))
42
+ {
43
+ if (isWall) return;
44
+ Debug.Log("トリガー");
45
+ isTrigger = true;
46
+ }
47
+ }
48
+
49
+ public void ExpSearch()
50
+ {
51
+ // プレイヤーから爆風に向かう方向のベクトルを計算
52
+ Vector3 direction = explosion.transform.position - transform.position;
53
+
54
+ // プレイヤーから爆風へのレイを飛ばし、障害物があるかどうかを判定
55
+ if (Physics.Raycast(transform.position, direction, out RaycastHit hit, 5f, obstacleLayer))
56
+ {
57
+ // レイが障害物に当たった場合、障害物が存在するため当たっていないと判断
58
+ Debug.Log("Blocked by an obstacle");
59
+ isWall = true;
60
+ }
61
+ else if(isTrigger)
62
+ {
63
+ // 障害物がない場合、プレイヤーと爆風の間に障害物はなく、当たっていると判断
64
+ Debug.Log("Hit");
65
+ }
66
+ }
67
+ }
68
+ ```
69
+ Physics.Raycastを実装して、もしTriggerの中にいて遮るものがある場合bool型でTrigger内にいる事であれば当たったことにしてしまおうというものです。