式姫で遊ぶ日記

ブラウザ3Dゲームを作る作戦その7: 衝突回避

f:id:iwanabot:20200506223524p:plain:w480

障害物を回避する

NPCがプレーヤーを追いかけてくるような状況で、障害物に引っかからないようにする話です。

調べてみるとたくさん方法があるみたいです。メッシュ上をいろんなアルゴリズムで経路探索したり、事前にマップに経路情報を埋め込んでおいたり、アリみたいにプレーヤーが通った経路を利用したりなど。

お手軽にできそうな方法としては、Raycaster が衝突するobjectを返してくれるのを利用する方法があるようです。
今回は衝突したオブジェクトのboundingSphereに沿って移動するようにしてみました。
f:id:iwanabot:20200506212625p:plain:w480
絵の中で目標が黒い矢印の方向にいるとすると、自分に一番近い壁のboundingSphere (の少し大きめ)の接線(緑)を目標方向にすれば、壁がどんな形でもおよそ引っかからずに目標に到達できると思います。ダメなケースを挙げればきりがないですが、フィールドがある程度パーツに分かれているなら簡単にできる方法として悪くないと思います。

ちなみにRaycaster は自分からターゲットに伸ばせば坂道など考えずに済むので楽だと思います。 
一番近いオブジェクトの boundingSphere のとり方ですが、

intersects = Vray.intersectObjects(fieldObjs.children, true); 

で取ってきたとすると、

bSphere = intersects[0].object.geometry.boundingSphere;

として取得できます。スケールや親の位置など諸々のことを考えると、例えばこの bSphere の中心が欲しいときは

bsCenter = intersects[0].object.localToWorld(bSphere.center.clone());

のようにobject.localToWorld をつかって変換するのが楽ですね。
これならRaycaster も追加の1本で済むので処理としてもそこまで重くはならないと思います。