> 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/3d/shape-components.md).

# 형상 컴포넌트

엔티티에 3D 형태와 충돌을 부여하는 다양한 컴포넌트에 대해 알아봅니다.

Decentraland의 3차원 장면은 다음을 기반으로 합니다 [엔터티-컴포넌트](https://en.wikipedia.org/wiki/Entity%E2%80%93component%E2%80%93system) 모델이며, 장면의 모든 것은 *entity*, 그리고 각 엔터티는 *컴포넌트* 그 특성과 기능을 규정합니다.

엔터티의 렌더링된 모양은 사용하는 컴포넌트에 따라 결정됩니다.

![](https://3980763956-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-417a02dcf0fd40f5032551a0c6996becac7e7166%2Fecs-simple-components-new.png?alt=media\&token=181a73c9-363a-4328-9874-6fed49447dc3)

## Creator Hub의 Scene Editor를 사용하세요

엔터티에 모양을 부여하는 가장 쉬운 방법은 Scene Editor를 사용하는 것입니다. 다음을 추가할 수 있습니다: **Mesh Renderer** 컴포넌트를 추가해 기본 도형을 제공하거나 **GLTF** 컴포넌트를 추가해 파일의 3D 모델을 참조할 수 있습니다. 참고: [컴포넌트 추가](/creator/content-creator-ko/scene-editor/build/components.md#add-components).

## 기본 도형

여러 기본 도형은 흔히 *프리미티브라고*, 엔터티에 `MeshRenderer` 컴포넌트에 할당됩니다.

다음 모양을 사용할 수 있습니다. 일부 모양에는 해당 모양에만 해당하는 선택적 추가 필드가 포함됩니다.

* **박스**:

  사용: `MeshRenderer.setBox()`, 엔터티를 전달합니다. 다음을 전달하세요: `uvs` 를 텍스처 정렬 매핑을 위한 추가 선택 필드로 사용합니다. 참고: [머티리얼](/creator/content-creator-ko/sdk7/3d/materials.md) 자세한 내용은.
* **평면**:

  사용: `MeshRenderer.setPlane()`, 엔터티를 전달합니다. 다음을 전달하세요: `uvs` 를 텍스처 정렬 매핑을 위한 추가 선택 필드로 사용합니다. 참고: [머티리얼](/creator/content-creator-ko/sdk7/3d/materials.md) 자세한 내용은.
* **구**:

  사용: `MeshRenderer.setSphere()`, 엔터티를 전달합니다.
* **원기둥**:

  사용: `MeshRenderer.setCylinder()`, 엔터티를 전달합니다. 다음을 전달하세요: `radiusTop` 및 `radiusBottom` 를 원기둥을 수정하기 위한 추가 선택 필드로 사용합니다.

  팁: 둘 중 하나를 `radiusTop` 또는 `radiusBottom` 0으로 설정하면 원뿔이 됩니다.

다음 예제는 큐브를 만듭니다:

```ts
const myCube = engine.addEntity()

Transform.create(myCube, {
	position: Vector3.create(8, 1, 8),
})

MeshRenderer.setBox(myCube)
```

다음 예제는 다음을 가진 원기둥을 만듭니다: `radiusTop` 0인 값을 가지며, 이는 원뿔을 만듭니다:

```ts
const myCone = engine.addEntity()

Transform.create(myCone, {
	position: Vector3.create(8, 1, 8),
})

MeshRenderer.setCylinder(myCone, 1, 0)
```

기본 도형에는 머티리얼이 포함되지 않습니다. 색상이나 텍스처를 부여하려면 [머티리얼 컴포넌트](/creator/content-creator-ko/sdk7/3d/materials.md) 를 같은 엔터티에 할당해야 합니다.

기본 도형을 클릭 가능하게 만들거나 플레이어가 통과하지 못하게 하려면 엔터티에 다음을 부여해야 합니다: *콜라이더* 를 통해 [MeshCollider](/creator/content-creator-ko/sdk7/3d/colliders.md) 컴포넌트에 할당됩니다.

이미 다음이 있는 엔터티의 모양을 변경하려면 `MeshRenderer` 컴포넌트가 있는 경우, `MeshRenderer.setBox()` 또는 다른 헬퍼 함수 중 하나를 실행하면 원래 모양을 덮어씁니다. 원래 `MeshRenderer` 것을 제거하거나 고급 구문을 사용할 필요가 없습니다.

```ts
const myCube = engine.addEntity()

Transform.create(myCube, {
	position: Vector3.create(8, 1, 8),
})

MeshRenderer.setBox(myCube)

// 모양 덮어쓰기
MeshRenderer.setSphere(myCube)
```

{% hint style="warning" %}
**📔 참고**:  `MeshRenderer` 컴포넌트는 다음을 통해 가져와야 합니다

> `import { MeshRenderer } from "@dcl/sdk/ecs"`

참조 [가져오기](/creator/content-creator-ko/sdk7/getting-started/coding-scenes.md#imports) 에서 이를 쉽게 처리하는 방법을 확인하세요.
{% endhint %}

## 3D 모델

더 복잡한 모양의 경우, Blender 같은 외부 도구에서 3D 모델을 만들고 다음에서 가져올 수 있습니다 *.glTF* 또는 *.glb* (바이너리 *.glTF*). [glTF](https://www.khronos.org/gltf) (GL Transmission Format)은 Khronos의 오픈 프로젝트로, 3D 에셋을 위한 공통적이고 확장 가능한 형식을 제공하며, 이는 효율적이고 현대적인 웹 기술과 매우 높은 상호운용성을 갖습니다.

장면에 외부 모델을 추가하려면 다음을 추가하세요: `GltfContainer` 컴포넌트를 엔터티에 추가하고 그 `src` 를 모델이 들어 있는 glTF 파일의 경로로 설정합니다.

```ts
const houseEntity = engine.addEntity()

GltfContainer.create(houseEntity, {
	src: 'models/House.gltf',
})
```

애니메이션의 `src` 필드는 필수이므로 컴포넌트를 생성할 때 값을 지정해야 합니다. 위 예제에서 모델은 `models` 장면 프로젝트 폴더의 루트 수준에 있는 폴더에 있습니다.

{% hint style="info" %}
**💡 팁**: 모델은 다음 위치에 별도로 보관하는 것을 권장합니다: `assets/scene/models` 장면 내부의 폴더.
{% endhint %}

glTF 모델에는 자체 포함된 텍스처, 머티리얼, 콜라이더 및 애니메이션이 포함될 수 있습니다. 참고: [3D 모델](https://github.com/decentraland/docs/blob/main/creator/3d-modeling/3d-models.md) 자세한 내용은 이를 참고하세요. 모델의 머티리얼을 재정의하려면 다음을 사용하세요: [GltfNodeModifiers](/creator/content-creator-ko/sdk7/3d/materials.md#modify-gltf-materials) 컴포넌트. 참고: [glTF 머티리얼 수정](/creator/content-creator-ko/sdk7/3d/materials.md#modify-gltf-materials) 자세한 내용은.

플레이어가 3D 모델을 통과하지 못하게 하거나 모델을 클릭 가능하게 만들려면 다음이 있어야 합니다: [콜라이더](/creator/content-creator-ko/sdk7/3d/colliders.md), 이는 모델에 포함되어 있거나 다음을 통해 제공될 수 있습니다: `MeshCollider` 컴포넌트에 할당됩니다.

모든 모델, 셰이더 및 텍스처는 다음의 매개변수 범위 내에 있어야 한다는 점을 기억하세요: [장면 제한 사항](/creator/content-creator-ko/sdk7/optimizing/scene-limitations.md).

{% hint style="warning" %}
**📔 참고**:  `GltfContainer` 컴포넌트는 다음을 통해 가져와야 합니다

`import { GltfContainer } from "@dcl/sdk/ecs"`

참조 [가져오기](/creator/content-creator-ko/sdk7/getting-started/coding-scenes.md#imports) 에서 이를 쉽게 처리하는 방법을 확인하세요.
{% endhint %}

### 3D 모델 미리 로드하기

어떤 경우에는 사용자 지정 3D 모델이 장면에 추가되지만 즉시 사용되지는 않습니다. 예를 들어, 사용자 지정 의자 모델은 플레이어가 다른 객체와 상호작용할 때만 로드될 수 있습니다. 이 시나리오에서는 모델 다운로드와 로드가 완료될 때까지 첫 상호작용에 시간이 걸릴 수 있습니다.

이를 방지하려면 다음을 사용하세요: `AssetLoad.create` 메서드를 사용해 필요하기 전에 에셋이 다운로드되도록 보장하세요.

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

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

자세한 내용은 다음을 확인하세요: [사전 로드 리소스](/creator/content-creator-ko/sdk7/optimizing/pre-load-resources.md) 문서.

### 3D 모델용 무료 라이브러리

직접 3D 모델을 만드는 대신 여러 무료 또는 유료 라이브러리에서 다운로드할 수도 있습니다.

시작할 수 있도록, 아래는 무료 또는 비교적 저렴한 콘텐츠가 있는 라이브러리 목록입니다:

* [IWB Catalog](https://dcl-iwb.co/)
* [Asset Ovi](https://assetovi.com/)
* [Builder의 에셋](https://github.com/decentraland/builder-assets/tree/master/assets)
* [SketchFab](https://sketchfab.com/)
* [Clara.io](https://clara.io/)
* [Archive3D](https://archive3d.net/)
* [SketchUp 3D Warehouse](https://3dwarehouse.sketchup.com/)
* [Thingiverse](https://www.thingiverse.com/) (주로 3D 프린팅용으로 제작된 3D 모델이지만, 가상 세계에 맞게 조정 가능)
* [ShareCG](https://www.sharecg.com/)
* [CGTrader](https://www.cgtrader.com/)

{% hint style="warning" %}
**📔 참고**: 다운로드하는 콘텐츠의 라이선스 제한에 주의하세요.
{% endhint %}

이들 사이트 중 여러 곳에서는 모델을 다운로드할 형식을 선택할 수 있습니다. 항상 *.glTF* 사용 가능한 형식을 선택하세요. 없다면 다음으로 변환해야 합니다 *glTF* 장면에서 사용하기 전에요. 이를 위해 Blender로 가져와 다음 형식으로 내보내는 것을 권장합니다: *.glTF* 거기에서.

### 3D 모델 최적화

장면의 3D 모델이 더 빠르게 로드되고 메모리를 덜 사용하도록 하려면 다음 모범 사례를 따르세요:

* 모델을 다음 형식으로 저장하세요: *.glb* 형식은 다음의 더 가벼운 버전입니다: *.gltf*.
* 동일한 텍스처를 공유하는 여러 모델이 있다면 텍스처를 별도 파일로 내보내세요. 이렇게 하면 여러 모델이 한 번만 로드하면 되는 단일 텍스처 파일을 참조할 수 있습니다.
* 장면에 나타났다 사라지는 엔터티가 있다면, 이 엔터티들을 풀링해서 지하에 두거나 0 스케일로 유지하는 것이 좋을 수 있습니다. 이렇게 하면 더 빨리 나타나는 데 도움이 되지만, 사용하지 않을 때도 메모리를 차지하게 됩니다. 참고: [엔터티와 컴포넌트](/creator/content-creator-ko/sdk7/architecture/entities-components.md#pooling-entities-and-components)

## 모양 늘리기

기본 도형과 3D 모델에는 엔터티의 스케일을 변경하여 조정할 수 있는 기본 치수가 있습니다: `Transform` 컴포넌트에 할당됩니다.

```ts
const primitiveEntity = engine.addEntity()

MeshRenderer.setBox(primitiveEntity)

Transform.create(primitiveEntity, {
	position: { x: 8, y: 1, z: 8 },
	scale: { x: 4, y: 0.5, z: 4 },
})
```

## 보이지 않게 만들기

엔터티에 다음을 부여하면 엔터티를 보이지 않게 만들 수 있습니다: `VisibilityComponent`, 그리고 그 `visible` 속성이 다음으로 설정된 *false*.

```ts
const myEntity = engine.addEntity()
Transform.create(myEntity, {
	position: Vector3.create(4, 0, 4),
})
MeshRenderer.setBox(myEntity)

VisibilityComponent.create(myEntity, { visible: false })
```

애니메이션의 `VisibilityComponent` 기본 도형이 있는 엔터티와 다음이 있는 엔터티 모두에 동일하게 적용됩니다: `GLTFContainer` 컴포넌트.

엔터티가 보이지 않더라도, 콜라이더에 할당된 충돌 레이어에 따라 플레이어의 이동을 막거나 뒤에 있는 엔터티 클릭을 방해할 수 있습니다.

### 가시성 전파

다음을 사용할 수 있습니다: `propagateToChildren` 필드를 사용해 `VisibilityComponent` 엔터티의 자식 트리의 모든 자식에 구성 설정을 적용할 수 있습니다. 만약 `propagateToChildren` 로 설정되면 *true*, 이 설정은 아래로 내려가는 모든 수준의 자식에게 영향을 미칩니다. 이렇게 하면 각 자식 엔터티를 보이거나 보이지 않게 표시하는 번거로운 작업을 많이 줄일 수 있습니다.

```ts
// 부모 엔터티(명시적으로 보이지 않음)
const parentEntity = engine.addEntity()
Transform.create(parentEntity, {
	position: Vector3.create(4, 0, 4),
})
MeshRenderer.setBox(parentEntity)
VisibilityComponent.create(parentEntity, { visible: false, propagateToChildren: true })

// 자식 엔터티(부모 때문에 암묵적으로 보이지 않음)
const child = engine.addEntity()
Transform.create(child, {
	position: Vector3.create(0, 1, 0),
	parent: parentEntity
})
MeshRenderer.setBox(child)
```

{% hint style="warning" %}
**📔 참고**: 엔터티 자체에 다음이 있으면 `VisibilityComponent`, 이는 부모의 모든 설정을 덮어씁니다.

엔터티 자체에 다음이 없으면 `VisibilityComponent`, 그렇다면 가시성은 다음이 있는 가장 가까운 부모에 의해 결정됩니다: `VisibilityComponent` 및 `propagateToChildren` 다음으로 설정된 *true*.
{% endhint %}

## 로딩 상태

3D 모델이 상당히 크다면 렌더링되는 데 눈에 띄는 시간이 걸릴 수 있으며, 이 시간은 플레이어의 하드웨어와 여러 다른 요인에 따라 달라질 수 있습니다. 때로는 다른 작업을 수행하기 전에 모델 로드가 완료되었는지 확인해야 합니다. 예를 들어, 플레이어를 하늘 위의 플랫폼으로 순간이동시키고 싶다면, 먼저 플랫폼이 완전히 렌더링되었는지 확인한 다음 플레이어를 그곳으로 옮겨야 합니다. 그렇지 않으면 플레이어가 플랫폼을 그대로 통과해 떨어질 수 있습니다.

3D 모델 렌더링이 완료되었는지 확인하려면 엔터티의 `GltfContainerLoadingState` 컴포넌트를 확인하세요. 이 컴포넌트는 읽기 전용이며, 다음이 있는 모든 엔터티에 존재합니다: `GltfContainer`컴포넌트에 할당됩니다.

이 컴포넌트에는 다음이라는 단일 속성이 있습니다: `currentState`, 다음 값 중 하나를 가지는 `LoadingState` 열거형.

다음 예제는 시스템을 사용해 엔터티의 3D 모델 로딩 상태를 주기적으로 확인합니다. 상태가 다음이면 `LoadingState.FINISHED`, 그곳에서 사용자 지정 로직을 수행하고 시스템 실행을 종료할 수 있습니다.

```ts
export function main() {
	const meshEntity = engine.addEntity()
	GltfContainer.create(meshEntity, { src: 'models/Monster.glb' })
	engine.addSystem((deltaTime) => {
		const loadingState = GltfContainerLoadingState.getOrNull(meshEntity)
		if (!loadingState) return
		switch (loadingState.currentState) {
			case LoadingState.LOADING:
				console.log('메시가 로드 중입니다')
				break
			case LoadingState.FINISHED:
				console.log('메시가 완료되었습니다')
				// 사용자 지정 로직 수행
				break
			case LoadingState.FINISHED_WITH_ERROR:
				console.log('메시가 완료되었지만 문제가 있을 수 있습니다')
				break
			case LoadingState.UNKNOWN:
				console.log('메시 상태를 알 수 없습니다')
				break
		}
	})
}
```

## 고급 구문

다음을 생성하기 위한 전체 구문은 `MeshRenderer` 컴포넌트를 단순화하는 헬퍼 없이 보면 다음과 같습니다:

```ts
MeshRenderer.create(myBox, {
	mesh: {
		$case: 'box',
		box: { uvs: [] },
	},
})

MeshRenderer.create(myPlane, {
	mesh: {
		$case: 'plane',
		plane: { uvs: [] },
	},
})

MeshRenderer.create(myShpere, {
	mesh: {
		$case: 'sphere',
		sphere: {},
	},
})

MeshRenderer.create(myCylinder, {
	mesh: {
		$case: 'cylinder',
		cylinder: {},
	},
})
```

기본 프로토콜은 MeshRenderer 컴포넌트를 이렇게 해석합니다. 헬퍼 함수는 이를 추상화하여 더 친숙한 구문을 제공하지만, 내부적으로는 이 구문을 출력합니다.

애니메이션의 `$case` 필드를 사용하면 허용된 유형 중 하나를 지정할 수 있습니다. 각 유형은 서로 다른 매개변수 집합을 지원합니다. 위 예제에서 `박스` 유형은 다음을 지원합니다: `uvs` 필드.

다음의 지원되는 값은 `$case` 다음과 같습니다:

* `박스`
* `평면`
* `구`
* `원기둥`

값에 따라 `$case`, 해당 모양에 대한 객체를 관련 속성과 함께 정의하는 것이 허용됩니다.

다음을 추가하려면 `MeshRenderer` 이 컴포넌트의 인스턴스가 이미 있을 수 있는 엔터티에 컴포넌트를 추가하려면 다음을 사용하세요: `MeshRenderer.createOrReplace()`. 헬퍼 함수들은 `MeshRenderer.setBox()` 컴포넌트의 기존 인스턴스를 덮어쓰도록 처리하지만, 실행 `MeshRenderer.create()` 이미 이 컴포넌트가 있는 엔터티에서 실행하면 오류가 반환됩니다.


---

# 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-ko/sdk7/3d/shape-components.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.
