前回までで敵キャラができたので、今度は敵キャラを一定間隔で生成するオブジェクトをつくっていきましょう。
敵キャラ生成オブジェクトの仕様
ここで作る敵キャラ生成オブジェクトは次のような動作をします。
- ランダムな間隔をあけてゾンビのインスタンスを生成する。ただしゾンビが一定数以上いる場合は新しいインスタンスを生成しない。
- インスタンスの生成位置はX座標に多少ばらつきを持たせるようにする。
では早速これをスクリプトに落とし込んでいきましょう。
敵キャラ生成オブジェクトのC#スクリプト
今回私が書いたC#スクリプトは次の通りです。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class EnemySpawner : MonoBehaviour { public bool spawnEnabled = false; [SerializeField] int maxEnemies = 10; [SerializeField] float minPositionX = -3; [SerializeField] float maxPositonX = 3; [SerializeField] float minSpawnInterval = 1; [SerializeField] float maxSpawnInterval = 3; [SerializeField] GameObject[] enemyPrefabs; bool spawning = false; void Update() { if (spawnEnabled) { StartCoroutine(SpawnTimer()); } } IEnumerator SpawnTimer() { if (!spawning) { if (SpawnEnemy()) { spawning = true; float interval = Random.Range(minSpawnInterval, maxSpawnInterval); yield return new WaitForSeconds(interval); spawning = false; } else { yield return null; } } yield return null; } bool SpawnEnemy() { GameObject[] enemies = GameObject.FindGameObjectsWithTag("Enemy"); if (enemies.Length >= maxEnemies) { return false; } else { int choosedIndex = Random.Range(0, enemyPrefabs.Length); float diffPositionX = Random.Range(minPositionX, maxPositonX); Vector3 position = new Vector3(transform.position.x + diffPositionX, transform.position.y, transform.position.z); Instantiate(enemyPrefabs[choosedIndex], position, Quaternion.identity); return true; } } }
スクリプトが書けたら、空のゲームオブジェクトを作って名前を「EnemySpawner」、タグを「Spawner」(※新しく追加してください)に変更して、このスクリプトをアタッチしてください。
スクリプトの解説
SpawnTimer()メソッド
後述の敵生成メソッドで敵を生成した場合、Random.Range()を使って次の生成までの待ち時間をランダムに設定します。
SpawnEnemy()メソッド
最初にGameObject.FindGameObjectsWithTag()で今シーンにいるすべての敵オブジェクトが格納された配列を得ます。そして、もしその配列の要素数が敵の最大数以上なら処理を終了し、そうでないならあらかじめ設定した敵の中からランダムに選んでインスタンスを生成します。
GameManagerの変更
次にGameManagerを少し変更します。変更する理由は、GameManager側でSpawnerのOn/Offを切り替えたいからです。全部載せると長くなってしまうので適当に省略しておきますね。
//--前略-- public class GameManager : MonoBehaviour { //--省略-- [SerializeField] EnemySpawner[] spawners; //--省略-- public IEnumerator GameStart() { yield return new WaitForSeconds(waitTime); centerText.enabled = true; centerText.text = "3"; yield return new WaitForSeconds(1); centerText.text = "2"; yield return new WaitForSeconds(1); centerText.text = "1"; yield return new WaitForSeconds(1); centerText.text = "GO!!"; firstPerson.playerCanMove = true; firstPerson.enableCameraMovement = true; gunCOntroller.shootEnabled = true; SetSpawners(true); yield return new WaitForSeconds(1); centerText.text = ""; centerText.enabled = false; } public IEnumerator GameOver() { gameOver = true; firstPerson.playerCanMove = false; firstPerson.enableCameraMovement = false; gunCOntroller.shootEnabled = false; SetSpawners(false); centerText.enabled = true; centerText.text = "Game Over"; yield return new WaitForSeconds(waitTime); DestroyEnemies(); centerText.text = ""; centerText.enabled = false; gameOver = false; } //--省略-- void SetSpawners(bool isEnable) { foreach(EnemySpawner spawner in spawners) { spawner.spawnEnabled = isEnable; } } }
Spawnerを格納する配列を用意して、そのSpawnerを一括してON/OFFできるメソッドを作りました。これでゲーム中でないときはゾンビが生成されないようになります。
変更ができたらGameManagerのSpawnersのところにシーン上のEnemySpawnerを設定してください。
実際の動作の様子
テストプレイして下の動画のように続々とゾンビが出現すればOKです。
※次のページでゾンビへのダメージ処理を追加すると倒せるようになります。