# Consulta de Components

Puedes [consultar componentes](https://docs.decentraland.org/creator/content-creator-es/scenes-sdk7/arquitectura/querying-components) con el método `engine.getEntitiesWith(...components)` para hacer seguimiento de todas las entidades en la escena que tienen ciertos componentes.

[Sistemas](https://docs.decentraland.org/creator/content-creator-es/scenes-sdk7/arquitectura/systems) típicamente iteran sobre las entidades en estas consultas, realizando las mismas operaciones en cada una. Tener un grupo predefinido de entidades válidas es una excelente manera de ahorrar recursos, especialmente para funciones que se ejecutan en cada tick del bucle del juego. Si en cada tick tu sistema tuviera que iterar sobre cada entidad de la escena buscando las que necesita, sería muy ineficiente.

Puedes acceder a las entidades en una consulta de la siguiente manera.

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

## Componentes requeridos

Al hacer una consulta, especifica qué componentes deben estar presentes en cada entidad que se agregue al grupo. Puedes listar tantos componentes como quieras, la consulta solo devolverá entidades que tengan **todos** los componentes enumerados.

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

{% hint style="info" %}
**💡 Tip**: Si tu consulta devuelve entidades con las que no necesitas lidiar, considera crear un componente personalizado para actuar como un [indicador](https://docs.decentraland.org/creator/content-creator-es/scenes-sdk7/entities-components#components-as-flags). Este componente no necesita tener propiedades, pero puede usarse para marcar un subgrupo específico de entidades que quizá quieras tratar de manera diferente.
{% endhint %}

## Usar consultas en un sistema

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

  // consulta entidades que incluyen tanto un Transform como un 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

  }
}

// Agrega el system al engine
engine.addSystem(rotationSystem)

```

En el ejemplo anterior, la `PhysicsSystem` function itera sobre las entidades en la consulta, que se ejecuta en cada tick del bucle del juego.

* Si la escena tiene varias *pelota* entidades, cada una con un `Position` y un `Física` componente, entonces serán manejadas y su posición se actualizará en cada tick.
* Si tu escena también tiene otras entidades, por ejemplo un *aro* y un *marcador* que solo tienen un `Transform` pero no un `Física` componente, entonces no se verán afectadas por `PhysicsSystem`.

## Lidiar con las entidades y componentes

El `getEntitiesWith` la función devuelve una colección, que incluye referencias a un conjunto de entidades y también puede opcionalmente incluir referencias a los componentes listados.

Usando la sintaxis más simple, obtienes solo una lista de referencias a las entidades correspondientes.

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

Mientras iteras sobre esta lista de entidades, puedes entonces obtener versiones de solo lectura o mutables de sus componentes, usando `.get` o `getMutable`.

```ts
for (const [entity] of engine.getEntitiesWith(Transform)) {
	//obtener versión de solo lectura
	const transformReadOnly = Transform.get(entity)

	// obtener versión mutable
	const transformMutable = Transform.getMutable(entity)
}
```

Opcionalmente también puedes obtener referencias a cada uno de los componentes listados directamente como parte de la colección devuelta por la consulta. Para hacerlo, simplemente declara múltiples referencias juntas, una por cada componente que quieras obtener. Agregar estas referencias es opcional, y no necesitas declarar referencias a *todos* los componentes en la consulta tampoco.

```ts
// devuelve referencias a la entidad y al primer componente listado
for (const [entity, component1] of engine.getEntitiesWith(
	MyCustomComponent1,
	MyCustomComponent2
)) {
	// iterar sobre la lista de entidades
}

// devuelve referencias a la entidad y a los dos primeros componentes listados
for (const [entity, component1, component2] of engine.getEntitiesWith(
	MyCustomComponent1,
	MyCustomComponent2
)) {
	// iterar sobre la lista de entidades
}
```

{% hint style="warning" %}
**📔 Nota**: Estas referencias son de solo lectura. Para obtener versiones mutables de esos componentes, necesitas usar la `.getMutable` función referenciando la entidad.
{% endhint %}

Luego puedes referirte a estas referencias mientras iteras sobre la colección de resultados; en cada entrada tendrás acceso a la entidad y a sus correspondientes referencias de componentes.

```ts
for (const [entity, transformReadOnly] of engine.getEntitiesWith(Transform)) {
	console.log('id de la entidad: ', entity)
	console.log('tiene position : ', transformReadOnly.position)
}
```

## Suscribirse a cambios

Un caso de uso común es ejecutar una función solo en caso de que los datos en cierto componente cambien. Usa la [OnChange](https://docs.decentraland.org/creator/content-creator-es/scenes-sdk7/arquitectura/subscribe-to-changes) function para evitar tener que definir un system y tener que comparar explícitamente valores antiguos con nuevos.
