パス(座標のリスト)を歩いているときにキャラクターを滑らかにする方法は?


15

座標(A *アルゴリズムからの出力)のリストがあり、キャラクターが回転しながらこのパスをスムーズにたどるようにしたいと思います。

だから私はAのようなものを持っており、Cを取得したい

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

これどうやってするの ?

編集

自分をもう少し明確にするために:

あるノードから別のノードへの移動方法を既に知っているので、スムーズな方向転換にもっと興味があります。

編集

多くの人々は、この(私も)私は彼がゲームAI(物理学)の多くを論じダニエル・シフマンの「コードの自然」へのリンクを掲載しています便利な問題例えばステアリング行動見つけたようhttp://natureofcode.com/book/chapter- 6-自律エージェント/#chapter06_section8


Unityにパスファインディングが組み込まれていませんか?
joltmode

@Tomまあはい、とにかく私のバージョンを実装しています。この質問のポイントは、パスを歩いているときにスムーズなターン(回転)を取得することです。
パトリク

3
この点でGoogleにとって良い用語は「ステアリング動作」です:)
ロイT.

3
@RoyT。もちろん !私はこれを数週間前に読んでいて、すでに忘れていました:/これは素晴らしい数学+物理学の説明付きのパスに関する素晴らしい記事ですnatureofcode.com
Patryk

1
リンクについて@Patrykに感謝したかった-本当に有益なように見え、ステアリングの動作に関する優れたリソースを探していました。
クリスチャン

回答:


7

タイルベースの環境でスムーズなパスが必要な場合、A *ウェイポイントにパススムージングを適用する方法はありません。プログラミングゲームAIに関する彼の本で、Matt Bucklandはシンプルで高速なアルゴリズムについて説明していますパスを滑らかにいます(基本的に、障害物と交差することなく削除できるすべてのエッジを削除します)。

このような不要なエッジを削除すると、最初のケース(A-> B)が解決されます。グラフのエッジを滑らかにするには、いくつかの方法があります。ほとんどの場合、エルミートスプラインが機能します(障害物の密度とタイルサイズに少し依存します)。別のオプションとして、現在のターゲットからタイルが半分離れるとすぐに、次のウェイポイントに向かってステアリングを開始するステアリング動作があります(これは、「エージェント」の移動/ターンの速さに依存します)。


9

他の人が述べたように、2番目のケースでは、何らかのスプラインを実装するか、実際にユニットに何らかのステアリング動作を与える必要があります。

ただし、前者の場合は、パスの平滑化よりも簡単で、より良い結果が得られる解決策があります。これはTheta *と呼ばれ、グリッド上のA *の単純な(そして比較的新しい)拡張機能であり、ユニットがグリッドポイント間で任意の方向に移動できるようにします。

シータ*とパスの平滑化

ここにTheta *(私が上の画像を盗んだ)を説明する素晴らしい記事があります


2

より人間に近い動きにするには、ステアリング動作と統合してみてください。(C#バージョンの古典的なOpenSteer http://sharpsteer.codeplex.com/)AStarの出力を取得し、ステアリング動作に運動を気にさせます(サンプルの1つは、これを行う方法を正確に示し、パスに従ってナビゲートします)


1

ポイントからポイントへのナビゲーションの場合、角度の違い(現在のプレーヤーの方向と現在のポイントから次のポイントへの方向)を使用し、動きが発生するにつれて徐々に角度を最終角度に変更しました。ここでこのゲームをチェックしてください。飛行機が1つの地点から別の地点に移動しますが、ターンは急ではありませんが、注意深く見ると経路のポイントを特定できます。(ゲームはモバイルでのみ機能しますが、iPhone / iPadが望ましいです)。


これはまさに私がやったことです。
パトリク

1

私は幸運を持っていたキャットマル-ロムスプライン(立方スプラインのタイプも@bummzackが推奨するように)。これらの利点は、スプラインが常に制御点を通過することですが、他の多くはそうではありません。次のようなものを実装します。

t    = <time*>
t12  = t + 1.0
t23  = t
t34  = t - 1.0
t123 = (t + 1.0) / 2.0
t234 = t / 2

c1 = controlpoint[0];
c2 = controlpoint[1];
c3 = controlpoint[2];
c4 = controlpoint[3];

l12 = lerp(c1, c2, t12);
l23 = lerp(c2, c3, t23);
l34 = lerp(c3, c4, t34);
position = lerp(lerp(l12, l23, t123), lerp(l23, l34, t234), t);

* timeは、コントロールポイント1と2の間の値[0,1]です。


0

A-> Bは、グリッドの代わりにナビゲーションメッシュを使用することで解決できます。これは、経路探索データ生成の大きな変更を意味します。

CやDのようなケースは単なるコーナーカットです。キャラクターがパス内で「コーナー」(前、現在、次のセルが直線上にないセル)内を移動している場合、前と次の両方のセルの方向に押します。 。唯一の問題は、実際の位置からの距離(押し出し距離)を決定することです。それはおそらく入力として現在のセルからの距離を必要とするでしょう。このようなもの:

push_dir = average( prevcell.pos, nextcell.pos ) - curcell.pos;
push_dist = cell_half_width - distance( char.pos, curcell.pos );
char.pos += push_dir * push_dist;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.