THREE.jsで当たり判定・特に「Ray(光線)を使用した当たり判定」として、いかにも「コレ使えよ!」と用意されている、
THREE.Raycaster オブジェクト、及び intersectObject メソッドがあります。
これはその名の通り「 指定位置から あるオブジェクトに対し、指定ベクトル上にある交差点を算出してくれる」という、それはまぁ3Dゲームの地形判定にうってつけのメソッドであります。
・・一見するとね。
ただ、こいつには罠が仕込んでありまして、
【非表示のオブジェクトに対しては、交差判定を行ってくれない】
という仕様になっております。
何がまずいかというと、
「地形は作りこんだモノを表示して、表示とは別に非表示のモデルを用意。その非表示オブジェクトから交差判定をする」ということが、できないんです。
単純に
heightObject.visible = false;
//略
var ray = new THREE.Raycaster(C_pos, baseV.normalize());
// 交差判定
var objs = ray.intersectObject(heightObject);
for (var i = 0; i < objs.length; i++) {
player1.Pos.y = objs[0].point.y;
}
としちゃうと
↑こうなっちゃう
ではどうするか。
ちょっと抜け穴チックですが、下記の通りにします。
heightObject.material.materials[0].visible = false;
いわば、「Object3Dでは表示対象。だけど、マテリアルで非表示対象」とすることで、上記のような「見えているものと当たり判定を別にする」ことが可能となりました。
この方法を使った時の懸念で「あれ、となると、他で【表示時と同じような、余計な計算・・・例えば、DrawMeshは走るけど、VertexShader側で透過100%とかやってない?」があったのですが、
Three.JsのRenderにて、「表示対象をリストアップ」する 【projectObject】というメソッドの中で、 material.visible がTrueでないものは、Drawリスト対象としない」という処理が行われているので、杞憂でした。
めでたしめでたし。