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

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

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

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

Q&A

解決済

1回答

4490閲覧

Unity : Raycastがいくつかのオブジェクトに対してヒットしない

japomondo

総合スコア23

Unity

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

0グッド

2クリップ

投稿2017/12/31 05:32

編集2018/01/01 10:29

###前提・実現したいこと
Raycastをヒットさせたい

###発生している問題・エラーメッセージ
・Box Colliderをコンポーネントに持つオブジェクトがあるが、Raycastがヒットしない
(ThirdPersonController in Standard Assets や a bike object (http://u3d.as/F6S))
・ヒットするオブジェクトもある(シンプルなCubeや、asset storeでダウンロードしたいくつかのオブジェクト

###該当のソースコード

Unity

1public void TryInteract () { 2 RaycastHit hit; 3 4 if (Physics.Raycast (transform.position, transform.forward, out hit, 1f)) { 5 6 // not working 7 if (hit.collider.name == "Bike") { 8 Debug.Log("Bike"); 9 10 // working 11 } else if (hit.collider.name == "Cube") { 12 Debug.Log("Cube"); 13 14 } else { 15 Debug.Log("Other"); 16 } 17 } 18 19 } 20

原因が分かる方がいらっしゃいましたら、ご教示いただけますと幸いです。良いお年を!

追記(いずれもBox Colliderコンポーネント付与):
イメージ説明
ヒットしない
Number of hits:0
UnityEngine.Debug:LogFormat(String, Object[])
PlayerControl:TryInteract() (at Assets/Original/Scripts/PlayerControl.cs:145)
PlayerControl:Update() (at Assets/Original/Scripts/PlayerControl.cs:80)

イメージ説明
ヒットする(上記バイクと同じパッケージのプレファブ)
Number of hits:1
UnityEngine.Debug:LogFormat(String, Object[])
PlayerControl:TryInteract() (at Assets/Original/Scripts/PlayerControl.cs:145)
PlayerControl:Update() (at Assets/Original/Scripts/PlayerControl.cs:80)
RailingA
UnityEngine.Debug:Log(Object)
PlayerControl:TryInteract() (at Assets/Original/Scripts/PlayerControl.cs:145)
PlayerControl:Update() (at Assets/Original/Scripts/PlayerControl.cs:80)

イメージ説明
ヒットする
Number of hits:2
UnityEngine.Debug:LogFormat(String, Object[])
PlayerControl:TryInteract() (at Assets/Original/Scripts/PlayerControl.cs:145)
PlayerControl:Update() (at Assets/Original/Scripts/PlayerControl.cs:80)
terraced1c (2)
UnityEngine.Debug:Log(Object)
PlayerControl:TryInteract() (at Assets/Original/Scripts/PlayerControl.cs:149)
PlayerControl:Update() (at Assets/Original/Scripts/PlayerControl.cs:80)
Road_Streight
UnityEngine.Debug:Log(Object)
PlayerControl:TryInteract() (at Assets/Original/Scripts/PlayerControl.cs:149)
PlayerControl:Update() (at Assets/Original/Scripts/PlayerControl.cs:80)

追記2:
ButtonのOnPointerClickでTryInteractメソッドを呼び出すようにしているのですが、スクーターに向かってRayを試みた結果コンソールに下記メッセージが表示され、Debug.Logでは何も表示されませんでした。

NullReferenceException: Object reference not set to an instance of an object PlayerControl.TryInteract () (at Assets/Original/Scripts/PlayerControl.cs:154) UnityEngine.Events.InvokableCall.Invoke () (at /Users/builduser/buildslave/unity/build/Runtime/Export/UnityEvent.cs:165) UnityEngine.Events.UnityEvent.Invoke () (at /Users/builduser/buildslave/unity/build/Runtime/Export/UnityEvent_0.cs:58) UnityEngine.UI.Button.Press () (at /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:36) UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:45) UnityEngine.EventSystems.ExecuteEvents.Execute (IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:50) UnityEngine.EventSystems.ExecuteEvents.Execute[IPointerClickHandler] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.EventFunction`1 functor) (at /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:261) UnityEngine.EventSystems.EventSystem:Update()

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

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

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

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

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

Bongo

2017/12/31 13:54

オブジェクトが入れ子になっていてnameの一致判定がうまくいかなかったのか...?と思いましたが、例示いただいたアセット(の中の、「Motor」という名前のスクーターのプレハブでいいんですよね?)では入れ子になっておらず、ちゃんとレイがヒットしてそのオブジェクトの名前を取得できているようでした。確認しますが、スクーターのオブジェクト名は「Bike」に変更してあって、レイは明らかにヒットして(バイクがレイ射出元のforward方向に位置していて、バイクとレイ射出元の間には他のコライダーは明らかに存在せず、バイクとレイ射出元の距離は1メートル以内)いるのにヒット判定に失敗しているということでしょうか?
japomondo

2017/12/31 15:59

スクーターのオブジェクト名は「Bike」に変更してあって、レイは明らかにヒットして(バイクがレイ射出元のforward方向に位置していて、バイクとレイ射出元の間には他のコライダーは明らかに存在せず、バイクとレイ射出元の距離は1メートル以内)いるのにヒット判定に失敗しているということでしょうか?→ご確認いただき誠にありがとうございます。ご質問いただいた点、すべて問題無いうえで失敗しております。
guest

回答1

0

ベストアンサー

すみません、まだ原因特定には至らないのですが、コードを記入したかったためこちらの欄に投稿します。
TryInteractを一旦下記のように変更してみて、「バイクにレイが当たるはずなのに判定失敗する」状況でTryInteractを実行すると出力はどうなるでしょうか?
何らかのコライダーが気づかないうちにレイに割り込んでいるのかと思ったのですが、それでも出力が「Number of hits:0」になってしまうでしょうか。
※ちなみに、オブジェクトのレイヤーは特に変更していない(「Default」のまま)のですよね?

C#

1 public void TryInteract() 2 { 3 var hits = Physics.RaycastAll(transform.position, transform.forward, 1f); 4 5 Debug.LogFormat("Number of hits:{0}", hits.Length); 6 7 foreach (var hit in hits) 8 { 9 Debug.Log(hit.collider.name); 10 } 11 /* 12 RaycastHit hit; 13 14 if (Physics.Raycast(transform.position, transform.forward, out hit, 1f)) 15 { 16 17 // not working 18 if (hit.collider.name == "Bike") 19 { 20 Debug.Log("Bike"); 21 22 // working 23 } 24 else if (hit.collider.name == "Cube") 25 { 26 Debug.Log("Cube"); 27 28 } 29 else 30 { 31 Debug.Log("Other"); 32 } 33 } 34 */ 35 }

###[追記]
最初のスクーターのスクリーンショットですが、どうやらキャラクターがコライダー内部へ侵入しており、レイ起点がコライダーの内側となっているために判定に失敗している可能性がありそうですね。
対策案として、レイキャストに失敗した場合、OverlapSphereを使って、レイ起点を中心とする半径0の球...要するにレイ起点が、何らかのコライダーとオーバーラップしているかを追加判定するというのはどうでしょうか。

C#

1 public void TryInteract() 2 { 3 RaycastHit hit; 4 Collider collider = null; 5 6 if (Physics.Raycast(transform.position, transform.forward, out hit, 1f)) 7 { 8 collider = hit.collider; // レイキャストに成功したらコライダーをcolliderに格納 9 } 10 11 if (collider == null) 12 { 13 var colliders = Physics.OverlapSphere(transform.position, 0f); // レイキャストに失敗した場合、レイ起点とオーバーラップするコライダーを探す 14 15 if (colliders.Length > 0) 16 { 17 collider = colliders[0]; // もしオーバーラップするコライダーがあれば、とりあえずその0番目をcolliderに格納 18 } 19 } 20 21 if (collider != null) 22 { 23 // not working 24 if (collider.name == "Bike") 25 { 26 Debug.Log("Bike"); 27 28 // working 29 } 30 else if (collider.name == "Cube") 31 { 32 Debug.Log("Cube"); 33 34 } 35 else 36 { 37 Debug.Log("Other"); 38 } 39 } 40 }

注意点として、もしプレイヤーキャラクター自身もコライダーを持っている場合、それとの交差も検出されてしまう可能性がありますので、適宜レイヤーマスクをかけるなりして不要な判定を除外する措置を加える必要があるかと思います。

投稿2017/12/31 22:09

編集2018/01/01 05:46
Bongo

総合スコア10807

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

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

japomondo

2018/01/01 03:57

コメントに感謝いたします。ご提案いただきましたコードを試させていただいたのですが、やはりヒットするオブジェクトとしないオブジェクトがあるようでした。その際にコンソールに表示された内容を追記いたしましたので、お目通しいただけますと幸いです。なお、ともにレイヤーはDefaultです。
japomondo

2018/01/01 10:31

お時間を割いていただき恐縮です。ご提案いただいた内容を試してみた結果を本文に追記いたしましたので、ご確認いただけますと幸いです。
japomondo

2018/01/01 10:56

Debug.DrawRayで光源を確認したところ爪先あたりから発していたため、キャラクターのお腹の高さあたりに子要素GameObjectを作り、そちらにRayを発するスクリプトを付与したところ、スクーターにもヒットしました…。元のRayは単に当たっていなかっただけのようです。申し訳ありません。何度もご助言いただき、本当にありがとうございました。
Bongo

2018/01/01 11:18

なるほど...そういうケースもありましたか。2枚目のスクリーンショットで、道路らしきオブジェクトとの衝突が検出されていた点にもっと注目するべきでした。こちらも勉強になり有意義でした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問