単体で敵の出現させる方法が出来たあなたには、1Wave分の敵を生成することも可能です。直接プログラムで行うのもいいですが、敵の出現データもスクリプタブルオブジェクトを使うことで、視覚的に編集を行いやすくしてみましょう。
敵の出現情報(Wave情報)
敵が現れるデータをどの様に編集するかですが、今回はスクリプタブルオブジェクトを活用したいと思います。
スクリプタブルオブジェクト用のスクリプト作成
今回の敵の出現データは1ライン分のみを作成します。実際のゲームだと3方向からやってきたりする場合、このデータを増やすことで対応出来ます。
処理としては、指定した秒数ごとに敵を出現させるかの判定を行い、データがセットされている場合敵の出現を行う。
- 出現チェックのインターバル時間
- 敵の出現順序
WaveDataスクリプトを作成して、次のようなスクリプタブルオブジェクトを作って見ましょう
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName = "WaveData", menuName = "TD/Create WaveData")]
public class WaveData : ScriptableObject
{
public float intervalSec = 1.0f;
public List<EnemyData> enemyDataList;
}
データの準備
スクリプトが編集できたら、実際にデータを作成します。ScriptableObjectフォルダの中で右クリック>Create>ScriptableObjects>Create WaveDataを選択します。
作られたアセットを選択肢、インスペクターを確認します。EnemyDataListのサイズを10と変更し、エンター。リストを展開すると10個分の枠が確保されます。確保できたら下図を参考にEnemyDataをセットしてみてください。
このデータだと、ゲーム開始後に2秒後、4秒後、6秒後に設定している敵を出現させることができるようなデータとして扱います。
Waveでの敵出現処理
作成したデータを利用して、敵を出現させてみましょう
Generator改良
前回のGeneratorでは、Startメソッドで指定された敵のデータを使って敵を出現させました。今回はWaveDataの中のデータを利用します。Generatorでは時間経過を見ながら、どの敵を出現させるかを判断させる必要があります。また、リストで指定した上限を超える場合、スクリプトを停止する必要があります。今回はenabledを使ってUpdateなどライフサイクルと呼ばれる機能を停止します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyGenerator : MonoBehaviour
{
[SerializeField] private LineRenderer lineRenderer;
[SerializeField] private Castle targetCastle;
[SerializeField] private WaveData waveData;
[SerializeField] private EnemyController enemyPrefab;
private float timer = 0.0f;
private int enemyIndex = 0;
private void Start()
{
// 最初の敵をすぐに出現させるために、timerをintervalSecに設定する
timer = waveData.intervalSec;
}
private void Update()
{
timer += Time.deltaTime;
if (waveData.intervalSec <= timer)
{
timer = 0.0f;
EnemyData enemyData = waveData.enemyDataList[enemyIndex];
// データがセットされている場合、敵を生成する
if (enemyData != null)
{
var enemy = Instantiate(enemyPrefab, transform.position, Quaternion.identity);
enemy.Initialize(enemyData, lineRenderer, targetCastle);
}
enemyIndex++;
if (waveData.enemyDataList.Count <= enemyIndex)
{
// 敵が全て出現したら、このスクリプトを無効にする
this.enabled = false;
}
}
}
}
インスペクターにセットして試運転
スクリプトが準備出来たら試運転してみたいと思います。インスペクターに設定を行う必要があるので注意。EnemyDataの代わりにWaveDataをセットする必要があります。手順通りであればセットできるアセットは1つだけなので右の丸ポチから呼び出すのが簡単かと思います。
うまく準備ができていれば、時間通りに敵が出現してくれます。
敵が残りっぱなしなので、終端で削除する
敵は作れたけど、お城に居座り続けているので削除する処理を追加してみましょう。EnemyControllerのLineMoverが終点に到着したときのイベントに追記します。ここではスクリプトの一部のみを抜粋します。
lineMover.OnEndReached += (sender, e) =>
{
Debug.Log("お城に到着したよ!");
if (this.targetCastle != null)
{
this.targetCastle.TakeDamage(power);
var impulseSource = GetComponent<CinemachineImpulseSource>();
impulseSource.GenerateImpulse(0.1f);
}
// 自分を削除する処理を追加
Destroy(gameObject);
};
コメント