見出し画像

【Unity 初心者向け】オブジェクトの移動④ | Rigidbodyでオブジェクトを動かす ― linearVelocity編

今回は、Rigidbodyを使ってオブジェクトを動かす方法を確認します。

これまでの記事では、Transformを使ってオブジェクトの位置を直接変更してきました。
前回はその中で、Translateメソッドを使ってオブジェクトを動かしてみました。

今回はそこから少し進んで、物理演算を使ってオブジェクトを動かす方法を学びます。

2Dゲームを例に、Rigidbody2DとlinearVelocityを使って左右へ移動させてみます。


1.TransformとRigidbodyの動きの違い

これまで使ってきたTransformでは、次のように位置を変更してオブジェクトを動かしていました。

transform.position += Vector3.right * speed * Time.deltaTime;

これは、オブジェクトの座標そのものを変更する方法です。
イメージとしては、「今いる場所から、少し右の場所へ移動させる」という処理、つまり瞬間移動の繰り返しです。

一方、Rigidbodyを使う場合は、位置を直接変更するのではなく、オブジェクトに速度を設定して動かします。

例えば、

rb.linearVelocity = new Vector2(5f, 0f);

とすると、「X方向へ毎秒 5 の速度で動く」という状態になります。

つまり、大きく分けると次の違いがあります。

  • Transform
    → 座標を直接変更して動かす

  • Rigidbody
    → 速度や重力などの物理演算を使って動かす

ジャンプや落下、衝突などを使うゲームでは、Rigidbodyを使った移動がよく使われます。


2.Rigidbody2Dコンポーネントについて

2-1.Rigidbody2Dを追加する

今回は2Dゲームを想定しているため、Rigidbody2Dを使います。
移動させたいオブジェクトを選択し、Inspectorから、

Add Component → Rigidbody 2D

を追加します。

Rigidbody2Dは、2Dオブジェクトを物理演算で動かすためのコンポーネントです。
追加すると、Inspectorにいくつかの設定項目が表示されます。

今回は、その中でも基本となる項目を確認しておきましょう。


2-2.Mass

Massは、オブジェクトの重さを設定する項目です。

例えば、

  • Mass = 1

  • Mass = 5

のように設定できます。

値が大きいほど重い物体として扱われます。

ただし、今回のように linearVelocity を直接設定して左右へ動かすだけであれば、Massの違いはほとんど感じない場合もあります。

衝突したときや力を加えたときに、Mass の違いが重要になってきます。


2-3.Gravity Scale

Gravity Scale は、重力の影響をどのくらい受けるかを設定します。

通常は、

GravityScale = 1

になっています。
値を大きくすると、より強く下方向へ引っ張られます。
逆に、

GravityScale = 0

にすると、重力の影響を受けなくなります。

ジャンプゲームなどでは、この Gravity Scale によって落下速度の感覚も変わってきます。


2-4.Linear Damping

Linear Dampingは、移動速度をどのくらい減衰させるかを設定する項目です。
摩擦や空気抵抗のような効果ととらえると、イメージしやすいと思います。

値を大きくすると、動いているオブジェクトの速度の減衰が大きくなります。
滑りやすい動きにしたい場合や、逆にすぐ止まる動きにしたい場合などに調整します。

今回作成を予定しているフレーム linearVelocity を設定する移動では、まずは初期値のままでも問題ありません。


3.スクリプトからRigidbody2Dを使う

3-1.スクリプトファイルの作成

スクリプトファイル:PlayerMove を作成し、移動させたいオブジェクトにアタッチします。

スクリプトから Rigidbody2D を操作するには、Rigidbody2D型の変数を用意します。

public Rigidbody2D rb;

さらに、移動速度を変更できるように float 型の変数:speed も用意します。

public float speed = 5f;

スクリプト全体は次のようになります。

public class PlayerMove : MonoBehaviour
{
    public Rigidbody2D rb;      // Rigidbody2Dコンポーネントへの参照
    public float speed = 5f;    // 移動速度

    void Update()
    {
        float x = Input.GetAxisRaw("Horizontal");   // 水平方向の入力を取得

        // Rigidbody2Dの速度を設定して移動させる
        rb.linearVelocity = new Vector2(
            x * speed,
            rb.linearVelocity.y
        );
    }
}

スクリプトをオブジェクトに追加したら、Inspector の rb欄に、そのオブジェクトのRigidbody2Dを設定しておきます。


3-2.Input.GetAxisRawで左右入力を取得

まずは次の部分です。

float x = Input.GetAxisRaw("Horizontal");

Input.GetAxisRaw("Horizontal")を使うと、左右方向の入力を取得できます。

基本的には、

  • 左入力 → -1

  • 入力なし → 0

  • 右入力 → 1

になります。
詳しくはこちらの記事でご確認ください。


3-3.linearVelocityとは

今回の重要な部分がこちらです。

