お疲れ様です。 せいさくしゃです。
それにしても、そろそろお正月の時期ですね。
明けましておめでとうございます。
今年も、少しずつブログの記事を書いていこうと思うので、これからも宜しくお願いします。
さて、今回も少し寄り道をして、私が好きなゲームAIについてお話ししようと思います。
突然ですが、ゲーム中に沢山のキャラが出てきてそれらが群れを成して移動する、という事を実装しようと思ったら皆さんならどうしますか?
単純に考えると常に同じ方向に移動したり、目標地点に向かって全員移動したり、やり方は色々あると思います。
(これらを実際にやると、明らかに不自然な動きをするのは大体見当つきますが。)
この群れを成して移動するというという事を実装する際に、便利な技術があります。
それは、「フロッキング」という技術です。
今回は、群れを作る為のこのフロッキングという技術を紹介したいと思います。
その中でも、群れを作る為の「フロッキング」という技術を紹介するぞ。
今回の目次
今回の解説
フロッキングの実際の動き
実際にはどんな感じで動くんだ?
まずは、実際のフロッキングの動き方を見てみましょう。
ここでは、白い四角が群れを成すオブジェクトです。
そして、赤い点が出てくると群れ全体がそこに向かって移動します。
このように、個々のオブジェクトが群れの一員として統率の取れたような動きをします。
ちなみに、これらのオブジェクトは当たり判定を取っていません。
しかも、当たり判定を取らなくても動けるのか。
フロッキングに必要な3つの考え方
このフロッキング、一見凄く複雑な計算をしているように見えるかもしれません。
しかし、このフロッキングは主に3つの考え方を組み合わせているだけでできています。
それは、「結合」、「整列」、「分離」の3つです。
この結合、整列、分離によって求められた向きと強さ(ベクトル)を平均して、一定速度で移動しているだけです。
これらの結合、整列、分離の3つについて詳しく見ていきましょう。
これらの結果の平均を取ることで移動する方向を決める訳だな。
群れをリアルに見せるための「視野」
早速見てみようぜ。
先程、結合、整列、分離の3つについて詳しく見ていこうといいました。
しかし、その前に少し下準備をしたいと思います。
これがあると、群れがよりリアルに見えるようになります。
その下準備とは、オブジェクトに「視野」を持たせることです。

視野があると、周囲に見えるオブジェクトが絞られてきます。
この見えているオブジェクトに合わせて自身を動かしているので、当然視野が変わると動き方も変わってきます。
この視野を持たせることによって、実際の群れの動きに近づけていく訳です。
ちなみに視野の求め方は、主に2つの要素を使います。
1つ目は、どこまで遠くまで見えるかを表す視野の半径(距離)。
2つ目は、どこまで視野が広いかを表す視野の角度。
この2つを考慮して、その中に入っているオブジェクトのみを感知して自身の動きの参考にしています。
この視野は、視野の半径(距離)と、視野の角度から求められるんだな。
フロッキングの3つの考え方「結合」「整列」「分離」
じゃあ、今度こそ結合、整列、分離の3つについて教えてくれよ。
これで、下準備は終わりました。
では、早速結合、整列、分離の3つについて解説します。

