ユニットの敵の「認識」をどのように実装すればよいですか?


12

Unity3dを使用して、RTS / TDハイブリッドプロトタイプゲームを開発しています。ユニットと敵の間の「認識」のための最良のアプローチは何ですか?すべてのユニットがすべての敵までの距離をチェックし、範囲内であれば交戦するのは正気ですか?

私が今行っているアプローチは、すべてのユニットにトリガー球を置くことです。敵がトリガーに入ると、ユニットは敵を認識し、距離チェックを開始します。これはいくつかの不必要なチェックを保存しますか?

ここでのベストプラクティスは何ですか?


私はユニット/敵の数は、最高司令官の規模であることを行っていることを追加する必要があります
フィル

回答:


10

境界ボリューム階層(BVH)を調べます。最も一般的に使用されるのは、衝突を検出する際に必要なチェックの数を減らすための衝突検出、またはオブジェクトの錐台カリングを実行するレンダリングです。既に球体を使用しているので、球体ツリーをお勧めしますが、AABBなどの他のボリュームの方が効率的かもしれません。Unityがこれまで使用したことのないものに対してどのようなサポートを提供しているかはわかりませんが、おそらく衝突検出またはエンジンのレンダリングパーツ内にこれに関する何かがあるでしょう。

基本的に、互いに近くにいる敵を複数の親球にグループ化します。ユニットを移動するとき、各敵をチェックする代わりに、親球に対してトリガー球をチェックします。トリガー球が親球と交差する場合、内部の各敵を確認します。そうでない場合は、その中にいるすべての敵を捨てることができます。最大球サイズまたは各球の敵の数に基づいて複数レベルの球を設定し、最上位の球に基づいてチェックを実行します。その後、各敵の距離チェックを実行することなく、各敵をチェックするためにツリーを歩いていくだけです。

各フレームに必要な手順:

  1. 敵を動かす
  2. 新しい敵の位置に合わせてBVHを再構築/更新します
  3. ユニットを移動し、球体ツリーに対してチェックします。

これにより、敵が多い場合に必要なチェックを減らすことができますが、ツリーがそれほど多くない場合、ツリーの更新と保存のオーバーヘッドはそれだけの価値がないかもしれません。私はあなたが何を望んでいるかを知るために最高司令官に精通していないので、私は単に「数百」と仮定しています。さまざまな状況でプロファイルを作成して、オーバーヘッドに見合うだけの価値があるかどうかを確認する必要があります。


3
+1このアプローチはいくつかのエラーがありますが、最も簡単です。OPはこれを実装してから、octreeのようなものを実装する場合があります。また、ほとんどのRTSでは、ユニットは多少の遅延を伴います。実際、ゲームのほとんどのAIは1秒あたり10〜30フレームで計算され、ゲームは1秒あたり30〜60フレームで実行されます(もちろん、数値は概算です)。
サマーサ

ありがとう、これはまさに私が一歩先へ進むために必要なものでした。BVHとそれをUnityに実装する方法を調べます。非常に教育的で有益な投稿です!+1
Phil

ああ、RTSを使用している場合はSupreme Commanderをチェックしてください。クリス・テイラーのすべてのゲームがそうであるように、それは実に素晴らしいゲームです。
フィル

7

Unityのコリジョンエンジンは基本的に既にあなたのためにそれを行うので、BVHを実装する必要はありません。

大きな範囲球トリガーを各ユニット(その範囲を表す)に接続し、OnCollisionEnter()およびOnCollisionExit()コールバックを処理して、各ユニットの範囲内にいる敵を追跡します。

興味のあるケース、別のユニットの球が球と衝突するときではなく、別のユニットが球と衝突するときです。


1
これは、少なくとも受け入れられた答えのすぐ上まで支持される必要があると思います。受け入れられた答えは勉強に適していますが、これが最も実用的な方法であるため、この答えは一番上にあるべきです。
バラキレックス

私はあなたが意味するOnTriggerEnter()と信じていますOnTriggerExit()か?
ジブスマート

1

非常にうまくスケーリングし、他の多くのものに使用できる別のソリューションは、影響マップです。ユニットの周囲にグリッドタイルのセットを生成して、X半径内でスキャンします。これらのタイルをスキャンして、それらのタイルの上に立つ敵を探します。最も近い敵を取得したい場合は、距離でセットを並べ替えることができます。

これは、特に、霧や戦争のような影響マップを使用して他のことを行う場合に最も効率的な方法です。

:ここで私はコンセプトを説明作ったビデオですhttps://www.youtube.com/watch?v=MEd6XV2Pecwが

そして、ここに実装があります:https : //www.youtube.com/watch?v=y_ewoxlZlgc

起動時にグリッドタイルのユニットコレクションを初期化するのではなく、コレクションが必要な場合にのみ初期化することをお勧めします。

または、タイルにXユニットを超えることはないことがわかっている場合は、Xの長さの配列を使用できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.