🚀
【Three.js】Group化したObjectを正しい位置にDrag&Dropする
結論
- Group(親)の座標とObject(子)の座標を計算する
- Object座標 - Group座標
let parent = this.draggable.parent
//ドラッグ対象のobjの位置を交差した座標に移動させる
this.draggable.position.x = target.x - parent.position.x; //parent(group)を取得し、座標補正
this.draggable.position.y = target.y -parent.position.y;
親(group)の座標を取得してslider(ドラッグする対象(子))の座標を計算する。
自分の備忘録として書いておきました。プログラムは独自クラスで動作したりしているので、this.raycasterなどはthisを取って考えてもらったり、Drag&Dropの位置補正のみに注目しているので、ご了承ください。
どのようなバグか
バグの状況
対処結果
対処法
objectの定義
const geometry = new THREE.BoxGeometry(width, height, depth);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
let backMesh=new THREE.Mesh(geometry, material);
backMesh.userData.ground = true;
const sliderGeo = new THREE.BoxGeometry(3, 2,2);
const sliderMat = new THREE.MeshBasicMaterial({ color: 0x0000ff });
let sliderMesh = new THREE.Mesh(sliderGeo, sliderMat);
sliderMesh.userData.draggable=true
sliderMesh.userData.name="SLIDER"
this.obj = new THREE.Group();
this.obj.add(backMesh);
this.obj.add(sliderMesh);
これはいつも通り。
Drag&Dropの処理
let parent = this.draggable.parent
//ドラッグ対象のobjの位置を交差した座標に移動させる
this.draggable.position.x = target.x - parent.position.x; //parent(group)を取得し、座標補正
this.draggable.position.y = target.y -parent.position.y;
結局はこれが大事。
dragObject() {
if (this.draggable != null) {
this.raycaster.setFromCamera(this.pointer, this.camera);
const found = this.raycaster.intersectObjects(this.scene.children); //交差したobjectを取得
if (found.length > 0) {
for (let i = 0; i < found.length; i++) {
if (!found[i].object.userData.ground) continue; //ground以外のobjだったら座標を取得しない
let target = found[i].point; //groundなどに当たった時の交差座標を取得
if (this.draggable.userData.name == "SLIDER") {
let parent = this.draggable.parent
//ドラッグ対象のobjの位置を交差した座標に移動させる
+ this.draggable.position.x = target.x - parent.position.x; //parent(group)を取得し、座標補正
+ this.draggable.position.y = target.y -parent.position.y;
}else{
this.draggable.position.x = target.x;
this.draggable.position.y = target.y;
}
}
}
}
}
Discussion