【Unity】AddForceメソッドとは?オブジェクトに力を加える処理

AddForceの使い方 Unity

こんにちは、ともくんのゲーム作り部屋にようこそ!

このページでは、

「UnityのAddForceメソッドってなに?」

「AddForceメソッドはどうやって使うの?」

というお悩みの方に向けた内容となっています。

UnityでRigidbodyを付けたオブジェクトを動かす際に使用するのが、AddForceというメソッドです。

AddForceメソッドは、オブジェクトに力を与えて動かすことができるメソッドで、Rigidbodyコンポーネントに定義されています。

このAddForceメソッドを使うことで、キャラクターを移動させたりジャンプさせたりなどの動きを行うことができます。

そこで、このページでは、UnityのAddForceメソッドについて、どんな特徴や仕様があるのか、また使い方までをまとめていきます。

この記事を書いた人

ゲーム作りを学び始めた一児のパパです。
このブログは、子供から「ゲームを作ってみたい!」と言われ、非プログラマーでゲーム作りをしたことない僕が、ゲーム作りの本を読んで独学でゲーム開発を学んでいるブログです。
同じように初めてゲーム作りをしている方と一緒に学んでいけるようなブログに出来たらいいなと思っています。
また、「このコードはおかしい」とか「もっと良い書き方があるよ!」などあれば、どんどん指摘して頂けると助かります。

AddForceとは?

まずは、AddForceがどういうメソッドなのかを紹介していきます。

オブジェクトに力を加えて動かすメソッド

AddForceメソッドとは、オブジェクトに対して力を加えてあげることができるメソッドです。

例えば、四角い箱がある場合に、後ろから手で押してあげることで、箱は押された方に動きます。

これと同じで、UnityではオブジェクトにAddForceメソッドを使うことで、オブジェクトに対して力が加わり、そのオブジェクトを動かすことができます。

そのため、このAddForceを使うことで、キャラクターの移動やジャンプなどオブジェクトを動かすことができます。

Rigidbodyコンポーネントに定義されている

AddForceメソッドは、Rigidbodyコンポーネントで定義されているメソッドです。

このRigidbodyコンポーネントは、オブジェクトに物理演算機能を持たせる機能で、重力や浮力などの様々な力を計算してくれます。

そして、Rigidbodyを付けたオブジェクトは、実際の世界と同じで、力を加えない限り動くことはありません。

この力を加えるのが、AddForceメソッドということになります。

なお、同じようにオブジェクトを動かすのに、UnityではTransformコンポーネントのTranslateメソッドも使われることがありますが、Rigidbodyを付けたオブジェクトにこのTranslateを使ってしまうと、物理演算を無視して動くことになるため、注意しておきましょう。

AddForceメソッドの使い方

ここからは、オブジェクトにAddForceメソッドを使って力を加える方法について紹介していきます。

AddForceメソッドは、Rigidbodyコンポーネントで定義されているので、Rigidbodyを取得してから使用する必要があります。

オブジェクトにRigidbodyを付ける

まずは、オブジェクトを選択してインスペクターウィンドウの「AddComponent」をクリックします。

そして、

  • 3Dゲームの場合は「Physics」「Rigidbody」
  • 2Dゲームの場合は「Physics2D」「Rigidbody2D」

を選択します。

なお、Rigidbodyを付けるとデフォルトで重力がかかることになるため、オブジェクトが落ちないようにコライダーを付けて床を配置しておきましょう。

Rigidbodyコンポーネントを取得する

次に、オブジェクトにアタッチしたスクリプトから、Rigidbodyコンポーネントを取得します。

コンポーネントを取得する場合は、GetComponentメソッドを使います。

using UnityEngine;

public class Test : MonoBehaviour
{
    Rigidbody2D rb; // Rigidbody型の変数

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();   // Rigidbodyを取得
    }
}

5行目でRigidbody型の変数を作り、9行目のStartメソッドの中でGetComponentを使って、Rigidbodyを取得して、その変数の中に入れてあげます。

変数の型やGetComponentで指定する際は、

  • 3Dゲーム ⇒ Rigidbody
  • 2Dゲーム ⇒ Rigidbody2D

と、それぞれ指定してあげます。

これで、AddForceメソッドを使う準備ができました。

AddForceメソッドを使う

AddForceメソッドを使う場合は、

Rigidbody.AddForce(加える力, フォースモード);

と、記述して使います。

第一引数:加える力をVector型で指定する

第一引数に、加える力の大きさと方向であるベクトルをVector型で指定します。

例えば、2Dゲームでのオブジェクトを動かす際に、オブジェクトに対して右の方向に力を加えたい場合、

using UnityEngine;

public class Test : MonoBehaviour
{
    Rigidbody2D rb; // Rigidbody型の変数
    Vector2 force = new Vector2(5, 0);    // 与える力のベクトル

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();   // Rigidbodyを取得
    }

    void FixedUpdate()
    {
        rb.AddForce(force); // 指定した力を与える
    }
}

のように、15行目でAddForceメソッドの引数にVector型で指定してあげることで、オブジェクトにその力が加わります。

また、オブジェクトの向きは、

と書くことで、TransformコンポーネントからVector型で取得することができます。

これを活用して、例えばジャンプのように上向きに力を加えたい場合、transform.upと力を掛け合わせて、

using UnityEngine;

public class Test : MonoBehaviour
{
    Rigidbody2D rb; // Rigidbody型の変数
    int force = 300;    // 与える力の大きさ

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();   // Rigidbodyを取得
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            rb.AddForce(transform.up * force); // 指定した力を与える
        }
    }
}

