# Colliders

As entidades que têm colliders ocupam espaço e bloqueiam o caminho de um jogador; as entidades sem colliders podem ser atravessadas pelo avatar de um jogador.

Os colliders também são necessários para tornar uma entidade clicável. Os eventos de botão baseiam-se na forma do collider de uma entidade, e não na sua forma visível.

Existem camadas de colisão separadas para interagir com a física do jogador ou com pointer events; os colliders podem ser configurados para interagir apenas com uma ou com a outra. Também podem ser configurados para interagir com camadas personalizadas, que podem ser usadas com [raycasts](/creator/content-creator-pt/scenes-sdk7/essenciais-de-conteudo-3d/colliders.md) para tratar do que fizer mais sentido para a scene.

{% hint style="warning" %}
**📔 Nota**: Os colliders não afetam a forma como outras entidades interagem entre si; as entidades podem sempre sobrepor-se. As definições de colisão só afetam a forma como a entidade interage com o avatar do jogador e com os eventos de botão. A Decentraland não tem um motor de física nativo, por isso, se quiser que as entidades caiam, colidam ou ressaltem, tem de programar esse comportamento na scene ou importar uma biblioteca para o tratar.
{% endhint %}

## Use o Scene Editor

A forma mais fácil de gerir os colliders de uma entidade é usar o [Scene Editor](/creator/content-creator-pt/scene-editor/comecar/about-editor.md).

