【Unity 初心者向け】オブジェクトの移動⑤ | Rigidbodyに力を加えて動かす ― AddForce編
これまで、Unityでオブジェクトを動かす方法をいくつか確認してきました。
前回は、Rigidbody2D の linearVelocity を使って、オブジェクトの速度を直接変更する方法を確認しました。
今回は、速度を直接決めるのではなく、オブジェクトに力を加えて動かす方法を確認します。
使用するのは、Rigidbody2D の AddForce です。
rb.AddForce(Vector2.right * power);AddForce を使うと、
オブジェクトを押す
ジャンプさせる
爆発で吹き飛ばす
ノックバックさせる
といった、物理演算らしい動きを作ることができます。
そして今回は、この「オブジェクトの移動」シリーズの最終回です。
最後には、これまで学習した移動方法を比較しながら、どの移動方法を使えばいいのか?についても整理していきます。
1.AddForceとは
1-1.AddForceの使用例
AddForce は、Rigidbody に力を加えるための命令です。
2Dの場合は、Rigidbody2D に対して使用します。
例えば、次のコードを見てみましょう。
rb.AddForce(Vector2.right * power);このコードでは、オブジェクトに右方向の力を加えています。
それぞれの部分を確認してみましょう。
rb は、操作する Rigidbody2D 型の変数です。
rbAddForce() が、Rigidbody2Dに力を加える命令です。
AddForce()Vector2.right は右方向を表します。
Vector2.rightそして、power が加える力の大きさです。
Vector2.right * powerつまり、「rb に対して、右方向へ power 分の力を加える」という意味になります。

1-2.linearVelocityとの違い
前回使用した linearVelocity と、今回の AddForce は、どちらも Rigidbody2D を動かすことができます。
ただし、考え方が大きく異なります。
前回の linearVelocity では、例えば次のように書きました。
rb.linearVelocity = new Vector2(
5f,
rb.linearVelocity.y
);これは「横方向の速度を5にする」という命令です。
つまり、速度そのものを直接指定しています。
一方、今回の AddForce は、
rb.AddForce(Vector2.right * power);のように書きます。
こちらは「右方向へ力を加える」という命令です。
速度を直接指定しているわけではありません。
力を加えた結果として、オブジェクトの速度が変化します。

2.AddForceを使って動かしてみよう
2-1.スクリプトファイルを作成
実際に、オブジェクトへ右方向の力を加えてみましょう。
スクリプトファイル:AddForceMove を作って、次のコードを入力します。
public class AddForceMove : MonoBehaviour
{
public Rigidbody2D rb; // Rigidbody2Dコンポーネントへの参照
public float power = 5f; // 力の大きさ
void FixedUpdate()
{
// 水平方向の入力を取得
rb.AddForce(Vector2.right * power);
}
}このスクリプトでは、
rb.AddForce(Vector2.right * power);を繰り返し実行しています。
そのため、オブジェクトには右方向の力が加わり続けます。

変数:rb にRigidbody2Dコンポーネントをセットして実行すると、最初はゆっくり動き始め、その後だんだん速度が上がっていきます。
ここが、linearVelocity との大きな違いです。
AddForce は、移動速度を設定しているのではなく、力を加えているという点を覚えておきましょう。
2-2.なぜFixedUpdateを使うの?
今回のコードでは、
void FixedUpdate()
{
rb.AddForce(Vector2.right * power);
}としています。
これまでよく使ってきた Update ではなく、FixedUpdate を使っています。
FixedUpdate は、Rigidbody などの物理演算を扱う処理でよく使用する関数です。
Update は画面の描画に合わせて実行されるため、実行回数がフレームレート(1フレームにかかる時間)によって変わります。
一方、FixedUpdate は一定の間隔で実行されます。
そのため、Rigidbody へ継続的に力を加えるような処理では、
FixedUpdate()を使うと扱いやすくなります。
今回のように、毎回Rigidbodyへ力を加える処理は FixedUpdate に書いておくとよいでしょう。
2-3.力を加え続けると速度が変わる
FixedUpdate の中で、
rb.AddForce(Vector2.right * power);を実行すると、一定間隔で力が加わり続けます。
処理のイメージは次のようになります。
右方向へ力を加える
↓
少し速度が上がる
↓
また右方向へ力を加える
↓
さらに速度が上がる
↓
また力を加える
↓
さらに速度が変化するこのように、AddForce は力を加えるたびにRigidbodyの速度へ影響を与えます。
例えば車のアクセルを想像すると分かりやすいでしょう。
アクセルを踏んだからといって、いきなり最高速度になるわけではありません。
力が加わることで、少しずつ速度が変化します。
AddForce も、それに近い考え方です。

