i-school - クリックした方向に向けてボールを発射する

設計


 ゲームのスタートと同時にボールを打ち出すのではなく、画面上の打ち出したい位置をクリックして、その方向に向かってボールを打ち出す処理を考えます。

 マウスやタップを検知する方法はいくつかありますが、検知しただけでは「どの位置」をタップしたかまではわかりません。
そこで今回はカメラの持つ機能を利用して、タップした位置情報をゲーム画面の座標に変換して利用することにします。

 タップの検知にはRay(見えない光線)機能を利用します。画面をタップすることでこの光線を画面の奥方向に向かって発射します。
その際、発射したRayがいずれかのゲームオブジェクトのコライダーに当たった場合に、当たった位置情報を取得して、
ボールの位置を『始点』、Rayが当たった位置を『終点』としたベクトルを取得し、利用する設計になっています。

 ただしこのまま取得したベクトルを利用してしまうと、Rayが当たった位置(終点)によってベクトルの大きさが変わってくるため、
それに合わせて発射速度が速くなったり、遅くなったりしてしまいます。
そこで取得したベクトルを正規化する(ベクトルの大きさを1にする)ことによって、
クリックした距離に関わらずボールの発射速度を一定にして発射するようにしています。(Playerが移動しても正常に機能します)
 

ボールに近い部分をクリック(Player移動後)
https://gyazo.com/90188552f088b6a4c4e3017ed4e992dd

ボールに近い部分をクリック
https://gyazo.com/1e7f46867d30afe92499ad33c2646bb6

ボールに遠い部分をクリック
https://gyazo.com/745fbd03cd85bc529214d19a7dcdb16b
 
 これらの動画を観比べて頂けると、クリック位置に関わらず、ボールの発射速度が変化していないことが確認できると思います。

実装手順


 以下の手順で実装を行います。

1.StartShotスクリプトを修正します



 新しい技術としては、以下の学習を行います。

・カメラを使ってクリックした位置をワールド座標に変換する処理
・Ray機能
・Physics.RaycastメソッドによるRay処理
・ベクトルの正規化


1.StartShotスクリプトを修正する




<ScreenPointToRay(Vector3 position) カメラを使ってクリックした位置をワールド座標に変換する処理>

 このメソッドはCameraクラスの持つメソッドの1つです。
 カメラを通じて画面のクリックした位置に対してRay(見えない光線)を打ち出す処理です。
 
 今回使用している Camera.main 変数は、MainCameraタグのついているカメラを自動的に取得してくれる変数になります。
そのため、MainCameraゲームオブジェクトのCameraコンポーネントを利用して、Rayを発射していることになります。
Unity公式スクリプト・リファレンス
https://docs.unity3d.com/ja/current/ScriptReferenc...


<Ray>
 
 見えない光線を発射する機能です。他のメソッドを合わせて使用することにより、コライダーの有無判定を行うことが可能です。
Unity公式リファレンス
https://docs.unity3d.com/ja/2019.4/Manual/CameraRa...
藍と淡々さま
【Unity】Rayの使い方まとめ
http://megumisoft.hatenablog.com/entry/2015/08/13/...


<Physics.Raycast(Ray ray, out RaycastHit hitInfo) Rayを使ったコライダーの有無判定処理>

 Physics.Raycast()メソッドには複数のオーバーロードがありますが、今回は上記のタイプの引数のPhysics.Raycastを利用しています。

 このメソッドは、rayを発射して、もしもオブジェクトの持つコライダーとぶつかった場合にはtrueを戻し、ぶつからない場合にはfalseを戻す処理を行います。
trueの場合には、outパラメータ修飾子を利用して、そのオブジェクト情報を必ずRaycastHit型で戻してくれることが保証されています。

 Ray部分がRayを発射する始点と方向の設定値、RaycastHit部分が戻り値が代入される変数の指定部分です。今回は事前に用意しておいたrayCastHit変数に代入されるようにしています。

 今回はカメラを通じてRayを発射し、ゲーム画面にある床部分(Yukaゲームオブジェクト)のコライダーを検知し、その座標を取得しています。
Unity公式スクリプト・リファレンス
Physics.Raycast
https://docs.unity3d.com/ja/current/ScriptReferenc...


<Vector3.normalized ベクトルの正規化>
 
 正規化処理です。magnitude(マグニチュード。長さ)を1としたベクトル(単位ベクトル)を返します。返り値はVector3型になります。

 現在のベクトルの方向を維持したまま、magnitudeが1、あるいは0の単位ベクトルを作成することが出来ます。(ベクトルの値が小さいと0になります。)

 この処理を行わないとクリックした位置へのmagnitudeがそのまま維持されてしまうため、ボールの速度が変化してしまいますが
正規化を行うことによって、クリックした位置の遠近に関わらず、magnitudeがすべて1に統一されるため、方向はそのままで、打ち出す力を統一することが出来ます。
 

Unity公式スクリプト・リファレンス
https://docs.unity3d.com/ja/current/ScriptReferenc...
TechProjin様
UnityのVector3でよく使うものまとめ
https://tech.pjin.jp/blog/2016/02/16/unity_vector3...