Unity公式サイトに掲載されているチュートリアルの2Dシューティングに挑戦。今回はプレイヤーの移動制限とタイトル作成のステップを行いました。チュートリアルを進めながら変更した箇所などをピックアップしています。
前回の記事はこちら
Unity:BGMと効果音をつける~公式チュートリアル 2Dシューティングに挑戦
チュートリアルページ:プレイヤーの移動制限と様々な修正
このステップの手順は次の通りです。
チュートリアルでは自機の移動範囲をゲーム画面内に制限する方法として、自機の制御方法をRigidbody2D から transform.position の制御に変更しています。
ここでは制御方法をRigidbody2D ままでスクリプト Player を変更しました。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
// スクリプト Spaceship コンポーネントを格納する変数
Spaceship spaceship;
// AudioSource コンポーネントを格納する変数
// AudioSource seShot;
// ゲームのスタート時の処理
void Start()
{
// Spaceshipコンポーネントを取得
spaceship = GetComponent<Spaceship>();
// AudioSource コンポーネントを取得
//seShot = GetComponent<AudioSource>();
// 弾の発射処理(コルーチン Shot )を実行
StartCoroutine("Shot");
}
// ゲーム実行中の繰り返し処理
void Update()
{
// 右・左のデジタル入力値を x に渡す
float x = Input.GetAxisRaw("Horizontal");
// 上・下のデジタル入力値 y に渡す
float y = Input.GetAxisRaw("Vertical");
// 移動する向きを求める
// x と y の入力値を正規化して direction に渡す
Vector2 direction = new Vector2(x, y).normalized;
// Spaceship コンポーネントの Move() 処理を実行
spaceship.Move(direction);
// 自機の移動制限処理を実行
Clamp();
}
// 自機の移動制限処理
void Clamp()
{
// 自機の移動座標最小値をビューポートから取得(最小値は0,0)
Vector2 min = Camera.main.ViewportToWorldPoint(new Vector2(0.05f, 0.1f));
// 自機の移動座標最大値ををビューポートから取得(最大値は1,1)
Vector2 max = Camera.main.ViewportToWorldPoint(new Vector2(0.95f, 0.85f));
// 自機の座標を取得してベクトル pos に格納
Vector2 pos = transform.position;
// pos.x の値を最小値 min 最大値 max の範囲に制限する
pos.x = Mathf.Clamp(pos.x, min.x, max.x);
// pos.y の値を最小値 min 最大値 max の範囲に制限する
pos.y = Mathf.Clamp(pos.y, min.y, max.y);
// 自機の移動範囲を pos の最小値と最大値の範囲に制限する
transform.position = pos;
}
// トリガーに入った時の処理
// 衝突した相手の Collider2D コンポーネントを引数 c に格納
void OnTriggerEnter2D(Collider2D c)
{
// レイヤー名を取得して layerName に格納
string layerName = LayerMask.LayerToName(c.gameObject.layer);
// レイヤー名が Bullet (Enemy) の場合
if (layerName == "Bullet (Enemy)")
{
// 弾の削除
Destroy(c.gameObject);
}
// レイヤー名が Bullet (Enemy) または Enemy の場合
if (layerName == "Bullet (Enemy)" || layerName == "Enemy")
{
// 爆発処理
// スクリプト Spaceship の関数 Explosion() を実行
spaceship.Explosion();
// プレイヤーを削除
Destroy(gameObject);
}
}
// 弾の発射処理(コルーチン)
IEnumerator Shot()
{
while (true)
{
// 弾をプレイヤーと同じ位置/角度で作成
spaceship.Shot(transform);
// ショット音を鳴らす
//seShot.Play();
// shotDelay 秒待つ
yield return new WaitForSeconds(spaceship.shotDelay);
}
}
}
チュートリアルでは スクリプト Spaceship の Move() 関数を使用しなくなったのでスクリプト Spaceship とEnemy を修正していますが、ここでは修正しないでそのまま使用します。
チュートリアルページ:タイトルを付ける
このステップの手順は次の通りです。
チュートリアルではGUI Text コンポーネントを使用してタイトルテキストを作成していますが、ここでは UI > Text を使用します。
[Hierarchy]ウィンドウ > [Create]ボタン > UI > Text を選択。作成された Text オブジェクトの名前を Text Title に変更。Rect Transform コンポーネントの設定はこのようにしました。
Text コンポーネントの設定はこのようにしました。親オブジェクト Canvas の Canvas Scaler > Reference Resolution の設定を変更しているので Font サイズは大きい値になります。
テキストのフォントサイズはリッチテキストを使用、タイトルと Press X のサイズを別々にしました。テキストフィールドの内容はこのようになっています。
チュートリアルのスクリプト Manager では Start() 関数でタイトルオブジェクトを検索して変数に格納していますが、ここではタイトルオブジェクトを格納する変数を public に変更。オブジェクトを [Inspector]ウィンドウから割り当てる方法に変えました。
さらに自機が撃破された際、別に用意したゲームオーバーテキストを表示する形にしました。
スクリプトはこのようになっています。 自機が撃破されるとコルーチン処理でゲームオーバーのテキストを3秒間表示。再びタイトルテキストを表示します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Manager : MonoBehaviour
{
// 自機を格納する変数
public GameObject player;
// テキストオブジェクトを格納する変数
public GameObject textTitle;
// ゲームオーバーテキストオブジェクトを格納する変数
public GameObject textGameOver;
// ゲームのスタート時の処理
void Start()
{
textGameOver.SetActive(false);
}
// ゲーム実行中の繰り返し処理
void Update()
{
// ゲーム中ではなく、さらにXキーが押されたらtrueを返す。
if (IsPlaying() == false && Input.GetKeyDown(KeyCode.X))
{
// ゲーム開始処理を実行
GameStart();
}
}
// ゲーム開始処理
void GameStart()
{
// タイトルオブジェクトを非表示にする
textTitle.SetActive(false);
// 自機を生成する
Instantiate(player, player.transform.position, player.transform.rotation);
}
// ゲームオーバー時の処理
public void GameOver()
{
// テキストオブジェクト表示のコルーチンを実行
StartCoroutine("ShowGameOver");
}
// ゲームプレイ中か判定する処理
public bool IsPlaying()
{
// タイトルオブジェクトが非表示であれば true を返す
return textTitle.activeSelf == false;
}
// ゲームオーバー時にテキストオブジェクトを表示する処理(コルーチン)
private IEnumerator ShowGameOver()
{
// タイトルオブジェクトを表示する
textGameOver.SetActive(true);
//3秒後に処理を中断
yield return new WaitForSeconds(3f);
// ゲームオーバーテキストオブジェクトを非表示にする
textGameOver.SetActive(false);
// タイトルテキストオブジェクトを表示する
textTitle.SetActive(true);
}
}
オブジェクト Manager のコンポーネント Manager の[Inspector]ウィンドウはこのようになっています。
ここまでの内容を動作確認用にWebGLでビルドしてみました。タイトルができてちょっとゲームらしくなってきました。
画像クリックで再生(ファイルサイズ:約7MB)