RTSローカル回避はどのように行われますか?


15

現在、ユニットの局所回避のための物理的衝撃力をシミュレートしていますが、この方法はユニットをフォーメーションから押し出すことがあり、ユニットが凝集すると非常に望ましくない効果があります。

Starcraft 2のようなRTSゲームの場合、ローカル回避はどのように行われますか?物理学はシミュレートされていますか、それとも全知のコントローラーがすべての場所を決定しますか?私はこの質問が少し広いかもしれないことを知っているので、Starcraft 2のローカルな回避行動をどのように達成するかについて具体的に尋ねています。動作するものなら何でも大歓迎です。

コードを探しているわけではありません-Starcraft 2(または同様のゲーム)がローカル回避を処理する方法の有用なリソースまたは説明だけです。

現在、衝突検出(貫通ベクトル)、衝突力、および速度による移動が実装されています。すべてのユニットは、衝突について別のユニットと照合されます-衝突すると、オブジェクトは貫通ベクトルによってすぐに相殺され、衝突力が適用されます。次に、別のループがオブジェクトをその速度で移動し、速度にドラッグを適用します。オフセットは、凝集したユニットに過剰な衝突力がかかる問題を緩和しますが、ユニットが時々飛び出すこともあります。

私が探しているソリューションは、次の要件を満たす必要があります(Starcraft 2のように)。

  • オブジェクトは重複しません。または、少なくとも重複を最終的に解決する必要があります。
  • オブジェクトは必要以上に押し合うことはないので、2つのユニットがフォーメーション内でお互いに隣接して移動できます。
  • オブジェクトが同じ目的地に向かって固まる場合、奇妙な動作はありません。
  • さまざまなサイズのユニット、さらにはさまざまな凸形状をサポートできます。

私がこれまで考えてきたのは、衝突を検出する代わりに、将来の衝突を検出して、重複が発生しないようにすることです。次に、2つのユニットの速度が重なり合わないように、制約を適用します。オーバーラップを超えた動きを制限するアルゴリズムをいじっています。


「群れの行動は」(用語をGoogleが)非常に広い問題、である
ラチェットフリーク

これは「広すぎる」との投票でキューに入っていました。私は同意する傾向があります。狭めようとしている:何を試しましたか?どのような「望ましくない効果」を避けたいですか?ユニットが隊形を保ちたいと言っているのは正しいですか?
アンコ

RTSゲームは、多くの場合、各マシンで同じ決定論的シミュレーションを実行する各クライアントによって機能します。したがって、基本的に、単一のマシンでそれを解決できれば、ローカルな回避テクニックが何であれ、マルチプレイヤーの状況に同じソリューションを適用できます。
アランウルフ

質問に対するフィードバックをありがとう。私は質問を少し絞り込み、私が達成しようとしていることを具体的に説明しました。
-JPtheK9

これは素晴らしいリソースです:red3d.com/cwr/steer
tbkn23

回答:


11

あなたが探しているのは、最適な相互衝突回避アルゴリズムのようです。先行する用紙はまた、読み取りの価値があります。この論文は少し複雑かもしれませんが、アルゴリズムの背後にある理論はかなり簡単です。

周囲に何らかの境界ボリュームを持つエージェント(ユニット)のシミュレーション(ゲーム)が既にあると仮定します。この境界ボリュームは、衝突の検出と応答を実行するためにすでに使用しているものです。エージェントごとv_pに、エージェントの目標に基づいている場合とそうでない場合がある優先速度を定義します。

次に、シミュレーションを実行します。

  1. 各エージェントについて、静止していると仮定して、将来の任意の時点で他の移動エージェントのいずれかと衝突するすべての速度を計算します。これは、「速度空間」で、交差する半平面のセット(速度障害物とも呼ばれます)として表すことができます。
  2. に最も近いこの空間内の点を決定しv_pます。これはユニットの新しい速度です。

すべてのエージェントが同じアルゴリズムを実行している場合、相互に補完し合う速度を選択し、他のエージェントを回避します。状況によっては、ホール内の誰かに直接歩いて同じ方向に邪魔にならないようにしようとすると、そのような厄介なことのような振動を引き起こす可能性がありますが、それを避ける方法については論文で説明しています。

上記のアルゴリズムの2つの段階を計算するには、ミンコフスキー和を使用して速度障害物を特定し、線形プログラミングモデル(シンプレックスアルゴリズムなど)を使用しv_pて、速度障害物を回避する最も近い点を決定します。また、衝突回避を行うためのコードが閲覧可能になっており、Unityなどのゲームエンジンで使用するためにC#に移植されています。この手法は、少なくともWarhammer 40,000で使用されています:Space Marineおよびその他のゲーム


それは素晴らしい記事であり、あなたの説明からその半分を読んだように感じます。この情報をありがとう。
-JPtheK9

0

私はあなたのユニットがどのように機能するかわかりませんが、それらはステートマシンのようなものだと思います:

可能な状態

  • (x、y、z)まで実行
  • 取得(enemy_id)
  • リソースの収集(ressource_id)

スタークラフトがこの問題にどのように取り組んでいるかに注意を払うと、あなたはそれを見つけるでしょう:

  1. ある方向に移動するスペースがある場合、文字はその方向に移動します。
  2. スペースがない場合は、途中のユニットが移動してスペースを作ります
  3. スペースを作るために移動する必要のあるユニットが既にコマンドを持っている場合、コマンドを保持しますが、最終的に場所を作るためにわずかにそれを修正します。