まず、結合は視野内のオブジェクトの中心(位置の平均)に向かって移動する考え方です。
他のオブジェクトの中心に向かうことによって、群れ全体をまとめていくことができます。
次に、整列は視野内のオブジェクトの向きの平均に自身の向きを合わせる考え方です。
他のオブジェクトと向きを合わせることによって、群れ全体が同じ方向へと向かうことができます。
最後に、分離は視野内のオブジェクトから離れていくように移動する考え方です。
一見矛盾しているように見えますが、要するに他のオブジェクトに近づき過ぎないようにするための考え方です。
これが、当たり判定を必要としない理由です。
なお、この分離に関しては視野内の平均ではなく、視野内のオブジェクトに対して個別に計算します。
そして、この離れていくベクトルの強さは、他のオブジェクトとの距離が近いほど強くなります。
この結合、整列、分離によって求められたそれぞれのベクトルを平均して、その方向に向かって進んでいきます。
整列は、視野内のオブジェクトの向きの平均に自身の向きを合わせる。
分離は、他のオブジェクトに近づき過ぎないように反対に向かって移動する。
この3つで求められたベクトルを平均して、その方向に向かうわけだな。
最後に向きの調整
じゃあ、後はその方向に向かって進めばいいんだな。
先程の、結合、整列、分離で進みたい方向が決まりました。
では、実際に動かす前に少し方向の調節をしたいと思います。
このまま動かすと、オブジェクトが360度自由に動くことができるため、下手をすると挙動不審な動きをします。
(例えば、右と左に交互に移動してブルブル震える等です)
そこで、オブジェクトを滑らかに動かす為に、オブジェクトが動ける角度を制限します。
やり方は、まず自身の向きと進行する予定の方向との角度がどれぐらいかを調べます。
そして、その角度があまりにも離れている場合は、その角度を制作者が決めた最大角度まで縮めた方向へ修正します。
こうすることにより、オブジェクトが急に震える等の挙動不審な動きが軽減されると思います。
こうして、最終的に移動する方向を決めたら、後はその方向に移動速度をかけて実際に移動させます。
ちなみに、今回は目標地点に向かって移動するという事も実装しました。
その際は、今回の結合、整列、分離の3つの計算に、目的地点への向きも足して平均を求めてください。
こうすると、オブジェクトが滑らかに動くんだな。
ちなみに、目標地点へ移動する場合は、目標地点への方向も足した上で平均を求めるんだな。
本来、このフロッキングは今回のように自由な方向に動ける事を想定して作られたものではありません。
例えるなら、船が動くように常に前に向かって進んでいて、曲がる時は舵を切って旋回するイメージです。
なので、移動方向を調節する際は、この舵を切る力(操舵力)をオブジェクトに加えて動かしている訳です。
しかし、船が動くような操舵力による移動方向の計算は、それだけで単純な移動と比べて難しいと思います。(せいさくしゃは作ったことがありません)
そこで、今回はその操舵力による移動を単純な方向と移動量による移動で代用しました。
その為、本来の操舵力による移動に近づけるために、滑らかに動かす必要があった訳です。
この動かし方は、せいさくしゃ自身がアレンジしたものなので、これが絶対という訳ではありません。
もし、他の方法で動かした方がいい等と思ったら、自身で動かし方を模索してみてください。
フロッキングを実装する際の注意点
じゃあ、このフロッキングをガンガン使っていけば、凄いゲームが作れそうだな。
今回のフロッキングは、群れを成す為の動かし方を提供してくれます。
しかし、このフロッキングを実装する際に、気を付けておく点があります。
主な注意点としては、フロッキングの処理に必要な計算量です。
このフロッキングは、それぞれのオブジェクトが全てのオブジェクトを参照して計算をしています。
つまり、オブジェクトが増えるほど、処理に必要な計算量と時間が大幅に跳ね上がり、ゲーム全体が重くなってしまいます。
なので、実際にゲームで使う際は、オブジェクトの量はほどほどにしておくといいと思います。
実際に使う時は、オブジェクト数をほどほどにしておくといいんだな。
フロッキングの実際の活用例
さて、群れを成すためのフロッキングですが、実際に群れを実装するようなゲームは少し想像しにくいかもしれません。
そこで、簡単なゲームシステムを作ってみました。
これは、リーダーが自分の兵士を持っていて、自身に追従させたり、目的地を設定してそこに向かわせたりします。
そして、敵が近くにいるとフロッキングをやめて、近くの敵を攻撃しに行きます。
こういった、群れ同士を戦わせる等といったゲームを作っても面白いかもしれません。
もちろん、単純に敵として群れを登場させるというものでもいいと思います。
今回のまとめ
今回は、群れを成すための「フロッキング」という素敵な技術を紹介しました。
端的にまとめると、以下の通りです。
- まず、オブジェクトの「視野」を設定します。
- 「結合」、「整列」、「分離」等によって移動する方向を決めます。
- 最後に、移動する角度を制限して移動します。
- フロッキングは処理が重くなりやすい為、オブジェクト数はほどほどにする。
こうする事で、個々のオブジェクトが統率の取れたようにいい感じに動いてくれます。
皆さんも、このフロッキングを活用して少しレベルの高そうなゲームを作ってみてはいかがでしょうか。
それでは、今回はここまでにしたいと思います。
お疲れ様でした。