[Unity][3D物理演算]オブジェクト同士のぶつけ方を解説

Unity
https://amzn.to/3bd8XOX

 今回は3Dのオブジェクトどうしのぶつけ方について解説していきます。そもそも、何も設定していない3Dオブジェクトはぶつけることすらできません。物理制御の対象にして、ぶつかったときのふるまいなどをコンポーネントに追加、設定していきます。

 こちらの記事で画面上に表示したそろばん珠を使って、それが動いた時にぶつかって止まるという動作を確認していきます。

Goal

オブジェクトを飛ばす、ぶつける、止まること!




ぶつける壁を準備する

 そろばん珠をぶつける壁を準備します。ヒエラルキーから右クリックでCubeを追加していきます。

 サイズが小さいので、InspectorScaleで大きくしておきます。また、Y方向にそろばん珠を飛ばしてぶつけてみたいので、Z.X座標を等しくし、Y座標を大きくすることで、上に配置しておきます。このようにCubeの真下にそろばん珠が配置されていればOKです。

 RigibodyとBox Colliderコンポーネントの追加

 物理演算の対象とするために、そろばん珠と先ほど追加したCubeの両方にRigibodyコンポーネントBox Colliderコンポーネントを追加します。追加はそれぞれオブジェクトを選択した状態で右のInspectorからAdd Component>Rigibodyで追加します。

 この二つのコンポーネントをもった3Dオブジェクトどうしがぶつかった時、物理演算による衝突が発生します。今、アプリを実行するとどうなるか、動かしてみます。

 徐々に落下してしまします。これは重力が有効になっているためです。Rigibodyの設定からUse Gravityのチェックを外して実行すると、落下しなくなりますので、チェックしておきましょう。

3Dオブジェクトを動かす

 ある一定の速度で3Dオブジェクトを動かしてみます。アプリ開始と同時に下側にあるそろばん珠を上にある壁に向かって飛ばしてみます。意図的にオブジェクトを動かしたり止めたり、衝突時の処理などオブジェクト固有の動作をさせたい時はScriptに記述します。そろばん珠のコンポーネントにScriptを追加して、エディタで以下のコードを入力します。(スクリプト名とclass名は等しくしてください)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SorobanScr : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        // forceは力を加える方向と力量
        // Y軸方向に動かしたいので、Y成分のみ値をいれて、その他は0にする
        Vector3 force = new Vector3(0.0f, 500f, 0.0f);

        // AddForceにforceを指定して力を加える
        // ForceMode.VelocityChangeは物体の重さを無視して、瞬間的に力を加える
        // パラメータ
        this.GetComponent<Rigidbody>().AddForce(
            force,
            ForceMode.VelocityChange);
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

 実行した結果は以下のようになります。衝突したらそのまま押しあがっていってしましました。

Rigibodyで動きに制約を加える

 上のブロックは衝突しても動いてほしくないです。また、そろばん珠は上下のみの動作で、ブロックに衝突したらぴたりととまってほしいです。そうなるようにRigibodyのパラメータを設定していきます。

衝突しても動かさない

 上のブロックが衝突されても動かないようにするにはRigibody>ConstraintsにあるFreeze PositionFreeze Rotationの全てにチェックを入れます。これで全方向に動かなくなります。

上下のみに動きを制約

  そろばん珠は左右に動くことはないので、動きを上下だけに制約したいです。このような時も同様にRigibody>ConstraintsにあるFreeze PositionとFreeze Rotationに以下の通りチェックを入れます。

衝突を確認する

 期待通りの動作になっていることを確認します。

 きっちり衝突して止まってくれました。

まとめ

 3Dオブジェクトの基本的な動かす>衝突させる>止めるというという動作をUnityで実装して正しく動くことが確認できました。これを組み合わせていけば、そろばんまでたどりつけそうな気がしてきました。
 注意点としてはオブジェクトのBox Colliderを薄くしすぎないという点があります。物理エンジンはフレーム毎に演算していますが、演算のタイミングで衝突の判定ができなかった時、すり抜けていってしまいます

https://amzn.to/3bd8XOX

コメント