🚀

【Three.js】Group化したObjectを正しい位置にDrag&Dropする

2023/09/19に公開

結論

  • 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の位置補正のみに注目しているので、ご了承ください。

どのようなバグか

バグの状況

https://twitter.com/Tebasaki_lab/status/1704015195298037793

対処結果

https://twitter.com/Tebasaki_lab/status/1704015401817096481

対処法

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