-
-
Notifications
You must be signed in to change notification settings - Fork 394
Description
代码示例
`import React, { useEffect, useState, useRef } from 'react';
import { Button } from 'antd-mobile';
import {
WebGLEngine,
Scene,
Entity,
Camera,
DirectLight,
Vector3,
AssetType,
GLTFResource,
Animator,
} from '@galacean/engine';
import { LitePhysics } from '@galacean/engine-physics-lite';
import { registerIncludes } from '@galacean/engine-toolkit';
import { ShaderLab } from '@galacean/engine-shader-lab';
import { OrbitControl } from '@galacean/engine-toolkit';
import './styles.less';
export default () => {
const canvasRef = useRef(null);
const engineRef = useRef<WebGLEngine | null>(null);
const sceneRef = useRef<Scene | null>(null);
const rootEntityRef = useRef<Entity | null>(null);
const modelEntityRef = useRef<Entity | null>(null);
const animatorRef = useRef<Animator | null>(null);
const requestRef = useRef<number | null>(null);
const [isLoading, setIsLoading] = useState(false);
// 初始化引擎
const initEngine = async () => {
if (!canvasRef.current) return;
try {
registerIncludes();
const shaderLab = new ShaderLab();
const engine = await WebGLEngine.create({
canvas: 'canvas',
physics: new LitePhysics(),
shaderLab,
graphicDeviceOptions: {
preserveDrawingBuffer: false,
},
});
engine.canvas.resizeByClientSize();
// 创建场景
const scene = engine.sceneManager.activeScene;
// 创建根实体
const rootEntity = scene.createRootEntity();
// 创建相机
const cameraEntity = rootEntity.createChild('camera');
const camera = cameraEntity.addComponent(Camera);
cameraEntity.addComponent(OrbitControl);
cameraEntity.transform.setPosition(0, 0, 2);
// 创建光源
const lightEntity = rootEntity.createChild('directLight');
const light = lightEntity.addComponent(DirectLight);
lightEntity.transform.setPosition(1, 1, 1);
lightEntity.transform.lookAt(new Vector3(0, 0, 0));
light.intensity = 1.0;
// 设置场景背景
scene.background.solidColor.set(0.5, 0.5, 0.5, 1);
engineRef.current = engine;
sceneRef.current = scene;
rootEntityRef.current = rootEntity;
await loadModel(
'https://mdn.alipayobjects.com/chain_myent/uri/file/as/mynftmerchant/202508141045460216.gltf',
);
engine.run();
// 窗口大小变化处理
const handleResize = () => {
engine.canvas.resizeByClientSize();
};
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
};
} catch (err) {
console.error('初始化引擎失败:', err);
}
};
// 加载模型
const loadModel = async (modelUrl: string) => {
if (!engineRef.current || !sceneRef.current) return;
setIsLoading(true);
const requestId = ++requestRef.current;
try {
console.log('开始加载模型:', modelUrl);
// 清除之前的模型
if (modelEntityRef.current) {
modelEntityRef.current.destroy();
modelEntityRef.current = null;
animatorRef.current = null;
}
// 加载GLTF资源
const gltfResource = await engineRef.current.resourceManager.load<GLTFResource>({
url: modelUrl,
type: AssetType.GLTF,
timeout: 20000,
});
//竟态检查
if (requestId !== requestRef.current) {
const gltfRoot = gltfResource.instantiateSceneRoot();
gltfRoot?.destroy();
return;
}
console.log('模型加载成功:', gltfResource);
// 创建模型实体
const modelEntity = rootEntityRef.current!.createChild('model');
const gltfRoot = gltfResource.instantiateSceneRoot();
// 将GLTF根节点添加到场景中
modelEntity.addChild(gltfRoot);
console.log(rootEntityRef.current, '===rootEntityRef.current');
modelEntityRef.current = modelEntity;
} catch (err) {
console.error('加载模型失败:', err);
} finally {
setIsLoading(false);
}
};
// 随机更换模型,MODEL_CONFIGS就是模型列表
const changeRandomModel = () => {
const randomIndex = Math.floor(Math.random() * MODEL_CONFIGS.length);
const newModelUrl = MODEL_CONFIGS[randomIndex].url;
console.log('切换到新模型:', newModelUrl);
loadModel(newModelUrl);
};
useEffect(() => {
initEngine();
return () => {
if (engineRef.current) {
engineRef.current.destroy();
}
};
}, []);
return (