ここでシナリオ1:

ここに画像の説明を入力してください

そこに行くスペースはありますか?はい ?それから行く

シナリオ2:

ここに画像の説明を入力してください

そこに行くスペースはありますか?番号 ?ちょっと私のためにスペースを作ってもらえますか?私はすでに前進するための命令を持っていますが、私はあなたを収容します。

したがって、実装する必要があるもの:

  • ユニットは周囲に注意する必要があります
  • ユニットは互いに通信する方法を持っている必要があります
  • 別のユニットを収容しながらコマンドを実行し続ける方法を実装する必要があります

情報と視覚化に感謝します。現在、ユニットが別の場所に移動できるかどうか、または別のユニットがそれを占有しているかどうかを調べるために、衝突検出を使用しています。私が理解しようとしている主なものは、他のユニットにどの距離を移動するか、またはどの速度で調整するかを伝える何らかのアルゴリズムです。つまり、ブロッキングユニットが、通過しようとしているユニットにどのように対応するかを示します。
JPtheK9

この動作は物理の更新ごとに計算されるため、実際に距離を伝える必要はありません。邪魔にならない限り移動します。方向については、2つのユニットの速度を単純に乗算します。これにより、調整中に移動し続けることができるように、途中でポイントが得られます。その後、あなたはそれをいじってそれを作ることができます。そうすれば、それは注文にもっと固執するか、より速く邪魔にならないようにします。
アントワーヌ

「邪魔になるまで動く」とはどういう意味ですか?そもそもユニットはどのように動くのですか?
JPtheK9

申し訳ありませんが、言及は忘れました。ユニットはステートマシンではありません。ロッカーには、フレームごとにシミュレートされる多くの機能があります。ただし、これらの機能は、宛先がX距離離れているかターゲットが存在するかどうかに関係なく、アクティブになったときにのみ効果があります。ユニットの動きは、能力によって変更できる速度の結果です。
-JPtheK9

0

それを行う1つの方法は、ユニットにフォーメーションを自動形成させ、フォーメーションの中心に対して相対的な位置に留まらせることです。次に、各ユニットを個別に移動する代わりに、フォーメーションの中心を移動します。

ユニットを適切な位置に保持するために、ボックス構成と単純なスプリングを使用して行う基本的な方法を次に示します。

// Defines a phalanx (box) formation
class Formation
    // Center of the box in the world
    Position center;
    // Width in # of units
    int width;
    // Height in # of units
    int height;
    // Space between units
    float scale;
    // How much force units will apply to stay near
    // their assigned spot.
    float springforce;

    // Return a position of a unit at the given row and column
    // Todo: add a rotation to this formation so it can rotate when moving.
    Position GetUnitPhalanxPosition(int row, int column)
        return new Position(center.X + column * scale - width * scale /2, 
                            center.Y + row * scale    - height* scale / 2);

// Represents a simple point object with a velocity and position;
// it belongs to a formation.
class Unit
    Position pos;
    Velocity vel;
    Formation formation;
    // What's our assigned spot in the formation?
    int row;
    int column;

    void Update(float dt)
        // Get the desired target position in the formation
        Position target = formation.GetUnitPhalanxPosition(row, column);
        // Apply a spring force toward the position (todo: you might want to damp this)
        vel += (target - position) * dt * formation.springforce;
        // Move along the velocity vector.
        pos += vel * dt;

ありがとう!これは本当に興味深い創造的なソリューションです。群衆の行動/形成のためにこれに似たものを実装しましたが、ユニットが重複するという問題がまだあります。2つのフォーメーションが互いにぶつかるとどうなりますか?
JPtheK9

設計次第だと思います。最も簡単なことは、この画像のような他のフォーメーションの近くのユニットから別の操舵力を加えることです。彼らはプレイヤーが選択した、あるいは「メタフォーメーション」を形成しているとき、あなたができるもう一つは、一緒にマージ地層である
mklingen

メタフォーメーションは本当に複雑でバグが多いように聞こえます:C。あなたがリンクした画像は、私が必要とするものであるかもしれません。操舵力に関する研究をさらに行うつもりです。画像の記事へのリンクはありますか?
JPtheK9

私はあなたと同様の問題を抱えていますが、どのようにそれを解決したかを知ることは興味深いでしょう。マイクロ衝突回避のためのreppel力を利用しながら、多分マクロ経路計画のための経路探索(A *)を組み合わせる:アイデアのワンショットは、この記事をeeading後に頭に浮かんだ
コールドスチール

0

一部の人々はリンクダンプに眉をひそめていますが、リアルタイム戦略ゲームボット(ISBN 978-91-7295-160-0)のマルチエージェントポテンシャルフィールドベースアプローチは非常に啓発的な論文であることがわかりました。私が詳しく説明できる以上の方法。この論文では、ゲーム開発のコンテキスト内での局所的な衝突回避を促進するために、人工的なポテンシャルフィールド(ロボット工学に由来する概念)の使用を検討しています。


ありがとう!研究は私への説明と同じくらい役に立ちます。この論文に飛び込みます。
-JPtheK9

インフルエンスマップは既に設定されていますが、これは私の好みには複雑すぎるようです。主なことは、異なるユニットがそれらを動かすためにポテンシャルフィールドを生成すること、そしてポテンシャルフィールドから移動する速度にデータを変換することです。基本的に、これは異なるサイズのユニットでは機能しないと思います。興味深いアイデアがたくさんありますが、素晴らしい読み物です。
-JPtheK9
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.