この記事は Babylon.js アドベントカレンダー 2022 の 23日目の記事です。
はじめに
Babylon.jsで、マウスカーソルを当てたオブジェクトの判定をする処理の書き方について記載しました。
サンプル:マウスカーソルを当てると、グラフの情報が画面左上に表示されています。
処理の概略
以下の3つの処理で実装します。
1.判定するオブジェクトを作成する。
2.マウスの割り込み(MoveとかClick)が発生したら、レイキャストでオブジェクトがあるか判定をする。
3.2で交差するオブジェクトがあれば、そのオブジェクトを対象にする。
処理の内容
1.オブジェクトを作成
今回はCreateBoxで立方体を作成しますが、メッシュならなんでもよさそうです。作成するコードは下記。
普通にCreateBoxをするだけですが、引数に名前を定義しておきます。
他に必要な情報があれば、作成したオブジェクトへ追加しちゃいましょう。
//オブジェクトを作成する
const box = BABYLON.MeshBuilder.CreateBox(【名前】, {width: 【幅】, height: 【高さ】, depth: 【奥行】})
box.position.x = 【X座標】;
box.position.y = 【y座標】;
box.position.z = 【z座標】;
box.追加情報 = 【使用したい任意の情報】;
2.マウスの移動時に判定を行う
マウスが移動した際に割り込ませたいので、onPointerMoveに下記の処理を行いします。
・レイキャストを作成
レイキャストは、光線(ray)を投射(Cast)するという意味で、直線上に存在するオブジェクトを取得します。
・createPickingRayで、マウスのポインター座標と視点(camera)を結んだ直線を 変数 に格納。
・pickWithRayで、上記の直線で最初に衝突したメッシュを格納します。
該当するオブジェクトがあれば(nullでなければ) 情報を画面に表示する処理を実行します。
//マウスの移動時にマウスカーソルの場所にオブジェクトがあるか判定する
scene.onPointerMove = function castRay(){
var ray = scene.createPickingRay(scene.pointerX, scene.pointerY, BABYLON.Matrix.Identity(), camera);
var hit = scene.pickWithRay(ray);
if (hit.pickedMesh){
//対象のオブジェクトがあれば処理をする
createGUIButton(hit.pickedMesh);
}
}
3.対象オブジェクトの処理を行う
オブジェクトの情報を画面に表示する処理です。
(Playgroundにテキストを切り替えながら表示するのに簡単だったのでボタンを使いました。本来の用途と違いますが)
ボタンを作成する際に、引数にボタンに埋め込む文字列(今回は名前と追加情報)を指定して、表示したい文字を含むボタンを作成して、
画面にボタンを追加しています。
function createGUIButton(pickedMesh){
//指定されたMeshオブジェクトの情報を表示する
let guiCanvas = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI");
//ボタン生成時に表示するテキストを指定する
let guiButton = BABYLON.GUI.Button.CreateSimpleButton("guiButton",
"オブジェクト名:" + pickedMesh.name + pickedMesh.追加情報 );
guiButton.width = 【ボタンのサイズ】;
guiButton.height = 【ボタンの幅】;
guiButton.color = 【文字色】;
guiButton.background = 背景色;
//ボタンを画面の左上に表示
guiButton.verticalAlignment = BABYLON.GUI.Control.VERTICAL_ALIGNMENT_TOP;
guiButton.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_LEFT;
guiCanvas.addControl(guiButton);
}
上記の処理で、マウスカーソルを重ねた場所にあるオブジェクトを指定して処理を行うことができます。
サンプルのURLは下記になります。
https://playground.babylonjs.com/#1JQRXD#24
終わりに
サンプルのようにマウスでオブジェクトを操作する時や、FPSで発射した弾が当たるかの判定なんかに使用できるかと思います。
日本語のサンプルが少なかったので、このメモが参考になれば幸いです。
参考文献
上記のレイキャストについてのドキュメントは下記のページを参考にさせていただきました。
https://doc.babylonjs.com/features/featuresDeepDive/mesh/interactions/picking_collisions