@react-three/react-three-fiber: 使用 useLoader() 在属性更改时加载新文件

4

我有一个功能性的React组件,最初通过props加载了一个gltf模型-这个路径是通过props传递的-这个能正常工作。

但是,如果props发生变化,组件会重新渲染-我已经检查过了-路径已更改,应该加载新的模型,但实际上没有加载。

如何做到这一点? 我想在状态更新时交换/替换正在渲染的对象。

我尝试了不同的加载器,将gltf本身设置为状态,但这些都没有起作用。我认为我缺少一个基本概念。请帮助

  function Character(props) {
      const spinner = useRef();
      console.log(props.model, "from modelpreviewer");
      const gltf = useLoader(GLTFLoader, props.model);
    
      return gltf ? (
        <primitive
          ref={spinner}
          object={gltf.scene}
        />
      ) : null;
    }

字符组件会呈现如下效果:

<Canvas
   camera={{ position: [0, 0, 10] }}>
    <ambientLight intensity={0.8} />
    <spotLight intensity={0.7} position={[300, 300, 400]} />
    <Suspense fallback={null}>
      <Character model={props.model} />
    </Suspense>
  </Canvas>
1个回答

3

我测试了useLoader在渲染纹理时的问题,对我来说工作得很好。这是一个简单的例子,它展示了每当props更改时纹理都会改变。

我猜你错过了正确的路径指向props.model。也许你可以硬编码一个props.model的值,以确保文件路径是否正确。

编辑

我找到了gltf只渲染一次的原因。答案在这里

在webgl/threejs中,您不能重用网格或将相同的对象放入场景中两次,它将被卸载并重新挂载。

另一种解决方案是克隆场景

const { scene } = useLoader(GLTFLoader, url)
const copiedScene = useMemo(() => scene.clone(), [scene])

我还提供了一个固定的例子,位于codesandbox上。


路径是正确的,我已经测试过了,并且它们也已经被导入了,所以这不是问题。 - Alex
我也修改了你的示例以使用gltf加载器,但仍然无法正常工作。我不知道这是否可能或者是否与场景有关。 - Alex
@AlexanderFrey,你能分享一下你的例子吗? - bcjohn
但我的仍然无法工作,我不知道该怎么办。 - Alex
1
兄弟,这在2022年真是太有帮助了。这完全解决了我的问题。谢谢! - Lee Merlas
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接