LessonEX 物理マテリアル
EX-1 物理マテリアル
Unityには物理マテリアル(Physics Material)という機能があります。物理マテリアルとは、オブジェクト同士の物理挙動を制御するために使用されるマテリアルのことです。物理マテリアルでは摩擦や反発など、オブジェクト同士の物理挙動に関わるパラメータを設定することができます。
例えば反発を強くすることで、ボールが弾む挙動を実装することができます。
まずは空の3Dプロジェクトを作成して、地面とボールを配置してください。

ボールにはRigidbodyをアタッチして、重力が適応されるようにしましょう。


次は物理マテリアルを作成しましょう。2Dと3Dで項目の場所が違うので注意してください。
【2Dの場合】
「Create」→「2D」→「Physics Material 2D」を選択
【3Dの場合】
「Create」→「Physic Material」を選択
今回は3DゲームなのでPhysic Materialを作成してください。


作成したPhysic MaterialのBouncinessを1に、Bounce CombineをMaximumに設定してください。
Bouncinessは反発係数で、値が大きいほど落下したオブジェクトが大きく跳ねるようになります。
Bounce Combineはオブジェクトが衝突した時のパラメータの計算方法を指定できます。Averageは衝突したオブジェクト同士の反発係数を平均化し、Minimumでは小さい方の値を使用、Multiplyでは反発係数を乗算、Maximumでは大きい方の値を使用します。
例えばBouncinessを1、Bounce CombineをAverageに設定した状態でBouncinessが0に設定されたボールと衝突した場合、双方のBouncinessの値が平均化されて反発係数は0.5になります。今回は反発係数が1の時の挙動を確認したいのでBounce CombineをMaximumに設定しています。
また、Dynamic Frictionはオブジェクトが移動しているときの摩擦係数で、Static Frictionはオブジェクトが静止しているときの摩擦係数になります。

作成した物理マテリアルを地面のオブジェクトにドラッグ&ドロップしてください。

これで落下したオブジェクトが反発係数1で弾むトランポリンのような床が完成しました。
ゲームを実行して確認してみてください。

Physic Materialを使うことでブロック崩しの挙動も簡単に作ることができます。
メインカメラをX軸周りに90度回転させて下向きにして、カメラに収まるようにブロック崩しのステージを作ってみてください。


上記サンプルのオブジェクトのTransformは以下のようになっています。
ボールにはRigidbodyをアタッチしておきましょう。

新しいスクリプトBallを作成 して、以下のように入力してください。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Ball : MonoBehaviour
{
void Start()
{
// ゲーム開始時に右上に力を加える
GetComponent<Rigidbody>().AddForce(new Vector3(5.0f, 0.0f, 5.0f), ForceMode.Impulse);
}
}
ゲームが開始した瞬間に右上に力を加えるだけのスクリプトです。
コードが書けたら保存して、ボールにアタッチしておいてください(Rigidbodyがアタッチされていないと実行時にエラーが出ます)
物理マテリアルを作成して、Dynamic FrictionとStatic Frictionを0にしてください。摩擦係数を0にすることで氷のようにボールが滑るようになります。
Friction Combineは小さい方の値(今回は0)を使用したいのでMinimumに設定しましょう。
反発の設定は先ほどと同じで、Bouncinessは1、Bounce CombineはMaximumを設定してください。

作成した物理マテリアルをSphereに設定してください。Sphere ColliderのMaterialに設定できていればOKです。Ballコンポーネントがアタッチできているかも確認しておきましょう。

ゲームを実行して、ボールがブロック崩しの挙動をすることを確認してみてください。

ブロック崩しとして完成させたい方は、ブロックがボールに触れた時に消滅する処理や、移動できるバーの設置などに挑戦してみましょう。
【ヒント】ボールが衝突した時の判定は OnCollisionEnter 関数で取得可能!