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

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

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

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

Unity

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

Q&A

解決済

1回答

3467閲覧

Rayの衝突とLayerMaskが不完全?

ITATI

総合スコア14

C#

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

Unity

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

0グッド

0クリップ

投稿2018/06/08 15:05

編集2019/02/23 11:49

実現したいこと

上の画像の右に発射されている16本の赤いRayが、壁に衝突すると青いRayになるようにしたいと考えています。
※足元の黄色いRayは、現時点ではオブジェクトへの接近をチェックするものです。

発生している問題

このRayを発射する為にキャラクターの当たり判定を外側のコライダー(Is triggerにチェック、レイヤー”Char”)で囲んでいますが、
それがRayと重なっている為、以下のソースでは常に青いRayが表示される様です。
int layerMask = LayerMask.GetMask(new string[] { "Object" });
でマスクに成功していると思うのですが、改善しません。

該当のソースコード

C#

1 // === レイキャスト用) ===================== 2 private Ray flont; 3 private Ray foot; 4 private Ray check; 5 const float skinWidth = .015f; 6 [HorizontalGroup("ray")] public int horizontalRayCount = 16; 7 [HorizontalGroup("ray")] public int verticalRayCount = 8; 8 float horizontalRaySpacing; 9 float verticalRaySpacing; 10 new BoxCollider2D collider; 11 RaycastOrigins raycastOrigins; 12 13protected virtual void Update() 14{ 15UpdateRaycastOrigins(); 16CalculateRaySpacing(); 17int layerMask = LayerMask.GetMask(new string[] { "Object" }); 18 19 for (int i = 0; i < horizontalRayCount; i++)//前面に出るレイ 20{ 21if (facing == true) {//右を向いたとき 22//右上からVector2(1,0)*iの間隔でRayを描画。Vector2(0,1)の長さのRAYでカラーは赤を指定 23RaycastHit2D flont; 24flont = Physics2D.Raycast(raycastOrigins.topRight - Vector2.up * horizontalRaySpacing * i, Vector2.right* 1, layerMask); 25if (flont.collider)//レイが物体に衝突時 26{ 27Debug.DrawRay(raycastOrigins.topRight - Vector2.up * horizontalRaySpacing * i, Vector2.right * 1, Color.blue);} 28else 29{Debug.DrawRay(raycastOrigins.topRight - Vector2.up * horizontalRaySpacing * i, Vector2.right * 1, Color.red);} 30 31//足元チェック用----------------------------------------------------------------------------+ 32RaycastHit2D check; 33check = Physics2D.Raycast(raycastOrigins.bottomRight - Vector2.down * horizontalRaySpacing, Vector2.right * -1 / 2, layerMask); 34Debug.DrawRay(raycastOrigins.bottomRight - Vector2.down * horizontalRaySpacing, Vector2.right * -1 / 2, Color.yellow);//右下に一本だけレイを描画 35 36if (check.collider) { Debug.Log(check.collider.gameObject.name); } 37} 38 39//以下はRay発射元コライダー角座標の設定を行うもの 40void UpdateRaycastOrigins()//Drawrayで直接角座標(vector2)を定義する事ができない為、ここに定義 41 { 42 Bounds bounds = collider.bounds;//ワールド座標でのコライダーのbounds範囲情報取得 43 bounds.Expand/*設定した amount によって sizeを変更*/(skinWidth/*コライダーの幅*/ * -2); 44 raycastOrigins.bottomLeft = new Vector2(bounds.min.x, bounds.min.y); //左下座標 45 raycastOrigins.bottomRight = new Vector2(bounds.max.x, bounds.min.y); //右下座標 46 raycastOrigins.topLeft = new Vector2(bounds.min.x, bounds.max.y); //左上座標 47 raycastOrigins.topRight = new Vector2(bounds.max.x, bounds.max.y); //左上座標 48 } 49 struct RaycastOrigins 50 { 51 public Vector2 topLeft, topRight, bottomLeft, bottomRight; 52 } 53 void CalculateRaySpacing()//数値に従い幅内のレイ数を振り分ける計算 54 { 55 Bounds bounds = collider.bounds; 56 bounds.Expand(skinWidth * -2); 57 58 horizontalRayCount = Mathf.Clamp(horizontalRayCount, 2, int.MaxValue); 59 verticalRayCount = Mathf.Clamp(verticalRayCount, 2, int.MaxValue); 60 61 horizontalRaySpacing = bounds.size.y / (horizontalRayCount - 1) ; 62 verticalRaySpacing = bounds.size.x / (verticalRayCount - 1); 63 }

