Following, springs & flocks

Wander Steering

ワンダー

進行方向を連続的に揺らして自然に徘徊させる。

7 / 10

Interactive demo

Preparing the demo…

Wander Steering

Drag to orbit, Ctrl/⌘ + scroll to zoom. Use two fingers on touch screens.

This explanation is currently available in Japanese.

ひとことで

「目的はないけれど、それらしく歩き回る」動きを作る操舵行動です。エージェントの前方に仮想の円を置き、その円周上の目標点を毎フレーム少しずつずらしながら追いかけます。向きの変化が連続するので、ランダムなのに滑らかで生き物らしい徘徊になります。

ゲームでの使いどころ

  • 野生動物・虫・魚:何もしていないときの動物の徘徊。
  • 待機中の NPC:広場をぶらつく町人、見張りの合間にうろうろする敵。
  • 群れの味付け:ボイドに弱いワンダーを足すと、群れ全体の動きが単調になりません。
  • 有限状態機械の「待機」状態:索敵状態や追跡状態とワンダーを状態機械で切り替えるのが定番の敵 AI です。

しくみ

  1. エージェントの進行方向に、距離 DD だけ前に半径 RR の円を置く。
  2. 円周上の角度 θ\theta の位置を目標点とする。
  3. 毎フレーム、θ\theta に小さな乱数を足す:θ←θ+random(−J,J) Δt\theta \leftarrow \theta + \text{random}(-J, J)\,\Delta t
  4. その目標点へシークする。
t=p+D v^+R (cos⁡θ,  0,  sin⁡θ)\mathbf{t} = \mathbf{p} + D\,\hat{\mathbf{v}} + R\,(\cos\theta,\; 0,\; \sin\theta)

ポイントは、乱数で変えるのが向きそのものではなく、目標点の角度であることです。目標点は円周上を少しずつしか動かないので、進行方向も連続的に変化します。

パラメータ効果
円までの距離 DD大きいほど、前に進もうとする傾向が強く直進的
円の半径 RR大きいほど、1 回の曲がりが大きい
揺らぎ JJ大きいほど、曲がる向きが頻繁に変わる

比較のために毎フレーム完全にランダムな方向へ引っ張ると、変化が打ち消し合ってその場で震えるだけになります(デモの「毎フレーム乱数」)。

実装のポイント

  • 角度はエージェントごとに保持:θ\theta は前フレームからの続きとして状態に持ちます。
  • ノイズで角度を決める:乱数の代わりに perlin(time * rate + seed) のような 1 次元のパーリンノイズを使うと、さらに滑らかでフレームレートに依存しない徘徊になります。
  • 範囲内に留める:放っておくとどこまでも歩いていくので、領域の外に近づいたら中心へ戻る力を足します(デモの囲い)。

つまずきやすい点

  • フレームレート依存:揺らぎを Math.random() * J のように Δt\Delta t を掛けずに足すと、フレームレートが高いほどよく曲がります。
  • 同じシードで同期してしまう:全員が同じ乱数列を使うと、群れが同じタイミングで曲がります。個体ごとに異なるシードやオフセットを与えます。
  • 目的のある移動には不向き:ワンダーは「目的がない」ことを表す動きです。巡回ルートがあるなら、通過点をシークさせます。

デモで試すこと

  1. 黄色の 1 匹の前にある水色の円と点が、ワンダーの目標です。点が円周上を少しずつ動き、虫がそれを追いかけていることを確認してください。
  2. 「方向の決め方」を毎フレーム乱数に切り替えると、虫たちはその場で震えるだけになります。
  3. 「円までの距離」を大きく、「円の半径」を小さくすると直進的な散歩に、逆にすると落ち着きなくくるくる回る動きになります。

References

Spring-It-On ↗

A general reference for this subcategory.