【Unity】3Dローグライクゲームの作り方〜Step12-13〜
前回の記事はこちら。
前回は自動生成されたダンジョンにマーキングしました。
敵をランダム配置する
今回は敵をランダム配置していきたいと思います。
まずFieldクラスに新しいメソッドを追加し、SetObjectメソッドを変更します。
// 新しいメソッドを追加
/**
* フィールドに敵を設置する
* nameに「Random」が指定されていた場合はその場所にランダムな敵を設置する
*/
private void SetEnemy(string name, int xgrid, int zgrid)
{
EActor actorId = EActor.SLIME;
if (name.Equals("Random"))
{
ExcelAppearData.EnemyAppearData enemyAppear =
appearDatabase.EnemyAppear.Find(n => n.floor == floorNum);
int maxRate = enemyAppear.rate1;
int p = Random.Range(1, maxRate + 1);
maxRate -= enemyAppear.rate1;
if (maxRate <= 0) actorId = enemyAppear.id1;
}
else if (!System.Enum.TryParse(name, out actorId)) return;
ExcelActorData.ActorData actorData = actorDatabase.Data.Find(n => n.id == actorId);
if (actorData == null) return;
GameObject enemyObj = (GameObject)Resources.Load("Prefabs/" + actorData.prefab);
GameObject enemy = Instantiate(enemyObj, enemies.transform);
enemy.GetComponent<ActorMovement>().SetPosition(xgrid, zgrid);
enemy.GetComponent<EnemyOperation>().target = playerMovement;
}
// メソッドを変更
public void SetObject(string name, string type, int xgrid, int zgrid)
{
switch (type)
{
case "Stairs":
/* 省略 */
case "Connection":
/* 省略 */
case "Enemy":
SetEnemy(name, xgrid, zgrid);
break;
case "Item":
/* 省略 */
}
}
そして、LoadFieldMap.RandomDungeonクラスのSetObjectsメソッドを変更します。
private void SetObjects(Field field)
{
/* 省略 */
SetObject("UpStairs", "Stairs", field, tmpData);
SetObject("DownStairs", "Stairs", field, tmpData);
int num = Random.Range(enemyNum[0], enemyNum[1] + 1);
for (int i = 0; i < num; i++)
SetObject("Random", "Enemy", field, tmpData);
num = Random.Range(itemNum[0], itemNum[1] + 1);
for (int i = 0; i < num; i++)
SetObject("Random", "Item", field, tmpData);
}
テストしてみます。自動で生成されたダンジョン内に敵がランダムで配置されればOKです。
その上で敵が自動巡回すればOKです。
最下層をマップデータに設定する
最下層(というよりかはプレイヤーのスタート地点ですが)を設定したいと思います。
なお、今回の実装では必ず1F(スタート地点)が固定マップであることを前提としています。
まず1Fのマップデータファイルを編集します。
上記のように今までDownStairsを置いていた場所にTypeに「StartPoint」を設定したオブジェクトを配置します。そして元々のDownStairsは削除するのではなく壁のある所(例えば0, 0の位置など)に配置し直します。
保存したら、マップデータファイルをAssetsフォルダ内のものと置き換えましょう。
次にFieldクラスに新しいパラメーターを追加し、メソッドを変更します。
// パラメーターを追加
private bool isStart = true;
// メソッドを変更
public void SetObject(string name, string type, int xgrid, int zgrid)
{
switch (type)
{
case "StartPoint":
if (isStart)
{
playerMovement.SetPosition(xgrid, zgrid);
isStart = false;
}
break;
case "Stairs":
if (name.Contains("Down"))
stairs.GetComponentsInChildren<ObjectPosition>()[1].SetPosition(xgrid, zgrid);
else
stairs.GetComponentsInChildren<ObjectPosition>()[0].SetPosition(xgrid, zgrid);
if (name.Contains(startStairs) && !isStart)
playerMovement.SetPosition(xgrid, zgrid);
break;
case "Connection":
/* 省略 */
case "Enemy":
/* 省略 */
case "Item":
/* 省略 */
}
}
テストしてみます。同じ場所にプレイヤーが表示されてはいますが、階段がなくなっているのでそれより下の階には行けなくなったと思います。
上の階に行って戻ってきたら、スタート地点ではなく、ちゃんと上り階段の上にプレイヤーが移動することも確認しておきましょう。
という訳で、他にも実装しないといけない事がありそうな気もしますが、
本ステップはこの辺りで終了させて頂きます。
ここまでお付き合い下さり、ありがとうございました。
この記事が気に入ったらサポートをしてみませんか?