Javascript 使用multimaterial three.js鼠标悬停不起作用
我有一个问题,我想在一个有多种材质的对象上做一个鼠标悬停 样品 它们不起作用。它总是显示“未捕获的TypeError:无法读取未定义的属性'setHex'” 我为此更改了交叉点代码,但不起作用:Javascript 使用multimaterial three.js鼠标悬停不起作用,javascript,three.js,hover,mouse,Javascript,Three.js,Hover,Mouse,我有一个问题,我想在一个有多种材质的对象上做一个鼠标悬停 样品 它们不起作用。它总是显示“未捕获的TypeError:无法读取未定义的属性'setHex'” 我为此更改了交叉点代码,但不起作用: function update() { // find intersections // create a Ray with origin at the mouse position and direction into the scene (camera direction)
function update()
{
// find intersections
// create a Ray with origin at the mouse position and direction into the scene (camera direction)
var vector = new THREE.Vector3( mouse.x, mouse.y, 1 );
projector.unprojectVector( vector, Camara );
var ray = new THREE.Raycaster( Camara.position, vector.sub( Camara.position ).normalize() );
// create an array containing all objects in the scene with which the ray intersects
var intersects = ray.intersectObjects( Escenario.children );
// INTERSECTED = El objeto en la escena actualmente más cercana a la cámara e intersectado por el Rayo proyectado desde la posición del ratón.
// Si hay una o más intersecciones (objetos encontrados con el ratón)
if ( intersects.length > 0 )
{
// Si el primer objeto encontrado es diferente del anterior encontrado
if (intersects[0].object != INTERSECTED)
{
// Restaura previamente el anterior al color del objeto original
if (INTERSECTED)
{
// INTERSECTED.material.color.setHex(INTERSECTED.currentHex);
INTERSECTED.material = INTERSECTED.currentHex;
}
// store reference to closest object as current intersection object
INTERSECTED = intersects[0].object;
// store color of closest object (for later restoration)
//INTERSECTED.currentHex = INTERSECTED.material.color.getHex();
for(var p =0; p < INTERSECTED.material.materials.length; p++)
{
INTERSECTED.currentHex = INTERSECTED.material.materials[p].emissive.getHex();
}
// set a new color for closest object
//INTERSECTED.material.color.setHex(0xffff00);
}
}
else // there are no intersections
{
// restore previous intersection object (if it exists) to its original color
if ( INTERSECTED )
{
INTERSECTED.material = INTERSECTED.currentHex;
}
// remove previous intersection object reference
// by setting current intersection object to "nothing"
INTERSECTED = null;
}
controls.update();
}
完整的代码可以在这里看到:
我能做什么?谢谢 试试这个。检查控制台以了解其工作原理。祝大家好运
/**
*鼠标移动事件。
*@param事件
*/
onMouseMove(事件){
event.preventDefault();
this.mouse.x=(event.offsetX/this.w)*2-1;
this.mouse.y=-(event.offsetY/this.h)*2+1;
//这个。检查交叉点(“悬停”);
}
/**
*检查是否发生交叉。
*/
检查交叉口(操作?){
//设置光线投射器。
this.raycaster.setFromCamera(this.mouse,this.camera);
//console.log(this.cubeChilds);
const intersects=this.raycaster.intersectObjects(this.scene.children);
控制台日志(交叉);
如果(操作=='hover'){
}
//更改要修改的图元的材质
此.mouse_荧光灯(相交);
}
鼠标\荧光灯(相交){
//函数_存在(currentValue){
//返回电流值<40;
// }
log('mouse_highLighter start:');
const new_material=新的三网格基本材质({
颜色:0xff0000,
});
const new_green_material=新的三网格基本材质({
颜色:0x00ff40,
});
//?如果存在相交对象
如果(相交长度>0){
if(this.INTERSECTED!==与[0]相交。对象){
//设置预览网格材质(如果存在)
如果(本条相交){
this.INTERSECTED.material=this.INTERSECTED\u last\u mat;
console.log('-1--');
}
this.INTERSECTED=与[0]相交。对象;
this.intersected_last_mat=this.intersected.material;
相交[0]。object.material=新的\u绿色\u材质;
console.log(this.INTERSECTED);
console.log('-2--');
}
}否则{
如果(本条相交){
this.INTERSECTED.material=this.INTERSECTED\u last\u mat;
console.log('-3--');
}
this.INTERSECTED=null;
console.log('-4--');
}
console.log('-5--');
这个。render();
}
如果您提供更多详细信息,例如它是否正常工作,可能会更好?哪一行有错误?是的,场景示例:当我在房间里移动鼠标指针时,它应该看起来像这个或其他颜色或纹理。有错误的行是176、163和169,谢谢!完整代码:因为您尝试在多重材质上设置颜色,该材质没有颜色
属性,但它有材质
属性,即材质数组。非常感谢prisoner849,如何在辅助变量中复制对象的材质数组以更改材质原始值?然后将修改后的材质更改为辅助变量的材质,当鼠标切换时,我会有完全相同的s错误
function update()
{
// find intersections
// create a Ray with origin at the mouse position and direction into the scene (camera direction)
var vector = new THREE.Vector3( mouse.x, mouse.y, 1 );
projector.unprojectVector( vector, Camara );
var ray = new THREE.Raycaster( Camara.position, vector.sub( Camara.position ).normalize() );
// create an array containing all objects in the scene with which the ray intersects
var intersects = ray.intersectObjects( Escenario.children );
// INTERSECTED = El objeto en la escena actualmente más cercana a la cámara e intersectado por el Rayo proyectado desde la posición del ratón.
// Si hay una o más intersecciones (objetos encontrados con el ratón)
if ( intersects.length > 0 )
{
// Si el primer objeto encontrado es diferente del anterior encontrado
if (intersects[0].object != INTERSECTED)
{
// Restaura previamente el anterior al color del objeto original
if (INTERSECTED)
{
// INTERSECTED.material.color.setHex(INTERSECTED.currentHex);
INTERSECTED.material = INTERSECTED.currentHex;
}
// store reference to closest object as current intersection object
INTERSECTED = intersects[0].object;
// store color of closest object (for later restoration)
//INTERSECTED.currentHex = INTERSECTED.material.color.getHex();
for(var p =0; p < INTERSECTED.material.materials.length; p++)
{
INTERSECTED.currentHex = INTERSECTED.material.materials[p].emissive.getHex();
}
// set a new color for closest object
//INTERSECTED.material.color.setHex(0xffff00);
}
}
else // there are no intersections
{
// restore previous intersection object (if it exists) to its original color
if ( INTERSECTED )
{
INTERSECTED.material = INTERSECTED.currentHex;
}
// remove previous intersection object reference
// by setting current intersection object to "nothing"
INTERSECTED = null;
}
controls.update();
}
function mostrarPiso()
{
// Cargamos el modelo de la escuela. En el primer parámetro está la url del modelo y en el segundo la función que se ejcuta al cargarlo. En este caso estoy utilizando una función anónima.
loader.load("modelos/informaticaPlanta0/PlantaBajaSinHabitacion.js", function (geometry, materials)
{
let material = new THREE.MultiMaterial(materials);
let object = new THREE.Mesh(geometry, material);
object.name = "pabellon";
Escenario.add(object);
}
);
loader.load("modelos/informaticaPlanta0/PlantaBajaHabitacion.js", function (geometry, materials)
{
let material = new THREE.MultiMaterial(materials);
let object = new THREE.Mesh(geometry, material);
object.name = "habitacion";
Escenario.add(object);
}
);
}
/**
* On mouse move event.
* @param event
*/
onMouseMove(event) {
event.preventDefault();
this.mouse.x = (event.offsetX / this.w) * 2 - 1;
this.mouse.y = -(event.offsetY / this.h) * 2 + 1;
// this.checkIntersection('hover');
}
/**
* Check if intersection happen.
*/
checkIntersection (operation?) {
// Setup the raycaster.
this.raycaster.setFromCamera(this.mouse, this.camera);
// console.log(this.cubeChilds);
const intersects = this.raycaster.intersectObjects(this.scene.children);
console.log(intersects);
if (operation === 'hover') {
}
// Change the material of the element that
this.mouse_highLighter (intersects);
}
mouse_highLighter (intersects) {
// function _exists(currentValue) {
// return currentValue < 40;
// }
console.log('mouse_highLighter start: ');
const new_material = new THREE.MeshBasicMaterial({
color: 0xff0000,
});
const new_green_material = new THREE.MeshBasicMaterial({
color: 0x00ff40,
});
// ? If intersected object exist
if ( intersects.length > 0 ) {
if ( this.INTERSECTED !== intersects[ 0 ].object ) {
// set the preview mesh material if exist
if ( this.INTERSECTED ) {
this.INTERSECTED.material = this.intersected_last_mat;
console.log('--1--');
}
this.INTERSECTED = intersects[ 0 ].object;
this.intersected_last_mat = this.INTERSECTED.material;
intersects[ 0 ].object.material = new_green_material;
console.log(this.INTERSECTED);
console.log('--2--');
}
} else {
if ( this.INTERSECTED ) {
this.INTERSECTED.material = this.intersected_last_mat;
console.log('--3--');
}
this.INTERSECTED = null;
console.log('--4--');
}
console.log('--5--');
this.render();
}