障害物の周りの多くの群がっている敵を効率的に経路探索する


20

私はゲームの敵の経路探索を改善しようとしています。現在、彼らは基本的に、プレイヤーとプレイヤー間の角度を計算し、その方向に移動することにより、プレイヤーの正確な位置に向かって絶えず移動しています。また、敵が互いの上に積み重なるのを防ぐ群れアルゴリズムを持っているので、敵が互いを挟むのではなくグループになります。

ただし、タイルベースのマップを追加したので、たとえば障害物や壁の周りを敵が通過できるようにする必要があります。私は最初、群れアルゴリズムが壁や障害物を遠ざけるオブジェクトと見なすように、「歩行不可能な」タイルに分離値を追加しようとしました。私の最初のテストでは、敵が歩くことのできないタイルのない目に見えない「壁」にぶつかったことが示されたので、これが実現可能かどうかはまだ解明していません。

A *を使用してプレーヤーへのパスを計算し、群れを防ぐために群れアルゴリズムを使用するには、パフォーマンスが重すぎるのではないかと考えていました。もともと私のゲームは波ベースのシューティングゲームになる予定でしたが、代わりにホットラインマイアミの静脈内でレベルベースにすることを決めたので、たまに大群とともに敵を減らし、それらが強くなります。

これは実行可能なソリューションですか?ゲームエンジンとしてSlick2DでJavaを使用しています。または、これら両方の問題に取り組むより良い解決策/アルゴリズムがありますか?


7
編集で説明したように、「これは重すぎます」は、プロファイラーに尋ねる質問です。これは、実装、ターゲットハードウェア、パフォーマンス予算、およびゲームのコンテキストに依存するためです。親密ですが、インターネットの見知らぬ人はそうではありません。群れの経路探索を効率的に行いたい場合は、それを支援する戦略を提案できますが、あなたのニーズに十分に効率的なものに答えることができるのは自分のプロファイリングだけです。特定のパフォーマンス問題をプロファイリングして特定する場合、その問題を解決する方法を見つけることもできます。
DMGregory

1
それらの実装方法はパフォーマンスに影響します。たとえば、リーダーでのみA *を実行し、フォロワーの群れに依存しています。
ピカレック

ゲームが主にこれらの敵と戦うことに基づいている場合、あなたが取るアルゴリズムはゲームの雰囲気に大きな影響を与えます。敵は常にプレイヤーのレベルと位置を完全に知っており、すべてを知っているAIの指示のように彼を追跡しているように感じますか?-他のアプローチは...敵はプレイヤーが彼に向かって視界実行の直接のライン上のノイズのみ作られた、またはプレーヤーは他の敵を叫んと知らせる一般的な方向に実行できるようにすることができ
ファルコ

@Falcoゲームはもはやウェーブベースではなく、レベルベースになるので、敵はゾンビなので...あなたを見つけるためにあなたが見なければならないか、騒がせなければならないようにすることを考えていました。ノイズの多い武器を使用する場合はどうですか?範囲内の音を発し、範囲内のすべての敵は発した音の位置に向かってパスし、そのエリアの周りをランダムにパスします。
ダリンボードロー

回答:


49

これは、フローフィールドのユースケースのように聞こえます。

この手法では、プレーヤーオブジェクトから外側に向かって単一のパス検索クエリを実行し、到達した各セルに到達したセルをマークします。

すべてのタイル/エッジの走査コストが等しい場合、単純な幅優先探索を使用できます。それ以外の場合、ダイクストラのアルゴリズム(ゴール/ヒューリスティックのないA *など)が機能します。

これにより、フローフィールドが作成されます。各ルックアップテーブルは、各セルを、その位置から最も近いプレーヤーオブジェクトに向かう次のステップに関連付けます。

これで、敵はそれぞれ独自のパス検索クエリを実行することなく、フローフィールドで現在位置を検索して、最も近いプレーヤーオブジェクトへの最短障害物回避パスの次のステップを見つけることができます。

これは、群れの中にいる敵が多いほど良くなります。1人の敵に対しては、マップ全体を検索するため、A *よりも高価です(ただし、すべての経路探索エージェントに到達すると、早期に削除できます)。しかし、敵を追加すると、共有パスセグメントを何度も計算するのではなく、一度計算することで、パスファインディングコストをより多く共有できるようになります。また、BFS / DijkdtraのほうがA *よりも単純であり、通常、検査対象のセルごとに評価する方が安価であるという事実からも得られます。

個別のA *が安価なものから、メモ化が安価なA *に分岐点が当たる正確な場所(過去のパス検索クエリの結果の一部を再利用して、次のクエリを高速化する)、安く、実装、エージェントの数、マップのサイズに依存します。しかし、限られたエリアで複数の方向から接近する敵の大群を計画する場合、1つのフローフィールドは、ほぼ確実に反復A *よりも安くなります。

極端な例として、ここに2万人のエージェントが全員適度に小さなグリッドで同時に経路探索するビデオを見ることができます


