BLOGワンダープラネットの開発者ブログです。モバイルゲーム開発情報を発信。人工知能こんにちは、エンジニアの成田です。以前のアリのフェロモントレイルに続き、今回も人工知能のシミュレーションを行ってみます。今回は人工生命のアルゴリズムとしてはメジャーであるBoidsを取り上げます。Reynolds氏が発表した人工生命プログラムで、鳥や魚、陸上動物の群れのような動きを行うオブジェクト(boid)の集合体です。このアルゴリズムの面白いところは各オブジェクトに簡単なルールをいくつか適用するだけで全体が複雑な動きを見せるところです。その意味では前回のアリのフェロモントレイルと同じくBoidsも群知能と言えます。Reynoldsが群れをシミュレーションするために定義したルールは衝突の回避...近隣の仲間との衝突を避ける速度の適合...近隣の仲間の速度に合わせようとする群れ中心化...近隣の仲間の近くに居ようとするこれだけです。各ルールの詳細は後で述べますが、各boidについてこれらのルールからboidが次に向かうべきベクトルを計算するだけというシンプルなアルゴリズムです。それにもかかわらず、各boidはリアルな動きを見せるため、昔からゲームや映画に本アルゴリズムがよく用いられてきました。2.実装それではBoidsを実装してみます。理由はありませんが今回はUnityを使ってみました。Boidの見た目を作成したいのですが、自分はモデリングできません。苦し紛れにこんなのを作ってみました。ピノキオの鼻みたいになってる方向が進行方向になります。これをプレハブとして複製して使います。このBoidにまずは基本の動きをさせましょう。スクリプトを追加します。次のようなソースです。PositionとVelocityのプロパティは、これらを変更した時にGameObjectの位置と角度も一緒に調整するようになっています。Update()内は高校物理のあれですね。等加速度運動の公式というやつです。物が空気や水の中を進むとき、抵抗のため一定の速度以上は出せません。これを模しているわけです。加速度は今はゼロにしているため、等速運動を行うはずです。次にシーン上のどこかにシミュレーション全体を管理するスクリプトを置きましょう。今はIObjectとVirtualBoidについては気にしないでください。Mainの各定数に関しても特に説明は必要ないと思いますが、Planeに関しては後々シミュレーション領域の壁にするために用意してあります。()内でプレハブから各boidをBoidCount個複製してランダムな位置にランダムな角度で配置し、シミュレーションを開始します。これを実行すると、各boidが同じ速度のままシミュレーション領域から飛び出していけば準備は完了です。Boidsのルールを実装していきましょう。a.衝突の回避...近隣の仲間との衝突を避けるboidは近隣の仲間との距離が近づきすぎてぶつかりそうになると逆方向へ逃げて衝突を回避しようとします。「近隣の仲間」を取得するメソッドをMainクラスに作成しましょう。引数に該当のboidを渡すと、そのboidから距離がBoidFOV以下となるboidのリストを返すメソッドです。これを利用してルールを実装します。近隣の各boidについて、正規化した逆ベクトルを作り距離の2乗で割ったベクトルを作成します。これによって遠いうちはゆっくり、近くなりすぎてしまうと急旋回して回避するようになります。これらを近隣のboid全体で平均します。これで衝突回避のルールができました。boidにシミュレーション領域に収まっていてもらうために、6隅の領域壁を仮想的なboidとすることで壁との衝突も同じ処理で回避することができます。Mainクラスに次のようなメソッドを作成します。このメソッドではboidの位置から各壁平面に対して垂線を落として、その足に当たる位置に仮想的なboidがあるものとします。本物のboidと同じく、boidの視界内にある場合だけリストで返します。本物のboidと仮想boidをリストに混ぜて同じように扱うことができます。これで衝突回避のアルゴリズムが完成しました。b.速度の適合...近隣の仲間の速度に合わせようとするこれは簡単です。boidの視界内のboidの速度ベクトルを平均して、そのベクトルと自分の速度ベクトルとの差分を取るだけです。c.群れ中心化...近隣の仲間の近くに居ようとする群れ中心化とは、近くの仲間たちの真ん中へ移動しようとすることです。boidの視界内のboidの位置の重心を取り、その位置と自分の位置との差分を取るだけです。最後にこれらの各ルールで作ったベクトルを合成します。Reynoldsは各ルールには優先度があると言っていますので、各ルールで作成したベクトルは加算平均を取るより重み付けをした加重平均をした方が良いでしょう。この重み付けなどのパラメータ調整は正直実行しながら調整していく泥臭い部分になってしまいます......プロジェクトファイルはこちらになります。engblog.zip実行してみましょう。最初はバラバラに動いていたboidが次第に群れを成して泳ぐ姿を見ることができると思います。上手くいかなかったらパラメータを調整してみる必要があるかもしれません。いかがでしたでしょうか。視覚的に動く人工知能は見てるだけでも面白いですよね。プロパティのキャッシュによる速度の違い今回のエンジニアブログを担当する加賀です。UnityのGameObjec...2015-07-13【Unity】Missingがあるアセットを検索する今回担当させていただく大橋です。Unityで、Missing状態のプロ...2015-02-17Cocos2d-xのゲームを遠隔操作してみよう(コマンド追加編)エンジニアブログ担当の岩原です。便利なEnumerable今回のエンジニアブログを担当する加賀です。2.0こんにちは、エンジニアの成田です。採用情報ワンダープラネットではモバイルゲーム開発者を募集しております。(S編)C/C++でネットワークプログラミングをやってみよう(2)スターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。