three.js 和 raycaster 中的条件 else 语句不是 运行
conditial else statements not running in three.js and raycaster
我开始关注一些 YouTube 教程,以供 three.js 初学者使用。我看到其中一个示例创建了三个漂浮在 space 中的球体,并使它们可点击。
所以我按照教程如何设置 three.js 场景并创建了 6 个 3d 圆柱体对象。我想要的是...
如果您单击某个对象,相机会指向并注视该对象,并且相机也会在该对象前面进行物理转换,因此我可以在那里显示文本或其他内容。到达那里后,我将限制控件,直到用户单击补间会将它们带回原始位置和方向的对象。
我试图让逻辑成为 如果 你点击了对象 1 && 你之前没有点击过它然后去看看它,else if 你点击对象 1 && 如果它被点击,那么相机将反向补间并回到原点... if else 你点击在对象 2 上 && 你之前没有点击过它然后去看看它,else if 你点击对象 2 && 如果它被点击了......依此类推,直到每个对象的两种情况都被考虑在内。我看到教程通过创建一个布尔变量来将状态设置为已被单击或未被单击来在一个对象上执行此操作。我试图将其合并到我的代码中,但我认为问题是 Javascript 系统没有标记或保留将变量更改为一个或另一个的信息....这可能是语法错误,它可能是我采用的方法根本不可能(未知的未知数),或者是一个简单的错字。
一旦我制作了 5 个单独的 If 语句,我就能够看到每个补间都按照我的意愿 朝向 对象但是 none 的补间响应检查它们是否已被单击的部分并将相机补间回到中心。
这是我的代码,其中包含 5 个对象之一供参考....
//ONE OF THE OBJECTS FOR REFERENCE
const minigeometry1 = new THREE.CylinderGeometry(5, 5, 0.5, 50);
const minimaterial1 = new THREE.MeshStandardMaterial({ color: 0xffff00 });
const minicylinder1 = new THREE.Mesh(minigeometry1, minimaterial1);
minicylinder1.name = 'minicylinder1';
minicylinder1.position.z = 7.5;
minicylinder1.position.x = -28
minicylinder1.rotation.z = Math.PI / 2;
scene.add(minicylinder1);
//CLICK EVENT ANIMATIONS
//CAMERA MOVEMENT TWEEN FUNCTION//
function tweenCamera(finalPosition, tweenSpeed) {
let initialPosition = new THREE.Vector3(camera.position.x, camera.position.y, camera.position.z);
new TWEEN.Tween(initialPosition)
.to(finalPosition, tweenSpeed)
.onUpdate(() => {
camera.position.set(initialPosition.x, initialPosition.y, initialPosition.z);
})
.easing(TWEEN.Easing.Cubic.Out)
.start();
}
//WHERE THE CAMERA IS CURRENTLY LOOKING, I THINK
let currentTarget = new THREE.Vector3();
currentTarget.set(controls.target.x, controls.target.y, controls.target.z);
let originTarget = new THREE.Vector3();
originTarget.set(0,0,0);
//TELLS CAMERA TO ORIENT TOWARD SPECIFIED OBJECT (target controls = camera orientation?)
let minicylinder1Target = new THREE.Vector3();
minicylinder1Target.set(minicylinder1.position.x, minicylinder1.position.y, minicylinder1.position.z);
let minicylinder2Target = new THREE.Vector3();
minicylinder2Target.set(minicylinder2.position.x, minicylinder2.position.y, minicylinder2.position.z);
let minicylinder3Target = new THREE.Vector3();
minicylinder3Target.set(minicylinder3.position.x, minicylinder3.position.y, minicylinder3.position.z);
let minicylinder4Target = new THREE.Vector3();
minicylinder4Target.set(minicylinder4.position.x, minicylinder4.position.y, minicylinder4.position.z);
let minicylinder5Target = new THREE.Vector3();
minicylinder5Target.set(minicylinder4.position.x, minicylinder5.position.y, minicylinder5.position.z);
//RAYCASTER SETUP AND CLICK EVENT FUNCTION
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
function onClick(event) {
//Normalized mouse coordinates (-1, +1)
mouse.x = (event.offsetX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
const intersects = raycaster.intersectObjects(scene.children, true);
//THIS DETERMINES WHETHER WE HAVE CLICKED ON AN OBJECT OR NOT
let coin1Clicked = false;
let coin2Clicked = false;
let coin3Clicked = false;
let coin4Clicked = false;
let coin5Clicked = false;
//IF WE CLICK ON COIN1 FROM THE MAIN POSITION, WE WILL ZOOM INTO IT
if ((getIndexInIntersectsArray(minicylinder1, intersects) > -1) && !coin1Clicked) {
//TWEEN TO ORIENT CAMERA TOWARDS COIN1
new TWEEN.Tween(currentTarget)
.to(minicylinder1Target, 2500)
.onUpdate(function() {
controls.target = currentTarget;
})
.easing(TWEEN.Easing.Quartic.InOut)
.start()
coin1Clicked = true;
//RESTRICT CAMERA ROTATION AND ZOOM OUT
tweenCamera(new THREE.Vector3(minicylinder1.position.x, minicylinder1.position.y, 25), 2500)
return coin1Clicked;
} else if ((getIndexInIntersectsArray(minicylinder1, intersects) > -1) && coin1Clicked) {
//TWEEN TO ORIENT CAMERA TOWARDS COIN1
new TWEEN.Tween(currentTarget)
.to(originTarget, 2500)
.onUpdate(function() {
controls.target = currentTarget;
})
.easing(TWEEN.Easing.Quartic.InOut)
.start()
coin1Clicked = false;
tweenCamera(new THREE.Vector3(origPos.position.x, origPos.position.y, origPos.position.z), 2500);
return coin1Clicked;
}
if ((getIndexInIntersectsArray(minicylinder2, intersects) > -1) && !coin2Clicked) {
//TWEEN TO ORIENT CAMERA TOWARDS COIN1
new TWEEN.Tween(currentTarget)
.to(minicylinder2Target, 2500)
.onUpdate(function() {
controls.target = currentTarget;
})
.easing(TWEEN.Easing.Quartic.InOut)
.start()
coin2Clicked = true;
//RESTRICT CAMERA ROTATION AND ZOOM OUT
tweenCamera(new THREE.Vector3(minicylinder2.position.x, minicylinder2.position.y, 25), 2500)
return coin2Clicked;
}
if ((getIndexInIntersectsArray(minicylinder3, intersects) > -1) && !coin3Clicked) {
//TWEEN TO ORIENT CAMERA TOWARDS COIN1
new TWEEN.Tween(currentTarget)
.to(minicylinder3Target, 2500)
.onUpdate(function() {
controls.target = currentTarget;
})
.easing(TWEEN.Easing.Quartic.InOut)
.start()
coin3Clicked = true;
//RESTRICT CAMERA ROTATION AND ZOOM OUT
tweenCamera(new THREE.Vector3(minicylinder3.position.x, minicylinder3.position.y, 25), 2500)
return coin3Clicked;
}
if ((getIndexInIntersectsArray(minicylinder4, intersects) > -1) && !coin4Clicked) {
//TWEEN TO ORIENT CAMERA TOWARDS COIN1
new TWEEN.Tween(currentTarget)
.to(minicylinder4Target, 2500)
.onUpdate(function() {
controls.target = currentTarget;
})
.easing(TWEEN.Easing.Quartic.InOut)
.start()
coin4Clicked = true;
//RESTRICT CAMERA ROTATION AND ZOOM OUT
tweenCamera(new THREE.Vector3(minicylinder4.position.x, minicylinder4.position.y, 25), 2500)
return coin4Clicked;
}
if ((getIndexInIntersectsArray(minicylinder5, intersects) > -1) && !coin5Clicked) {
//TWEEN TO ORIENT CAMERA TOWARDS COIN1
new TWEEN.Tween(currentTarget)
.to(minicylinder5Target, 2500)
.onUpdate(function() {
controls.target = currentTarget;
})
.easing(TWEEN.Easing.Quartic.InOut)
.start()
coin5Clicked = true;
//RESTRICT CAMERA ROTATION AND ZOOM OUT
tweenCamera(new THREE.Vector3(minicylinder5.position.x, minicylinder5.position.y, 25), 2500)
return coin5Clicked;
}
}
function getIndexInIntersectsArray(elem, array) {
var ind = -1;
for (var i = 0; i < array.length; i++) {
if (array[i].object.name == elem.name) {
ind = i;
}
}
return ind;
}
window.addEventListener("click", (event) => {
onClick(event);
})
var animate = function() {
requestAnimationFrame(animate);
cylinder.rotation.y += 0.025;
minicylinder1.rotation.y += 0.025;
minicylinder2.rotation.y += 0.025;
minicylinder3.rotation.y += 0.025;
minicylinder4.rotation.y += 0.025;
minicylinder5.rotation.y += 0.025;
controls.update();
render();
TWEEN.update();
};
function render() {
renderer.render(scene, camera);
}
animate();
有人可以分享任何见解吗?请问漂亮吗?
提前致谢!
P.S。如果您觉得我的代码效率低下...我敢肯定,我想我可以使用 switch 语句,但我还不知道该怎么做,因为这是第一个我做过的项目所以我没有什么可以比较的。
自言自语:经过测试...processing/displaying 的流量中断在哪里? (我想不出一个合适的词),通过向控制台打印消息以查看 was/wasn 没有像我想要的那样发生的事情,我意识到我必须把
让coin1Clicked = false;
.
.
.
让 coin5Clicked = false;
代码在我的 onClick 函数之外。我不知道为什么,因为我认为我正在使它们成为局部变量(相对于全局变量),这不应该成为问题,至少我认为。一旦我将它们设为全局变量,if...else 语句就开始工作了!进入 GSAP!
我开始关注一些 YouTube 教程,以供 three.js 初学者使用。我看到其中一个示例创建了三个漂浮在 space 中的球体,并使它们可点击。
所以我按照教程如何设置 three.js 场景并创建了 6 个 3d 圆柱体对象。我想要的是...
如果您单击某个对象,相机会指向并注视该对象,并且相机也会在该对象前面进行物理转换,因此我可以在那里显示文本或其他内容。到达那里后,我将限制控件,直到用户单击补间会将它们带回原始位置和方向的对象。
我试图让逻辑成为 如果 你点击了对象 1 && 你之前没有点击过它然后去看看它,else if 你点击对象 1 && 如果它被点击,那么相机将反向补间并回到原点... if else 你点击在对象 2 上 && 你之前没有点击过它然后去看看它,else if 你点击对象 2 && 如果它被点击了......依此类推,直到每个对象的两种情况都被考虑在内。我看到教程通过创建一个布尔变量来将状态设置为已被单击或未被单击来在一个对象上执行此操作。我试图将其合并到我的代码中,但我认为问题是 Javascript 系统没有标记或保留将变量更改为一个或另一个的信息....这可能是语法错误,它可能是我采用的方法根本不可能(未知的未知数),或者是一个简单的错字。
一旦我制作了 5 个单独的 If 语句,我就能够看到每个补间都按照我的意愿 朝向 对象但是 none 的补间响应检查它们是否已被单击的部分并将相机补间回到中心。
这是我的代码,其中包含 5 个对象之一供参考....
//ONE OF THE OBJECTS FOR REFERENCE
const minigeometry1 = new THREE.CylinderGeometry(5, 5, 0.5, 50);
const minimaterial1 = new THREE.MeshStandardMaterial({ color: 0xffff00 });
const minicylinder1 = new THREE.Mesh(minigeometry1, minimaterial1);
minicylinder1.name = 'minicylinder1';
minicylinder1.position.z = 7.5;
minicylinder1.position.x = -28
minicylinder1.rotation.z = Math.PI / 2;
scene.add(minicylinder1);
//CLICK EVENT ANIMATIONS
//CAMERA MOVEMENT TWEEN FUNCTION//
function tweenCamera(finalPosition, tweenSpeed) {
let initialPosition = new THREE.Vector3(camera.position.x, camera.position.y, camera.position.z);
new TWEEN.Tween(initialPosition)
.to(finalPosition, tweenSpeed)
.onUpdate(() => {
camera.position.set(initialPosition.x, initialPosition.y, initialPosition.z);
})
.easing(TWEEN.Easing.Cubic.Out)
.start();
}
//WHERE THE CAMERA IS CURRENTLY LOOKING, I THINK
let currentTarget = new THREE.Vector3();
currentTarget.set(controls.target.x, controls.target.y, controls.target.z);
let originTarget = new THREE.Vector3();
originTarget.set(0,0,0);
//TELLS CAMERA TO ORIENT TOWARD SPECIFIED OBJECT (target controls = camera orientation?)
let minicylinder1Target = new THREE.Vector3();
minicylinder1Target.set(minicylinder1.position.x, minicylinder1.position.y, minicylinder1.position.z);
let minicylinder2Target = new THREE.Vector3();
minicylinder2Target.set(minicylinder2.position.x, minicylinder2.position.y, minicylinder2.position.z);
let minicylinder3Target = new THREE.Vector3();
minicylinder3Target.set(minicylinder3.position.x, minicylinder3.position.y, minicylinder3.position.z);
let minicylinder4Target = new THREE.Vector3();
minicylinder4Target.set(minicylinder4.position.x, minicylinder4.position.y, minicylinder4.position.z);
let minicylinder5Target = new THREE.Vector3();
minicylinder5Target.set(minicylinder4.position.x, minicylinder5.position.y, minicylinder5.position.z);
//RAYCASTER SETUP AND CLICK EVENT FUNCTION
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
function onClick(event) {
//Normalized mouse coordinates (-1, +1)
mouse.x = (event.offsetX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
const intersects = raycaster.intersectObjects(scene.children, true);
//THIS DETERMINES WHETHER WE HAVE CLICKED ON AN OBJECT OR NOT
let coin1Clicked = false;
let coin2Clicked = false;
let coin3Clicked = false;
let coin4Clicked = false;
let coin5Clicked = false;
//IF WE CLICK ON COIN1 FROM THE MAIN POSITION, WE WILL ZOOM INTO IT
if ((getIndexInIntersectsArray(minicylinder1, intersects) > -1) && !coin1Clicked) {
//TWEEN TO ORIENT CAMERA TOWARDS COIN1
new TWEEN.Tween(currentTarget)
.to(minicylinder1Target, 2500)
.onUpdate(function() {
controls.target = currentTarget;
})
.easing(TWEEN.Easing.Quartic.InOut)
.start()
coin1Clicked = true;
//RESTRICT CAMERA ROTATION AND ZOOM OUT
tweenCamera(new THREE.Vector3(minicylinder1.position.x, minicylinder1.position.y, 25), 2500)
return coin1Clicked;
} else if ((getIndexInIntersectsArray(minicylinder1, intersects) > -1) && coin1Clicked) {
//TWEEN TO ORIENT CAMERA TOWARDS COIN1
new TWEEN.Tween(currentTarget)
.to(originTarget, 2500)
.onUpdate(function() {
controls.target = currentTarget;
})
.easing(TWEEN.Easing.Quartic.InOut)
.start()
coin1Clicked = false;
tweenCamera(new THREE.Vector3(origPos.position.x, origPos.position.y, origPos.position.z), 2500);
return coin1Clicked;
}
if ((getIndexInIntersectsArray(minicylinder2, intersects) > -1) && !coin2Clicked) {
//TWEEN TO ORIENT CAMERA TOWARDS COIN1
new TWEEN.Tween(currentTarget)
.to(minicylinder2Target, 2500)
.onUpdate(function() {
controls.target = currentTarget;
})
.easing(TWEEN.Easing.Quartic.InOut)
.start()
coin2Clicked = true;
//RESTRICT CAMERA ROTATION AND ZOOM OUT
tweenCamera(new THREE.Vector3(minicylinder2.position.x, minicylinder2.position.y, 25), 2500)
return coin2Clicked;
}
if ((getIndexInIntersectsArray(minicylinder3, intersects) > -1) && !coin3Clicked) {
//TWEEN TO ORIENT CAMERA TOWARDS COIN1
new TWEEN.Tween(currentTarget)
.to(minicylinder3Target, 2500)
.onUpdate(function() {
controls.target = currentTarget;
})
.easing(TWEEN.Easing.Quartic.InOut)
.start()
coin3Clicked = true;
//RESTRICT CAMERA ROTATION AND ZOOM OUT
tweenCamera(new THREE.Vector3(minicylinder3.position.x, minicylinder3.position.y, 25), 2500)
return coin3Clicked;
}
if ((getIndexInIntersectsArray(minicylinder4, intersects) > -1) && !coin4Clicked) {
//TWEEN TO ORIENT CAMERA TOWARDS COIN1
new TWEEN.Tween(currentTarget)
.to(minicylinder4Target, 2500)
.onUpdate(function() {
controls.target = currentTarget;
})
.easing(TWEEN.Easing.Quartic.InOut)
.start()
coin4Clicked = true;
//RESTRICT CAMERA ROTATION AND ZOOM OUT
tweenCamera(new THREE.Vector3(minicylinder4.position.x, minicylinder4.position.y, 25), 2500)
return coin4Clicked;
}
if ((getIndexInIntersectsArray(minicylinder5, intersects) > -1) && !coin5Clicked) {
//TWEEN TO ORIENT CAMERA TOWARDS COIN1
new TWEEN.Tween(currentTarget)
.to(minicylinder5Target, 2500)
.onUpdate(function() {
controls.target = currentTarget;
})
.easing(TWEEN.Easing.Quartic.InOut)
.start()
coin5Clicked = true;
//RESTRICT CAMERA ROTATION AND ZOOM OUT
tweenCamera(new THREE.Vector3(minicylinder5.position.x, minicylinder5.position.y, 25), 2500)
return coin5Clicked;
}
}
function getIndexInIntersectsArray(elem, array) {
var ind = -1;
for (var i = 0; i < array.length; i++) {
if (array[i].object.name == elem.name) {
ind = i;
}
}
return ind;
}
window.addEventListener("click", (event) => {
onClick(event);
})
var animate = function() {
requestAnimationFrame(animate);
cylinder.rotation.y += 0.025;
minicylinder1.rotation.y += 0.025;
minicylinder2.rotation.y += 0.025;
minicylinder3.rotation.y += 0.025;
minicylinder4.rotation.y += 0.025;
minicylinder5.rotation.y += 0.025;
controls.update();
render();
TWEEN.update();
};
function render() {
renderer.render(scene, camera);
}
animate();
有人可以分享任何见解吗?请问漂亮吗? 提前致谢!
P.S。如果您觉得我的代码效率低下...我敢肯定,我想我可以使用 switch 语句,但我还不知道该怎么做,因为这是第一个我做过的项目所以我没有什么可以比较的。
自言自语:经过测试...processing/displaying 的流量中断在哪里? (我想不出一个合适的词),通过向控制台打印消息以查看 was/wasn 没有像我想要的那样发生的事情,我意识到我必须把
让coin1Clicked = false; . . . 让 coin5Clicked = false;
代码在我的 onClick 函数之外。我不知道为什么,因为我认为我正在使它们成为局部变量(相对于全局变量),这不应该成为问题,至少我认为。一旦我将它们设为全局变量,if...else 语句就开始工作了!进入 GSAP!