と17行目のように書いてあげることで、オブジェクトに対して上向きに力を加えることができます。

第二引数:フォースモードを指定する

第二引数にForceModeとして、力をどのように加えるかを指定することができます。

このForceModeには、

  • Force
  • Acceleration
  • Impulse
  • VelocityChange

の4つがありますが、2Dはこの中の「Force」「Impulse」だけになります。

また、ForceModeを第二引数に指定する場合は、

  • 2Dゲーム ⇒ ForceMode2D.
  • 3Dゲーム ⇒ ForceMode.〇〇

と、記述することになります。

なお、第二引数を省略した場合は「Force」と同じになります。

Force

Forceは、継続的に力を加えるモードで、そのオブジェクトは徐々に加速するような形になります。

また、オブジェクトの質量であるMassの数値が考慮されて、そのオブジェクトが動くことになります。

例えば、四角形のオブジェクトを2つ作り、赤色のMassの値を「1」、青色のMassの値を「2」として、モードを「Force」にして同じ力を与え続けた場合、

using UnityEngine;

public class Test : MonoBehaviour
{
    Rigidbody rb;   // Rigidbody型の変数
    int force = 10;    // 与える力の大きさ

    void Start()
    {
        rb = GetComponent<Rigidbody>(); // Rigidbodyコンポーネントを取得
    }

    void FixedUpdate()
    {
        rb.AddForce(transform.right * force, ForceMode.Force); // 指定した力を与える
    }
}

どちらも加速を続けていますが、質量の軽い赤色のオブジェクトの方が早く動いています。

Acceleration

Accelerationも、Forceと同じく継続的に力を加えていきますが、オブジェクトの質量の数値を考慮しないモードになっています。

そのため、異なる質量同士のものを同じように移動する場合に使われます。

例えば、先ほどの例で使ったオブジェクトに対して、モードを「Acceleration」にして力を与えた場合、

using UnityEngine;

public class Test : MonoBehaviour
{
    Rigidbody rb;   // Rigidbody型の変数
    int force = 800;    // 与える力の大きさ

    void Start()
    {
        rb = GetComponent<Rigidbody>(); // Rigidbodyコンポーネントを取得
    }

    void FixedUpdate()
    {
        rb.AddForce(transform.right * force, ForceMode.Acceleration); // 指定した力を与える
    }
}

質量に関係なく、どちらも同じ動きをしているのが分かります。

Impulse

Impulseは、力を一瞬で加えるモードで、指定した力を1秒間与えた際の力を一瞬で加えます。

また、オブジェクトの質量のMassの値が考慮されて、動きが変わります。

先ほどの例と同じようなスクリプトで、スペースキーを押したら「Impulseで一度だけ力を加えるとした場合、

using UnityEngine;

public class Test : MonoBehaviour
{
    Rigidbody rb;   // Rigidbody型の変数
    int force = 800;    // 与える力の大きさ

    void Start()
    {
        rb = GetComponent<Rigidbody>(); // Rigidbodyコンポーネントを取得
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            rb.AddForce(transform.right * force, ForceMode.Impulse); // 指定した力を与える
        }
    }
}

スペースキーを押すとオブジェクトに最初大きな力が動きますが、その後は力が加わりません。

また、質量の軽い赤いオブジェクトの方がより早く動くことになります。

VelocityChange

VelocityChangeは、Impulseと同様に力を一瞬加えますが、オブジェクトの質量の数値を考慮しないモードになっています。

こちらも先ほどと同じ例で使ってみると、

using UnityEngine;

public class Test : MonoBehaviour
{
    Rigidbody rb;   // Rigidbody型の変数
    int force = 800;    // 与える力の大きさ

    void Start()
    {
        rb = GetComponent<Rigidbody>(); // Rigidbodyコンポーネントを取得
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            rb.AddForce(transform.right * force, ForceMode.VelocityChange); // 指定した力を与える
        }
    }
}

のように質量には関係なく、オブジェクトが移動しているのが分かります。

AddForceの注意点:モードによって「FixedUpdate」内で処理する

AddForceメソッドの第二引数のForceModeで、「Force」「Acceleration」で力を継続的に加えていく場合は、Updateメソッドではなく「FixedUpdate」内で使うようにしましょう。

Updateメソッドで使ってしまうと、フレーム毎に処理されてしまい、フレームの呼び出される時間が一定でないことから、物理演算が上手く働かなくなります。

一方で、FixedUpdateはフレームごとではなく、一定の時間間隔ごとに呼ばれるイベント関数で、この中で継続的に力を与えてあげることで、物理演算が上手く働くようになります。

そのため、ForceModeを「Force」もしくは「Acceleration」にして繰り返し処理を行う場合は、「FixedUpdate」を使って処理するようにしましょう。

まとめ

このページでは、Unityで使うことができるAddForceメソッドについて、どういうものなのか、特徴や仕様から使い方までを紹介していきましたが、いかがでしたでしょうか?

AddForceメソッドは、Rigidbodyコンポーネントで定義されているメソッドで、オブジェクトに力を与えることができます。

AddForceの第一引数に、力と力の方向を表すベクトルをVector型で指定することで、その力をオブジェクトに加えることができます。

また力の与え方には、継続的に力を加える方法と、瞬間的に力を加える方法があり、それぞれ第二引数にForceModeとして指定することができます。

最後までお読みいただきまして、ありがとうございました!

コメント