Physics Material
Physics Material は表面の物理を制御するアセットです——二つの Collider が触れたときの摩擦と弾みを、氷の滑りからゴムボールまで表現します。Friction Combine と実行時の差し替え方を実践的に整理できます。図解とシミュレーターで摩擦と弾みを試し、自学にも使えます。
想像してみてください...
Physics Material は遊び場の地面です。ざらざらしたコンクリート → 球はすぐ止まる(高摩擦)。 磨いた石 → 遠くまで滑る(低摩擦)。ゴム → 高く跳ねる(高弾み)。砂 → 鈍く落ちる(低弾み)。 Unity では Physics Material を独立アセットとして作り、任意の Collider に割り当てて世界との関わり方を変えます。
概念の詳細
Physics Material(3D では .physicMaterial、2D では .physicsMaterial2D
)は ScriptableObject 風のアセットで、主な四つのフィールドがあります:
Dynamic Friction(滑走中、0–1)、
Static Friction(静止から動き出す、通常 Dynamic より高い)、
Bounciness(0 = 弾まない、1 = 最大弾み)、および二つの Combine ——
Friction Combine と
Bounce Combine(Average/Min/Max/Multiply)。
異なる Physics Material の Collider が触れると、Unity が値を合成します。 Average:friction = (frictionA + frictionB) / 2。 Minimum:friction = min(frictionA, frictionB) — 氷に便利(片方が 0 なら常に勝つ)。Combine の優先度:Average < Minimum < Maximum < Multiply。
重要:Unity で Bounciness = 1 は完全な無損失跳ねではありません。
減衰と重力は跳ねの間も効きます。ほぼ完全な跳ねには Bounciness = 1、
Bounce Combine = Maximum、Rigidbody drag = 0 を使います。
実行時に collider.material または
collider.sharedMaterial で差し替えできます。同じアセットを共有する全インスタンスに
効かせたいときは sharedMaterial(メモリ節約)。
実世界のマテリアルプリセット
🧱 レンガ
Dynamic Friction: 0.6
Static Friction: 0.6
Bounciness: 0.0
🧊 氷
Dynamic Friction: 0.02
Static Friction: 0.02
Bounciness: 0.0
🏀 ゴム
Dynamic Friction: 0.8
Static Friction: 0.8
Bounciness: 0.8
🪵 木材
Dynamic Friction: 0.48
Static Friction: 0.48
Bounciness: 0.0
| Combine Mode | 計算式 | 使うとき |
|---|---|---|
| Average | (A + B) / 2 | デフォルト、平均 |
| Minimum | min(A, B) | 氷(片方が 0 ならそちらが勝つ) |
| Maximum | max(A, B) | ゴム(最大バウンス) |
| Multiply | A × B | 粘着面、乗算 |
ハンズオン手順
Physics Material を作成
Project Panel → 右クリック → Create → Physics Material(3D)または Physics Material 2D。表面名で命名(Rubber、Ice…)。
Friction と Bounciness を設定
Dynamic Friction(0–1)、Static Friction(0–1)、Bounciness(0–1)。プリセット表を使うか実験。
Combine Mode を選ぶ
Friction/Bounce Combine:デフォルトは Average。氷は Minimum、弾むゴムは Maximum。
Collider に割り当て
GameObject を選択 → Collider → "Material" スロット → Project から Physics Material をドラッグ。
Play して調整
Play Mode に入り動きを見て値を調整。再生中も Physics Material を編集できます。
インタラクティブシミュレーター
Friction と Bounciness を調整し、球を落として効果を確認しましょう。
パラメータを設定して「ボールを落とす」
コード例
基本キャラが異なる表面に立つとき、実行時に Physics Material を差し替える。
using UnityEngine;
public class SurfaceMaterialSwapper : MonoBehaviour
{
public PhysicMaterial normalMat, iceMat, rubberMat;
Collider col;
void Start() => col = GetComponent<Collider>();
void OnCollisionStay(Collision collision)
{
// Read the ground tag
string tag = collision.gameObject.tag;
col.material = tag switch
{
"Ice" => iceMat,
"Rubber" => rubberMat,
_ => normalMat,
};
}
void OnCollisionExit(Collision _)
{
col.material = normalMat; // Restore when leaving the ground
}
}コード例
上級実行時に Physics Material を作りゲーム状態から調整——アセットファイル不要。
using UnityEngine;
// Create and own a PhysicMaterial at runtime — no Project asset
public class DynamicPhysicsMaterial : MonoBehaviour
{
Collider col;
PhysicMaterial dynMat;
[Range(0f, 1f)] public float friction = 0.4f;
[Range(0f, 1f)] public float bounciness = 0f;
void Awake()
{
col = GetComponent<Collider>();
// Runtime PhysicMaterial, no Project asset needed
dynMat = new PhysicMaterial("Dynamic")
{
dynamicFriction = friction,
staticFriction = friction * 1.2f,
bounciness = bounciness,
frictionCombine = PhysicMaterialCombine.Average,
bounceCombine = PhysicMaterialCombine.Maximum
};
col.material = dynMat;
}
// Call from elsewhere to change live (e.g. character frozen)
public void SetIce()
{
dynMat.dynamicFriction = 0.01f;
dynMat.staticFriction = 0.01f;
col.material = dynMat; // Re-assign so Unity picks up the new values
}
}📌 要点
- ▸0 = 摩擦なし / 弾みなし、1 = 最大
- ▸Static Friction > Dynamic Friction(実物理)
- ▸Minimum Combine:片方が 0 → 結果も 0(理想の氷)
- ▸col.material は私有コピー;sharedMaterial は共有
- ▸実行時に PhysicMaterial を編集したら col.material を再代入
⚠️ よくあるミス
❌ 再代入せず collider.material.bounciness = X
Unity が内側の変更を検知せず——値が古いまま
✅ 新値を作って代入:col.material = updatedMat;
❌ Bounciness = 1 なのに球がエネルギーを失う
Rigidbody.drag > 0 と重力がエネルギーを食う
✅ drag = 0 と Bounce Combine = Maximum