UnityUnityメモ

Unityで物理マテリアルを活用!オブジェクトを滑らせてスペースキーで停止させる方法

Unity

1. はじめに

Unityでゲームを作るとき、オブジェクトの物理挙動をシミュレートすることはよくありますよね。特に、物体が滑ったり、停止したりする動きを再現するのは、リアルなゲーム体験を作る上で欠かせません。

この記事では、Unityの「物理マテリアル」を使って、オブジェクト(例:Cube)が斜面(Plane)を滑り落ちるシンプルなシミュレーションを作成します。さらに、スペースキーを押すことで抗力(空気抵抗)を高め、オブジェクトをその場で停止させる仕組みをスクリプトで追加します。


このシステムを学ぶことで、以下のスキルが身につきます:

  • 物理マテリアルを活用してオブジェクトの摩擦や跳ね返りを調整する方法
  • Rigidbodyの抗力を操作して動きをコントロールするテクニック
  • キーボード入力を使ったスクリプトの基本

初心者の方でも安心して進められるよう、わかりやすく説明していきます。Unityの物理エンジンの魅力を一緒に体験していきましょう!

Unityを触ったことがないという方はコチラの記事から見てみてください!



2. Unityプロジェクトの準備

Unityで物理マテリアルや抗力設定を使ったシーンを作成するには、まず新しいプロジェクトを用意しましょう。以下の手順に従えば、初心者でも簡単に準備ができます!


1. Unity Hubで新規プロジェクトを作成

  1. Unity Hubを起動します。
  2. 画面上部にある「プロジェクト」タブをクリックします。
  3. 新規プロジェクトボタンをクリックします。
  4. 3D」を選択します。
  5. プロジェクト名を「PhysicsMaterialDemo」など、わかりやすい名前にします。
  6. 保存先を選択して「作成」ボタンをクリックします。

※ Unityのバージョンは、推奨される最新版を使用してください。


2. プロジェクトビューの整理

効率的に作業を進めるために、フォルダを整理しましょう。

  1. Projectウィンドウで右クリックして「Create」→「Folder」を選びます。
  2. 以下のフォルダを作成します:
    • Scenes(シーンデータを保存する場所)
    • Scripts(スクリプトファイルを保存する場所)
    • Materials(物理マテリアルを保存する場所)

これでプロジェクトの準備が完了です!次のステップでは、3Dオブジェクトをシーンに配置していきます。簡単な準備で、ゲーム開発がスムーズに進む基礎を整えましょう!



3. オブジェクトの配置

Unityでオブジェクトを配置するのはとても簡単です。このセクションでは、斜面(Plane)と滑り落ちるオブジェクト(Cube)を作成して配置する方法を説明します。


1. Planeを作成する

  1. ヒエラルキー(Hierarchy)ウィンドウで、右クリックします。
  2. メニューから「3D Object」→「Plane」を選択します。
  3. 生成されたPlaneを選択し、インスペクター(Inspector)ウィンドウで以下のように設定します。
    • Position: X: 0, Y: 0, Z: 0
    • Rotation: X: 25(斜めにするため)
    • Scale: X: 2, Y: 1, Z: 2(大きくして滑らせやすくします)

2. Cubeを作成する

  1. 再度ヒエラルキーウィンドウで右クリックします。
  2. 「3D Object」→「Cube」を選択します。
  3. CubeがPlaneの上にあることを確認し、以下のように設定します。
    • Position: X: 0, Y: 1, Z: 0(Planeの上に置くため少し上に配置します)
    • Scale: X: 1, Y: 1, Z: 1(デフォルトのままでOK)

3. RigidbodyをCubeに追加する

Cubeが滑り落ちるようにするためには、Rigidbodyコンポーネントを追加する必要があります。

  1. ヒエラルキーウィンドウでCubeを選択します。
  2. インスペクターウィンドウの「Add Component」ボタンをクリックします。
  3. 「Rigidbody」と入力し、表示された「Rigidbody」を選択して追加します。
  4. Rigidbodyの設定はデフォルトのままで構いませんが、Cubeが滑りやすいように「Use Gravity」がオンになっていることを確認してください。

4. Planeの傾斜を調整する

Planeの傾斜が足りないとCubeが滑り落ちない場合があります。

  • インスペクターでPlaneを選択し、Rotation Xを少し増減させて、適切な傾斜を調整しましょう。(例: 30度に設定)

