pmndrs / gltfjsx

🎮 Turns GLTFs into JSX components
https://gltf.pmnd.rs
MIT License
4.71k stars 310 forks source link

Using GLTFJSX with React Native #142

Closed RichardBrowning closed 2 years ago

RichardBrowning commented 2 years ago

Hello,

I am having a problem using .js file generated with GLTFJSX in react native / expo. I used the same process to generate JS file as I did with react.js. npx gltfjsx model.gltf However, it does not work and returns this message below to me:

[Unhandled promise rejection: Error: Unable to download file: Error Domain=NSURLErrorDomain Code=-1002 "unsupported URL" UserInfo={NSErrorFailingURLStringKey=/animated-sphere.glb, NSErrorFailingURLKey=/animated-sphere.glb, _NSURLErrorRelatedURLSessionTaskErrorKey=(]
at node_modules/react-native/Libraries/BatchedBridge/NativeModules.js:104:50 in promiseMethodWrapper
at node_modules/expo-modules-core/build/NativeModulesProxy.native.js:27:27 in moduleName.methodInfo.name
at node_modules/expo-file-system/build/FileSystem.js:105:17 in downloadAsync
at node_modules/expo-file-system/build/FileSystem.js:101:7 in downloadAsync
at node_modules/expo-asset/build/PlatformUtils.js:52:25 in _downloadAsyncManagedEnv

This is the JS file generated. I made some modifications but it is mostly original:

/*
Auto-generated by: https://github.com/pmndrs/gltfjsx
*/

import React, { useRef, useState, useEffect } from 'react'
import { useGLTF, useAnimations } from '@react-three/drei/native';

export default function Model({ ...props }) {
  const [leftRight, setLeftRight] = useState(false);
  const group = useRef()
  const { nodes, materials, animations } = useGLTF('/animated-sphere.glb')
  const { actions } = useAnimations(animations, group)
  console.log(actions);
  useEffect(() => {
    if (leftRight) {
      actions.LeftRight.play();
      actions.UpDown.stop();
    } else {
      actions.UpDown.play();
      actions.LeftRight.stop();
    }
  });
  return (
    <group ref={group} {...props} dispose={null}>
      <group>
        <group position={[4.08, 5.9, -1.01]} rotation={[1.89, 0.88, -2.05]} />
        <group position={[7.36, 4.96, 6.93]} rotation={[1.24, 0.33, -0.76]} />
        <mesh name="Sphere" geometry={nodes.Sphere.geometry} material={materials['Red Shiny']} onClick={() => setLeftRight(!leftRight)} />
      </group>
    </group>
  )
}

useGLTF.preload('/animated-sphere.glb')

The .glb file is under the /public folder, in the Root.

I believe this is a problem that useGLTF cannot find the file. If so, how may I make changes to the path, please?

Thank you in advance.

CodyJasonBennett commented 2 years ago

You'll need to import your model as a module and let your bundler transform it:

import modelPath from './path/to/model.glb'

useGLTF(modelPath)
RichardBrowning commented 2 years ago

The solution works flawlessly. Thank you very much!

bendgk commented 1 year ago

Sorry, I'm not sure if this solution still works anymore.

"react-native": "0.71.8", "@react-three/drei": "^9.77.0", "@react-three/fiber": "^8.13.3",

gltfjsx: 6.2.9