このテクニックは本当にきれいに聞こえます。確かめます。
ダリンボードロー

15
これは、*希望Aを繰り返し呼び出しよりも多くのマップの検索、せずに部分的流れ場を構築するハイブリッドアルゴリズムを使用することが可能ですし、決して二度同じ位置を検索しません。基本的な考え方は、任意の敵を選択し、プレイヤーからその敵に向けてA *検索を開始し、通常のフローフィールド生成と同じように、セルに遭遇したときにセルをマークすることです。検索でその敵が見つかったら、別の敵(まだ見つけていない)をターゲットとして選択し、新しいヒューリスティックに従ってオープンセットを再ソートし、検索を続けます。すべての敵を見つけたら停止します。
イルマリカロネン

1
衝突を避けることはどうですか?これは(ある程度)OPで言及されています(プレーヤーに到達するときにクリッピングを回避します)。何かが移動するたびにフルdjikstrasを再実行する必要があるように思えます(または追加のロジックを追加する)
Mars

2
@Mars OPは群れについて話すので、すべての人が同じ速度で動くことができると思います。衝突が問題になる唯一の場所はボトルネックであり、群れの一部が停止して待機する必要があります。ただし、パスファインディングを実際に変更する必要はありません-ほとんどの場合、単純なキューがおそらく十分に機能し、一部のパスバイアス(同様のコストの代替パスの擬似ランダム選択)は、より自然な群れを生成するために機能しますまた、特定の単一タイルギャップを通過しようとする群れ全体を回避するフロー:)
Luaan

3
@Luaanタイルベースのゲームでは、衝突が発生する頻度に驚くでしょう。個人的には、「キューイング」オプションは最適ではありません。また、ユニットが相互に通過できない場合、ユニットが最終位置と他の多数のエッジケースに到達し始めるときに再計算する必要があります。群れが難しい;)
火星

8

A *はパフォーマンスに影響しません。アルゴリズムを変えることでこの状況にアプローチします。時々A *を実行し、その間に次のステップに自由に足を踏み入れるか、回避する必要があるかを確認します。

たとえば、A *ターゲットの場所からのプレイヤーの距離を追跡します。しきい値を超えている場合は、a *を再計算し、移動を更新します。ほとんどのゲームは、ウェイポイントの組み合わせを使用します。たとえば、パス検索用の簡略化されたグリッドや、レイキャストを使用した回避ステアリングアルゴリズムでウェイポイント間の移動を処理するロジックです。私の意見では、エージェントは近くの障害物を回避して遠方のウェイポイントまで走ろうとするのが最善のアプローチです。

ここで有限状態マシンを操作し、Mat Bucklandの著書「Programming Game AI By Example」を読むのが最善です。この本は、あなたの問題に対する実証済みのテクニックを提供し、必要な数学を詳述しています。この本のソースコードはWebで入手できます。本はC ++ですが、いくつかの翻訳(Javaを含む)が利用可能です。


2
更新頻度が低いA *アプローチでは、更新をずらして、1つのフレームで何人の敵がパスを変更できるかの予算を維持すると役立つ場合があります。これにより、フレームあたりのピークパス検索コストに上限を設定し、複数のフレームにわたって合計コストを償却することで、多くのAIパスをより堅牢に処理できます。フレームの予算を超えた場合に1つまたは2つのフレームに古いパスを使用するAI、または近い場合は推測航法にフォールバックすることは、通常は混乱を生じさせません。
DMGregory

2
おそらくここでは明らかですが、特定のフレーム内のパスの一部のみを更新する場合は、プレーヤーまでの距離に基づいた優先システムが必要になる場合があります。プレーヤーの近くの敵がパスを更新することはおそらく重要ですが、遠くの敵が古いパスを使用することはおそらく問題ありません。
AC

4

それは実現可能であるだけでなく、90年代の商用ゲーム-BattleZone(1998)で行われたと思います。

そのゲームには、タイルベースではない無料の動きと、タイルベースのベース構造を持つ3Dユニットがありました。

これはどのように機能するように見えたのですか:

まず、A *または類似のもの(パスを見つけることができる時間に厳密な制限があるA *のバリエーションであるため、実行するのにリソースが多すぎることはありませんが、目的地までずっとパスを見つけるとは限りません)は、タイルベースの障害物に引っかかることなく、目的地に到達するためのホバータンクのパスを見つけるために使用されます。

その後、タンクは、そのパス内の近くのタイルの中心に引き付けられ、障害物や他の近くのタンクなどで撃退されたかのように、空いている空間を飛び回ります。


1
それで、パスをたどるのに良い方法は何ですか?キディコーナリングを許可する場合、敵が障害物のコーナーに衝突するのを防ぐことができる必要があります。敵と障害物の両方の群れ行動を維持し、それらの状況に対処するためにA *を追加する必要がありますか?
ダリンボードロー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.