rb.linearVelocity

linearVelocityは、Rigidbody2D の 現在の移動速度 を表します。

2Dでは、

new Vector2(X方向の速度, Y方向の速度)

という形で速度を設定します。例えば、

rb.linearVelocity = new Vector2(5f, 0f);

とすると、

  • X方向 → 5

  • Y方向 → 0

の速度になり、オブジェクトは右方向へ移動します。


3-4.入力とspeedを使って左右へ動かす

今回のコードでは、X方向の速度を次のようにしています。

x * speed

speedが5の場合、右キーを押すと、

1 × 5 = 5

となり、左キーの場合は、

-1 × 5 = -5

です。


3-5.Y方向のrb.linearVelocity.y

コードをもう一度見てみましょう。

rb.linearVelocity = new Vector2(
    x * speed,
    rb.linearVelocity.y
);

X方向には新しい速度を設定しています。
しかしY方向には、

rb.linearVelocity.y

を設定しています。

これは、現在のY方向の速度をそのまま残すためです。
例えば、キャラクターがジャンプしている途中では、Y方向に上向きや下向きの速度があります。

もし次のように書いてしまうと、

rb.linearVelocity = new Vector2(
    x * speed,
    0
);

毎フレームY方向の速度が0に戻されてしまい、重力による落下やジャンプの速度まで消してしまいます。
そのため、

rb.linearVelocity.y

を使って、現在の上下方向の速度を残しています。
考え方としては、

X方向は自分で操作する

Y方向は重力やジャンプなどの物理演算に任せる

という形です。


4.当たり判定の追加

このままプレイをすると、Rigidbody2D の 重力の効果で Player は落下してしまいます。

4-1.足場の追加

足場となる地面を用意し、地面に当たり判定を追加します。
Hierarchy で右クリック

 2D Object → Sprite → Square

で四角形を作ります。
インスペクターで下のように設定し、Playerの足元に足場を作ります。

  • Transform:Playerの下に配置

  • SpriteRenderer:任意の色

  • BoxCollider:追加

4-2.Playerの当たり判定

Playerにも当たり判定を付けておきます。

Player を覆うように当たり判定の位置を調整しておきます。

この状態で動きを確認してみましょう。
今回は左右の動きだけですが、Playerが左右に移動するのが確認できたと思います。

ジャンプなど、もっと Rigidbody2D を使った動きを確認したい場合は、次のマガジンで、ゲームを作ってみるのもいいかも。


5.Transformで動かす場合との違いを整理

ここで、これまで使ってきた ransform の移動と比べてみましょう。

Transformの場合

transform.position += Vector3.right * speed * Time.deltaTime;

位置そのものを少しずつ変更しています。
つまり「どこにいるか」を変更している ということです。

Rigidbody2Dの場合

rb.linearVelocity = new Vector2(
    x * speed,
    rb.linearVelocity.y
);

こちらは位置を直接変更しているわけではありません。
「どの方向へ、どのくらいの速度で動くか」を設定しています。
その速度をもとに、Unityの物理演算がオブジェクトを移動させます。

TransformとRigidbodyは、どちらか一方が常に正しいというわけではありません。

例えば、

  • 決められた位置へ移動させる

  • UIや演出用のオブジェクトを動かす

  • 物理演算を必要としない移動

であれば、Transformを使う方法が分かりやすい場合があります。

一方、

  • プレイヤーの移動

  • ジャンプ

  • 落下

  • 衝突

  • 押される物体

  • 物理的な動きを使うゲーム

では、Rigidbodyを使う方法が向いています。

特に、Rigidbody を使っているオブジェクトを Transform で直接動かすと、物理演算との動きがかみ合わなくなることがあります。

物理演算を使うオブジェクトは、できるだけ Rigidbody を通して動かす、と覚えておくとよいでしょう。


6.今回のまとめ

今回は、Rigidbody2DとlinearVelocityを使ってオブジェクトを動かす方法を確認しました。

次回は、Rigidbody に力を加えて動かす AddForce を使います。

linearVelocity が速度を直接設定する方法なのに対して、AddForce は力を加えることで速度を変化させます。Mass の影響や ForceMode2D.Force とImpulse の違いも確認しながら、ジャンプ処理を作ってみましょう。

そして最終回では、Transform・linearVelocity・AddForceのどれを使えばよいのかを比較して、この移動シリーズをまとめます。


こちらはUnity初心者向けの記事をテーマ別にまとめています。
▼ Unity初心者向け記事まとめはこちら


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

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


ファイブボックスでは、スクラッチやUnityの個別指導のオンラインレッスンを行っています。
ご興味のある方は当サイト、オンラインレッスンから、無料体験授業へお問い合わせ下さい。

いいなと思ったら応援しよう!

ファイブボックス よろしければ応援お願いします! いただいたチップはクリエイターとしての活動費に使わせていただきます!