これで、PlaneとCubeが適切に配置され、Cubeが自然に滑り落ちる準備が整いました!次は、物理マテリアルを適用して滑らせやすくする方法を説明します。



4. 物理マテリアルの作成と適用

では、Unityで物理マテリアルを作成し、それをオブジェクトに適用する方法を説明します。この手順では、CubeがPlaneを滑り落ちる自然な動きを作り出すために、摩擦を調整します。

1. 物理マテリアルを作成する

  1. プロジェクトウィンドウで新しい物理マテリアルを作成します。
    • プロジェクトウィンドウの空白部分を右クリックします。
    • 「Create」→「Physics Material」を選びます。
    • 作成した物理マテリアルにわかりやすい名前を付けます(例: SlideMaterial)。
  2. 物理マテリアルの設定を変更します。
    • 作成したSlideMaterialを選択すると、インスペクターにその設定が表示されます。
    • Dynamic FrictionStatic Frictionを0.1に設定します。
      • Dynamic Frictionは動いている物体の摩擦を調整します。
      • Static Frictionは静止している物体の摩擦を調整します。
    • Friction Combineを「Minimum」に設定します。
      • これは、衝突する2つの物体の摩擦の中で最小値を使用する設定です。

2. CubeとPlaneに物理マテリアルを適用する

  1. Planeに物理マテリアルを適用します。
    • ヒエラルキーウィンドウでPlaneを選択します。
    • インスペクターでMesh Colliderコンポーネントを見つけます。
    • その中の「Material」欄に、作成したSlideMaterialをドラッグ&ドロップします。
  2. Cubeに物理マテリアルを適用します(必要に応じて)。
    • ヒエラルキーウィンドウでCubeを選択します。
    • インスペクターでBox Colliderコンポーネントを見つけます。
    • その中の「Material」欄に、同じくSlideMaterialをドラッグ&ドロップします。

これで、CubeがPlaneを滑り落ちる準備が整いました!次のステップでは、スペースキーで抗力を調整してCubeを停止させるスクリプトを追加していきます。



5. スクリプトの作成

まず、Cubeの動きを制御するためのC#スクリプトを作成します。スクリプトでは、Cubeが斜面を滑り落ちるときに、スペースキーを押すことで抗力を増やし、Cubeを停止させる仕組みを実装します。

スクリプトを作成する方法

  1. プロジェクトウィンドウを開きます
    Unityエディター下部に表示されている「Project」ウィンドウを確認してください。
  2. 新しいスクリプトを作成します
    プロジェクトウィンドウ内で右クリックし、「Create」→「C# Script」を選択します。新しく作成されたスクリプトに「StopCube」と名前を付けましょう。
  3. スクリプトを編集します
    作成したスクリプトをダブルクリックして、スクリプトエディター(通常はVisual Studio)を開きます。以下のコードを入力してください。
using UnityEngine;

public class StopCube : MonoBehaviour
{
    private Rigidbody rb;
    public float dragOnSpace = 20f;
    private float originalDrag;

    void Start()
    {
        rb = GetComponent<Rigidbody>();
        originalDrag = rb.drag;
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            rb.drag = dragOnSpace;
        }
        if (Input.GetKeyUp(KeyCode.Space))
        {
            rb.drag = originalDrag;
        }
    }
}

コードの詳細解説

  1. Startメソッド
    このメソッドはゲーム開始時に一度だけ実行されます。
    • rb = GetComponent<Rigidbody>();
      CubeにアタッチされたRigidbodyを取得します。これで、スクリプト内で物理挙動を操作できるようになります。
    • originalDrag = rb.drag;
      Rigidbodyの元々の抗力(drag)の値を保存しておきます。スペースキーを放したときに、元の値に戻すためです。
  2. Updateメソッド
    このメソッドは毎フレーム実行されます。スペースキーの押下と放す動作を監視し、それに応じて抗力を変更します。
    • Input.GetKeyDown(KeyCode.Space)
      スペースキーが押された瞬間に実行されます。ここでdragを高い値に変更して、Cubeの滑りを止めます。
    • Input.GetKeyUp(KeyCode.Space)
      スペースキーを放した瞬間に実行されます。dragを元の値(originalDrag)に戻して、再び滑りやすくします。

