Unity公式サイトに掲載されているチュートリアルの2Dシューティングに挑戦。今回は背景と敵機のWave作成のステップを行いました。チュートリアルを進めながら変更した箇所などをピックアップしています。

前回の記事はこちら
Unity:敵の作成と当たり判定~公式チュートリアル 2Dシューティングに挑戦
背景を作る
チュートリアルページ:背景を作る
このステップの手順は次の通りです。
- 3枚の画像を表示させる
- Frontを作る
- MiddleとBackを作る
- 3枚の位置を調整する
- 背景をスクロールさせる
ゲーム画面の縦横比を変更する
チュートリアルではゲーム画面の縦横比が4:3で制作していますが、ここでは16:9に変更します。
Main Cameraを選択して [Inspector]ウィンドウ > Camera > Size を 3 に設定。

機体や弾が画面外に出たら消去するオブジェクト DestroyArea も同じく変更します。
DestroyArea を選択。 [Inspector]ウィンドウ > Box Collider 2D > Size > X 10.67 Y 6 に設定。

マテリアルを作る
チュートリアルではマテリアルがあらかじめ用意されている形で進んでいますが、プロジェクト内に見当たらなかったのでフォルダとマテリアルファイルを先に作成しました。
[Project]ウィンドウ > [Create]ボタン > Folder を選択。Materials フォルダを作成。次に [Project]ウィンドウ > [Create]ボタン > Material を選択。3つのマテリアル(Background-Front、Background-Middle、Background-Back)を作成。
マテリアルのシェーダーは Unlit/Transparent に設定します。

マテリアルにテクスチャを割り当てます。
[Project]ウィンドウでマテリアルファイルを選択して、[Inspector]ウィンドウのテスクチャスロットを表示しておきます。[Project]ウィンドウ > Texturesフォルダのテクスチャを[Inspector]ウィンドウのテスクチャスロットにドラッグ&ドロップで割り当てます。

マテリアルが完成しました。

Frontを作る
背景オブジェクトのスケールも変更します。
Backgrounds > Front を選択して [Inspector]ウィンドウ > Transform > Scale X 10.67 / Y 6 / Z 0 に設定。

元のテクスチャが縦横比4:3の画像なので、縦横比16:9に変更した 背景オブジェクトに割り当てると横に引き延ばされますが、とりあえず今はこのままにしておきましょう。

背景をスクロールさせる
こちらの手順で作成するスクリプト Emitter にコメントを追加しました。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Background : MonoBehaviour
{
// スクロール速度を格納する変数(初期値 0.1)
public float speed = 0.1f;
// ゲーム実行中の繰り返し処理
void Update()
{
// ゲーム進行時間を0から1にループ変化する値を y に格納
float y = Mathf.Repeat(Time.time * speed, 1);
// 新規ベクトル offset を作成して Y座標が変化する値を渡す
Vector2 offset = new Vector2(0, y);
// Render コンポーネントを取得してマテリアルのテクスチャに座標 offset 値を設定する
GetComponent<Renderer>().sharedMaterial.SetTextureOffset("_MainTex", offset);
}
}
Wave型の仕組み作り
チュートリアルページ:Wave型の仕組み作り
このステップの手順は次の通りです。
- Waveの作成
- Waveを呼び出すEmitter (エミッター)を作成する
Waveの作成
ここの手順でチュートリアルでは左右の敵機の位置のX値は-1、1 となっていますが、ゲーム画面の縦横比変更に合わせて X-2.5と2.5 に変更しました。

プレハブの数が6つになりました。

Waveを呼び出すEmitter (エミッター)を作成する
こちらの手順で作成するスクリプト Emitter にコメントを追加けました。チュートリアルではスクリプトの処理については詳しく解説されていないので、配列の処理を理解するのに悩みました。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Emitter : MonoBehaviour
{
// 敵機のプレハブ Wave を格納する配列
public GameObject[] waves;
// 現在の敵機のインデックス
private int currentWave;
//ゲームスタート時の処理(コルーチン)
IEnumerator Start()
{
// 配列が空であれば(Wave が存在しなければ)
if (waves.Length == 0)
{
// コルーチン終了
yield break;
}
// 繰り返し処理
while (true)
{
// 配列に格納されたプレハブ Wave からインスタンスを生成して wave に格納
GameObject wave = (GameObject)Instantiate(waves[currentWave],
transform.position, Quaternion.identity);
// 敵機 wave を Emitter の子要素にする
wave.transform.parent = transform;
// Emitter の子要素の敵機 wave の数が 0 でなければ
while (wave.transform.childCount != 0)
{
// 削除されるまで待機する
yield return new WaitForEndOfFrame();
}
// 敵機 wave の削除
Destroy(wave);
// 現在の敵機のインデックスに加算し、配列に格納された数以上になれば
if (waves.Length <= ++currentWave)
{
// 現在の敵機のインデックスを 0 にする
currentWave = 0;
}
}
}
}
WebGL
ここまでの内容を動作確認用にWebGLでビルドしてみました。ちょっとゲームらしくなってきました。
画像クリックで再生(ファイルサイズ:約6MB)