> For the complete documentation index, see [llms.txt](https://docs.decentraland.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.decentraland.org/creator/content-creator-zh/chang-jing-sdk7/you-hua/pre-load-resources.md).

# 预加载资源

预加载资源可让资源在场景启动时就被下载好，这样玩家首次与它们交互时就已准备就绪。

在某些情况下，资源会被添加到场景中，但不会立即使用。比如，只有当玩家按下按钮时，才会播放一个音频文件。在这种情况下，玩家第一次按下按钮时，音频可能会晚几秒才播放，因为只有在需要时才会下载该文件。

为避免此问题，请使用 `AssetLoad` 组件，以确保这些资源会在需要之前下载完成并可供使用。

```ts
import { AssetLoad } from "@dcl/sdk/ecs"

AssetLoad.create(engine.RootEntity, {
  assets: [
    "assets/scene/bundle1/explosionSound.mp3",
    "assets/scene/bundle1/explosion.glb",
  ],
})
```

在……中列出的资源 `AssetLoad` 组件中的资源会被下载并加入内存，确保场景需要加载它们时可以立即使用。

一些重要注意事项：

* 你可以将 `AssetLoad` 组件放在任何实体上（不只是 RootEntity），并且可以根据需要在任意多个实体上使用。这样有助于为场景中不同的关卡或区域处理独立的加载状态。
* 该 `AssetLoad` 组件用于将资源添加到内存，而不是移除它们。将资源从列表中移除并不会释放 `AssetLoad.create` 内存。
* 如果某个资源在场景加载时会立即使用（例如放置在场景中的 GLB 模型，或持续播放的背景音效），则无需使用 `AssetLoad` 组件，因为它已经在下载中了。
* 向……添加资源时请注意 `AssetLoad.create`，并且只预加载那些在场景启动时并不需要的资源，以避免不必要的性能开销。
* 你只能预加载作为场景文件一部分上传的资源。此功能不能用于预加载来自外部 URL 的图片

## 响应加载状态

如果场景能够对每个资源下载完成做出响应，那么预加载资源会更有用。例如，你可能希望保持加载界面，直到所有资源都准备就绪；向玩家显示进度；或者优雅地处理下载失败的资源。

要跟踪这一点，请使用 `assetLoadLoadingStateSystem`。调用其 `registerAssetLoadLoadingStateEntity` 方法，传入持有 `AssetLoad` 组件的实体以及一个回调函数。每当该实体的某个资源的加载状态发生变化时，回调都会执行。

```ts
import {
  AssetLoad,
  LoadingState,
  assetLoadLoadingStateSystem,
} from "@dcl/sdk/ecs"

const preloader = engine.addEntity()
AssetLoad.create(preloader, {
  assets: [
    "assets/scene/bundle1/explosionSound.mp3",
    "assets/scene/bundle1/explosion.glb",
  ],
})

assetLoadLoadingStateSystem.registerAssetLoadLoadingStateEntity(
  preloader,
  (assetLoadState) => {
    console.log(
      `Asset ${assetLoadState.asset} is now: ${assetLoadState.currentState}`
    )
  }
)
```

回调会接收一个包含以下属性的对象：

* `asset`：状态发生变化的资源路径。它会匹配你在 `AssetLoad` 组件。
* `currentState`：来自 `LoadingState` 枚举的值，用于描述该资源的新状态。

该 `LoadingState` 枚举可以包含以下值：

* `LoadingState.LOADING`：该资源当前正在下载。
* `LoadingState.FINISHED`：该资源已成功下载完成，并可供使用。
* `LoadingState.FINISHED_WITH_ERROR`：找到了该资源，但在下载时发生了错误。
* `LoadingState.NOT_FOUND`：在提供的路径中未找到资源。
* `LoadingState.UNKNOWN`：该资源的状态未知。

以下示例使用加载状态，根据预加载进度来改变实体的颜色：

```ts
import {
  AssetLoad,
  LoadingState,
  Material，
  assetLoadLoadingStateSystem,
} from "@dcl/sdk/ecs"
import { Color4 } from "@dcl/sdk/math"

function getLoadingColor(state: LoadingState): Color4 {
  switch (state) {
    case LoadingState.FINISHED:
      return Color4.Green()
    case LoadingState.LOADING:
      return Color4.Yellow()
    case LoadingState.FINISHED_WITH_ERROR:
    case LoadingState.NOT_FOUND:
      return Color4.Red()
    default:
      return Color4.Gray()
  }
}

assetLoadLoadingStateSystem.registerAssetLoadLoadingStateEntity(
  preloader,
  (assetLoadState) => {
    Material.setPbrMaterial(myEntity, {
      albedoColor: getLoadingColor(assetLoadState.currentState),
    })
  }
)
```

{% hint style="info" %}
**💡 提示**：你可以向现有的 `AssetLoad` 组件中添加更多资源，例如在响应玩家操作时。请使用 `AssetLoad.getOrCreateMutable()` 来获取该组件，并将新的路径追加到其 `assets` 数组中。已注册的回调也会在这些新添加的资源下载时触发。
{% endhint %}

{% hint style="info" %}
**💡 提示**：如需查看该组件的可运行示例，请参阅 [`88,-12-asset-load`](https://github.com/decentraland/sdk7-test-scenes/tree/main/scenes/88,-12-asset-load) 测试场景，其中通过一个 `AssetLoad` 组件预加载了一个 mp3、一个纹理、一个视频和一个 glb，并通过 `assetLoadLoadingStateSystem` ——其中包括一个故意缺失的路径，它会解析为 `NOT_FOUND`.
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.decentraland.org/creator/content-creator-zh/chang-jing-sdk7/you-hua/pre-load-resources.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
