i-school - おはじきゲーム 手順4
 以下の内容で順番に実装を進めていきます。

手順4 −手球の挙動制御を実装−
 7.PhysicsMaterial2Dを作成して、手球と壁に反発設定をする
 8.手球用スクリプトを修正する(反発設定をし、手球が壁に接触して跳ね返る)



 新しい学習内容は、以下の通りです。

・PhysicsMaterial2Dの作成方法と利用方法
・Vector2.Reflectメソッド



7.PhysicsMaterial2Dを作成して、手球と壁に反発設定をする


 Unityの物理演算の機能の1つに Physics Material 2D というものがあります。
この機能を利用することでゲームオブジェクト同士の衝突時の摩擦や弾性を調整することが出来ます。

PhysicsMaterial2D
Unity公式マニュアル
Physics Material 2D
https://docs.unity3d.com/ja/2019.4/Manual/class-Ph...


PhysicsMaterial2Dを作成する


 Project内で右クリックしてメニューを表示し、Create => Physics Material 2D で作成することが出来ます。
(あるいは、アセットメニュー (Assets => Create => Physics Material 2D ) でも作成できます。)

 名前は Bound に変更します。フォルダを作成してその中で Bound を管理をしてもよいです。

 


PhysicsMaterial2Dの内容を設定する


 Boundを選択してください。インスペクターに情報が表示されますので、下記の画像のように設定をしてください。


Bound(PhysicsMaterial2D) インスペクター画像



 Frictionは、コライダーの摩擦係数です。値が 0 のときは摩擦がまったく発生せず、大きいほど摩擦がかかり、エネルギーが失われて停止しやすくなります。
 Bouncinessは、衝突時の表面から弾むときの強さです。値が 0 の場合はまったく弾まず、値が 1 の場合はエネルギー損失なく弾みます。


 これで設定は完了です。続いてこの Bound をゲームオブジェクトに設定します。


PhysicsMaterial2Dをゲームオブジェクトに設定する


 
PhysicsMaterial2Dの設定場所はゲームオブジェクトにアタッチされている Collider コンポーネントの中にあります。

 まずは CharaBall ゲームオブジェクトを選択して、インスペクターを確認します。
CapsuleCollider2D コンポーネントの Material 欄に、Bound をドラッグアンドドロップしてアサインします。
これで設定されました。


CharaBallゲームオブジェクト インスペクター画像



 続いて、4つの壁(Wall ゲームオブジェクト)にも同じように Bound を設定します。各壁には BoxCollier2D コンポーネントがアタッチされていますので
こちらの Material 欄に Bound をドラッグアンドドロップしてアサインします。

 同じコンポーネントにアサインする場合には、ヒエラルキー上で複数選択しておくことで、一括でのアサインが可能です。


動画 複数のゲームオブジェクトに同じアサイン情報の設定を行う場合
https://gyazo.com/61a99edfe8ac398e3aaa86e0204b3780


各 Wall ゲームオブジェクトのインスペクター画像

Wall_Leftゲームオブジェクト



Wall_Rightゲームオブジェクト



Wall_Topゲームオブジェクト



Wall_Bottomゲームオブジェクト


 
 これで設定は完了です。


8.手球用スクリプトを修正する(反発設定をし、手球が壁に接触して跳ね返る)


 【7】の手順でゲームオブジェクト同士の反発設定が完了しましたので、次は、手球のスクリプトを修正します。
反発設定をしてあるからといって自動的に跳ね返るようにはなりません。

 現在の手球の速度を保持するための変数を1つ追加します。この情報を使って、壁に接触した際の角度の計算を行います。

 またOnCollisionEnter2Dメソッドを使って壁と接触した場合に、壁と手球の速度・角度に応じて跳ね返る計算処理処理を実装します。


CharaBall.cs

 <= クリックすると開きます



<Vector2.Reflectメソッド>


 法線を基準にした反射ベクトルを取得できるメソッドです。

 Vector2 Reflect (Vector2 inDirection, Vector2 inNormal)

 第1引数の inDirection は現在の進行ベクトルです。手球の方向と速度です。
 第2引数の inNormal は法線ベクトル(面(ここでは壁)に対して垂直方向のベクトル)です。

 この2つの値を渡した結果が反射ベクトル(跳ね返り用のベクトル)となって Vector2 型の値として戻されます。
斜め方向から手球が壁に接触した場合には、その反射方向を計算して、跳ね返らせてくれるようにしています。

 またこの計算を行うために、新しい procVelocity 変数の宣言をしています。

  private Vector2 procVelocity = Vector2.zero;   // Velocity計算保持用


 // 跳ね返り用のベクトル(反射角度)をReflectメソッドを利用して計算(第1引数でボールの方向と速度、第2引数は壁に垂直な単位ベクトル)
 Vector2 reflectVector = Vector2.Reflect(procVelocity, normalVector);

 // 次の速度の計算用にVelocityの値を保持しておく
  procVelocity = rb.velocity;


参考サイト
Unity公式スクリプトリファレンス
Vector2 Reflect
https://docs.unity3d.com/ja/current/ScriptReferenc...


図解があり、わかりやすい説明が載っています
stackoverrun
Unity - Vector2.Reflect()の使い方
https://stackoverrun.com/ja/q/11321749


ゲームを実行して動作を確認する


 手球用のCharaBallスクリプトを修正したらゲームを実行して動作を確認します。

 ゲーム実行と同時に動き出した手球が壁に接触すると、反発設定と跳ね返りの処理によって自然な方向に跳ね返るようになっていれば問題ありません。


検証動画 手球が壁に接触した際に跳ね返る
https://gyazo.com/094cdc9e58a52b528bd3ade5b115040c


 以上でこの手順は終了です。