# Consulta de Components

Você pode [consultar componentes](https://docs.decentraland.org/creator/content-creator-pt/scenes-sdk7/arquitetura/querying-components) com o método `engine.getEntitiesWith(...components)` para acompanhar todas as entidades na cena que possuem certos componentes.

[Sistemas](https://docs.decentraland.org/creator/content-creator-pt/scenes-sdk7/arquitetura/systems) normalmente iteram sobre as entidades nessas consultas, realizando as mesmas operações em cada uma. Ter um grupo pré-definido de entidades válidas é uma ótima maneira de economizar recursos, especialmente para funções que são executadas a cada tick do loop do jogo. Se a cada tick seu sistema tivesse que iterar por todas as entidades na cena procurando as que precisa, isso seria muito ineficiente.

Você pode acessar as entidades em uma consulta da seguinte forma.

```ts
for (const [entity] of engine.getEntitiesWith(Transform)) {
	//...
}
```

## Componentes obrigatórios

Ao fazer uma consulta, especifique quais componentes precisam estar presentes em cada entidade que for adicionada ao grupo. Você pode listar quantos componentes quiser; a consulta retornará apenas entidades que tenham **todos** os componentes listados.

```ts
for (const [entity] of engine.getEntitiesWith(
	Transform,
	Physics,
	NextPosition
)) {
	//...
}
```

{% hint style="info" %}
**💡 Tip**: Se sua consulta retornar entidades com as quais você não precisa lidar, considere criar um componente personalizado para atuar como um [sinalizador](https://docs.decentraland.org/creator/content-creator-pt/scenes-sdk7/entities-components#components-as-flags). Este componente não precisa ter nenhuma propriedade, mas pode ser usado para marcar um subgrupo específico de entidades que você pode querer tratar de forma diferente.
{% endhint %}

## Usar consultas em um sistema

```ts
// Definir um System
function PhysicsSystem(dt: number) {

  // consultar entidades que incluem tanto um Transform quanto um Physics component
  for (const [entity] of engine.getEntitiesWith(Transform, Physics)) {
    const transform = Transform.getMutable(entity)
	cons vel = Physics.get(entity).velocity
	position.x += vel.x
	position.y += vel.y
	position.z += vel.z

  }
}

// Adicionar o system ao engine
engine.addSystem(rotationSystem)

```

No exemplo acima, a `PhysicsSystem` function itera sobre as entidades da consulta, que é executada a cada tick do loop do jogo.

* Se a cena tiver várias *bola* entidades, cada uma com um `Position` e um `Física` componente, então elas serão tratadas, e sua posição será atualizada a cada tick.
* Se sua cena também tiver outras entidades, por exemplo um *arco* e um *placar* que tenham apenas um `Transform` mas não um `Física` componente, então elas não serão afetadas por `PhysicsSystem`.

## Lidando com as entidades e componentes

O `getEntitiesWith` a função retorna uma coleção, que inclui referências a um conjunto de entidades e também pode opcionalmente incluir referências aos componentes listados.

Usando a sintaxe mais simples, você busca apenas uma lista de referências às entidades correspondentes.

```ts
const [entity] of engine.getEntitiesWith(myComponent, myOtherComponent)
```

Ao iterar essa lista de entidades, você pode então buscar versões somente leitura ou mutáveis de seus componentes, usando `.get` ou `getMutable`.

```ts
for (const [entity] of engine.getEntitiesWith(Transform)) {
	// obter versão somente leitura
	const transformReadOnly = Transform.get(entity)

	// obter versão mutável
	const transformMutable = Transform.getMutable(entity)
}
```

Você também pode opcionalmente buscar referências a cada um dos componentes listados diretamente como parte da coleção retornada pela consulta. Para fazer isso, simplesmente declare múltiplas referências juntas, uma para cada componente que você deseja buscar. Adicionar essas referências é opcional, e você também não precisa declarar referências para *todos* os componentes na consulta.

```ts
// retorna referências para a entidade e o primeiro componente listado
for (const [entity, component1] of engine.getEntitiesWith(
	MyCustomComponent1,
	MyCustomComponent2
)) {
	// iterar sobre a lista de entidades
}

// retorna referências para a entidade e os dois primeiros componentes listados
for (const [entity, component1, component2] of engine.getEntitiesWith(
	MyCustomComponent1,
	MyCustomComponent2
)) {
	// iterar sobre a lista de entidades
}
```

{% hint style="warning" %}
**📔 Nota**: Essas referências são somente leitura. Para buscar versões mutáveis desses componentes, você precisa usar o `.getMutable` função referenciando a entidade.
{% endhint %}

Você pode então se referir a essas referências enquanto itera sobre a coleção de resultados; em cada entrada você terá acesso à entidade e às suas respectivas referências de componentes.

```ts
for (const [entity, transformReadOnly] of engine.getEntitiesWith(Transform)) {
	console.log('id da entidade: ', entity)
	console.log('tem posição : ', transformReadOnly.position)
}
```

## Inscrever-se em mudanças

Um caso de uso comum é executar uma função apenas caso os dados em certo componente mudem. Use a [OnChange](https://docs.decentraland.org/creator/content-creator-pt/scenes-sdk7/arquitetura/subscribe-to-changes) function para evitar ter que definir um system e ter que comparar explicitamente valores antigos com valores novos.
