2016年11月6日日曜日

【ウディタ】ARPGの戦闘システムをつくる(2)NPCのAI

前回の記事を書いたあと、NPCのAIづくりをやっていました。
やたら重かったり、使い勝手が悪かったりしたのと、最終的に落ち着いたもののバグ取りに時間がかかって、結局5日ほどを費やしてしまいました。

処理の方法ですが、
確率行動+特定条件下で指定された行動をする
という形に落ち着きました。細かい条件指定とかはできないですが、まあターン制のバトルじゃないので、ある程度ゆるいAIでないとうまくいかないでしょう、きっと。負荷もきついしね。

個人的な要件としては、
味方属性のNPCの存在を考慮すること(シナリオ上の理由から)。
敵属性の仲間同士で補助ができるような処理をつくること。
RPGらしく一定HP切ったら本気モードとかできるようにしたい。
ある程度NPCが手加減できる仕様を入れること。
状況に応じて多少戦い方を変えられるとなおよし
…こんな感じ。まあ、以前クエストシステムとか作っていたときよりはざっくりとしたところから形にしています。大丈夫かよって感じもするでしょうが、実際ほぼ期待通りの動作ができているので、いいんじゃないでしょうか。期待通りの動作をするまでにいくつかバグ出たので潰したりもしましたし…。

仕様

NPCが使用できる技は基本3種類まで。あとは特殊行動用に+3種類があります
また、行動処理と移動処理には、キャンセル率を設定できます。移動はランダム移動時にそれっぽく見せるため、行動処理は、技が撃てるときに必ず撃つようにすると鬼畜難易度になってしまうためです。
ぎゃくにいえば、キャンセル率を調整することで難易度調整できるということでもあります。雑魚敵は高めに、ボスは低めにといった感じ。重要ですね。

特殊行動
特定条件を満たしたとき、必ず実行する行動
条件は、
①自身の残りHP%が、指定%以上または以下のとき
②行動(攻撃/回復)した回数が指定回数目のとき
③敵または味方との距離が、指定範囲の内または外にいるとき
で、「または」を挟んでいる要素はどちらか選択する形になるので、実質的には7種類の条件が存在します

この条件を満たしたとき、
AIを切り替えるか、指定された技を使うことができます。
AI切り替えは何度でもできますが、指定された技は一度しか使えません。技が一度しか撃てないのは、節目ごとに大技を放つような使い方を想定しているため。

これでなにができるかというと、たとえば
・敵が離れたところにいるとき、自己強化に特化したAIに切り替えて待ち構える
・敵が近距離戦闘タイプだったので、自身も近距離戦闘のAIに切り替えて応戦。間合いが取れたら遠距離攻撃のAIに戻す
・HPが減ってきたので大技をぶっ放す/本気モードのAIに切り替える

みたいな感じ。1キャラ1AIではなく、複数種のNPCが1つのAIを使えるようなつくりにしたことで、AI切り替えが実装できました
わりと重要なシステムです。

行動
指定された範囲内に敵または味方がいたとき、攻撃または回復を確率で選択し、確率で最も高威力または最も低コストの技を選択して、技を発動する処理。
当たり判定の範囲を考慮すると、どうあがいても処理がめっちゃ増えるので考慮してません。

走査
指定された範囲内にいる、最も残りHP%の低い敵味方、最も近い敵味方と走査しているキャラとの距離と見つけた敵味方のイベント番号をデータベースに保存する処理。
主人公だけ探すのではなく、敵同士とか、味方同士の情報も探せるので、敵が弱っている仲間を回復しに向かう行動なんかができます。

ウディタ関連のサイトでこういう走査処理について扱っているところは少ないと思うのですが、数少ないそのサイトでは、この処理走査をする処理はどうあがいてもスッゲー重くなると書かれていました。主人公だけ探すなら楽らしいけど。
ちなみに自分は負荷対策で、生きている戦闘可能キャラかつ画面内にいるNPCのみ処理するようにしています。画面外からひっそり近づいてくるNPCは今のところ作れないというわけです

移動
確率で敵か味方に、
指定範囲内に対象がいるときだけ、
確率で残りHP%が最も減っているやつか最も近いやつに接近する処理です。
敵か味方を確率で選択する処理は実質死んでいるようなもので、実際は敵100%か味方100%にしないと、NPCが敵と味方の間を右往左往し始めて使い物にならなくなります
範囲内に誰もいなかったらランダムに移動します。

まだ経路探索処理という、障害物を回避できるようなかしこい処理が未実装なので、これから重くなる処理です。それさえできればもうAI処理の処理部分はできあがりとなるはず…。
さっきウディタ公式のコモン集を見たらちょうど経路探索処理をしてくれるコモンがあったので、組みこめそうな処理だったら組み込むかもしれません。無理だったら自分で組みます。


そんなわけでおおむねAI処理ができたので、画面処理を作っているのですが、これもむずかしい…。