![見出し画像](https://assets.st-note.com/production/uploads/images/36727709/rectangle_large_type_2_3d8080ab4bb63720f897622a5cc40cb1.png?width=1200)
【Unity】3Dローグライクゲームの作り方〜Step11-6〜
前回の記事はこちら。
前回はミニマップを改良しました。
敵の種類を追加
いつまでも敵が1種類だとつまらないので、種類を増やしてみたいと思います。有難いことに「RPG Monster Duo PBR Polyart」には2種類敵キャラクターが用意されているので、もう片方のカメっぽいキャラクターを追加してみましょう(勿論他のキャラクターを追加しても構いません)。
まずプレハブを用意します。Field上のEnemies階層下に追加したいキャラクターを配置し、名前を任意に変更します(筆者は「Enemy2」にしました)。
アニメーターコントローラーの設定
次にアニメーターコントローラーを新たに用意しましょう。
AnimatorControllersフォルダ内に新しくアニメーターコントローラーを追加し、名前を変更します(筆者は「EnemyAnimator2」にしました)。
EnemyAnimator1を開き、中身を全てコピーして下さい。それを新しく作成したアニメーターコントローラーの中に貼り付けましょう。
上記のような流れになればOKです。もしEntryの線がWalkingに伸びていない時はWalkingを「右クリック」→「レイヤーデフォルトステートとして設定する」を選択するといいでしょう。
Triggerパラメーター「Attack」を追加しておくのも忘れずに行って下さい。
後は中身のアニメーションをそのキャラクターにあったものに入れ替えるだけです。
出来上がったら、先ほど作成した敵キャラクターのオブジェクトのControllerにこれを設定しておきます。
コンポーネントの設定
次に敵オブジェクトに必要なコンポーネントを追加したいと思います。
必要なコンポーネントは以下の通りです。
・Actor Params Controll → 項目設定しない
・Inventory
・Actor Movement
・Actor Attack
・Enemy Operation → 項目設定しない
・Actor Action
・Actor Use Items
数が多いですが(すみません)頑張って追加しましょう。また、それぞれの項目も忘れずに設定しておきます。ただし、上記で「項目設定しない」としたもの2つについては触らないようにお願いします。
EActorに追記
列挙定数EActorに以下を追記します。「TURTLE」は任意に変更して下さい。
TURTLE = 2
ここまでできたら、敵オブジェクトをプレハブ化し、ヒエラルキータブ内からは削除して下さい。
ExcelActorDataファイルに追記
まずはExcelActorDataファイルから行います。
まず1枚目に対応するID名などを入力します。
次にstatusで指定した名前で新しいシートを作成し、そこに新たな敵キャラクターのステータスを入力しましょう。
若干スライムより強くしてみました。
更にExcelActorDataクラスに以下のパラメーターを追記します。
public List<Params> Enemy2;
「Enemy2」は先ほどstatusで指定した値にしておきましょう。
これができたらXLSXファイルを保存(ダウンロード)し、Resources/Datasフォルダ内のものと置き換えます。
ExcelAppearDataファイルに追記
以下のようにします。id2からが追加した分です。
ExcelAppearData.EnemyAppearDataクラスに以下のパラメーターを追記します。
public EActor id2;
public int lvmin2;
public int lvmax2;
public int rate2;
できたらXLSXファイルを保存(ダウンロード)し、Resources/Datasフォルダ内のものと置き換えましょう。
次にFieldクラスのSetEnemyメソッドを変更します。
private void SetEnemy(string name, int xgrid, int zgrid)
{
EActor actorId = EActor.SLIME;
ExcelAppearData.EnemyAppearData enemyAppear =
appearDatabase.EnemyAppear.Find(n => n.floor == floorNum);
if (name.Equals("Random"))
{
int maxRate = enemyAppear.rate1 + enemyAppear.rate2;
int r = Random.Range(1, maxRate + 1);
if (r <= enemyAppear.rate1) actorId = enemyAppear.id1;
else actorId = enemyAppear.id2;
}
else if (!System.Enum.TryParse(name, out actorId)) return;
ExcelActorData.ActorData actorData = actorDatabase.Data.Find(n => n.id == actorId);
if (actorData == null) return;
int lv = 1;
if (actorId == enemyAppear.id1) lv = Random.Range(enemyAppear.lvmin1, enemyAppear.lvmax1 + 1);
if (actorId == enemyAppear.id2) lv = Random.Range(enemyAppear.lvmin2, enemyAppear.lvmax2 + 1);
GameObject enemyObj = (GameObject)Resources.Load("Prefabs/" + actorData.prefab);
GameObject enemy = Instantiate(enemyObj, enemies.transform);
enemy.GetComponent<ActorMovement>().SetPosition(xgrid, zgrid);
enemy.GetComponent<ActorParamsController>().SetLv(lv);
enemy.GetComponent<EnemyOperation>().target = playerMovement;
}
ビルドしたら、テストしたいと思います。
その前にマップファイルの敵オブジェクトを「Random」か「Turtle(任意のID名)」にしておくと確認しやすいでしょう。
ちゃんと新しい敵が追加されましたか?
サイズ調整も行っておきましょう。
次回はアイテムの追加方法をまとめたいと思います。
おまけ:敵が追いかけて来なくなる
という不具合を把握したので少し改善しました。
private bool DetectTarget(ActorMovement actorMovement)
{
Field field = GetComponentInParent<Field>();
Pos2D agrid = actorMovement.grid;
Pos2D tgrid = target.newGrid;
ObjectPosition room = field.GetInRoom(agrid.x, agrid.z);
if (room == null)
{
if (agrid.x == tgrid.x)
{
for (int z = Mathf.Min(agrid.z, tgrid.z), ez = Mathf.Max(agrid.z, tgrid.z); z < ez; z++)
{
if (field.IsCollide(agrid.x, z)) return false;
}
return true;
}
if (agrid.z == tgrid.z)
{
for (int x = Mathf.Min(agrid.x, tgrid.x), ex = Mathf.Max(agrid.x, tgrid.x); x < ex; x++)
{
if (field.IsCollide(x, agrid.z)) return false;
}
return true;
}
return false;
}
if (field.IsInRoomOf(room, tgrid.x, tgrid.z)) return true;
else
{
if (agrid.x == tgrid.x)
{
for (int z = Mathf.Min(agrid.z, tgrid.z), ez = Mathf.Max(agrid.z, tgrid.z); z < ez; z++)
{
if (field.IsCollide(agrid.x, z)) return false;
}
return true;
}
if (agrid.z == tgrid.z)
{
for (int x = Mathf.Min(agrid.x, tgrid.x), ex = Mathf.Max(agrid.x, tgrid.x); x < ex; x++)
{
if (field.IsCollide(x, agrid.z)) return false;
}
return true;
}
}
return false;
}
敵が部屋にいる時もプレイヤーが同じ部屋にいない場合は、敵が通路にいる時と同じ判定をすることにしました。
この記事が気に入ったらサポートをしてみませんか?