I made three copies of the model, and want to change the color when the mouse hovers it. But when I hover one of the models, the rest of the two models also change color.
The most stupid way is to create three identical glb model files, I have tried it can work, but I still hope to shared the code.
import { useGLTF } from "@react-three/drei";
import{ Hover } from "modifiers/Hover";
export default function MyScene() {
const gltf = useGLTF("/example.glb");
const positions = [
{ x: -4, y: 1.6, z: 3.5, rx: 0, ry: 0, rz: 0 },
{ x: 0, y: 0, z: 3.5, rx: 0, ry: 0, rz: 0 },
{ x: 1.15, y: 1.6, z: 7.7, rx: 0, ry: Math.PI/2, rz: 0 },
];
return (
<>
{positions.map((position, index) => {
const clone = gltf.scene.clone();
clone.position.set(position.x, position.y, position.z);
clone.rotation.set(position.rx, position.ry, position.rz);
return <Hover key={index} > <primitive object={clone} /> </Hover>
})}
</>
);
}
Hover function:
import React, { useRef, useState, ReactNode} from "react";
import { Group, Raycaster, Vector3 } from "three";
import { useFrame } from "@react-three/fiber";
export function Hover(props: HoverProps) {
const {
children,
} = props;
const hoverRef = useRef<Group>(null);
const raycaster = new Raycaster();
const posTemp = new Vector3();
const [isHover, setHover] = useState(false);
const [intersectState, setIntersectState] = useState('');
let intersections;
useFrame(({ camera }) => {
if(hoverRef.current) {
raycaster.set(camera.position, camera.getWorldDirection(posTemp));
intersections = raycaster.intersectObject(hoverRef.current, true);
if(intersections && intersections.length > 0 ){
setIntersectState(intersections);
intersections[0].object.material.emissive.setHex(0xffff00);
} else {
if(intersectState && intersectState.length > 0) {
intersectState[0].object.material.emissive.setHex(0x333333);
setIntersectState(null);
}
}
}
});
return (
<group name="hover" ref={hoverRef}>
{children}
</group>
);
}