0

I've created a react-three-fiber functional component to load a glb file of a butterfly with animation and I am returning a primitive with the scene of the glb passed as an object prop. It is nested in a mesh, that is nested in a scene, that is nested in a group.

function Butterfly({ speed, factor, url, ...props }) {
  const { scene, nodes, materials, animations } = useLoader(GLTFLoader, url);
  const group = useRef()
  const [mixer] = useState(() => new THREE.AnimationMixer())
  useEffect(() => mixer.clipAction(animations[0], group.current).play(), [])
   useFrame((state, delta) => {
    group.current.rotation.y -= Math.sin((delta * factor) / 2) * Math.cos((delta * factor) / 2) * 2
    mixer.update(delta * speed)
  })
  return (
    <group ref={group} dispose={null}>
      <scene name="Scene" {...props}>
        <mesh
        name="Object_0"
        >
          <primitive object={scene}/>
         </mesh>
      </scene>
    </group>
  )
}

This component is then returned in separate function in each iteration of an array.

function Butterflies() {
  const copyArray = new Array(100).fill()
  console.log(copyArray);
  return copyArray.map((j, i) => {
    const x = (15 + Math.random() * 30) * (Math.round(Math.random()) ? -1 : 1)
    const y = -10 + Math.random() * 20
    const z = -5 + Math.random() * 10
    return <Butterfly key={i} position={[x, y, z]} rotation={[0, x > 0 ? Math.PI : 0, 0]}  speed='5' factor='1.5' url='/blue_butterfly.glb' />
  })
}

However, this function is only returning one butterfly instead of 100.

single butterfly

I think my issue has something to do with the return in the Butterfly component. I've tried only returning the primitive with props and a ref, but that doesn't render anything. I've tried going through the console.log of the the glb file and found the geometry and tried passing that as a prop to the mesh along with the materials, but that only rendered a white butterfly shape without the animation from the scene. Why is this only returning 1 butterfly instead of 100?

2
  • I'm not sure, but this may be happening because scene is the same across all butterfly components, so it's only aded to the last butterfly. Commented Nov 23, 2020 at 0:32
  • This helped me solve it. I just had to make a copy of the glb file for each loop. So I just made it loop through an array of 10 and made 10 copies of the glb file. Commented Nov 23, 2020 at 23:07

1 Answer 1

1

I assume Butterflies() is in Butterflies.js and you are trying return many <Butterfly> here, however react component can only have one parent.

try this in Butterflies():

function Butterflies() {
  const copyArray = new Array(100).fill()
  console.log(copyArray);
  return(
    <>
    {copyArray.map((j, i) => {
    const x = (15 + Math.random() * 30) * (Math.round(Math.random()) ? -1 : 1)
    const y = -10 + Math.random() * 20
    const z = -5 + Math.random() * 10
    return <Butterfly key={i} position={[x, y, z]} rotation={[0, x > 0 ? Math.PI : 0, 0]}  speed='5' factor='1.5' url='/blue_butterfly.glb' />
  })}
    </>)}

Or store it in a variable first, for the example:

function Butterflies() {
  const copyArray = new Array(100).fill()
  console.log(copyArray);
  const items=copyArray.map((j, i) => {
    const x = (15 + Math.random() * 30) * (Math.round(Math.random()) ? -1 : 1)
    const y = -10 + Math.random() * 20
    const z = -5 + Math.random() * 10
    return <Butterfly key={i} position={[x, y, z]} rotation={[0, x > 0 ? Math.PI : 0, 0]}  speed='5' factor='1.5' url='/blue_butterfly.glb' />
    })
  return(
    <>
    {items}
    </>
)}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.