【学習】横スクロールアクション(ミニゲーム実践②)
これまでの学習では、
- 落ち物キャッチゲームでプレイヤー、生成、当たり判定、UI を組み合わせた
- ジャンプの実装を学んだ
という形でゲームの基本を押さえてきました。
しかし、横スクロールアクションのように、ジャンプと敵、床との当たり判定を組み合わせたゲームはまだ作っていません。
横スクロールアクションの基本
を作って、より本格的なゲームの流れを学びます。
今回は 第15回の内容を横スクロール用に作り替え、ジャンプして敵を避ける横スクロールアクション の基本を作ります。PlayerController やオブジェクト構成が変わるため、落ち物キャッチの内容は上書きされます。
今日作るもの
- プレイヤーが左右に動き、スペースでジャンプする
- 床に立って、落下しない
- 敵が左右に動く
- 敵に当たるとゲームオーバー(シーン切り替え)
必要なオブジェクト
| オブジェクト | 役割 |
|---|---|
| Player | 左右移動+ジャンプ。Rigidbody2D、Collider2D(Is Trigger オフ) |
| Ground | 床。Collider2D(Is Trigger オフ)、Rigidbody2D は Static |
| Enemy(プレハブ) | 左右に往復。Collider2D(Is Trigger オフ) |
| Main Camera | ゲーム画面 |
手順1:床を作る
- 2D Object → Sprite で Ground を作成(四角形で横長に)
- Box Collider 2D を追加(Is Trigger オフ)
- Rigidbody2D は不要。または追加する場合は Body Type を Static
- Tag は "Ground"(任意)
手順2:プレイヤーを設定する
- Rigidbody2D:Body Type = Dynamic、Gravity Scale = 3
- Box Collider 2D:Is Trigger オフ(床と物理的に衝突するため)
- ジャンプ付きの PlayerController と PlayerInput をアタッチ(Actions に InputSystem_Actions、Default Map を Player に設定)
手順3:敵のプレハブを作る
- 2D Object → Sprite で Enemy を作成
- Box Collider 2D を追加(Is Trigger オフ)
- Rigidbody2D は不要、または Kinematic
- Tag を "Enemy" に設定
- EnemyController スクリプトをアタッチ(左右往復)
- プレハブ化
手順4:プレイヤーが敵に当たったらゲームオーバー
PlayerController の OnCollisionEnter2D で、Enemy に当たったらシーンを切り替えます。
補足:GameOverScene は第17回で作成します。第16回の時点で動作確認する場合は、File → New Scene で空のシーンを作成し、File → Save As で GameOverScene として保存、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 でスコアを保持
- 複数の敵 … プレハブで敵を配置、またはスポナーで生成
- アニメーション … プレイヤーの歩き、ジャンプのアニメーション