2-4.Massによって動き方が変わる
Rigidbody2Dには、Mass という項目があります。
Mass はオブジェクトの質量を表します。
同じ AddForce を使っていても、Mass の値によって動き方が変わります。
例えば、
rb.AddForce(Vector2.right * power);という同じ力を加えた場合でも、Mass が小さいオブジェクトは動きやすくなります。
一方、Mass が大きいオブジェクトは動きにくくなります。
つまり、同じ力なら、軽い物体ほど速度が変化しやすく、重い物体ほど速度が変化しにくいということです。
これは現実世界でも同じです。
軽いボールと重い箱を同じ力で押した場合、軽いボールのほうが簡単に動きます。
AddForce を使うと、こうした Rigidbody の物理設定も動きに影響します。

3.FoeceMode について
AddForce では、力の加え方を指定することもできます。
そのときに使用するのが、
ForceMode2Dです。
例えば、次のように書くことができます。
rb.AddForce(
Vector2.right * power,
ForceMode2D.Force
);AddForce の2つ目の引数として、
ForceMode2D.Forceを指定しています。
2Dでよく使うのは、次の2つです。
ForceMode2D.Force
ForceMode2D.Impulse
ForceMode2D.Impulseです。
この2つは、力の加え方が異なります。
3-1.Force ― 力を加え続ける
まずは、
ForceMode2D.ForceForce は、継続的に力を加えるような動きに向いています。
イメージとしては、「物体をグーッと押し続ける」という感じです。
例えば、
車を加速させる
宇宙船を推進させる
風で物体を押す
キャラクターを徐々に加速させる
といった動きに使えます。
なお、
rb.AddForce(Vector2.right * power);のように、2つ目の ForceMode2D を省略した場合も、通常は Force として力が加えられます。
そのため、最初に使った、
rb.AddForce(Vector2.right * power);も Force を使用していると考えてよいでしょう。
3-2.Impulse ― 一瞬だけ強い力を加える
次は、
ForceMode2D.ImpulseImpulse は、力を一瞬だけ加えたいときに使います。
イメージとしては「ドンッ!」と一度だけ強く押すような感じです。
例えば、
ジャンプする
ボールを蹴る
爆発で吹き飛ばす
敵から攻撃を受けてノックバックする
といった動きに向いています。

3-3.AddForceでジャンプさせてみよう
Impulse の分かりやすい使用例が、ジャンプです。
次のスクリプトを作成してみましょう。
using UnityEngine;
public class Jump : MonoBehaviour
{
public Rigidbody2D rb;
public float jumpPower = 5f;
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
rb.AddForce(
Vector2.up * jumpPower,
ForceMode2D.Impulse
);
}
}
}
スペースキーを押したときに、
rb.AddForce(
Vector2.up * jumpPower,
ForceMode2D.Impulse
);を実行しています。まず、
Vector2.upは上方向を表します。
そのため、
Vector2.up * jumpPowerで、上方向へ加える力の大きさを作っています。
さらに、2つ目の引数として、
ForceMode2D.ImpulseImpulse はオブジェクトへ瞬間的な衝撃を与えるような力の加え方です。
ジャンプでは、上方向へ長時間力を加え続けるというよりも、キーを押した瞬間に「ポンッ」と上方向へ勢いを与える、という動きにしたいため、Impulse が分かりやすい使い方になります。
ここで、「Input.GetKeyDown() はキーを押した瞬間に1回だけ実行されるのだから、Force を使っても同じなのでは?」と思うかもしれません。
しかし、
何回AddForceを呼び出すか?と、その1回の力をどのように物理演算へ反映するか?は別の話です。
例えば、
rb.AddForce(
Vector2.up * jumpPower,
ForceMode2D.Force
);とした場合も、GetKeyDown() を使っていれば AddForce 自体は1回しか実行されません。
ただし Force は、継続的に力を加える用途に向いたモードで、1回だけ実行した場合は「一瞬だけ少し押す」ような力になります。
一方、
rb.AddForce(
Vector2.up * jumpPower,
ForceMode2D.Impulse
);では、その1回の呼び出しで「一瞬にまとまった力を与える」ような動きになります。
ジャンプのように、
キーを押した瞬間に
上方向へ
はっきりとした勢いを与えたい
という処理では、ForceMode2D.Impulse が扱いやすいでしょう。
jumpPower の値が同じ場合、Force と Impulse では動き方が同じにはなりません。

