今回はrigidbodyを使用した場合の移動や、力の加え方について見ていきましょう。
(rigidbodyがわからない人は、ぜひ下の記事で学んでみてください。自信のない人も復習しておきましょう!)
物理演算は、重力や摩擦などが関わってくるため、単なる移動も一苦労です。
しっかり理解した上で行わないと、不自然な動きをしてしまいます。
正しく理解し、自然な物理演算を行いましょう。
今回は、基本を学んだ後に上記のような、具体的な動きの実装方法を一緒に見ていきましょう。
ボールを蹴った時のような移動
座標の上書きによる瞬間的な移動
速度を書き換える移動
それではよろしくお願いいたします。
rigidbodyの移動の基本
Unityでオブジェクトを移動させる場合「transform.position」を書き換えたり「transform.Translate関数」を利用して移動させていると思います。
Transformを利用した座標操作ですね。
(もしTransformの復習をしたい場合は、こちらの記事をご覧ください)
しかしrigidbodyをつけているオブジェクトの場合、Transformを利用した移動は基本してはいけません。
物理演算が反映されないからです。
では一体どうやって移動させるのでしょうか?
答えは簡単で「Transform」ではなく「rigidbody」の関係の関数を利用するんです。
それでは移動関係の関数を順に見ていきましょう。
AddForceを使った移動
まずはAddForce関数を使った移動です。
AddForce関数を利用した移動が、rigidbodyを使用しているオブジェクトの主な移動方法となります。
AddForceの特徴
AddForceを和訳すると「力を加える」となります。
名前の通り、オブジェクトに物理的な力を加え移動させる関数なんです。
言葉よりも見た方がわかりやすいでしょうし、実際に見て学んでみましょう。
実際に動かしてみよう!
では早速実際にAddForce関数を利用して動かしてみましょう!
プログラムは以下の通りです。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class MyObject : MonoBehaviour { void FixedUpdate () { Rigidbody rb = this.GetComponent<Rigidbody> (); // rigidbodyを取得 Vector3 force = new Vector3 (0.0f,0.0f,1.0f); // 力を設定 rb.AddForce (force); // 力を加える } }
結果は以下の通りです。
ちゃんと地面を転がっていますね!
力を与え続けているので加速していることがわかると思います。
物理演算している感じのする、良い感じの移動です。
いろいろな動きをAddForceで実現してみよう
また第二引数にForceModeパラメータを送ることで、いろいろな動きを再現できます。
rb.AddForce (force, ForceMode.Force);
引数の与え方はこんな感じです。
ではこれを使ってできる、動きを見ていきましょう。
車がだんだん加速していくような移動
こちらは「車の加速」など断続的に力を加える場合に使います。
実はデフォルト値なので、第二引数に何も与えないとこの挙動になります。
つまり先ほど見た動きをすることになります。
試しに第二引数に「ForceMode.Force」を加えて見ましょう。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class MyObject : MonoBehaviour { void FixedUpdate () { Rigidbody rb = this.GetComponent<Rigidbody> (); // rigidbodyを取得 Vector3 force = new Vector3 (0.0f,0.0f,0.5f); // 力を設定 rb.AddForce (force, ForceMode.Force); // 力を加える } }
結果は以下となります。
結果も先ほどと全く同じで、徐々に加速する動きですね!
ボールを蹴った時のような移動
次は第二引数へ「Impulse」を与えるとボールを蹴った時のような挙動を実現できます。
「Force」が断続的な力の加え方をするのに対し、「Impulse」は一瞬で力を与える時に使うわけです。
また力は一瞬で加える必要があるため、最初の一度しか呼ばれないようにしましょう。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class MyObject : MonoBehaviour { bool isFirst = true; // 最初の一回を判定するフラグ void FixedUpdate () { // 一回だけ呼ばれる if (isFirst) { isFirst = false; // 一回はすぎた Rigidbody rb = this.GetComponent<Rigidbody> (); // rigidbodyを取得 Vector3 force = new Vector3 (0.0f, 8.0f, 1.0f); // 力を設定 rb.AddForce (force, ForceMode.Impulse); // 力を加える } } }
挙動としては以下のようになります。
一瞬で力が加わり跳ねていますね!
良い感じです。
よく使う引数なのでしっかり覚えておきましょう!
座標の上書きによる瞬間的な移動
次は座標の上書きによる瞬間的な移動について見ていきましょう。
具体的には「rigidbody.position」を直接書き換える移動方法です。
これは「transform.position」と同じで、座標を直接操作する移動方法です。
つまり当たり判定や物理演算を無視した、強制的な座標変更となります。
主に移動というよりも、座標の初期値設定、強制的な場所移動などに使えるでしょう。
実際に動かしてみよう!
今回使うプログラムは以下の通りです。
rigidbody.positionから値を取得し、加算して、代入上書きを行っています。
void FixedUpdate () { Rigidbody rb = this.GetComponent<Rigidbody> (); // rigidbodyを取得 Vector3 now = rb.position; // 座標を取得 now += new Vector3 (0.0f,0.0f,0.05f); // 前に少しずつ移動するように加算 rb.position = now; // 値を設定 }
結果を見てみましょう。
地面を移動していますがボールが回転しないなど、自然な物理演算が行われていませんね。
これは座標の上書きのみが行われ続けているからです。
速度を書き換える移動
最後に速度の操作方法を見てみましょう。
「rigidbody.velocity」を使うと速度ベクトル(どの方向へどのぐらいの速度が出ているか)の保持・取得が可能です。
ただ、velocityを直接編集することは基本は推奨されていません。
なぜなら力や質量などを計算に入れずに、突然速度が変化したら物理演算として不自然な挙動をしてしまうからです。
とはいえ、特定条件下での使い道は多い関数ですので、以下のリンク先へ切り分けて説明しています。
きになる人はぜひ読んでおいてください。
まとめ
いかがでしたでしょうか。
この辺りが物理演算を使った基本的な動きとなります。
とはいえ、これ以外にも力の加え方は多数存在します。
実現したいことが増えてきたら、また新しく学んでみましょう。