学習記事一覧 · Unity基礎

【学習】プレイヤーを動かす(Transform.Translate、AddForce)

これまでの学習では、

  • 入力の取得を学んだ
  • 当たり判定を設定した
  • Sprite で画像を表示した

という形でゲームの要素を揃えてきました。

しかし、プレイヤーの「動き」をまとめて実装する方法を学んでいません。

Transform.Translate と Rigidbody2D.AddForce

という2つの方法があります。

今回は プレイヤーを動かす 2つの方法と、それぞれの使い分けを学びます。

今日学ぶこと

  • Transform.Translate … 直接位置を変更する。シンプルな移動
  • Rigidbody2D.AddForce … 力を加えて動かす。物理演算を使う
  • ジャンプ … AddForce で上方向に力を加える
  • 左右反転 … 移動方向に合わせて Sprite を反転する

方法1:Transform.Translate(シンプルな移動)

Transform.Translate は、現在の位置から指定した量だけ移動します。当たり判定に影響されず、壁をすり抜ける可能性があります。

// OnMove で moveInput を受け取り、Update で移動
float moveX = moveInput.x * speed * Time.deltaTime;
float moveY = moveInput.y * speed * Time.deltaTime;
transform.Translate(moveX, moveY, 0);
  • シンプルで分かりやすい
  • Rigidbody2D がなくても動く
  • 物理演算(重力・衝突)とは連動しない

方法2:Rigidbody2D.AddForce(物理演算)

Rigidbody2D.AddForce は、オブジェクトに力を加えて動かします。重力や壁との衝突が有効になります。

Rigidbody2D rb = GetComponent<Rigidbody2D>();
float moveX = moveInput.x * speed;
rb.AddForce(new Vector2(moveX, 0));
  • 物理演算と連動する
  • 壁にぶつかると止まる
  • 慣性があるので、止めたいときは velocity を 0 にするなど追加処理が必要

方法2の改良:velocity で直接速度を設定

AddForce だと慣性で滑りやすいため、velocity を直接設定する方法もよく使います。

Rigidbody2D rb = GetComponent<Rigidbody2D>();
float moveX = moveInput.x * speed;
rb.velocity = new Vector2(moveX, rb.velocity.y);

上下移動(Y)はそのままにして、左右(X)だけを入力で制御します。ジャンプ時は velocity.y が変わるので、それを維持できます。


ジャンプの実装

OnJump でスペースキーを押した瞬間に、上方向に力を加えます。

void OnJump(InputValue value)
{
    if (value.isPressed)
    {
        rb.AddForce(new Vector2(0, jumpForce), ForceMode2D.Impulse);
    }
}

jumpForce は Inspector で調整します(例:10 ~ 15)。Rigidbody2D の Gravity Scale を 1 以上にしておきます。


左右反転(移動方向に合わせる)

移動方向に合わせて Sprite を左右反転します。

if (moveX > 0)
    transform.localScale = new Vector3(1, 1, 1);   // 右向き
else if (moveX < 0)
    transform.localScale = new Vector3(-1, 1, 1);   // 左向き

SpriteRenderer の Flip X を使う方法もあります。


完成コード例

using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerController : MonoBehaviour
{
    [SerializeField] private float speed = 5f;
    [SerializeField] private float jumpForce = 12f;

    private Rigidbody2D rb;
    private Vector2 moveInput;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
    }

    void OnMove(InputValue value)
    {
        moveInput = value.Get<Vector2>();
    }

    void OnJump(InputValue value)
    {
        if (value.isPressed)
        {
            rb.AddForce(new Vector2(0, jumpForce), ForceMode2D.Impulse);
        }
    }

    void Update()
    {
        float moveX = moveInput.x * speed;
        rb.velocity = new Vector2(moveX, rb.velocity.y);

        if (moveX > 0)
            transform.localScale = new Vector3(1, 1, 1);
        else if (moveX < 0)
            transform.localScale = new Vector3(-1, 1, 1);
    }
}

※プレイヤーに PlayerInput をアタッチし、Actions に InputSystem_Actions、Default Map を Player に設定してください。


プログラムの流れ

OnMove で moveInput を取得、OnJump でジャンプ

Update で velocity を左右の速度に設定

スペースキーで AddForce(ジャンプ)

移動方向に合わせて Scale で反転

重要ポイント

Transform.Translate はシンプル、Rigidbody2D は物理演算と連動します。

  • Translate … 直接移動。シンプルだが物理と連動しない
  • AddForce / velocity … 物理演算と連動。壁や床との衝突が有効
  • ジャンプ … OnJump + AddForce(Impulse)
  • 左右反転 … localScale の X を -1 にする

発展アイデア

プレイヤーの動きが分かったら、次のステップです。

  • プレハブと生成 … 敵や弾を生成する
  • 当たり判定 … 敵に当たったらダメージ、アイテム取得
  • 横スクロールアクション … ジャンプと敵を組み合わせる

プレイヤーを動かすことは アクションゲームの基本 です。次はプレハブで敵や弾を生成しましょう。