> 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-pt/scenes-sdk7/fundamentos-de-conteudo-3d/shape-components.md).

# Components de Forma

Saiba mais sobre os diferentes components que dão às entities sua forma 3D e colisão.

Cenas tridimensionais no Decentraland são baseadas no [Entity-Component](https://en.wikipedia.org/wiki/Entity%E2%80%93component%E2%80%93system) modelo, em que tudo em uma cena é uma *entity*, e cada entity pode incluir *componentes* que moldam suas características e funcionalidade.

A forma renderizada de uma entity é determinada pelo componente que ela usa.

![](https://2402076176-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)

## Use o Scene Editor no Creator Hub

A maneira mais fácil de dar uma forma a uma entity é usar o Scene Editor. Você pode adicionar um **Mesh Renderer** componente para fornecer uma forma primitiva, ou um **GLTF** componente para referenciar um modelo 3D de um arquivo. Veja [Add Components](/creator/content-creator-pt/scene-editor/construir/components.md#add-components).

## Formas primitivas

Várias formas básicas, muitas vezes chamadas de *primitivas*, podem ser adicionadas a uma entity ao dar à entity um `MeshRenderer` component.

As seguintes formas estão disponíveis. Várias formas incluem campos adicionais opcionais, específicos dessa forma.

* **box**:

  Use `MeshRenderer.setBox()`, passando a entidade. Passe `uvs` como um campo opcional adicional, para mapear o alinhamento da textura. Veja [materiais](/creator/content-creator-pt/scenes-sdk7/fundamentos-de-conteudo-3d/materials.md) para mais detalhes.
* **plane**:

  Use `MeshRenderer.setPlane()`, passando a entidade. Passe `uvs` como um campo opcional adicional, para mapear o alinhamento da textura. Veja [materiais](/creator/content-creator-pt/scenes-sdk7/fundamentos-de-conteudo-3d/materials.md) para mais detalhes.
* **sphere**:

  Use `MeshRenderer.setSphere()`, passando a entidade.
* **cylinder**:

  Use `MeshRenderer.setCylinder()`, passando a entidade. Passe `radiusTop` e `radiusBottom` como campos opcionais adicionais, para modificar o cilindro.

  DICA: Defina um dos `radiusTop` ou `radiusBottom` para 0 para criar um cone.

O exemplo a seguir cria um cubo:

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

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

MeshRenderer.setBox(myCube)
```

O exemplo a seguir cria um cilindro com um `radiusTop` de 0, o que produz um cone:

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

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

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

As formas primitivas não incluem materiais. Para dar a elas uma cor ou textura, você deve atribuir um [componente Material](/creator/content-creator-pt/scenes-sdk7/fundamentos-de-conteudo-3d/materials.md) à mesma entity.

Para tornar uma primitiva clicável, ou para impedir que os jogadores atravessem-na, você deve dar à entity um *Collider* via um [MeshCollider](/creator/content-creator-pt/scenes-sdk7/fundamentos-de-conteudo-3d/colliders.md) component.

Para alterar a forma de uma entity que já possui um `MeshRenderer` componente, execute `MeshRenderer.setBox()` ou qualquer uma das outras funções auxiliares e ela substituirá a forma original. Não há necessidade de remover o original `MeshRenderer` nem de usar a sintaxe avançada.

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

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

MeshRenderer.setBox(myCube)

// sobrescrever forma
MeshRenderer.setSphere(myCube)
```

{% hint style="warning" %}
**📔 Nota**: O `MeshRenderer` component deve ser importado via

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

Veja [Importações](/creator/content-creator-pt/scenes-sdk7/primeiros-passos/coding-scenes.md#imports) para saber como lidar facilmente com estes.
{% endhint %}

## modelos 3D

Para formas mais complexas, você pode construir um modelo 3D em uma ferramenta externa como Blender e então importá-lo para *.glTF* ou *.glb* (binário *.glTF*). [glTF](https://www.khronos.org/gltf) (GL Transmission Format) é um projeto aberto da Khronos que fornece um formato comum e extensível para assets 3D que é ao mesmo tempo eficiente e altamente interoperável com tecnologias web modernas.

Para adicionar um modelo externo a uma cena, adicione um `GltfContainer` componente a uma entity e defina seu `src` como o caminho do arquivo glTF que contém o modelo.

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

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

O `src` campo é obrigatório, você deve atribuir um valor a ele ao construir o componente. No exemplo acima, o modelo está localizado em uma `models` pasta na raiz da pasta do projeto da scene.

{% hint style="info" %}
**💡 Dica**: Recomendamos manter seus modelos separados na `assets/scene/models` pasta dentro da sua cena.
{% endhint %}

Modelos glTF podem incluir suas próprias texturas, materiais, colliders e animações incorporados. Veja [modelos 3D](https://github.com/decentraland/docs/blob/main/creator/3d-modeling/3d-models.md) para mais informações sobre isso. Para substituir os materiais de um modelo, use o [GltfNodeModifiers](/creator/content-creator-pt/scenes-sdk7/fundamentos-de-conteudo-3d/materials.md#modify-gltf-materials) componente. Veja [Modificar materiais glTF](/creator/content-creator-pt/scenes-sdk7/fundamentos-de-conteudo-3d/materials.md#modify-gltf-materials) para mais detalhes.

Para impedir que os jogadores atravessem um modelo 3D, ou para tornar um modelo clicável, você deve ter um [Collider](/creator/content-creator-pt/scenes-sdk7/fundamentos-de-conteudo-3d/colliders.md), que pode estar incorporado no modelo ou ser fornecido via um `MeshCollider` component.

Lembre-se de que todos os modelos, seus shaders e suas texturas devem estar dentro dos parâmetros das [limitações da scene](/creator/content-creator-pt/scenes-sdk7/otimizacao/scene-limitations.md).

{% hint style="warning" %}
**📔 Nota**: O `GltfContainer` component deve ser importado via

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

Veja [Importações](/creator/content-creator-pt/scenes-sdk7/primeiros-passos/coding-scenes.md#imports) para saber como lidar facilmente com estes.
{% endhint %}

### Pré-carregando um modelo 3D

Em alguns casos, um modelo 3D personalizado é adicionado à cena, mas não é usado imediatamente. Por exemplo, um modelo de cadeira personalizado pode só ser carregado quando o player interage com outro objeto. Nesse cenário, a primeira interação pode levar algum tempo até terminar de baixar e carregar o modelo.

Para evitar isso, use o `AssetLoad.create` método para garantir que o asset seja baixado antes de ser necessário.

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

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

Para mais informações, consulte a [Recursos de pré-carregamento](/creator/content-creator-pt/scenes-sdk7/otimizacao/pre-load-resources.md) documentação.

### Bibliotecas gratuitas de modelos 3D

Em vez de criar seus próprios modelos 3D, você também pode baixá-los de várias bibliotecas gratuitas ou pagas.

Para começar, abaixo está uma lista de bibliotecas que têm conteúdo gratuito ou relativamente barato:

* [IWB Catalog](https://dcl-iwb.co/)
* [Asset Ovi](https://assetovi.com/)
* [Assets do 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/) (modelos 3D feitos principalmente para impressão 3D, mas adaptáveis a Virtual Worlds)
* [ShareCG](https://www.sharecg.com/)
* [CGTrader](https://www.cgtrader.com/)

{% hint style="warning" %}
**📔 Nota**: Preste atenção às restrições de licença que o conteúdo que você baixa possui.
{% endhint %}

Observe que em vários desses sites, você pode escolher em qual formato baixar o modelo. Sempre escolha *.glTF* formato, se disponível. Se não estiver disponível, você deve convertê-los para *glTF* antes de poder usá-los em uma cena. Para isso, recomendamos importá-los para o Blender e exportá-los como *.glTF* a partir daí.

### Otimize modelos 3D

Para garantir que os modelos 3D na sua cena carreguem mais rápido e ocupem menos memória, siga estas boas práticas:

* Salve seus modelos em *.glb* formato, que é uma versão mais leve de *.gltf*.
* Se você tiver vários modelos que compartilham as mesmas texturas, exporte seus modelos com as texturas em um arquivo separado. Dessa forma, vários modelos podem se referir a um único arquivo de textura que só precisa ser carregado uma vez.
* Se a sua cena tem entidades que aparecem e desaparecem, pode ser uma boa ideia agrupar essas entidades e mantê-las subterrâneas, ou com escala 0. Isso ajudará a fazê-las aparecer mais rápido; a desvantagem é que elas ocuparão memória quando não estiverem em uso. Veja [entities and components](/creator/content-creator-pt/scenes-sdk7/arquitetura/entities-components.md#pooling-entities-and-components)

## Esticando uma forma

Formas primitivas e modelos 3D têm dimensões padrão que você pode alterar mudando a escala no `Transform` component.

```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 },
})
```

## Tornar invisível

Você pode tornar uma entity invisível ao dar a ela um `VisibilityComponent`, com sua `visible` propriedade definida como *false*.

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

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

O `VisibilityComponent` funciona da mesma forma para entities com formas primitivas e com `GLTFContainer` components.

Se uma entity for invisível, seu Collider pode bloquear o caminho de um player e/ou impedir clicar em entities que estejam atrás dela, dependendo das camadas de colisão atribuídas ao Collider.

### Propagar visibilidade

Você pode usar o `propagateToChildren` campo no `VisibilityComponent` para aplicar uma configuração a cada filho na árvore de filhos da entity. Se `propagateToChildren` é definido como *true*, essas configurações afetam todos os filhos em todos os níveis abaixo. Isso pode economizar muito trabalho tedioso ao marcar cada entity filha como invisível ou visível também.

```ts
// Entidade pai (explicitamente invisível)
const parentEntity = engine.addEntity()
Transform.create(parentEntity, {
	position: Vector3.create(4, 0, 4),
})
MeshRenderer.setBox(parentEntity)
VisibilityComponent.create(parentEntity, { visible: false, propagateToChildren: true })

// Entidade filha (implicitamente invisível por causa do pai)
const child = engine.addEntity()
Transform.create(child, {
	position: Vector3.create(0, 1, 0),
	parent: parentEntity
})
MeshRenderer.setBox(child)
```

{% hint style="warning" %}
**📔 Nota**: Se uma entity tiver sua própria `VisibilityComponent`, isso substitui qualquer configuração dos pais.

Se uma entity não tiver sua própria `VisibilityComponent`, então sua visibilidade é determinada pelo seu pai mais próximo com uma `VisibilityComponent` e `propagateToChildren` definido como *true*.
{% endhint %}

## Estado de carregamento

Se um modelo 3D for bastante grande, pode levar algum tempo perceptível para ser renderizado; esse tempo pode variar dependendo do hardware do player e de muitos outros fatores. Às vezes, você precisa garantir que um modelo tenha terminado de carregar antes de executar outra ação. Por exemplo, se você quiser teleportar o player para uma plataforma no céu, primeiro você precisa garantir que a plataforma esteja totalmente renderizada antes de mover o player para lá, ou então o player pode cair direto pela plataforma.

Para verificar se um modelo 3D terminou de ser renderizado, verifique o `GltfContainerLoadingState` componente. Este componente é somente leitura e existe em qualquer entity que também tenha um `GltfContainer`component.

Este componente tem uma única propriedade chamada `currentState`, contendo um valor do `LoadingState` enum.

O exemplo a seguir usa um system para verificar periodicamente o estado de carregamento do modelo 3D de uma entity. Se o estado for `LoadingState.FINISHED`, talvez você queira executar uma lógica personalizada ali e encerrar a execução do system.

```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('mesh está CARREGANDO')
				break
			case LoadingState.FINISHED:
				console.log('mesh está CONCLUÍDA')
				// Executar lógica personalizada
				break
			case LoadingState.FINISHED_WITH_ERROR:
				console.log('mesh está CONCLUÍDA MAS PODE TER PROBLEMAS')
				break
			case LoadingState.UNKNOWN:
				console.log('mesh está em um ESTADO DESCONHECIDO')
				break
		}
	})
}
```

## Sintaxe avançada

A sintaxe completa para criar um `MeshRenderer` component, sem quaisquer helpers para a simplificar, é assim:

```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: {},
	},
})
```

É assim que o protocolo base interpreta os componentes MeshRenderer. As funções auxiliares abstraem isso e expõem uma sintaxe mais amigável, mas nos bastidores elas geram essa sintaxe.

O `$case` campo permite especificar um dos tipos permitidos. Cada tipo oferece suporte a um conjunto diferente de parâmetros. No exemplo acima, o `box` tipo oferece suporte a um `uvs` campo.

Os valores suportados para `$case` são os seguintes:

* `box`
* `plane`
* `sphere`
* `cylinder`

Dependendo do valor de `$case`, é válido definir o objeto para a forma correspondente, passando quaisquer propriedades relevantes.

Para adicionar um `MeshRenderer` componente a uma entity que possivelmente já tenha uma instância deste componente, use `MeshRenderer.createOrReplace()`. As funções auxiliares como `MeshRenderer.setBox()` lidam com a substituição de instâncias existentes do componente, mas executar `MeshRenderer.create()` em uma entity que já possui este componente retorna um erro.


---

# 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-pt/scenes-sdk7/fundamentos-de-conteudo-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.
