mirror of
https://github.com/galacean/engine.git
synced 2026-07-02 14:24:49 +08:00
132 lines
4.7 KiB
Plaintext
132 lines
4.7 KiB
Plaintext
---
|
||
order: 4
|
||
title: 模型的加载与使用
|
||
type: 图形
|
||
group: 模型
|
||
label: Graphics/Model
|
||
---
|
||
|
||
加载与使用模型资产,一般会遇到以下两种情况:
|
||
|
||
- 已经随场景文件预加载的模型,在脚本中的使用
|
||
- 未预加载的模型,在脚本中的加载与使用
|
||
|
||
在编辑器中,**放置在场景中的模型**都会随着场景文件被预先加载,依照步骤 **资产界面** -> **左键拖动模型缩略图** -> **拖动至[视图界面](/docs/interface/viewport)** -> **松开左键** -> **调整坐标** 即可将模型放置在对应场景中。
|
||
|
||
> 编辑器不能直接调整模型节点的 scale 属性, 所以通常情况下, 你需要把模型节点拖拽到一个 entity 节点下, 然后调整 entity 节点的 scale 属性。
|
||
|
||
<Image src="https://gw.alipayobjects.com/zos/OasisHub/8e088349-f36d-4d16-a525-bbb63fe00105/import.gif" alt="import" />
|
||
|
||
这种情况下,在运行时只需寻找场景中特定的节点即可获取对应的模型对象。
|
||
|
||
```typescript
|
||
// 根据节点名寻找模型节点
|
||
const model1 = scene.findEntityByName("ModelName");
|
||
// 根据节点路径寻找模型节点
|
||
const model2 = scene.findEntityByPath("ModelPath");
|
||
```
|
||
|
||
## 加载模型
|
||
|
||
只要有模型的 URL 信息,我们就可以很方便地加载这个模型。
|
||
|
||
```typescript
|
||
engine.resourceManager
|
||
.load({ url: "glTF's URL", type: AssetType.GLTF })
|
||
.then((glTF: GLTFResource) => {
|
||
// 获取 glTF 模型实例化的模型对象
|
||
const root = glTF.instantiateSceneRoot();
|
||
// 将模型对象添加到场景中
|
||
scene.addRootEntity(root);
|
||
});
|
||
```
|
||
|
||
在编辑器中,可以直接获取模型资产的 URL ( **[资产面板](/docs/assets/interface)** -> **右键模型资产缩略图** -> **Copy file info / Copy relative path**):
|
||
|
||
<Image src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*T6-QR7KrH8oAAAAAAAAAAAAADhuCAQ/original" alt="import" style={{zoom: "50%"}} />
|
||
|
||
没有导入编辑器的模型,对应的 URL 就是存放模型资产的路径。
|
||
|
||
## 加载进度
|
||
|
||
加载模型时也可以通过 [onProgress](/apis/core/#AssetPromise-onProgress) 事件来获取总任务/详细任务的加载进度。
|
||
|
||
```typescript
|
||
this.engine.resourceManager
|
||
.load(["b.gltf"])
|
||
.onProgress(
|
||
(loaded, total) => {
|
||
console.log("task loaded:", loaded, "task total:", total);
|
||
},
|
||
(url, loaded, total) => {
|
||
console.log("task detail:", url, "loaded:", loaded, "total:", total);
|
||
}
|
||
```
|
||
|
||
<Image src="https://gw.alipayobjects.com/zos/OasisHub/b1623aee-4f1b-405a-b5b5-c63b64dbb9de/image-20240313112859472.png" alt="image-20240313112859472" style={{zoom: "50%"}} />
|
||
|
||
## 使用模型
|
||
|
||
加载完毕的模型对象会返回包含了渲染信息和动画信息的根节点,它的使用和普通节点没有什么区别。
|
||
|
||
### 1. 选择场景根节点
|
||
|
||
glTF 可能包含多个场景根节点 `sceneRoots`,开发者可以手动选择希望实例化的根节点。
|
||
|
||
```typescript
|
||
engine.resourceManager
|
||
.load({ url: "glTF's URL", type: AssetType.GLTF })
|
||
.then((glTF: GLTFResource) => {
|
||
// 选择根节点数组中下标为 1 的模型对象,默认下标为 0
|
||
const root = glTF.instantiateSceneRoot(1);
|
||
// 将模型对象添加到场景中
|
||
scene.addRootEntity(root);
|
||
});
|
||
```
|
||
|
||
### 2. 播放动画
|
||
|
||
若模型携带了动画信息,可以从根节点上获取 [Animator](/apis/core/#Animator) 组件,然后选择播放任意动画片段。
|
||
|
||
```typescript
|
||
engine.resourceManager
|
||
.load({ url: "glTF's URL", type: AssetType.GLTF })
|
||
.then((glTF: GLTFResource) => {
|
||
// 获取 glTF 模型实例化的模型对象
|
||
const root = glTF.instantiateSceneRoot();
|
||
// 将模型对象添加到场景中
|
||
scene.addRootEntity(root);
|
||
// 获取 glTF 资产的动画信息
|
||
const { animations } = glTF;
|
||
// 获取模型对象挂载的动画组件
|
||
const animation = root.getComponent(Animator);
|
||
// 播放第一个动画
|
||
animation.playAnimationClip(animations[0].name);
|
||
});
|
||
```
|
||
|
||
### 3. 多材质切换
|
||
|
||
glTF [多材质插件](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_variants) 可以用来切换材质。
|
||
|
||
```typescript
|
||
engine.resourceManager
|
||
.load({ url: "glTF's URL", type: AssetType.GLTF })
|
||
.then((glTF: GLTFResource) => {
|
||
// 获取 glTF 模型实例化的模型对象
|
||
const root = glTF.instantiateSceneRoot();
|
||
// 将模型对象添加到场景中
|
||
scene.addRootEntity(root);
|
||
// 获取插件信息
|
||
const { extensionsData } = glTF;
|
||
// 根据插件信息切换材质
|
||
const variants: IGLTFExtensionVariants = extensionsData?.variants;
|
||
if (variants) {
|
||
const extensionData = extensionsData;
|
||
const replaceVariant = variants[0];
|
||
const { renderer, material } = replaceVariant;
|
||
renderer.setMaterial(material);
|
||
}
|
||
});
|
||
```
|