Three.js: cómo agregar una URL personalizada a un modelo GLTF cargado
Tengo una galaxia compuesta por 3 planetas y una nave espacial, y quiero hacer que todos ellos sean clicables para cargar otra página. Logré hacerlo con los 3 planetas agregando planet.userData = {URL: "my.html"};
pero no con la nave espacial, que es un modelo cargado GLTF.
Así es como cargué la nave espacial:
const loader = new GLTFLoader();
loader.load('models/spaceship.glb', function(gltf) {
const spaceship = gltf.scene;
spaceship.scale.set(0.08, 0.08, 0.08);
spaceship.userData = {URL: "my.html"}; //Agregando la URL aquí
objects.push(spaceship); //Esto es para el raycasting
scene.add(spaceship);
}, undefined, function(error){
console.error(error);
});
Y esta es la función para el evento Mouse Down:
function onDocumentMouseDown(){
mouse.x = (event.clientX/window.innerWidth)*2-1;
mouse.y = -(event.clientY/window.innerHeight)*2+1;
const raycaster = new THREE.Raycaster();
raycaster.setFromCamera(mouse, camera);
const intersects = raycaster.intersectObjects(objects, true);
if ( intersects.length > 0 ) {
window.open(intersects[0].object.userData.URL); // <-- No funciona
}
}
Cuando hago clic en la nave espacial, el valor de la URL es “undefined”. Estoy seguro de que hay otra forma de hacerlo, pero no puedo encontrar ninguna solución. ¡Muchas gracias de antemano a cualquiera que ayude!
davy.ai
Parece que el modelo GLTF cargado para la nave espacial no tiene asignada la propiedad
userData
. Según el código proporcionado, parece que esta líneaspaceship.userData = {URL: "my.html"};
se está ejecutando correctamente. Sin embargo, cuando se revisa el arrayintersects
en busca de objetos clicables, la propiedaduserData
del objeto de la nave espacial devuelveundefined
.Una posible solución podría ser verificar si el array
intersects
está vacío y, en ese caso, intentar buscar la propiedaduserData
en alguno de los padres del objeto. Esto se puede lograr recorriendo la jerarquía de padres del objeto hasta que se encuentre la propiedaduserData
o se alcance el objeto raíz.Aquí tienes un ejemplo de cómo se podría implementar esto:
En este ejemplo, si el objeto clicado no tiene
userData
, el bucle recorrerá los objetos padre hasta que encuentre el primer objeto conuserData
. Si no se encuentra ningún objeto conuserData
, el bucle finalizará cuando llegue al objeto raízscene
.¡Espero que esto ayude!