4.どの移動方法を使えばいい?
ここまでの「Unity オブジェクトの移動」シリーズでは、いくつかの移動方法を確認してきました。
最後に、それぞれの違いを整理してみましょう。
transform.position
transform.position += new Vector3(
speed * Time.deltaTime,
0,
0
);transform.position は、オブジェクトの座標そのものを変更する方法です。Unityでオブジェクトが動く基本であり、「位置が変わるとオブジェクトが動く」という考え方を理解するのに適しています。
単純な移動や、指定した場所へ移動させたい場合にも使いやすい方法です。
Transform.Translate
transform.Translate(
Vector3.right * speed * Time.deltaTime
);Translate は「現在位置から、この方向へ移動する」という書き方がしやすい方法です。
右へ進む、前へ進む、といった方向を意識した移動をシンプルに書くことができます。
linearVelocity
rb.linearVelocity = new Vector2(
speed,
rb.linearVelocity.y
);linearVelocity は、Rigidbody2D の速度を直接変更します。
そのため「この速度で動いてほしい」という場合に使いやすい方法です。
一定速度で移動するキャラクターなどにも向いています。
AddForce
rb.AddForce(
Vector2.right * power
);AddForce は、Rigidbody2Dへ力を加えます。
速度を直接決めるのではなく、力を加えた結果として速度が変化します。
そのため、
加速
ジャンプ
ノックバック
吹き飛ばし
など、物理演算を活かした動きを作りやすい方法です。

ここまでいくつかの移動方法を学習してきましたが「どの方法が一番優れている」というわけではありません。
例えば、キャラクターを一定速度で左右へ動かしたいのであれば、linearVelocity が扱いやすいことがあります。
ジャンプさせたいのであれば、
AddForceと、
ForceMode2D.Impulseの組み合わせが使いやすいでしょう。
また、物理演算が必要ない単純なオブジェクト移動なら、
transform.positionや、
Transform.Translateのほうがシンプルに作れる場合もあります。
大切なのは「どんな動きを作りたいのか」を考えて、その目的に合った方法を選ぶことです。
Unityでは、同じように見える動きでも、実装方法はいくつもあります。
ゲームを作りながら「今回はどの方法が使いやすいかな?」と考えられるようになると、プログラムの組み立て方も少しずつ分かってきます。
5.今回のまとめ
今回は、Rigidbody2Dに力を加えてオブジェクトを動かす AddForce について確認しました。

こちらはUnity初心者向けの記事をテーマ別にまとめています。
▼ Unity初心者向け記事まとめはこちら
こちらのマガジン「ミニゲーム作成講座 全8回セット」でもシーンの切り替えなどを活用して、初心者でも知識ゼロから作れるミニゲーム作成講座を紹介しています。

さらにステップアップの「スマホで遊ぶジャンプゲーム 8回セット」のマガジンもぜひご活用ください。

ファイブボックスでは、スクラッチやUnityの個別指導のオンラインレッスンを行っています。
ご興味のある方は当サイト、オンラインレッスンから、無料体験授業へお問い合わせ下さい。
いいなと思ったら応援しよう!
よろしければ応援お願いします! いただいたチップはクリエイターとしての活動費に使わせていただきます!