注意点

  • dragOnSpaceの値はインスペクターから調整できます。例えば、20という値はCubeが完全に止まるのに十分ですが、必要に応じて変更してください。
  • RigidbodyがCubeにアタッチされていることを確認してください。これがないと、スクリプトが正しく動作しません。

次は、このスクリプトをCubeにアタッチする方法を説明します!



6. スクリプトのアタッチ

さて、次は作成したスクリプトをオブジェクトにアタッチして、実際に動作するように設定していきます!スクリプトが正しく機能するためには、この手順がとても重要です。


スクリプトをCubeにアタッチする方法

  1. プロジェクトウィンドウでスクリプトを確認する
    • まず、作成したスクリプト「StopCube.cs」がプロジェクトウィンドウに保存されていることを確認します。
    • スクリプトがない場合は、「Assets」フォルダの中に保存されているか再確認しましょう。
  2. スクリプトをCubeにドラッグ&ドロップ
    • プロジェクトウィンドウで「StopCube.cs」を選びます。
    • スクリプトをそのままヒエラルキーウィンドウ内のCubeオブジェクトにドラッグ&ドロップします。
    • Cubeを選択してインスペクターを確認すると、「StopCube」コンポーネントが追加されているはずです。
  3. インスペクターでスクリプトのプロパティを設定
    • Cubeを選択した状態でインスペクターウィンドウを確認します。
    • 「StopCube」コンポーネントが見つかったら、Drag On Spaceプロパティの値を適切な数値に設定します。
      • 例: 20(高めの値でCubeがすぐに停止します)
    • これでスクリプトが正しく機能する準備が整いました!

アタッチ後の確認

スクリプトが正常にアタッチされているか確認するために、以下のポイントをチェックしてください:

  • Cubeのインスペクターに「StopCube」が表示されている。
  • Drag On Spaceの値が設定されている。
  • CubeにRigidbodyコンポーネントが追加されている(これがないと動作しません!)。

注意点

  • スクリプトを複数のオブジェクトにアタッチしたい場合は、同じ手順で他のオブジェクトにもドラッグ&ドロップしてください。
  • アタッチに問題がある場合は、プロジェクトウィンドウやヒエラルキーウィンドウでスクリプトやオブジェクトが正しく選択されているか確認しましょう。

これでスクリプトのアタッチは完了です!次は実際にプレイモードで動作を確認してみましょう。Spaceキーを押して、Cubeが止まる動きをチェックしてみてください!



7. 実行と確認

さて、ここまで準備が整ったら、いよいよ作った仕組みが正しく動作するか確認してみましょう!以下の手順でテストを行います。


1. プレイモードを開始

Unityエディターの上部にある「Play」ボタンをクリックして、プレイモードを開始します。


2. Cubeが斜面を滑り落ちるか確認

  • プレイモードが開始すると、CubeがPlaneの斜面を滑り落ちる様子が見られるはずです。
  • 滑りが確認できない場合は、以下をチェックしてください:
    • Planeの角度が十分傾いているか:Planeを選択し、「Transform」コンポーネントのRotationを調整してください(例:X軸を30度に設定)。
    • CubeにRigidbodyコンポーネントが設定されているか:Cubeを選択し、Inspectorウィンドウに「Rigidbody」が表示されていることを確認してください。
    • Physics Materialが正しく適用されているか:CubeとPlaneのColliderに物理マテリアルが設定されていることを確認してください。

3. スペースキーを押してCubeを停止

  • キーボードのスペースキーを押すと、Cubeが滑るのをピタッと止めるはずです。
  • 抗力が強くなることで、物理エンジンが動きを制御します。この挙動が確認できたら成功です!

4. スペースキーを離すと滑り再開

  • スペースキーを離すと、Cubeが再び滑り始めるのがわかります。
  • これは、スクリプト内で元の抗力値(drag)が復元されているためです。

5. 問題があれば確認

もし動作に問題があれば、以下を再度確認してください:

  • スクリプトのエラー:スクリプトにエラーが出ていないか確認します。エディター下部の「Console」ウィンドウをチェックしてみてください。
  • 入力設定:スペースキーが正しく認識されていない場合があります。設定を確認するか、別のキー(例:Eキー)で試してみてください。

すべて正しく動作していれば、Cubeが滑り落ち、スペースキーで停止するシステムの完成です!おめでとうございます!

