学習記事一覧 · Unity基礎

【学習】横スクロールアクション(ミニゲーム実践②)

これまでの学習では、

  • 落ち物キャッチゲームでプレイヤー、生成、当たり判定、UI を組み合わせた
  • ジャンプの実装を学んだ

という形でゲームの基本を押さえてきました。

しかし、横スクロールアクションのように、ジャンプと敵、床との当たり判定を組み合わせたゲームはまだ作っていません。

横スクロールアクションの基本

を作って、より本格的なゲームの流れを学びます。

今回は 第15回の内容を横スクロール用に作り替えジャンプして敵を避ける横スクロールアクション の基本を作ります。PlayerController やオブジェクト構成が変わるため、落ち物キャッチの内容は上書きされます。

今日作るもの

  • プレイヤーが左右に動き、スペースでジャンプする
  • 床に立って、落下しない
  • 敵が左右に動く
  • 敵に当たるとゲームオーバー(シーン切り替え)

必要なオブジェクト

オブジェクト 役割
Player 左右移動+ジャンプ。Rigidbody2D、Collider2D(Is Trigger オフ)
Ground 床。Collider2D(Is Trigger オフ)、Rigidbody2D は Static
Enemy(プレハブ) 左右に往復。Collider2D(Is Trigger オフ)
Main Camera ゲーム画面

手順1:床を作る

  1. 2D Object → Sprite で Ground を作成(四角形で横長に)
  2. Box Collider 2D を追加(Is Trigger オフ)
  3. Rigidbody2D は不要。または追加する場合は Body Type を Static
  4. Tag は "Ground"(任意)

手順2:プレイヤーを設定する

  1. Rigidbody2D:Body Type = Dynamic、Gravity Scale = 3
  2. Box Collider 2D:Is Trigger オフ(床と物理的に衝突するため)
  3. ジャンプ付きの PlayerController と PlayerInput をアタッチ(Actions に InputSystem_Actions、Default Map を Player に設定)

手順3:敵のプレハブを作る

  1. 2D Object → Sprite で Enemy を作成
  2. Box Collider 2D を追加(Is Trigger オフ)
  3. Rigidbody2D は不要、または Kinematic
  4. Tag を "Enemy" に設定
  5. EnemyController スクリプトをアタッチ(左右往復)
  6. プレハブ化

手順4:プレイヤーが敵に当たったらゲームオーバー

PlayerController の OnCollisionEnter2D で、Enemy に当たったらシーンを切り替えます。

補足:GameOverScene は第17回で作成します。第16回の時点で動作確認する場合は、File → New Scene で空のシーンを作成し、File → Save AsGameOverScene として保存、File → Build Settings で追加しておいてください。


完成コード例

PlayerController.cs

using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;

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);
    }

    void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.CompareTag("Enemy"))
        {
            SceneManager.LoadScene("GameOverScene");
        }
    }
}

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

EnemyController.cs

using UnityEngine;

public class EnemyController : MonoBehaviour
{
    [SerializeField] private float speed = 2f;
    [SerializeField] private float leftLimit = -4f;
    [SerializeField] private float rightLimit = 4f;
    private int direction = 1;

    void Update()
    {
        transform.Translate(speed * direction * Time.deltaTime, 0, 0);
        if (transform.position.x >= rightLimit) direction = -1;
        if (transform.position.x <= leftLimit) direction = 1;
    }
}

プログラムの流れ

プレイヤーが左右+ジャンプで移動

床(Ground)と物理衝突して立つ

敵が左右に往復

プレイヤーが敵にぶつかると OnCollisionEnter2D

GameOverScene に切り替え

重要ポイント

横スクロールアクションでは、物理演算当たり判定の使い分けが重要です。

  • … Collider2D(Is Trigger オフ)、Static
  • プレイヤー … Rigidbody2D + ジャンプ、敵とは OnCollisionEnter2D
  • … 左右往復。プレイヤーとぶつかったらゲームオーバー
  • シーン切り替え … SceneManager.LoadScene で GameOverScene へ

発展アイデア

  • リトライボタン … GameOverScene にボタンを配置し、ゲームシーンを再読み込み
  • スコアの引き継ぎ … DontDestroyOnLoad でスコアを保持
  • 複数の敵 … プレハブで敵を配置、またはスポナーで生成
  • アニメーション … プレイヤーの歩き、ジャンプのアニメーション