I’m creating a little point-and-click game in which there are pieces of an environment (PNGs) split off into layers and layered throughout the z-axis to give off the illusion of depth for these 2D images. Within these environments, I’m layering props that I want the user to be able to click and do something. I am trying to do this using raycasting. The props are set up in an array that is then passed to the target of the intersectObjects() function. However, I keep getting an empty array returned.
let propList = [];
//Creating Scene
const scene = new THREE.Scene();
//Load Textures
//environments
const environmentLayer1 = new THREE.TextureLoader().load('../assets/environment/1.png');
const environmentLayer2 = new THREE.TextureLoader().load('../assets/environment/2.png');
const environmentLayer3 = new THREE.TextureLoader().load('../assets/environment/3.png');
const environmentLayer4 = new THREE.TextureLoader().load('../assets/environment/4.png');
const environmentLayer5 = new THREE.TextureLoader().load('../assets/environment/5.png');
const environmentLayer6 = new THREE.TextureLoader().load('../assets/environment/6.png');
const environmentLayer7 = new THREE.TextureLoader().load('../assets/environment/7.png');
const environmentLayer8 = new THREE.TextureLoader().load('../assets/environment/8.png');
const environmentLayer9 = new THREE.TextureLoader().load('../assets/environment/9.png');
//props
const propLayer1 = new THREE.TextureLoader().load('../assets/props/Leash.png');
const propLayer2 = new THREE.TextureLoader().load('../assets/props/Envelope.png');
const propLayer3 = new THREE.TextureLoader().load('../assets/props/Photo.png');
// Binding Textures to Material
//environment
const environmentTexture1 = new THREE.MeshBasicMaterial({
map: environmentLayer1,
transparent: true,
opacity: 1
});
const environmentTexture2 = new THREE.MeshBasicMaterial({
map: environmentLayer2,
transparent: true,
opacity: 1
});
const environmentTexture3 = new THREE.MeshBasicMaterial({
map: environmentLayer3,
transparent: true,
opacity: 1
});
const environmentTexture4 = new THREE.MeshBasicMaterial({
map: environmentLayer4,
transparent: true,
opacity: 1
});
const environmentTexture5 = new THREE.MeshBasicMaterial({
map: environmentLayer5,
transparent: true,
opacity: 1
});
const environmentTexture6 = new THREE.MeshBasicMaterial({
map: environmentLayer6,
transparent: true,
opacity: 1
});
const environmentTexture7 = new THREE.MeshBasicMaterial({
map: environmentLayer7,
transparent: true,
opacity: 1
});
const environmentTexture8 = new THREE.MeshBasicMaterial({
map: environmentLayer8,
transparent: true,
opacity: 1
});
const environmentTexture9 = new THREE.MeshBasicMaterial({
map: environmentLayer9,
transparent: true,
opacity: 1
});
//props
const propTexture1 = new THREE.MeshBasicMaterial({
side: THREE.DoubleSide,
map: propLayer1,
opacity: 1
});
const propTexture2 = new THREE.MeshBasicMaterial({
side: THREE.DoubleSide,
map: propLayer2,
opacity: 1
});
const propTexture3 = new THREE.MeshBasicMaterial({
side: THREE.DoubleSide,
map: propLayer3,
opacity: 1
});
// Geometry
//environment
const environmentPlane1 = new THREE.PlaneGeometry(4440,2760);
const environmentPlane2 = new THREE.PlaneGeometry(4440,2760);
const environmentPlane3 = new THREE.PlaneGeometry(4440,2760);
const environmentPlane4 = new THREE.PlaneGeometry(4440,2760);
const environmentPlane5 = new THREE.PlaneGeometry(4440,2760);
const environmentPlane6 = new THREE.PlaneGeometry(4440,2760);
const environmentPlane7 = new THREE.PlaneGeometry(4440,2760);
const environmentPlane8 = new THREE.PlaneGeometry(4440,2760);
const environmentPlane9 = new THREE.PlaneGeometry(4440,2760);
//props
const propPlane1 = new THREE.PlaneGeometry(500, 500);
const propPlane2 = new THREE.PlaneGeometry(500, 500);
const propPlane3 = new THREE.PlaneGeometry(500, 500);
// Bind Material and Geometry to Mesh
//environment
const environmentMesh1 = new THREE.Mesh(environmentPlane1, environmentTexture1);
environmentMesh1.position.set(0,0,-1600);
environmentMesh1.scale.set(2.1,2.1,0);
const environmentMesh2 = new THREE.Mesh(environmentPlane2, environmentTexture2);
environmentMesh2.position.set(0,0,-1400);
environmentMesh2.scale.set(1.95,1.95,0);
const environmentMesh3 = new THREE.Mesh(environmentPlane3, environmentTexture3);
environmentMesh3.position.set(0,300,-1300);
environmentMesh3.scale.set(1.7,1.7,0);
const environmentMesh4 = new THREE.Mesh(environmentPlane4, environmentTexture4);
environmentMesh4.position.set(0,400,-1000);
environmentMesh4.scale.set(1.7,1.7,0);
const environmentMesh5 = new THREE.Mesh(environmentPlane5, environmentTexture5);
environmentMesh5.position.set(0,0,-800);
environmentMesh5.scale.set(1.6,1.6,0);
const environmentMesh6 = new THREE.Mesh(environmentPlane6, environmentTexture6);
environmentMesh6.position.set(0,250,-600);
environmentMesh6.scale.set(1.45,1.45,0);
const environmentMesh7 = new THREE.Mesh(environmentPlane7, environmentTexture7);
environmentMesh7.position.set(0,0,-400);
environmentMesh7.scale.set(1.3,1.3,0);
const environmentMesh8 = new THREE.Mesh(environmentPlane8, environmentTexture8);
environmentMesh8.position.set(0,200,-200);
environmentMesh8.scale.set(1.15,1.15,0);
const environmentMesh9 = new THREE.Mesh(environmentPlane9, environmentTexture9);
environmentMesh9.position.set(0,0,450);
environmentMesh9.scale.set(.7,.7,0);
//props
const propMesh1 = new THREE.Mesh(propPlane1, propTexture1);
propMesh1.position.set(400,-800, -195);
propMesh1.scale.set(.8,.8,0);
propMesh1.userData.type = "prop";
const propMesh2 = new THREE.Mesh(propPlane2, propTexture2);
propMesh2.position.set(1100,0,-1350);
propMesh2.scale.set(.8,.8,0);
propMesh2.userData.type = "prop";
const propMesh3 = new THREE.Mesh(propPlane3, propTexture3);
propMesh3.position.set(-1600,700,-850);
propMesh3.scale.set(.8,.8,0);
propMesh3.userData.type = "prop";
propList.push(propMesh1);
propList.push(propMesh2);
propList.push(propMesh3);
//Adding Mesh To Scene
//environment
scene.add(environmentMesh9);
scene.add(environmentMesh8);
scene.add(environmentMesh7);
scene.add(environmentMesh6);
scene.add(environmentMesh5);
scene.add(environmentMesh4);
scene.add(environmentMesh3);
scene.add(environmentMesh2);
scene.add(environmentMesh1);
scene.add(propMesh2);
scene.add(propMesh3);
scene.add(propMesh1);
scene.updateMatrixWorld();
console.log(scene.children);
// Camera
let aspectRatio = window.innerWidth / window.innerHeight;
const camera = new THREE.PerspectiveCamera(70, aspectRatio, 0.1, 10000);
camera.position.z = 1480;
// Renderer
const renderer = new THREE.WebGLRenderer(({ antialias: true }));
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(Math.min(window.devicePixelRatio,2));
document.querySelector("body").appendChild(renderer.domElement);
// Keyboard Controls
let forwardBack = 50;
let upDown = .02;
document.addEventListener("keydown", onDocumentKeyDown, false);
function onDocumentKeyDown(event){
var key = event.which;
if(key == 87){
camera.position.z -= forwardBack;
}
else if(key == 83){
camera.position.z += forwardBack;
}
else if(key == 37){
camera.rotation.y += upDown;
}
else if(key == 39){
camera.rotation.y -= upDown;
}
};
console.log(propList);
//Racyaster function -- NOT WORKING
//this is not working. It should return an array that includes all of the planes in the scene.
// The user clicks and is returning that "intersects" is empty
const raycaster = new THREE.Raycaster();
renderer.domElement.addEventListener('click', (event) =>{
// Calculate the mouse position in normalized device coordinates
const mouse = new THREE.Vector2();
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
// Update the arrowHelper to point in the direction of the mouse click
// Set the origin of the raycaster to the camera position
raycaster.ray.origin.copy(camera.position);
// Update the direction of the raycaster based on the mouse position
raycaster.setFromCamera(mouse, camera);
// Check for intersections with the propList
const intersects = raycaster.intersectObjects([propMesh1, propMesh2, propMesh3]);
// If there is an intersection, log the position of the first one to the console
// NOT RETURNING ANYTHING
console.log(intersects);
if (intersects.length > 0) {
const selectedObject = intersects[0].object;
selectedObject.material.color.set(0xffffff * Math.random());
}
});
// Update matrix
// Animation function
function animate(){
//camera.rotation.x -= count;
//camera.position.z -= count;
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
I’ve been working at this for hours and I can’t seem to get it to work. Here is what the environment looks like with the props: