You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Expo Three应用中无法导入.obj文件的问题求助

Expo导入.obj文件报错:Unable to resolve "missing-asset-registry-path"

错误信息

Android Bundling failed 26225ms (D:\Dev\expo\nook\node_modules\expo\AppEntry.js)
Unable to resolve "missing-asset-registry-path" from "assets\Suzanne.obj"

当前配置与代码

metro.config.js

const path = require('path');
const root = path.resolve(__dirname, '..');

module.exports = {
    projectRoot: __dirname,
    watchFolders: [root],

    resolver: {
      sourceExts: ['js', 'jsx', 'json', 'ts', 'tsx', 'cjs'],
      assetExts: ['glb', 'gltf', 'mtl', 'obj', 'png', 'jpg'],
    },
  }

App.js

import React, { Component } from "react";
import * as THREE from "three";
import { GLView } from "expo-gl";
import { Renderer } from "expo-three";
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader';
import { Asset } from 'expo-asset';

export default class App extends Component {
  render() {
    return (
      <GLView style={{ flex: 1 }} onContextCreate={this._onGLContextCreate} />
    );
  }
  _onGLContextCreate = async (gl) => {
    // 1. Scene
    var scene = new THREE.Scene();
    // 2. Camera
    const camera = new THREE.PerspectiveCamera(
      75,
      gl.drawingBufferWidth / gl.drawingBufferHeight,
      0.1,
      1000
    );
    // 3. Renderer
    const renderer = new Renderer({ gl });
    renderer.setSize(gl.drawingBufferWidth, gl.drawingBufferHeight);

    // Load object
    const objAsset = Asset.fromModule(require('./assets/Suzanne.obj'));
    await objAsset.downloadAsync();
    const uri = objAsset.localUri || objAsset.uri;

    const loader = new OBJLoader();
    loader.load(
      uri,
      (object) => {
        // Add the loaded object to your scene
        scene.add(object);
      },
      (xhr) => {
        console.log((xhr.loaded / xhr.total) * 100 + '% loaded');
      },
      (error) => {
        console.error('Error loading OBJ file:', error);
      }
    );

    // const geometry = new THREE.BoxGeometry();
    // const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
    // const cube = new THREE.Mesh(geometry, material);
    // scene.add(cube);

    camera.position.z = 5;
    const animate = () => {
      requestAnimationFrame(animate);
      cube.rotation.x += 0.01;
      cube.rotation.y += 0.01;
      renderer.render(scene, camera);
      gl.endFrameEXP();
    };
    animate();
  };
}

解决方案

1. 修正metro.config.js配置

手动设置projectRoot和watchFolders容易导致路径识别混乱,改用Expo官方默认配置扩展资源类型:

const { getDefaultConfig } = require('expo/metro-config');

const config = getDefaultConfig(__dirname);

// 添加OBJ、MTL等3D资源扩展名
config.resolver.assetExts.push('obj', 'mtl');

module.exports = config;

2. 简化资源加载逻辑

无需通过Asset.fromModule处理,直接使用require获取资源URI:

// 替换原加载代码
const objUri = require('./assets/Suzanne.obj').default;

const loader = new OBJLoader();
loader.load(
  objUri,
  (object) => {
    scene.add(object);
  },
  (xhr) => {
    console.log((xhr.loaded / xhr.total) * 100 + '% loaded');
  },
  (error) => {
    console.error('Error loading OBJ file:', error);
  }
);

3. 清除缓存重启项目

执行命令清除Metro缓存,避免旧配置残留:

npx expo start --clear

4. 修复动画函数错误

动画函数中引用了已注释的cube变量,会导致运行时报错,修改为:

// 先定义模型引用
let loadedObject = null;

// 在loader的成功回调中赋值
loader.load(
  objUri,
  (object) => {
    loadedObject = object;
    scene.add(object);
  },
  // ...其他回调
);

// 修改动画函数
const animate = () => {
  requestAnimationFrame(animate);
  if (loadedObject) {
    loadedObject.rotation.x += 0.01;
    loadedObject.rotation.y += 0.01;
  }
  renderer.render(scene, camera);
  gl.endFrameEXP();
};

内容的提问来源于stack exchange,提问作者kev14762

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 11:05:20