【学習】プレイヤーを動かす(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 にする
発展アイデア
プレイヤーの動きが分かったら、次のステップです。
- プレハブと生成 … 敵や弾を生成する
- 当たり判定 … 敵に当たったらダメージ、アイテム取得
- 横スクロールアクション … ジャンプと敵を組み合わせる
プレイヤーを動かすことは アクションゲームの基本 です。次はプレハブで敵や弾を生成しましょう。