これで基本的な動作は完成しました。次は、応用アイデアを試してさらに楽しい仕組みを作ってみましょう!



8. 応用アイデア

今回のプロジェクトでは、スペースキーを押してCubeの抗力を一時的に高め、滑りを止める仕組みを作成しました。ここでは、この基本的な仕組みを応用して、さらに面白い挙動を追加する方法を紹介します。

1. 抗力の値を徐々に変化させる

スペースキーを押した瞬間に抗力が一気に上がるのではなく、時間をかけて徐々に抗力を増加させる方法です。これにより、より自然な動きが表現できます。

以下のコードを例にしてみましょう:

void Update()
{
if (Input.GetKey(KeyCode.Space))
{
rb.drag = Mathf.Lerp(rb.drag, dragOnSpace, Time.deltaTime * 5f);
}
else
{
rb.drag = Mathf.Lerp(rb.drag, originalDrag, Time.deltaTime * 5f);
}
}

Mathf.Lerpを使用することで、現在の抗力から目標の抗力値へスムーズに移行します。Time.deltaTimeを掛けることでフレームレートに依存しない動作になります。

2. 抗力の調整を別のキーに割り当てる

スペースキー以外のキーで異なる挙動を追加することも可能です。たとえば、Shiftキーを押すと抗力が逆に減少し、Cubeがより速く滑るようにする方法を見てみましょう:

void Update()
{
if (Input.GetKey(KeyCode.Space))
{
rb.drag = Mathf.Lerp(rb.drag, dragOnSpace, Time.deltaTime * 5f);
}
else if (Input.GetKey(KeyCode.LeftShift))
{
rb.drag = Mathf.Lerp(rb.drag, 0, Time.deltaTime * 5f); // 抗力を減少
}
else
{
rb.drag = Mathf.Lerp(rb.drag, originalDrag, Time.deltaTime * 5f);
}
}

Shiftキーを押すと、抗力が0に近づき、Cubeが滑りやすくなる様子を確認できます。

3. カスタム物理マテリアルの導入

現在のPhysics Materialはシンプルな設定ですが、カスタムPhysics Materialを使用することで、より細かい動きをコントロールできます。たとえば、以下のようなカスタマイズが可能です:

  • Dynamic Friction: Cubeが移動しているときの摩擦力
  • Static Friction: Cubeが静止しているときの摩擦力
  • Friction Combine: 摩擦の組み合わせ方法(最低値、平均値、最大値など)

カスタムPhysics Materialを適用して、Cubeが特定の条件下で異なる挙動を示すように設定してみてください。

4. Cubeの移動を記録してリプレイ機能を追加

Cubeが滑る軌跡を記録し、リプレイ機能を実装することで、より高度なゲームシステムを作成することもできます。記録は、Cubeの位置を毎フレーム保存することで行えます。

以下は位置記録の簡単な例です:

private List<Vector3> positions = new List<Vector3>();

void FixedUpdate()
{
positions.Add(transform.position);
}

後で、このリストの位置を順番に適用することで、リプレイが可能になります。


このように、基本的な仕組みを活用しながら新しいアイデアを試すことで、よりダイナミックで面白いゲーム挙動を作り出すことができます。ぜひ挑戦してみてください!



よくある質問

Q
Rigidbodyを追加するときにどの設定が必要ですか?
A

基本的にはデフォルト設定で問題ありませんが、「Use Gravity」をオンにしておくと自然に滑り落ちる挙動になります。

Q
物理マテリアルの「Friction」と「Bounciness」はどう設定すれば良いですか?
A

滑りやすくする場合は「Friction」を0に設定します。「Bounciness」は跳ね返りの強さを調整するため、今回は不要です。

Q
スクリプトがうまく動作しない場合の原因は何ですか?
A

主な原因としては、Rigidbodyが正しく設定されていない、スクリプトがCubeにアタッチされていない、または入力キーが設定通りでないことが考えられます。

おすすめのアセット

スノーボードゲームスターターパックは、Unityでスノーボードゲームを簡単に作成できるテンプレートです。このパックには、滑らかなキャラクターコントロール、リアルな物理挙動、シンプルなUI、スコアシステムなど、必要な機能が揃っています。ゲーム開発の基礎を学びながら、オリジナルのスノーボードゲームを作ってみましょう。