質問: 3Dゲームを製作しています。 3D空間上に配置された薄いパネル(コライダが設定されている)を画面上でタッチ・スワイプした時に、スワイプした方向がパネルにとって左右方向により近いならtrueを、上下方向により近いならfalseを返すメソッドを書きたいです。 メインカメラが移動してパネルを見る角度が変化する設定なので、実装方法として、 1:タップしたポイントと指(あるいはマウス)を離したポイントをWorldToScreenPointでスクリーン座標に変換し、2点の差を取ることでスワイプのベクトルを得る。 2:パネルの上下方向(transform.up)と左右方向(transform.right)をスクリーン座標に投影・変換する。 3:"1"で得たベクトルと"2"で得た2ベクトルとの角度をそれぞれVector2.Angleで測り、左右方向との角度の方が小さければtrueを、上下方向との角度の方が小さければfalseを返す。 というのを考えています。 そこで質問なのですが、WorldToScreenPointで空間上の点をスクリーン座標上に投影・変換するように、ベクトルをスクリーン座標に投影・変換することは可能ですか? あるいは上記のような実装をする上でより適した方法はありますか? 試したこと: Camera.main.WorldToScreenPoint(transform.up/right);で変換してみたのですが、エラーこそ出ないものの、これで得られるベクトルは常にスクリーン上での上下・左右方向となってしまい、期待している「パネルにおける上下左右方向をスクリーンに投影したもの」にはなりませんでした。
回答: タップ開始点と終了点をそれぞれScreenToWorldPointでワールド座標にして、両者の差を取ってワールド座標系でのスワイプベクトルとし、それをさらにパネルのtransformのInverseTransformVectorに渡してパネルローカル座標系でのスワイプベクトルを求める、というのはどうでしょう? あとはその変換したスワイプベクトルのxの絶対値とyの絶対値を比較すれば(パネルがローカル座標においてZ軸+に面しており、パネル上縁がY軸+を向いている場合です)、パネルに対して左右にスワイプしたか上下にスワイプしたか判定できるのではないでしょうか。 [補足を追記] 最初の部分で申し上げました、タップ開始点と終了点のワールド座標を求めるという件についてですが、たとえばカメラからレイキャストしてパネルとの衝突点を取っているのでしたら、衝突点がそのままワールド座標で得られるのでScreenToWorldPointを使う必要はないでしょう。ご質問者さんの設計に合った方法を試してみてください。