Pode adicionar um **Mesh Collider** component à sua entidade para atribuir uma forma primitiva (cubo, plano, esfera, cilindro ou cone) à sua entidade. Depois pode escolher [camadas de colisão](#collision-layers) num dropdown.

Também pode configurar as camadas de colisão num **GLTF** component para alterar a [camadas de colisão](#collision-layers) predefinida usada na geometria do collider ou na geometria visível do model. Veja [Add Components](/creator/content-creator-pt/scene-editor/construir/components.md#add-components).

![](/files/ab25955c85c888292d8d42aabc90e2afd354c6a1)

## Colliders em formas primitivas

O `MeshCollider` component dá a uma entidade um collider simples baseado numa forma primitiva (caixas, esferas, planos, cilindros ou cones).

As entidades que têm um `MeshRenderer` component para lhes dar uma [forma primitiva](/creator/content-creator-pt/scenes-sdk7/essenciais-de-conteudo-3d/shape-components.md#primitive-shapes) não têm colliders por predefinição. Também tem de dar à entidade um `MeshCollider` component.

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

* **caixa**:

  Use `MeshCollider.setBox()`, passando a entidade.
* **plano**:

  Use `MeshCollider.setPlane()`, passando a entidade.
* **esfera**:

  Use `MeshCollider.setSphere()`, passando a entidade.
* **cilindro**:

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

{% hint style="info" %}
**💡 Dica**: Defina `radiusTop` ou `radiusBottom` como 0 para criar um cone.
{% endhint %}

Este exemplo define uma entidade em forma de caixa que não pode ser atravessada.

```ts
// criar entidade
const myCollider = engine.addEntity()

// forma visível
MeshRenderer.setBox(myCollider)

// collider
MeshCollider.setBox(myCollider)
```

A forma usada por `MeshCollider` não precisa necessariamente de corresponder à usada por `MeshRenderer`. Também pode adicionar um `MeshCollider` a uma entidade que tem um model 3D de um `GLTFContainer` component, ou a uma entidade que não tem qualquer forma visível.

{% hint style="warning" %}
**📔 Nota**: O `MeshCollider` component e `ColliderLayer` devem ser importados via

`import { MeshCollider, ColliderLayer } from "@dcl/sdk/ecs"`

Veja [Imports](/creator/content-creator-pt/scenes-sdk7/comecar/coding-scenes.md#imports) para saber como lidar facilmente com estes casos.
{% endhint %}

## Colliders em models 3D

Os models 3D podem receber colliders em dois níveis diferentes de geometria:

* `visibleMeshesCollisionMask`: Refere-se à geometria visível do model. Por predefinição, esta geometria não tem colliders.
* `invisibleMeshesCollisionMask`: refere-se aos meshes de collider, cujo nome termina em `_collider`. Por predefinição, esta geometria é tratada como um collider tanto para a física como para os pointer events.

Qualquer mesh incorporado como parte de um model 3D cujo nome termine em `_collider` é tratado como parte da `invisibleMeshesCollisionMask` camada e interpretado como um collider por predefinição.

Definir a geometria do collider como uma camada invisível separada permite muito mais controlo e é bastante menos exigente para o sistema do que usar a geometria visível, uma vez que o objeto de colisão costuma ser muito mais simples (com menos vertices) do que o model original.

Se um model não tiver qualquer geometria de collider e quiser fazê-lo afetar a física ou os sistemas de pointer events, pode:

* Atribuir camadas de colisão diretamente à geometria visível, através do `visibleMeshesCollisionMask`.

{% hint style="warning" %}
**📔 Nota**: Se a geometria visível do objeto tiver muitos vertices, note que isto pode ter um custo de desempenho maior.
{% endhint %}

* Dar à entidade um `MeshCollider` component, para lhe dar um collider com forma primitiva.
* Sobrepor uma entidade invisível que tenha um `MeshCollider` component.
* Editar o model numa ferramenta externa como o Blender para incluir um *mesh de collider*. O collider tem de ser nomeado *x\_collider*, em que *x* é o nome do model. Portanto, para um model chamado *house*, o collider tem de ser nomeado *house\_collider*.

Também pode querer atribuir a camada de colisão dos pointer events ao `visibleMeshesCollisionMask` caso queira que as dicas de hover e os pointer events respondam com mais precisão ao contorno da entidade. Note que isto é mais exigente em termos de desempenho.

{% hint style="warning" %}
**📔 Nota**: Certifique-se de que não tem a mesma camada (física, pointer events ou camadas personalizadas) atribuída a ambos `visibleMeshesCollisionMask` e `invisibleMeshesCollisionMask`, pois isso seria uma utilização muito ineficiente dos recursos. Pode ter camadas diferentes em cada um, como física na camada invisível e pointer events na camada visível.
{% endhint %}

```ts
// criar entidade
const myEntity = engine.addEntity()

// atribuir forma GLTF
GltfContainer.create(myEntity, {
	src: '/models/myModel.gltf',
	invisibleMeshesCollisionMask: ColliderLayer.CL_PHYSICS,
	visibleMeshesCollisionMask: ColliderLayer.CL_POINTER,
})
```

Veja [modelos 3D](https://github.com/decentraland/docs-creator/blob/main/creator/3d-modeling/3d-models/README.md) para mais detalhes sobre como adicionar geometria invisível de collider a um model 3D.

{% hint style="warning" %}
**📔 Nota**: O `GltfContainer` component e `ColliderLayer` devem ser importados via

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

Veja [Imports](/creator/content-creator-pt/scenes-sdk7/comecar/coding-scenes.md#imports) para saber como lidar facilmente com estes casos.
{% endhint %}

### modelos animados

Ao definir colliders para usarem a geometria visível num model que inclui [animações baseadas em armature](/creator/content-creator-pt/modelacao-e-animacoes-3d/animations.md), as animações não são seguidas pelos colliders. Os meshes de collider mantêm a sua forma original. Se uma animação envolver a deformação da geometria de um mesh, os meshes de collider mantêm a forma não animada enquanto a animação decorre.

Ao reproduzir animações que envolvem mover meshes inteiros sem alterar a sua forma, essas alterações são refletidas com precisão pelos colliders. Por exemplo, se uma plataforma se mover como parte de uma animação, o collider da plataforma também se move com a animação.

## camadas de colisão

A scene pode lidar com camadas de colisão separadas, que têm comportamentos diferentes.

Pode configurar um `MeshCollider` component ou o `GltfContainer` component para responder apenas a um tipo de interação, a vários tipos ou a nenhum. Para fazer isso, no `MeshCollider` defina a propriedade `collisionMask` e em `GltfContainer` defina a propriedade `visibleMeshesCollisionMask` ou `invisibleMeshesCollisionMask` propriedades para um ou vários dos seguintes valores:

* `ColliderLayer.CL_PHYSICS`: Bloqueia apenas o movimento do jogador (e não afeta os pointer events)
* `ColliderLayer.CL_POINTER`: Responde apenas a pointer events (e não bloqueia o movimento do jogador)
* `ColliderLayer.CL_CUSTOM1` até `CL_CUSTOM8`: Pode ser usado juntamente com raycasts, para que um raio detete apenas colisões com uma camada específica.
* `ColliderLayer.CL_NONE`: Não responde a colisões de qualquer tipo.

{% hint style="warning" %}
**📔 Nota**: Para desativar colisões de um `MeshCollider` component, elimine o component. Não defina a camada de colisão como `ColliderLayer.CL_NONE`. Há um problema conhecido com o `MeshCollider` component. Em vez de desativar todas as colisões, torna este valor equivalente ao valor predefinido (`ColliderLayer.CL_PHYSICS | ColliderLayer.CL_POINTER`).
{% endhint %}

```ts
// criar entidade
const myEntity = engine.addEntity()
// forma visível
MeshRenderer.setBox(myEntity)

// criar um componente MeshCollider que só responde à física do jogador
MeshCollider.setBox(myEntity, ColliderLayer.CL_PHYSICS)
```

Uma única máscara de colisão pode responder a várias camadas de colisão. Use o `|` carácter como um *ou*, para incluir tantas camadas quantas precisar. O valor predefinido de um MeshCollider é `ColliderLayer.CL_PHYSICS | ColliderLayer.CL_POINTER`.

```ts
MeshCollider.setBox(
	myEntity,
	ColliderLayer.CL_CUSTOM1 |
		ColliderLayer.CL_CUSTOM3 |
		ColliderLayer.CL_PHYSICS |
		ColliderLayer.CL_POINTER
)
```

Pode usar as 8 camadas personalizadas diferentes para o que melhor se adequar à sua scene, por exemplo, uma pode ser usada para cálculos de linha de visão de NPC, enquanto outra para estimar trajetórias de objetos em queda. Usar camadas diferentes para sistemas diferentes permite usar menos recursos, pois em cada caso estará apenas a verificar colisões com as entidades relevantes.

Veja [Raycasting](/creator/content-creator-pt/scenes-sdk7/interatividade/raycasting.md) para saber mais sobre como usar camadas de colisão personalizadas.

### Câmaras e colliders

Quando a câmara de um jogador se move em modo de terceira pessoa, a câmara pode ser bloqueada por colliders ou não, dependendo das camadas de colisão atribuídas às entidades. Tenha isto em atenção ao desenhar a sua scene; pode querer impedir que a câmara atravesse paredes ou outras entidades.

Para evitar que a câmara atravesse paredes, tem de atribuir tanto as `ColliderLayer.CL_PHYSICS` como as `ColliderLayer.CL_POINTER` camadas às entidades que quer que bloqueiem a câmara. É importante que ambas as camadas sejam atribuídas à mesma geometria na entidade. Portanto, se atribuir a `ColliderLayer.CL_PHYSICS` camada à camada visível da entidade, também tem de atribuir a `ColliderLayer.CL_POINTER` camada à mesma geometria.

Por exemplo, no Creator Hub, a seguinte combinação de definições impedirá a câmara de atravessar paredes:

![](/files/84402d7a6e5fababb082f27e946c9b01bed14fdd)

Ambas as `ColliderLayer.CL_PHYSICS` como as `ColliderLayer.CL_POINTER` camadas são atribuídas à mesma camada invisível da geometria da entidade. Se ambas fossem atribuídas à camada visível, o resultado seria o mesmo. Este é o comportamento predefinido, tanto ao adicionar uma entidade via Creator Hub como via código.

![](/files/f6463a691082c11a4dea718e140b8e3dce45d6fd)

Neste segundo exemplo, a câmara pode atravessar a parede, porque a `ColliderLayer.CL_PHYSICS` camada é atribuída à camada invisível da entidade, e a `ColliderLayer.CL_POINTER` camada é atribuída à camada visível da entidade, mesmo que ambas as geometrias tenham a mesma forma geral.

```ts
// SEM CÂMARA A ATRAVESSAR A PAREDE
// predefinição (tanto o pointer como a física usam a geometria invisível)
GLTFContainer.create(myEntity, {
	src: '/models/myModel.gltf',
})

// SEM CÂMARA A ATRAVESSAR A PAREDE
// Ambos usam a mesma geometria invisível
GltfContainer.create(myEntity2, {
	src: '/models/myModel.gltf',
	invisibleMeshesCollisionMask:
		ColliderLayer.CL_PHYSICS | ColliderLayer.CL_POINTER,
})

// SEM CÂMARA A ATRAVESSAR A PAREDE
// Ambos usam a mesma geometria visível
GltfContainer.create(myEntity2, {
	src: '/models/myModel.gltf',
	visibleMeshesCollisionMask:
		ColliderLayer.CL_PHYSICS | ColliderLayer.CL_POINTER,
})

// SIM, A CÂMARA ATRAVESSA A PAREDE
// física e pointer estão em camadas diferentes
GltfContainer.create(myEntity2, {
	src: '/models/myModel.gltf',
	invisibleMeshesCollisionMask: ColliderLayer.CL_PHYSICS,
	visibleMeshesCollisionMask: ColliderLayer.CL_POINTER,
})

// SIM, A CÂMARA ATRAVESSA A PAREDE
// física e pointer estão em camadas diferentes
GltfContainer.create(myEntity2, {
	src: '/models/myModel.gltf',
	invisibleMeshesCollisionMask: ColliderLayer.CL_POINTER,
	visibleMeshesCollisionMask: ColliderLayer.CL_PHYSICS,
})
```

### Bloqueio de pointer

Só as formas que têm colliders podem ser ativadas com [pointer events](/creator/content-creator-pt/scenes-sdk7/interatividade/eventos-de-botao/click-events.md). Uma entidade também precisa de ter um collider para bloquear a passagem de pointer events e evitar atingir entidades atrás dela. Portanto, por exemplo, um jogador não consegue apanhar algo que está trancado dentro de um baú, se o baú tiver colliders à sua volta. Os pointer events do jogador são afetados apenas por meshes que estão ativos na `ColliderLayer.CL_POINTER` camada.

Por predefinição, um MeshCollider afeta tanto a camada Physics como a camada Pointer, mas pode alterar este valor para afetar apenas uma, ou nenhuma, e afetar em vez disso camadas personalizadas.

{% hint style="warning" %}
**📔 Nota**: Além dos colliders, uma entidade também precisa de ter um `PointerEvents` component para responder a pointer events. Os auxiliares do `pointerEventsSystem` também tratam deste requisito.
{% endhint %}

```ts
// responde apenas à física do jogador
// por exemplo, para uma parede invisível que não pode atravessar, mas através da qual pode clicar
MeshCollider.setBox(myEntity, ColliderLayer.CL_PHYSICS)

// responde apenas ao pointer do jogador
// por exemplo, para um item que pode clicar para apanhar, mas atravessar livremente
MeshCollider.setBox(myEntity2, ColliderLayer.CL_POINTER)
```

Por predefinição, a geometria visível de um `GLTFContainer` não é mapeada para quaisquer camadas de colisão, mas a geometria invisível afeta tanto a camada Physics como a camada Pointer. Pode alterar este valor para afetar apenas uma, ou nenhuma, e afetar em vez disso camadas personalizadas. Também pode configurar a camada da geometria visível da mesma forma.

```ts
// predefinição (tanto o pointer como a física usam a geometria invisível)
GLTFContainer.create(myEntity, {
	src: '/models/myModel.gltf',
})

// a física do jogador usa a geometria invisível mais simples
// pointer events usam o contorno detalhado completo da geometria visível
GltfContainer.create(myEntity2, {
	src: '/models/myModel.gltf',
	invisibleMeshesCollisionMask: ColliderLayer.CL_PHYSICS,
	visibleMeshesCollisionMask: ColliderLayer.CL_POINTER,
})

// tanto a física do jogador como os pointer events usam o contorno detalhado completo da geometria visível
// a geometria invisível mais simples é mapeada para ColliderLayer.CL_NONE para evitar calcular ambas
GltfContainer.create(myEntity, {
	src: '/models/myModel.gltf',
	invisibleMeshesCollisionMask: ColliderLayer.CL_NONE,
	visibleMeshesCollisionMask:
		ColliderLayer.CL_POINTER | ColliderLayer.CL_PHYSICS,
})

// não responder a colisões de qualquer tipo, com a geometria visível ou invisível:
GltfContainer.create(myEntity, {
	src: '/models/myModel.gltf',
	invisibleMeshesCollisionMask: ColliderLayer.CL_NONE,
})
```

## Sintaxe avançada de MeshCollider

A sintaxe completa para criar um `MeshCollider` component, sem quaisquer auxiliares para o simplificar, é a seguinte:

```ts
MeshCollider.create(myBox, {
	mesh: {
		$case: 'box',
		box: {},
	},
})

MeshCollider.create(myPlane, {
	mesh: {
		$case: 'plane',
		plane: {},
	},
})

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

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

É assim que o protocolo base interpreta os componentes MeshCollider. As funções auxiliares abstraem isto e expõem uma sintaxe mais amigável, mas nos bastidores produzem esta sintaxe.

O `$case` campo permite-lhe especificar um dos tipos permitidos. Cada tipo suporta um conjunto diferente de parâmetros.

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

* `caixa`
* `plano`
* `esfera`
* `cilindro`

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


---

# Agent Instructions: 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:

```
GET https://docs.decentraland.org/creator/content-creator-pt/scenes-sdk7/essenciais-de-conteudo-3d/colliders.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
