プレイするゲームがないなら、自分で作ればいいじゃない!
ということで Unity 初心者が「ゲームを作る」ゲームをやっていきます!
今回は「敵をウェーブシステムで生成してみた」の記事です
内容
ウェーブ(敵やイベント等の情報の塊)を用意して
ウェーブを管理するシステムを作成する
前回のランダム生成から…
ランダム任せは難しい・・・ということで
巷で「ウェーブ」と呼ばれるものを作ってみる!
やりたいこと
- エディタで敵の配置、設定を行う
- 小分けにできるようにして確認しやすいように
- 敵だけでなく色々なものを設定したい
ウェーブオブジェクトクラス
ウェーブに組み込みたいオブジェクトはこのクラスを継承させる
public class WaveObj : MonoBehaviour
{
enum END_TYPE
{
NONE = 0,
EXISTENCE, // 存在していたらウェーブ終了にならない
}
[SerializeField] END_TYPE endType = END_TYPE.NONE;
// ウェーブを終了していいか
public bool IsEnd()
{
if (endType == END_TYPE.EXISTENCE)
{
if (gameObject) { return false; }
}
return true;
}
}
IsEnd
true にならないと次のウェーブに進まない
今回は敵を倒さないと次に進めないようにするために使用
ウェーブクラス
WaveObj クラスと生成時間を管理するクラス
時間になると設定した WaveObj をアクティブ状態にする
public class Wave : MonoBehaviour
{
[System.Serializable]
struct ObjData
{
public int generateFrame;
public WaveObj waveObj;
}
[SerializeField] List<ObjData> objList; // オブジェクトリスト
int nowObj = 0; // 今のオブジェクト
int frame = 0;
bool waveEnd = false;
void Start()
{
// 全てのオブジェクトを無効にする
for (int i = 0; i < objList.Count; ++i)
{
if (objList[i].waveObj)
{
objList[i].waveObj.gameObject.SetActive(false);
}
}
}
void Update()
{
if (objList.Count <= 0 || waveEnd) return;
++frame;
// オブジェクトを有効にする
while(frame >= objList[nowObj].generateFrame)
{
if (objList[nowObj].waveObj)
{
objList[nowObj].waveObj.gameObject.SetActive(true);
}
NextObj();
if (waveEnd) { break; }
}
}
// 次のオブジェクトへ
void NextObj()
{
if (nowObj < (objList.Count - 1))
{
++nowObj;
frame = 0;
}
else
{
waveEnd = true;
}
}
// ウェーブ終了
public bool IsEnd()
{
// オブジェクト毎の終了判定
for (int i = 0; i < objList.Count; ++i)
{
if (objList[i].waveObj)
{
if (!objList[i].waveObj.IsEnd())
{
return false;
}
}
}
// 全てのオブジェクトが有効になっていれば終了
return waveEnd;
}
// 全てのオブジェクトが消えたか
public bool IsDelete()
{
for (int i = 0; i < objList.Count; ++i)
{
if( objList[i].waveObj )
{
if (objList[i].waveObj.gameObject)
{
return false;
}
}
}
return true;
}
}
ウェーブ管理クラス
Wave クラスを管理するクラス
Wave クラスが終了判定になったら次のウェーブを生成する
public class WaveManager : MonoBehaviour
{
[SerializeField] List<Wave> waveList; // ウェーブリスト
[SerializeField, Min(0)] int waveIndex = 0; // ウェーブ番号
List<Wave> cloneList = new List<Wave>(); // クローンリスト
int cloneIndex = 0; // クローン番号
bool listEnd = false; // 終了フラグ
void Start()
{
StartWave(waveIndex);
}
void Update()
{
// ウェーブの削除確認
for (int i = 0; i < cloneList.Count; ++i)
{
if (cloneList[i] && cloneList[i].IsDelete())
{
Destroy(cloneList[i].gameObject);
}
}
if (waveList.Count <= 0 || IsEnd()) return;
// ウェーブが終わった
if(cloneList[cloneIndex].IsEnd())
{
// 次のウェーブへ
NextWave();
}
}
// ウェーブ開始
void StartWave(int _index)
{
cloneList.Add( (Wave)Instantiate(waveList[_index]) );
}
// 次のウェーブへ
void NextWave()
{
if(waveIndex < (waveList.Count - 1))
{
++waveIndex;
++cloneIndex;
StartWave(waveIndex);
}
else
{
listEnd = true;
}
}
// 全てのウェーブが終了したか
public bool IsEnd()
{
return listEnd;
}
}
waveIndex
インスペクタービューで設定できるようにして
確認したいウェーブから始められるようにする
エディタ画面
空のオブジェクトを作成して、Wave をアタッチする
作成したオブジェクトを親にして、WaveObj を継承したオブジェクトを追加
最後にプレハブ化する
空のオブジェクトを作成して、WaveManager をアタッチ
プレハブ化したウェーブを設定する
サンプル動画
試しに3つのウェーブを作ったものです
ウェーブ2は全ての敵を倒さないと次に進まない仕様
さいごに
ステージ作るためのシステムができたので
ステージを構成するオブジェクトを増やしていきたい!
コメント