今回は3Dのオブジェクトどうしのぶつけ方について解説していきます。そもそも、何も設定していない3Dオブジェクトはぶつけることすらできません。物理制御の対象にして、ぶつかったときのふるまいなどをコンポーネントに追加、設定していきます。
こちらの記事で画面上に表示したそろばん珠を使って、それが動いた時にぶつかって止まるという動作を確認していきます。
ぶつける壁を準備する
そろばん珠をぶつける壁を準備します。ヒエラルキーから右クリックでCubeを追加していきます。
サイズが小さいので、InspectorのScaleで大きくしておきます。また、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 PositionとFreeze Rotationの全てにチェックを入れます。これで全方向に動かなくなります。
上下のみに動きを制約
そろばん珠は左右に動くことはないので、動きを上下だけに制約したいです。このような時も同様にRigibody>ConstraintsにあるFreeze PositionとFreeze Rotationに以下の通りチェックを入れます。
衝突を確認する
期待通りの動作になっていることを確認します。
きっちり衝突して止まってくれました。
まとめ
3Dオブジェクトの基本的な動かす>衝突させる>止めるというという動作をUnityで実装して正しく動くことが確認できました。これを組み合わせていけば、そろばんまでたどりつけそうな気がしてきました。
注意点としてはオブジェクトのBox Colliderを薄くしすぎないという点があります。物理エンジンはフレーム毎に演算していますが、演算のタイミングで衝突の判定ができなかった時、すり抜けていってしまいます。
コメント