> 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-ko/sdk7/architecture/composites.md).

# 컴포지트

컴포지트 파일로부터 런타임에 엔티티와 컴포넌트의 트리를 생성하세요

하나의 *컴포지트* 다음의 트리 구조를 설명하는 파일입니다 [엔티티와 컴포넌트](/creator/content-creator-ko/sdk7/architecture/entities-components.md). 각 엔티티를 하나씩 생성하는 코드를 작성하는 대신, 그 구조를 컴포지트 파일에 저장해 두고 한 번의 호출로 전체를 스폰할 수 있습니다.

이미 자신도 모르게 컴포지트를 사용하고 있을 수도 있습니다:

* 모든 씬에는 `main.composite` 파일이 있습니다. 여기에는 여러분이 시각적으로 추가하고 구성한 모든 내용이 들어 있습니다. [씬 편집기](/creator/content-creator-ko/scene-editor/get-started/about-editor.md). 이 파일은 씬이 시작될 때 자동으로 로드됩니다.
* [사용자 지정 아이템](/creator/content-creator-ko/scene-editor/interactivity/custom-items.md) 은(는) 다음과 같이 저장됩니다 `composite.json` 파일입니다. 각 Custom Item은 여러 씬에서 재사용할 수 있는 컴포지트입니다.

이 페이지에서는 런타임에 코드로 컴포지트를 스폰하는 방법을 다룹니다. 예를 들어 씬 로직의 일부로 Custom Item을 동적으로 스폰하는 경우입니다.

## 컴포지트 스폰하기

컴포지트를 스폰하는 데는 두 단계가 필요합니다: **로드** 컴포지트 파일을, 그런 다음 **스폰** 합니다. 로드는 비동기이고 스폰은 동기이므로, 패턴은 항상 로드 후 스폰입니다:

```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-ko/scene-editor/interactivity/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 %}

## 현재 제한 사항: 중첩 컴포지트

스폰은 자체 포함된 컴포지트와 Custom Item에서 작동합니다. 컴포지트는 자신의 엔티티 중 하나에서 다른 컴포지트를 참조할 수 있지만 `loadComposite()` 하지 않습니다 **아닙니다** 그 중첩 참조를 재귀적으로 처리합니다. 전달한 파일만 로드합니다.

스폰할 때 `Composite.instance()` 이미 메모리에 있는 중첩 참조를 재귀적으로 처리합니다. 중첩 컴포지트가 로드되어 있지 않으면(다음을 제외한 모든 경우 `main.composite`씬에 번들로 포함된 유일한 컴포지트를 제외하면), 해당 분기는 경고를 기록하고 건너뜁니다. 중첩 참조가 있는 컴포지트를 스폰하려면 다음을 호출하세요 `loadComposite()` 참조된 각 파일에 대해 먼저 수행하세요 — 또는 더 간단하게, 스폰하는 컴포지트를 자체 포함형으로 유지하세요.

## 관련 페이지

* [엔티티 및 컴포넌트](/creator/content-creator-ko/sdk7/architecture/entities-components.md) — 컴포지트가 설명하는 구성 요소입니다.
* [사용자 지정 아이템](/creator/content-creator-ko/scene-editor/interactivity/custom-items.md) — 컴포지트로 저장된 재사용 가능한 항목입니다.
* [Smart Items - 고급](/creator/content-creator-ko/scene-editor/interactivity/smart-items-advanced.md#about-spawning-entities) — Spawn Entity 작업을 사용해 코드 없이 컴포지트를 스폰합니다.
* [씬 파일](/creator/content-creator-ko/sdk7/kinds-of-projects/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 dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.decentraland.org/creator/content-creator-ko/sdk7/architecture/composites.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
