> 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/jia-gou/composites.md).

# 组合文件

在运行时从组合文件生成一棵实体和组件树

一个 *组合体* 是一个描述……树结构的文件 [实体和组件](/creator/content-creator-zh/chang-jing-sdk7/jia-gou/entities-components.md)。与其逐个编写代码来创建每个实体，不如将该结构存储在组合体文件中，并通过一次调用生成整个结构。

你可能已经在不知不觉中使用过组合体：

* 每个场景都有一个 `main.composite` 文件。它保存了你在 [场景编辑器](/creator/content-creator-zh/chang-jing-bian-ji-qi/ru-men/about-editor.md)中以可视化方式添加和配置的所有内容。这个文件会在场景启动时自动加载。
* [自定义项目](/creator/content-creator-zh/chang-jing-bian-ji-qi/jiao-hu-xing/custom-items.md) 会保存为 `composite.json` 文件。每个自定义物品都是一个可在各场景间复用的组合体。

本页介绍如何在运行时通过代码生成一个组合体，例如在场景逻辑中动态生成一个自定义物品。

## 生成一个组合体

生成一个组合体需要两步： **加载** 该组合体文件，然后 **生成** 它。加载是异步的，生成是同步的，因此模式始终是先加载后生成：

```ts
import { engine, Composite, getCompositeProvider } from "@dcl/sdk/ecs";

export async function spawnBarrel() {
  const src = "barrel.composite";
  const provider = getCompositeProvider();
  if (!provider || !provider.loadComposite) return;

  // 1. 从文件中加载组合体
  const resource = await provider.loadComposite(src);

  // 2. 生成它：创建其所有实体和组件
  const barrel = Composite.instance(engine, resource, provider);
  return barrel;
}
```

`provider.loadComposite(src)` 读取组合体文件并将其加载到内存中。在一个使用 `@dcl/sdk`构建的普通场景中，系统已为你配置好组合体提供器，你可以通过 `getCompositeProvider()` 函数从 `@dcl/sdk/ecs`.

`Composite.instance()` 随后创建组合体中描述的所有实体及其所有组件，并返回 **根实体** 所生成树的根实体。之后可使用该返回的实体读取或修改组件，例如重新定位或移除生成的物品。

{% hint style="info" %}
**💡 提示**：若要在不写代码的情况下完成同样的事情，请使用 **生成实体** 场景编辑器中的操作。参见 [关于生成实体](/creator/content-creator-zh/chang-jing-bian-ji-qi/jiao-hu-xing/smart-items-advanced.md#about-spawning-entities).
{% endhint %}

{% hint style="warning" %}
**📔 注意**：你必须先加载组合体，才能生成它。 `Composite.instance()` 是同步的，只能生成已在内存中的组合体。只有 `main.composite` 随场景捆绑并可从一开始就使用；任何其他组合体文件都必须先通过 `loadComposite()` 先加载。若要同步检查某个组合体是否已可用，请使用 `provider.getCompositeOrNull(src)`.

`loadComposite()` 具有幂等性：它会按每个组合体的 `src` 字符串进行索引，因此再次使用相同路径调用它不会重新加载文件，而是返回已加载的组合体。你可以在每次生成前安全地调用它，而无需担心重复加载同一个文件。
{% endhint %}

### 生成到现有实体上

默认情况下 `Composite.instance()` 会创建一个新实体来承载生成的树。传入一个 `rootEntity` 选项中的参数，即可生成到你已有的实体上：

```ts
// 直接在场景根节点生成组合体，不使用包装实体
const barrel = Composite.instance(engine, resource, provider, {
  rootEntity: engine.RootEntity,
})
```

## 定位已生成的组合体

要将已生成的组合体放置在特定的位置、旋转或缩放，请在 `Transform` 由……返回的根实体上设置一个 `Composite.instance()`.

```ts
import { engine, Composite, getCompositeProvider, Transform } from "@dcl/sdk/ecs";
import { Vector3 } from "@dcl/sdk/math";

export async function spawnBarrel() {
  const src = "barrel.composite";
  const provider = getCompositeProvider();
  if (!provider || !provider.loadComposite) return;

  const resource = await provider.loadComposite(src);

  // 将组合体生成在特定位置
  const barrel = Composite.instance(engine, resource, provider);
  Transform.createOrReplace(barrel, {
    position: Vector3.create(8, 0, 8),
  });
}
```

{% hint style="warning" %}
**📔 注意**: `Transform.createOrReplace()` 会替换根实体现有的 Transform 组件。只有根实体会受影响，子实体会保持相对于根实体的位置。
{% endhint %}

## 当前限制：嵌套组合体

生成适用于自包含的组合体和自定义物品。一个组合体可以从其某个实体引用另一个组合体，但 `loadComposite()` 不会 **不是** 递归处理这些嵌套引用：它只会加载你传入的文件。

在生成时， `Composite.instance()` 会递归处理已在内存中的嵌套引用。如果某个嵌套组合体尚未加载（除 `main.composite`外，你的场景中唯一捆绑的组合体），则该分支会记录警告并跳过。要生成带有嵌套引用的组合体，请先对 `loadComposite()` 每个被引用的文件调用该操作——或者更简单些，保持你要生成的组合体为自包含。

## 相关页面

* [实体与组件](/creator/content-creator-zh/chang-jing-sdk7/jia-gou/entities-components.md) ——组合体所描述的构建块。
* [自定义项目](/creator/content-creator-zh/chang-jing-bian-ji-qi/jiao-hu-xing/custom-items.md) ——以组合体形式存储的可复用物品。
* [智能物品 - 高级](/creator/content-creator-zh/chang-jing-bian-ji-qi/jiao-hu-xing/smart-items-advanced.md#about-spawning-entities) ——使用“生成实体”操作，无需代码即可生成组合体。
* [场景文件](/creator/content-creator-zh/chang-jing-sdk7/xiang-mu-lei-xing/scene-files.md) ——其中 `main.composite` 位于你的场景项目中。


---

# 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/jia-gou/composites.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.