試したこと

↓字が小さいですが、左下端に取得されたオブジェクト名が表示されています。

//足元チェック用----------------------------------------------------------------------------+
より下のソースにより、オブジェクト名の取得に成功している為、おそらくlayerMaskは機能しています。
※layerMaskが失敗しているときはPlayer( "char" レイヤー)のGameobjectしか取得しませんでした。
ただし、オブジェクトに接触していないときは常にPlayer( "char" レイヤー)のGameobjectが取得されてしまいます。
また、動画の様にオブジェクト名情報は坂道と、壁に埋まった時しか取得できません。
このことからRayの衝突にも問題があるように見受けられます。

何か解決策があればご教示お願いします。

06/12:
次の様にソースを書き換え、マスクを無効にしても、Objectを認識する場合があることが分かりました。
おそらくObjectの配置を調整したものが偶然認識できるようになっっていたものと思われます。

//足元チェック用----------------------------------------------------------------------------+ RaycastHit2D check; check = Physics2D.Raycast(raycastOrigins.bottomRight - Vector2.down * horizontalRaySpacing, Vector2.right * -1 / 2, layerMask); //↓ check = Physics2D.Raycast(raycastOrigins.bottomRight - Vector2.down * horizontalRaySpacing, Vector2.right * -1 / 2);

このことから、レイヤーマスクが機能していないものと思われます。

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

Unity 2018.1.1f1

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

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

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

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

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

sakura_hana

2018/06/09 04:41

念の為、全てのオブジェクトのレイヤー指定が正しいか確認してみてください。また、int layerMask = LayerMask.GetMask(new string[] { "Default" }); にするとどうなるか(もしブロックオブジェクトのレイヤーを変えているならそっちも)試してみてください。
ITATI

2018/06/11 15:53

レイヤーを"char""object"の2つのみに制限してみましたが結果は変わらずでした。int layerMask = LayerMask.GetMask(new string[] { "Default" });も結果は同じでした。本文に追記しましたが、マスク自体が機能していないようで、Rayが初めに接触する"char"のオブジェクト名が取得されるため、本件の問題が発生しているものと推測します。
guest

回答1

0

ベストアンサー

Physics2D.Raycastは第3引数が距離、第4引数がレイヤーマスクを示します。
Physics2D.Raycast - Unity スクリプトリファレンス

check = Physics2D.Raycast(raycastOrigins.bottomRight - Vector2.down * horizontalRaySpacing, Vector2.right * -1 / 2, Mathf.Infinity, layerMask);
こうすれば動くのではないかと。

投稿2018/06/12 04:18

sakura_hana

総合スコア11427

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

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

ITATI

2018/06/12 15:10

オブジェクト名の取得に成功しました。2ヶ月ほど悩んでいた問題がようやく解決しました。有難う御座います。 ちなみに、レイがオブジェクトに衝突時にDrawRAYの色を変える場合は次の記述で成功しました。 ``` RaycastHit2D flont; //右上から-vector2(0,1)*iの間隔でRayを発射,右の方向へ,1の距離,objectのレイヤーの衝突情報を取得 flont = Physics2D.Raycast(raycastOrigins.topRight - Vector2.up * horizontalRaySpacing * i, Vector2.right* 1,1, layerMask); if (flont.collider){/*処理*/} ``` ご協力いただき、有難う御座いました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問