シューティングゲームは縦型の方が雰囲気が出るよねってことで、縦型画面にしてみようと思います。
今回のゴール
縦型画面にして調整する
ゲーム画面で縦横比を調整する
ゲーム画面で縦横比を調整します。Free Aspectとなっているところをクリックすると様々な解像度を選ぶことができます。しかし、縦型の画面は選択肢にないので新しく作ります。「追加」をクリックして、ラベルを「9:16 Aspect」、タイプを「アスペクト比」、幅と高さをXは9、Yは16に設定してOKを押します。

すると画面が縦画面になります。しかしゲームを実行してみると、全体が入り切れていません。自機は表示されず、敵機も大きすぎます。

MainCameraを選択して、インスペクタの「投影方法」から「サイズ」を「10」にします。また、背景が青いのを黒にしたいので、「環境」の「背景タイプ」を「ソリッドカラー」にして「背景」は黒にします。


さらに、画面のサイズに合わせるために、自機や敵機の出現位置、移動範囲などを調整します。横位置は-5から5の範囲、縦位置は-9から9の範囲にスクリプトを修正します。
StageManager.cs
using UnityEngine;
using UnityEngine.UI;
public class StageManager : MonoBehaviour
{
public GameObject Player; // プレイヤーのプレハブ
public GameObject Enemy01; // 敵のプレハブ1
public GameObject Enemy02; // 敵のプレハブ2
public GameObject Enemy03; // 敵のプレハブ3
public GameObject Enemy04; // 敵のプレハブ4
public GameObject[] Enemy; // 敵のプレハブを配列で保持
public Text ScoreText; // スコアを表示するUIテキスト
public Text HighScoreText; // ハイスコアを表示するUIテキスト
GameObject playerInstance; // プレイヤーのインスタンスを保持する変数
int timer = 0; // タイマー
int PlayerDamageTimer; // 無敵時間
const int timerMax = 40; // タイマーの最大値
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
// ゲームの初期状態を設定
GameData.score = 0; // スコアを初期化
GameData.highScore = PlayerPrefs.GetInt("HighScore", 0); // ハイスコアを保存から読み込む
GameData.playerLife = 2; // プレイヤーのライフを初期化
ScoreText.text = GameData.score.ToString(); // スコアテキストを初期化
HighScoreText.text = GameData.highScore.ToString(); // ハイスコアテキストを初期化
playerInstance = Instantiate(Player, new Vector3(0, -9.0f, 0), Quaternion.identity); // プレイヤーを生成
PlayerDamageTimer = 300; // 無敵時間を300フレームに設定
timer = 0; // タイマーを初期化
GameData.gameState = GameState.Playing; // ゲーム状態をPlayingに設定
QualitySettings.vSyncCount = 0; // VSyncCount を Dont Sync に変更
Application.targetFrameRate = 60; // 60fpsを目標に設定
}
// Update is called once per frame
void Update() // 毎フレーム呼び出される
{
timer++; // タイマーをインクリメント
switch (GameData.gameState) // ゲームの状態に応じた処理を実行
{
case GameState.Playing: // ゲームプレイ中の処理
// ゲームがプレイ中の処理
if (timer == 10)
{ // タイマーが10のときに敵を生成
Instantiate(Enemy01, new Vector3(Random.Range(-5f, 5f), 10f, 0f), Quaternion.Euler(0, 0, 180)); // 敵をランダムな位置に生成
}
else if (timer == 20)
{ // タイマーが20のときに敵を生成
Instantiate(Enemy02, new Vector3(-6f, 7f, 0f), Quaternion.Euler(0, 0, -140)); // 敵を固定位置に生成
}
else if (timer == 30)
{ // タイマーが30のときに敵を生成
Instantiate(Enemy03, new Vector3(Random.Range(-5f, 5f), 10f, 0f), Quaternion.Euler(0, 0, 180)); // 敵をランダムな位置に生成
}
else if (timer == 40)
{ // タイマーが40のときに敵を生成
Instantiate(Enemy04, new Vector3(Random.Range(-5f, 5f), 10f, 0f), Quaternion.Euler(0, 0, 180)); // 敵をランダムな位置に生成
}
break;
case GameState.PlayerDamaged: // プレイヤーがダメージを受けたときの処理
// プレイヤーが被弾したときの処理
// ここではダメージを受けたことを示すためのタイマーを使用
// PlayerDamageTimerはダメージを受けた後の無敵時間を表す
if (PlayerDamageTimer % 5 < 3) // 無敵時間中はプレイヤーを点滅させる
{
playerInstance.SetActive(false); // プレイヤーを非表示にする
}
else
{
playerInstance.SetActive(true); // プレイヤーを表示する
}
PlayerDamageTimer--; // 無敵時間をデクリメント
if (PlayerDamageTimer <= 0) // 無敵時間が終わったら
{
GameData.gameState = GameState.Playing; // 無敵時間が終わったらゲーム状態をPlayingに戻す
playerInstance.SetActive(true); // プレイヤーを再表示する
}
break;
case GameState.GameOver: // ゲームオーバーの処理
// ゲームオーバーの処理
if (GameData.score > GameData.highScore) // ハイスコアの更新
{
GameData.highScore = GameData.score; // ハイスコアを更新
}
// ここでゲームオーバーの画面を表示する処理を追加
UnityEngine.SceneManagement.SceneManager.LoadScene("GameOver"); // GameOverはゲームオーバーのシーン名
break;
default:
break;
}
ScoreText.text = GameData.score.ToString(); // スコアテキストを更新
if (timer > timerMax) timer = 0; // タイマーが最大値を超えたらリセット
}
public void playerDamaged() // プレイヤーがダメージを受けたときの処理
{
if (GameData.gameState == GameState.Playing) // 通常プレイ中なら
{
GameData.gameState = GameState.PlayerDamaged; // ゲーム状態をPlayerDamagedに変更
PlayerDamageTimer = 300; // 無敵時間をリセット
if (GameData.playerLife > 0) // プレイヤーのライフが残っている場合
{
GameData.playerLife--; // ライフを1減らす
}
else
{
GameData.gameState = GameState.GameOver; // ライフが0になったらゲームオーバー状態に変更
// ハイスコアの処理
if (GameData.score > GameData.highScore) // ハイスコアの更新
{
GameData.highScore = GameData.score; // ハイスコアを更新
}
PlayerPrefs.SetInt("HighScore", GameData.highScore); // ハイスコアを保存
PlayerPrefs.Save(); // PlayerPrefsの変更を保存
}
}
}
}
Enemy.cs
using UnityEngine;
public class Enemy : MonoBehaviour
{
public GameObject explosionEffect; // 爆発エフェクトのプレハブ
//このクラスの変数など
protected Rigidbody2D rb;
protected const float speed = 3f;
protected const int score = 50;
protected int lifeTime = 0;
StageManager stageManager;
// Start is called once before the first execution of Update after the MonoBehaviour is created
protected void Start()
{
rb = GetComponent<Rigidbody2D>();
rb.linearVelocity = transform.up * speed;
stageManager = GameObject.Find("StageManager").GetComponent<StageManager>();
}
// Update is called once per frame
protected void Update()
{
lifeTime++;
//if (lifeTime > 3600) Destroy(gameObject);
if (transform.position.y < -10 || transform.position.y > 10 || transform.position.x < -6 || transform.position.x > 6)
{
Destroy(gameObject);
}
}
protected void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.CompareTag("Player"))
{
// Playerに衝突した場合の処理
stageManager.playerDamaged();
// Destroy(gameObject);
}
else if (collision.gameObject.CompareTag("Bullet"))
{
// Bulletに衝突した場合の処理
GameData.score += score;
Destroy(collision.gameObject);
Instantiate(explosionEffect, transform.position, Quaternion.identity);
Destroy(gameObject);
}
}
}
PlayerControl.cs
using UnityEngine;
public class PlayerControl : MonoBehaviour
{
// このクラスで使う変数など
public GameObject Bullet;
int BulletTimer = 0;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
}
// Update is called once per frame
void Update()
{
if (++BulletTimer > 12 && GameData.gameState == GameState.Playing)
{
Instantiate(Bullet,transform.position,Quaternion.identity);
BulletTimer = 0;
}
}
private void FixedUpdate()
{
//左矢印が入力されたら、自機を左に動かす
if (Input.GetKey(KeyCode.LeftArrow)) transform.Translate(-0.1f, 0, 0);
//右矢印が入力されたら、自機を右に動かす
if (Input.GetKey(KeyCode.RightArrow)) transform.Translate(0.1f, 0, 0);
//画面外に移動しないように制限をかける
transform.position = new Vector2(Mathf.Clamp(transform.position.x, -5.0f, 5.0f), transform.position.y);
}
}
縦画面に合わせて、タイトル画面とゲームオーバー画面を作り直しました。


縦画面に変更できました。

今回は変更点が多いのと、効果音やアニメーションも追加したので、パッケージとして出力しました。試す場合は、解凍してインポートしてください。
今回はここまでです。お疲れ様でした。
コメント