【学習】落ち物キャッチゲーム(ミニゲーム実践①)

2026年11月2日

広告

これまでの学習では、

  • プレイヤーを動かした
  • プレハブでオブジェクトを生成した
  • 当たり判定を設定した
  • UI でスコアを表示した

という形でゲームの要素を学んできました。

しかし、それらを1つのゲームにまとめる実践はまだしていません。

今回は落ち物キャッチゲームを作って、学んだことを総合的に使います。上から落ちてくるアイテムを、プレイヤーでキャッチするゲームです。

この記事の進め方

今日作るもの

  • プレイヤーが左右に動く
  • 上からアイテムが落ちてくる
  • プレイヤーがアイテムに触れるとスコアが増える
  • スコアを UI に表示する

必要なオブジェクト

オブジェクト役割
Player左右キーで動く。Collider2D(Trigger)、Rigidbody2D
Item(プレハブ)上から落ちる。Collider2D(Trigger)、Rigidbody2D
Spawner一定間隔で Item を生成する空オブジェクト
Canvas / Textスコア表示
Main Cameraゲーム画面を写す
落ち物キャッチゲームの構成スコア: 30SpawnerPlayerPlayer左右に動く。Trigger で拾うItem(プレハブ)上から落ちてくるSpawner一定間隔で Item を生成Canvas / Textスコアを表示
落ち物キャッチゲームの構成:Player・Item・Spawner・スコア表示

手順1:プレイヤーを作る

  1. Hierarchy の「+」→ 2D Object → Sprites → Square で四角形を作成し、名前を Player にする
  2. Transform の Position を (0, -4, 0) にして、画面の下に置く
  3. Add Component で Rigidbody2D を追加し、Gravity Scale を 0 にする(プレイヤーが落ちないようにするため)
  4. Add Component で Box Collider 2D を追加し、Is Trigger をオンにする
  5. Inspector 上部の Tag を Player にする(最初から用意されているタグです)
  6. Add Component で Player Input を追加し、Actions に InputSystem_Actions、Default Map に Player を設定する。Behavior は Send Messages のままにする
  7. PlayerController スクリプトを作成して次のコードを書き、Player にアタッチする

PlayerController.cs

using UnityEngine;
using UnityEngine.InputSystem;

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

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

    void Update()
    {
        float moveX = moveInput.x * speed * Time.deltaTime;
        transform.Translate(moveX, 0, 0);
    }
}

OnMove は、Player Input が移動キー(A / D キーや矢印キー)の入力を受け取ったときに呼ばれます。ここで ▶ を押して再生し、プレイヤーが左右に動くことを確認しておきましょう。

別の書き方:Keyboard.current でキーを直接調べる

Input System では、以前の Input Manager の Input.GetKey と同じように、キーが押されているかを直接調べる書き方もできます。この書き方なら、手順6の Player Input を追加しなくても動きます。

PlayerController.cs(Keyboard.current 版)

using UnityEngine;
using UnityEngine.InputSystem;

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

    void Update()
    {
        var keyboard = Keyboard.current;
        if (keyboard == null) return;   // キーボードがない環境への備え

        // ← キーまたは A キー / → キーまたは D キー
        bool left  = keyboard.leftArrowKey.isPressed
                  || keyboard.aKey.isPressed;
        bool right = keyboard.rightArrowKey.isPressed
                  || keyboard.dKey.isPressed;

        float x = 0f;
        if (left)  x = -1f;
        if (right) x = 1f;

        transform.Translate(x * speed * Time.deltaTime, 0, 0);
    }
}

isPressed は「押している間ずっと true」です。以前の書き方との対応は次のとおりです。

旧 Input ManagerInput System
Input.GetKey(KeyCode.A)Keyboard.current.aKey.isPressed
Input.GetKeyDown(KeyCode.Space)Keyboard.current.spaceKey.wasPressedThisFrame
Input.GetKeyUp(KeyCode.Space)Keyboard.current.spaceKey.wasReleasedThisFrame
Input.GetMouseButtonDown(0)Mouse.current.leftButton.wasPressedThisFrame

Keyboard.current 版は、どのキーを調べているかがコードからすぐ分かるのが長所です。一方、OnMove 版はキーボードだけでなくゲームパッドにもそのまま対応でき、キーの割り当ても後から変えられます。どちらを使っても、このゲームは同じように動きます。


手順2:スコアを表示する

アイテムのスクリプトは ScoreManager を使うので、先にスコア表示を作っておきます。

  1. Hierarchy の「+」→ UI → Legacy → Text でテキストを作成し、名前を ScoreText にする(Canvas と EventSystem も自動で作られます)
  2. ScoreText の Rect Transform で Width を 300、Height を 60 に広げ、Text の Font Size を 36、Color を白にする。Scene ビューで画面の左上あたりに移動する
  3. Hierarchy の「+」→ Create Empty で空の GameObject を作り、名前を ScoreManager にする
  4. ScoreManager スクリプトを作成して次のコードを書き、ScoreManager にアタッチする
  5. ScoreManager の Inspector にある Score Text 欄に、Hierarchy の ScoreText をドラッグする

