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

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

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

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

Q&A

1回答

351閲覧

c#のRayに関する質問

shiroshiro_me

総合スコア19

Unity

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

0グッド

0クリップ

投稿2018/10/02 08:19

Rayによって任意に動かせるゲームオブジェクトEyeと自身の座標がある一定以下になったときに自身もRayによって動くような機能を実装したいです。Fove0というHMDを使ったコンテンツを開発していて、Rayは視線を表し、その発信源はコライダを反転させた球の内側にあるカメラです。EyeはあらかじめRayと球体の内側の衝突位置を動くようプログラムされており、自分自身もEyeと重なったときにEyeと同じ挙動をするように実装したいです。そのようなスクリプトを書いてみましたが思ったように動きませんでした。問題は取得するEyeの座標が動いた後の座標ではなく、再生当初のEyeの座標を取得してしまっていると考えられることと、transitionがtrueになったあと、Rayに対応して動かずに、座標(0,0,0)の原点に戻ってしまうことです。transitionがtrueになったあとの処理はEyeと同じで、Eyeはちゃんと動いているのに自身は動いてくれません。
言葉足らずで分かりにくく、大変申し訳ありませんが回答よろしくお願いします。

c#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class Transition : MonoBehaviour { 6 7 private float nowTime; 8 private float distance; 9 private float cnt; 10 private bool transition = false; 11 public GameObject Eye; 12 public float startTime = 1f; 13 public float transitionTime = 0.5f; 14 15 public enum LeftOrRight 16 { 17 Left, 18 Right 19 } 20 21 [SerializeField] 22 public LeftOrRight whichEye; 23 public FoveInterfaceBase foveInterface; 24 private int layerMask = 1 << 9; 25 26 // Use this for initialization 27 void Start() 28 { 29 nowTime = 0f; 30 cnt = 0f; 31 layerMask = 1 << 9; 32 } 33 34 // Latepdate ensures that the object doesn't lag behind the user's head motion 35 void Update() 36 { 37 if (transition) 38 { 39 //transform.position = Eye.transform.position; 40 FoveInterfaceBase.EyeRays rays = foveInterface.GetGazeRays(); 41 42 Ray r = whichEye == LeftOrRight.Left ? rays.left : rays.right; 43 44 RaycastHit hit; 45 Physics.Raycast(r, out hit, Mathf.Infinity, layerMask); 46 if (hit.point != Vector3.zero) // Vector3 is non-nullable; comparing to null is always false 47 { 48 transform.position = hit.point; 49 } 50 else 51 { 52 transform.position = r.GetPoint(3.0f); 53 } 54 return; 55 } 56 57 //startTimeをこえるまでは処理をしない。 58 nowTime += Time.deltaTime; 59 if (nowTime < startTime) 60 { 61 return; 62 } 63 64 //自分とEyeとの距離がある一定以下になった時間をカウント 65 distance = (transform.position - Eye.transform.position).sqrMagnitude; 66 if(cnt > 0f && distance > 1f) 67 { 68 cnt = 0f; 69 return; 70 } 71 if(distance < 1f) 72 { 73 cnt += Time.deltaTime ; 74 } 75 76 if (cnt > transitionTime) 77 { 78 transition = true; 79 } 80 } 81} 82

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

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

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

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

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

guest

回答1

0

取得するEyeの座標が動いた後の座標ではなく、再生当初のEyeの座標を取得してしまっていると考えられる

そんなことはありません。
ソース内にあるEye.transform.positionはEyeの現在位置を指しています。
(Eyeを動かしているソースにもよりますが、少なくとも誤差は1フレーム以内だと思います)

transitionがtrueになったあと、Rayに対応して動かずに、座標(0,0,0)の原点に戻ってしまう
Eyeはちゃんと動いているのに自身は動いてくれません。

ソースを見る限り、自分の位置が(0,0,0)でhit.pointも(0,0,0)なら原点で止まったままになります。(Rayの長さが0になる為、r.GetPoint(3.0f)も0になるんじゃないかと)
(Rayの発信元に付いているコライダーにぶつかっているとか?)
rの始点とhit.pointhit.transform.nameをそれぞれDebug.Logで出して確認してみてください。

投稿2018/10/03 01:22

sakura_hana

総合スコア11425

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

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

shiroshiro_me

2018/10/03 05:53

回答ありがとうございます。 Eyeの座標問題は解決しました。オブジェクトの選択ミスでした。Eyeと自身が一定距離以下で一定時間重なったかどうかの判定は上手くいったと考えられます。しかしその後の動作の問題は解決していません。 Debug.Logの結果、r, hit.pointはすべて0の数字を出し、hit.transform.nameはエラーNullReferenceExceptionにより出力できませんでした。 layerMaskによりRayが球体のみと衝突するように設定しているはずなのですが…
sakura_hana

2018/10/03 06:14

hit.transform.nameでNullエラーってことは、Raycastで衝突してないんだと思います。 bool isHit = Physics.Raycast(r, out hit, Mathf.Infinity, layerMask); こうすると衝突していればisHitがtrueに、していなければfalseになります。 Debug.Log(isHit);で確認と、if文追加して衝突してない時はどうするか設定してください。 衝突しない原因としては、layerMaskの指定がおかしい・球体のレイヤー設定がおかしい・Rayがおかしい(すごく短い等)が考えられますので、こちらも今一度確認してみてください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問