This explanation is currently available in Japanese.
ひとことで
「目的はないけれど、それらしく歩き回る」動きを作る操舵行動です。エージェントの前方に仮想の円を置き、その円周上の目標点を毎フレーム少しずつずらしながら追いかけます。向きの変化が連続するので、ランダムなのに滑らかで生き物らしい徘徊になります。
ゲームでの使いどころ
- 野生動物・虫・魚:何もしていないときの動物の徘徊。
- 待機中の NPC:広場をぶらつく町人、見張りの合間にうろうろする敵。
- 群れの味付け:ボイドに弱いワンダーを足すと、群れ全体の動きが単調になりません。
- 有限状態機械の「待機」状態:索敵状態や追跡状態とワンダーを状態機械で切り替えるのが定番の敵 AI です。
しくみ
- エージェントの進行方向に、距離 だけ前に半径 の円を置く。
- 円周上の角度 の位置を目標点とする。
- 毎フレーム、 に小さな乱数を足す:
- その目標点へシークする。
ポイントは、乱数で変えるのが向きそのものではなく、目標点の角度であることです。目標点は円周上を少しずつしか動かないので、進行方向も連続的に変化します。
| パラメータ | 効果 |
|---|---|
| 円までの距離 | 大きいほど、前に進もうとする傾向が強く直進的 |
| 円の半径 | 大きいほど、1 回の曲がりが大きい |
| 揺らぎ | 大きいほど、曲がる向きが頻繁に変わる |
比較のために毎フレーム完全にランダムな方向へ引っ張ると、変化が打ち消し合ってその場で震えるだけになります(デモの「毎フレーム乱数」)。
実装のポイント
- 角度はエージェントごとに保持: は前フレームからの続きとして状態に持ちます。
- ノイズで角度を決める:乱数の代わりに
perlin(time * rate + seed)のような 1 次元のパーリンノイズを使うと、さらに滑らかでフレームレートに依存しない徘徊になります。 - 範囲内に留める:放っておくとどこまでも歩いていくので、領域の外に近づいたら中心へ戻る力を足します(デモの囲い)。
つまずきやすい点
- フレームレート依存:揺らぎを
Math.random() * Jのように を掛けずに足すと、フレームレートが高いほどよく曲がります。 - 同じシードで同期してしまう:全員が同じ乱数列を使うと、群れが同じタイミングで曲がります。個体ごとに異なるシードやオフセットを与えます。
- 目的のある移動には不向き:ワンダーは「目的がない」ことを表す動きです。巡回ルートがあるなら、通過点をシークさせます。
デモで試すこと
- 黄色の 1 匹の前にある水色の円と点が、ワンダーの目標です。点が円周上を少しずつ動き、虫がそれを追いかけていることを確認してください。
- 「方向の決め方」を毎フレーム乱数に切り替えると、虫たちはその場で震えるだけになります。
- 「円までの距離」を大きく、「円の半径」を小さくすると直進的な散歩に、逆にすると落ち着きなくくるくる回る動きになります。