ScoreManager.cs

using UnityEngine;
using UnityEngine.UI;

public class ScoreManager : MonoBehaviour
{
    [SerializeField] private Text scoreText;
    private int score = 0;

    void Start()
    {
        // ゲーム開始時に「スコア: 0」を表示する
        scoreText.text = "スコア: " + score;
    }

    public void AddScore(int points)
    {
        score += points;
        scoreText.text = "スコア: " + score;
    }
}

Start でゲーム開始時に「スコア: 0」を表示し、AddScore が呼ばれるたびに表示を更新します。今回は日本語をそのまま表示できる Legacy の Text を使います。


手順3:アイテムのプレハブを作る

  1. Hierarchy の「+」→ 2D Object → Sprites → Circle で円を作成し、名前を Item にする。Sprite Renderer の Color を黄色などに変えると、プレイヤーと見分けやすくなります
  2. Add Component で Rigidbody2D を追加する(Gravity Scale は 1 のまま。重力で落ちていきます)
  3. Add Component で Circle Collider 2D を追加し、Is Trigger をオンにする
  4. ItemController スクリプトを作成して次のコードを書き、Item にアタッチする
  5. Hierarchy の Item を Project ウィンドウへドラッグしてプレハブにする。プレハブができたら、Hierarchy の Item は削除する

ItemController.cs

using UnityEngine;

public class ItemController : MonoBehaviour
{
    void OnTriggerEnter2D(Collider2D other)
    {
        if (other.CompareTag("Player"))
        {
            FindFirstObjectByType<ScoreManager>().AddScore(10);
            Destroy(gameObject);
        }
    }

    void Update()
    {
        if (transform.position.y < -6f)
            Destroy(gameObject);  // 画面外で削除
    }
}

Player に触れたら AddScore(10) でスコアを加算して自分を削除し、画面の下(y が -6 より下)まで落ちたときも自分を削除します。


手順4:スポナーを作る

  1. Hierarchy の「+」→ Create Empty で空の GameObject を作り、名前を ItemSpawner にする
  2. ItemSpawner スクリプトを作成して次のコードを書き、ItemSpawner にアタッチする
  3. ItemSpawner の Inspector にある Item Prefab 欄に、Project の Item プレハブをドラッグする

ItemSpawner.cs

using UnityEngine;

public class ItemSpawner : MonoBehaviour
{
    [SerializeField] private GameObject itemPrefab;
    [SerializeField] private float interval = 1.5f;

    void Start()
    {
        InvokeRepeating("Spawn", 1f, interval);
    }

    void Spawn()
    {
        float x = Random.Range(-4f, 4f);
        Instantiate(itemPrefab, new Vector3(x, 6, 0), Quaternion.identity);
    }
}

InvokeRepeating で、1秒後から 1.5 秒ごとに Spawn を呼び出します。Spawn は x 座標をランダムに決めて、画面の上(y = 6)に Item を生成します。


動作確認

▶ を押して再生し、次の4つを確認しましょう。

  • 左右キーでプレイヤーが動く
  • 上からアイテムが次々に落ちてくる
  • アイテムに触れるとスコアが 10 ずつ増える
  • 取り逃したアイテムが画面の下で消える(再生中の Hierarchy で Item(Clone) が増え続けなければ OK)

プログラムの流れ

流れ
ゲーム開始
        ↓
ItemSpawner が一定間隔で Item を生成
        ↓
Item が落下、Player に触れると OnTriggerEnter2D
        ↓
ScoreManager.AddScore でスコア加算、Item を Destroy
        ↓
スコアが UI に表示される

重要ポイント

落ち物キャッチゲームは、これまで学んだ要素の集大成です。

  • プレイヤー … 入力で左右移動
  • プレハブ … Item を Instantiate で生成
  • 当たり判定 … OnTriggerEnter2D でキャッチを検知
  • UI … スコアを Text で表示
  • Destroy … キャッチした Item と画面外の Item を削除

発展アイデア

  • ゲームオーバー … 一定時間で終了、または落ちたアイテムが一定数超えたら終了
  • 複数種類のアイテム … 得点が違う、悪いアイテム(マイナス)など
  • 効果音 … キャッチ時に SE を再生
  • ハイスコア … PlayerPrefs で保存
  • 移動範囲の制限 … Mathf.Clamp でプレイヤーが画面の外に出ないようにする

補足:次の第17回について

第17回の横スクロールアクションは、新しいプロジェクト(ActionGame)で作ります。今回の CatchGame プロジェクトは上書きされないので、そのまま残しておけます。

訪問数 128 回, 今日の訪問数 2回

広告

Unity

Posted by hidepon