> 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-es/escenas-sdk7/fundamentos-del-contenido-3d/camera.md).

# Camera

Como creador, puedes tener control total sobre la cámara del jugador. De forma predeterminada, los jugadores son libres de elegir entre el modo de cámara en primera o tercera persona mientras exploran tu escena, pero puedes imponer una modalidad de cámara diferente.

Las cámaras virtuales pueden ser estáticas, pueden girar para mirar siempre al jugador o a alguna otra Entity, o pueden adjuntarse al jugador o a alguna otra Entity para acompañarlo siempre.

{% hint style="warning" %}
**📔 Nota**: Para cambiar entre las cámaras predeterminadas en primera y tercera persona, consulta [áreas modificadoras de cámara](#1st-and-3rd-person-camera-modes).
{% endhint %}

## modos de cámara en primera y tercera persona

Normalmente, los jugadores pueden cambiar entre la cámara en primera y tercera persona pulsando V en el teclado. Usa una `CameraModeArea` para forzar el modo de cámara a primera o tercera persona para todos los jugadores que se encuentren dentro de un área específica de tu escena.

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

CameraModeArea.create(entity, {
	area: Vector3.create(4, 3, 4),
	mode: CameraType.CT_FIRST_PERSON,
})
```

Si el modo de cámara actual de un jugador no coincide con el de la `CameraModeArea`, pasará a ese modo de cámara. Aparecerá un toast en pantalla para aclarar que este cambio se debe a la escena. Mientras esté dentro, los jugadores no pueden cambiar su modo de cámara. Cuando un jugador salga de la `CameraModeArea`, su modo de cámara se restaurará al que tenía antes de entrar.

Usa `CameraModeArea` en regiones donde los jugadores tendrían una experiencia significativamente mejor usando un modo de cámara específico. Por ejemplo, la primera persona es ideal si el jugador necesita hacer clic en un objeto pequeño, o la tercera persona puede ser útil para que los jugadores noten alguna Entity que tu escena haya adjuntado sobre su cabeza. No asumas que los jugadores saben cómo cambiar de modo de cámara; muchos jugadores primerizos podrían no saber que tienen esa opción, o no recordar la tecla para hacerlo.

{% hint style="warning" %}
**📔 Nota**: Las áreas modificadoras de cámara se ven afectadas por la *posición* y *rotación* del componente Transform de su Entity anfitriona, pero no se ven afectadas por la *escala*.
{% endhint %}

{% hint style="warning" %}
**📔 Nota**: Si superpones varias áreas modificadoras de cámara, la última en ser instanciada por el código de tu escena tendrá prioridad sobre las demás.
{% endhint %}

Al crear un `CameraModeArea` componente, debes proporcionar lo siguiente:

* `área`: Tamaño del área modificadora
* `modo`: Qué modo de cámara forzar en esta área, de la `CameraType` .

Los modos de cámara admitidos son:

* `CameraType.CT_FIRST_PERSON`
* `CameraType.CT_THIRD_PERSON`

### Consultar el modo de cámara

Puedes consultar el modo de cámara del jugador usando el `CameraMode` componente en la `engine.CameraEntity`.

```ts
const cameraMode = CameraMode.get(engine.CameraEntity)
if (cameraMode.mode === CameraType.CT_FIRST_PERSON) {
	console.log('The player is using the 1st person camera')
} else {
	console.log('The player is using the 3rd person camera')
}
```

También puedes suscribirte a los cambios en el modo de cámara usando el `onChange` función en el `CameraMode` component.

```ts
CameraMode.onChange(engine.CameraEntity, (cameraMode) => {
	if (!cameraMode) return
	console.log('The player\'s camera mode changed to', cameraMode.mode)
})
```

## Uso de cámaras virtuales

Para usar un comportamiento de cámara personalizado en tu escena, necesitas dos cosas:

* Crear una VirtualCamera: crea una Entity en tu escena y dale un `VirtualCamera`.
* Asignar esa cámara virtual: agrega una `MainCamera` component a la [Entity reservada](/creator/content-creator-es/escenas-sdk7/arquitectura/entities-components.md#reserved-entities) `engine.CameraEntity`, con una referencia a la Entity con la `VirtualCamera` component.

La cámara quedará entonces adjunta a la Entity con el `VirtualCamera` componente. Si la Entity se mueve o rota, la cámara se moverá con ella.

```ts
function main() {
	const myCustomCamera = engine.addEntity()
	Transform.create(myCustomCamera, {
		position: Vector3.create(1, 2, 1),
	})
	VirtualCamera.create(myCustomCamera, {})

	const mainCamera = MainCamera.createOrReplace(engine.CameraEntity, {
		virtualCameraEntity: myCustomCamera,
	})
}
```

En este ejemplo, la cámara estará siempre en una posición fija en la escena, siempre que el jugador permanezca dentro de los límites de la escena. En cuanto el jugador salga de los límites de la escena, se restaurará el comportamiento predeterminado de la cámara.

### Campo de visión

Puedes reemplazar el campo de visión (FOV) predeterminado del Explorer para una cámara virtual configurando la `fov` propiedad, en grados. El reemplazo solo se aplica mientras esta cámara virtual esté activa. Omitir `fov` usa el valor predeterminado del Explorer (normalmente 60 grados).

```ts
const cinematicCamera = engine.addEntity()
Transform.create(cinematicCamera, {
	position: Vector3.create(8, 3, 2),
})
VirtualCamera.create(cinematicCamera, {
	fov: 45,
})
```

Un FOV más estrecho (valor menor) acerca el zoom, útil para cinemáticas o apuntar. Un FOV más amplio (valor mayor) muestra más de la escena, útil para vistas panorámicas.

Tu escena puede incluir tantas Entities con un `VirtualCamera`componente como quieras, y cambiar dinámicamente entre varias cámaras virtuales a medida que el jugador se mueve, o mientras realiza ciertas acciones. Solo una cámara virtual está activa en un momento dado; esto lo asigna el `MainCamera` componente en `engine.CameraEntity`.

Para volver al comportamiento de cámara predeterminado, establece el valor en `undefined` en `MainCamera.virtualCameraEntity`. Luego, el jugador es libre de cambiar entre cámaras en primera y tercera persona. Si quieres que el jugador use solo uno de estos dos modos, puedes usar una [áreas modificadoras de cámara](#1st-and-3rd-person-camera-modes) para forzar uno de los dos.

{% hint style="warning" %}
**📔 Nota**: Las áreas modificadoras de cámara solo tienen efecto sobre el jugador si no hay cámaras virtuales activas. Si la escena está usando actualmente una cámara virtual y el jugador entra en un área modificadora de cámara, no ocurre nada.

Si un modelo 3D incluye un `camera` node como parte de su contenido, no puede usarse con el SDK. Debes crear todas las cámaras como Entities con el SDK.
{% endhint %}

```ts
function main() {
	// cámara virtual personalizada
	const myCustomCamera = engine.addEntity()
	Transform.create(myCustomCamera, {
		position: Vector3.create(1, 2, 1),
	})
	VirtualCamera.create(myCustomCamera, {})

	const mainCamera = MainCamera.createOrReplace(engine.CameraEntity, {
		virtualCameraEntity: myCustomCamera,
	})

	// cubo clicable
	const clickCube = engine.addEntity()
	Transform.create(clickCube, { position: Vector3.create(8, 0, 8) })
	MeshRenderer.setBox(clickCube)
	MeshCollider.setBox(clickCube)
	pointerEventsSystem.onPointerDown(
		{
			entity: clickCube,
			opts: { button: InputAction.IA_POINTER, hoverText: 'Reset camera' },
		},
		() => {
			// restablecer la cámara al comportamiento predeterminado
			const mainCamera = MainCamera.getMutable(engine.CameraEntity)
			mainCamera.virtualCameraEntity = undefined
		}
	)
}
```

{% hint style="info" %}
**💡 Consejo**: Cuando la cámara se aparta del avatar, suele ser una buena práctica congelar también los movimientos del avatar. Así el jugador no avanza a ciegas hacia obstáculos. Consulta [Modificadores de entrada](/creator/content-creator-es/escenas-sdk7/interactividad/player-avatar.md#freeze-the-player)
{% endhint %}

Para permitir que el jugador controle una cámara virtual con el mouse, lee la `screenDelta` propiedad del `PrimaryPointerInfo` componente para ver cuánto se movió el cursor en cada frame, y luego aplica ese movimiento a la rotación de la cámara. Esto funciona incluso cuando el cursor está bloqueado. Consulta [Movimiento del mouse](/creator/content-creator-es/escenas-sdk7/interactividad/mouse-movement.md) para un ejemplo completo de control de cámara con el mouse.

## Vista a vuelo de pájaro

Puedes usar una cámara virtual para ver la escena desde una vista cenital; puede ser una variación divertida de la perspectiva normal de tu avatar y habilitar diferentes mecánicas de juego.

Debes evitar colocar una cámara mirando en dirección perfectamente vertical hacia abajo. En su lugar, inclina siempre la cámara ligeramente; incluso 1 grado es suficiente. Esto se debe a que los controles de dirección del jugador se basan en la perspectiva de la cámara, no en la orientación del avatar. Si la cámara mira desde una vista de pájaro perfecta, no hay una definición clara de qué dirección es cuál. Una inclinación imperceptible de 1 grado es suficiente para establecer una dirección hacia adelante.

```ts
function main() {
	// cámara de vista de pájaro
	const myCustomCamera = engine.addEntity()
	Transform.create(myCustomCamera, {
		position: Vector3.create(8, 5, 8),
		rotation: Quaternion.fromEulerDegrees(91, 0, 0),
		// Ten en cuenta que la rotación es 91º, no 90º
	})
	VirtualCamera.create(myCustomCamera, {})

	const mainCamera = MainCamera.createOrReplace(engine.CameraEntity, {
		virtualCameraEntity: myCustomCamera,
	})
}
```

## Transiciones de cámara

Cada vez que la escena cambia entre cámaras virtuales, o entre el comportamiento de cámara predeterminado y las cámaras virtuales, los jugadores ven una transición. La posición, la rotación y cualquier otro parámetro de la cámara virtual cambian suavemente durante un periodo de tiempo.

La configuración de transición de una cámara virtual determina cómo transicionas *a* esa cámara, desde cualquier otra cámara de la escena, incluida la predeterminada. No afectan a cómo transicionas *fuera de* esa cámara.

```ts
VirtualCamera.create(myCustomCamera1, {
	defaultTransition: { transitionMode: VirtualCamera.Transition.Time(6) },
})
```

{% hint style="info" %}
**💡 Consejo**: Para evitar tener una transición y pasar instantáneamente a una cámara, establece el tiempo o la velocidad de transición en 0.
{% endhint %}

Según tu caso de uso, quizá prefieras establecer la velocidad de la transición en lugar de la duración:

* **Tiempo fijo**: Estableces la duración de la transición; la cámara se moverá tan rápido como necesite para completar el recorrido en ese periodo de tiempo.
* **Velocidad fija**: Estableces a qué velocidad quieres que se mueva la cámara virtual durante la transición; la duración dependerá de la distancia. El valor usado para la velocidad se interpreta como **metros por segundo**.

A continuación hay ejemplos de ambos modos de transición:

```ts
// duración fija
VirtualCamera.create(myCustomCamera1, {
	defaultTransition: { transitionMode: VirtualCamera.Transition.Time(6) },
})

// velocidad fija
VirtualCamera.create(myCustomCamera1, {
	defaultTransition: { transitionMode: VirtualCamera.Transition.Speed(3) },
})
```

A continuación hay un ejemplo completo con dos cámaras virtuales, y transiciones entre ellas:

```ts
function main() {
	// cámara virtual personalizada 1
	const myCustomCamera1 = engine.addEntity()
	Transform.create(myCustomCamera1, {
		position: Vector3.create(1, 2, 1),
	})
	VirtualCamera.create(myCustomCamera1, {
		defaultTransition: { transitionMode: VirtualCamera.Transition.Time(1) },
	})

	// cámara virtual personalizada 2
	const myCustomCamera2 = engine.addEntity()
	Transform.create(myCustomCamera2, {
		position: Vector3.create(1, 2, 1),
	})
	VirtualCamera.create(myCustomCamera2, {
		defaultTransition: { transitionMode: VirtualCamera.Transition.Time(3) },
	})

	const mainCamera = MainCamera.createOrReplace(engine.CameraEntity, {
		virtualCameraEntity: myCustomCamera1,
	})

	// cubo clicable
	const clickCube = engine.addEntity()
	Transform.create(clickCube, { position: Vector3.create(8, 0, 8) })
	MeshRenderer.setBox(clickCube)
	MeshCollider.setBox(clickCube)
	pointerEventsSystem.onPointerDown(
		{
			entity: clickCube,
			opts: { button: InputAction.IA_POINTER, hoverText: 'Reset camera' },
		},
		() => {
			// restablecer la cámara al comportamiento predeterminado
			const mainCamera = MainCamera.getMutable(engine.CameraEntity)
			mainCamera.virtualCameraEntity =
				mainCamera.virtualCameraEntity ==
					? myCustomCamera2
					: myCustomCamera1
		}
	)
}
```

Las transiciones siempre se mueven en línea recta, sin considerar ningún obstáculo en el recorrido. En su lugar, podrías crear una transición manualmente usando otra cámara virtual como intermediaria; así tendrías control total sobre sus movimientos. Esta cámara virtual intermedia podría realizar un [Tween](/creator/content-creator-es/escenas-sdk7/fundamentos-del-contenido-3d/move-entities.md#move-between-two-points) desde la posición de la primera cámara hasta la posición de la segunda cámara, o seguir una ruta más personalizada que evite obstáculos o haga un desvío cinematográfico.

## Seguimiento de cámara

Puedes configurar una cámara virtual para que siempre mire en la dirección del jugador, o de alguna Entity específica de la escena. La posición de la cámara permanecerá estática, pero su rotación cambiará para mantener siempre centrada a esta Entity.

Esto puede lograrse con la `lookAtEntity` propiedad en el `VirtualCamera` componente. Para seguir al jugador, usa [Entity reservada](/creator/content-creator-es/escenas-sdk7/arquitectura/entities-components.md#reserved-entities) `engine.PlayerEntity`.

```ts
const myCustomCamera1 = engine.addEntity()
Transform.create(myCustomCamera1, {
	position: Vector3.create(1, 2, 1),
})
VirtualCamera.create(myCustomCamera1, {
	lookAtEntity: engine.PlayerEntity,
})
```

Si una Entity está siendo seguida por la cámara, esto solo cambiará la rotación, no la posición de la cámara.

A medida que la cámara rota, el Transform de la Entity con el `VirtualCamera` componente no cambia. Sin embargo, puedes leer la rotación de la cámara desde el Transform en `engine.CameraEntity`. La rotación y la posición de esta Entity serán absolutas; no estarán condicionadas por las de la Entity con el `VirtualCamera` componente. La rotación de este Transform se ve afectada como por el `lookAtEntity` comportamiento.

{% hint style="warning" %}
**📔 Nota**: Si configuras la cámara virtual con un `lookAtEntity` que haga referencia a la misma Entity que contiene la cámara virtual, o a la `engine.CameraEntity` Entity, el comportamiento resultante será el mismo que no asignar ninguna Entity en absoluto.
{% endhint %}

## Adjuntar al jugador

Otro uso de la cámara virtual es seguir al jugador desde una distancia o ángulo personalizados, adjuntando una cámara virtual a la Entity del jugador. Ten en cuenta que el jugador no puede cambiar libremente la rotación de la cámara, así que en este caso la rotación de la cámara quedará fijada a la de la cámara virtual. Esto podría ser útil, por ejemplo, para juegos de carreras, donde se espera que el jugador mire siempre hacia adelante.

```ts
function main() {
	const myCustomCamera = engine.addEntity()
	Transform.create(myCustomCamera, {
		position: Vector3.create(0, 1, 5),
		parent: engine.PlayerEntity,
	})
	VirtualCamera.create(myCustomCamera, {
		defaultTransition: { transitionMode: VirtualCamera.Transition.Time(2) },
	})

	const mainCamera = MainCamera.createOrReplace(engine.CameraEntity, {
		virtualCameraEntity: myCustomCamera,
	})
}
```

## Cámaras y colliders

Cuando la cámara de un jugador se mueve en modo tercera persona, la cámara puede quedar bloqueada por colliders o no, dependiendo de las collision layers asignadas a las Entities. Ten esto en cuenta al diseñar tu escena; quizá quieras evitar que la cámara atraviese paredes u otras Entities.

Ver [Colliders](/creator/content-creator-es/escenas-sdk7/fundamentos-del-contenido-3d/colliders.md#cameras-and-colliders) para más detalles sobre cómo configurar colliders para tu escena.

## Modo espectador (cámara de observador)

Puedes crear un modo espectador que cambie al jugador del movimiento normal del avatar a una cámara de libre recorrido o que siga al jugador. Esto es útil para roles de observador en juegos competitivos, cámaras de director para eventos en vivo o sistemas de repetición.

El patrón combina varias características del SDK:

| Característica                      | API del SDK                               | Propósito                                 |
| ----------------------------------- | ----------------------------------------- | ----------------------------------------- |
| Vista de cámara personalizada       | `VirtualCamera` + `MainCamera`            | Reemplaza la cámara del jugador           |
| Congelar el movimiento del avatar   | `InputModifier` (`disableAll: true`)      | Libera WASD para controlar la cámara      |
| Seguir a los jugadores en la escena | `onEnterScene` / `onLeaveScene`           | Construye una lista de objetivos a seguir |
| Controles de cámara                 | `inputSystem.isPressed(InputAction.IA_*)` | WASD para pitch/yaw, E/F para zoom        |
| Mouse-look                          | `PrimaryPointerInfo.screenDelta`          | Gira la cámara con el mouse               |

### Arquitectura del rig de cámara

Usa un **rig de dos Entities** para que yaw y pitch permanezcan independientes:

```
rigRoot (Entity)           -- posición en el mundo + rotación yaw
└── rigCamera (child)      -- rotación pitch + desplazamiento orbital
    └── VirtualCamera
```

`rigRoot` contiene el yaw (giro izquierda/derecha) y se interpola hacia el objetivo a seguir o un pivote de free-cam. `rigCamera` gestiona pitch (inclinación arriba/abajo) y la distancia orbital desde la raíz. Dividir yaw y pitch entre dos Transforms mantiene la matemática de Euler sencilla.

### Activar y desactivar

```ts
// Activar el modo espectador
const rigRoot = engine.addEntity()
Transform.create(rigRoot, {
  position: Vector3.create(8, 8, 8),
  rotation: Quaternion.fromEulerDegrees(0, 0, 0),
})

const rigCamera = engine.addEntity()
Transform.create(rigCamera, { parent: rigRoot })
VirtualCamera.create(rigCamera, {})

MainCamera.createOrReplace(engine.CameraEntity, { virtualCameraEntity: rigCamera })
InputModifier.createOrReplace(engine.PlayerEntity, {
  mode: InputModifier.Mode.Standard({ disableAll: true }),
})
```

```ts
// Desactivar el modo espectador
// IMPORTANTE: vacía MainCamera ANTES de eliminar la entidad VirtualCamera.
// Si eliminas la entidad primero, el engine seguirá enlazando una referencia muerta
// y la vista caerá a los pies del jugador.
const mainCamera = MainCamera.getMutableOrNull(engine.CameraEntity)
if (mainCamera) mainCamera.virtualCameraEntity = undefined

engine.removeEntity(rigCamera)
engine.removeEntity(rigRoot)

InputModifier.createOrReplace(engine.PlayerEntity, {
  mode: InputModifier.Mode.Standard({ disableAll: false }),
})
```

{% hint style="danger" %}
**Advertencia:** Vacía siempre `MainCamera.virtualCameraEntity` antes de eliminar la entidad de la cámara. Eliminar la entidad primero deja al engine apuntando a una referencia muerta, lo que rompe la vista.
{% endhint %}

### Límites de la cámara

El engine desactiva `VirtualCamera` Entities que se mueven fuera de los límites de parcelas de tu escena. Si la cámara sale del área de la escena, deja de funcionar sin avisar. Recorta la posición de la cámara para que permanezca dentro del AABB de la escena en cada frame, con un pequeño margen.

```ts
// Ejemplo de límites para una escena de 1x1 parcelas (16 m x 16 m)
const BOUNDS_MIN = Vector3.create(0, 0, 0)
const BOUNDS_MAX = Vector3.create(16, 20, 16)
const BOUNDS_MARGIN = 0.5
```

Para escenas más grandes, establece los límites para que coincidan con tus `scene.json` parcelas. La altura máxima para N parcelas por lado es aproximadamente `log2(N+1) * 20` metros, así que una escena de 4x4 parcelas usaría `Vector3.create(64, 80, 64)`.

### Seguimiento de jugadores

Usa `onEnterScene` y `onLeaveScene` para construir una lista en vivo de jugadores en tu escena. Luego, los jugadores pueden ir alternando entre objetivos a seguir con teclas (por ejemplo, `IA_ACTION_3` y `IA_ACTION_4`). Al seguir a un jugador, la raíz del rig interpola hacia la posición del Transform del jugador seguido, y la cámara hija orbita a una distancia configurable.

```ts
import { onEnterScene, onLeaveScene } from '@dcl/sdk/src/players'

const playerEntities = new Map<string, Entity>()
let playerIds: string[] = []

onEnterScene((player) => {
  if (!player) return
  playerIds.push(player.userId)
  playerEntities.set(player.userId, player.entity)
})

onLeaveScene((userId) => {
  if (!userId) return
  playerIds = playerIds.filter((id) => id !== userId)
  playerEntities.delete(userId)
})
```

Para seguir a un jugador en cada frame, interpola la raíz del rig hacia su posición:

```ts
const followEntity = playerEntities.get(followTargetId)
if (followEntity) {
  const targetPos = Transform.get(followEntity).position
  const rootTransform = Transform.getMutable(rigRoot)
  rootTransform.position = Vector3.lerp(
    rootTransform.position,
    Vector3.add(targetPos, Vector3.create(0, 1, 0))ેત્ર
    0.1
  )
}
```

Ver [El jugador entra o sale de la escena](/creator/content-creator-es/escenas-sdk7/interactividad/event-listeners.md#player-enters-or-leaves-scene) para más sobre `onEnterScene` y `onLeaveScene`.

### Mouse-look mientras se observa

Lee `PrimaryPointerInfo.screenDelta` cada frame para girar la cámara con el mouse. Esto funciona mientras el pointer está bloqueado. Consulta [Movimiento del mouse](/creator/content-creator-es/escenas-sdk7/interactividad/mouse-movement.md) para un ejemplo completo de control de cámara con el mouse.

```ts
const MOUSE_SENSITIVITY = 0.15 // degrees per pixel
let yaw = 0
let pitch = 45

function spectateMouseLook() {
  const isLocked = PointerLock.getOrNull(engine.CameraEntity)?.isPointerLocked ?? false
  if (!isLocked) return

  const delta = PrimaryPointerInfo.getOrNull(engine.RootEntity)?.screenDelta
  if (!delta) return

  yaw = (yaw + delta.x * MOUSE_SENSITIVITY) % 360
  // Resta delta.y para que mover el mouse hacia arriba incline la cámara hacia arriba; limita para evitar un volteo
  pitch = Math.max(-25, Math.min(80, pitch - delta.y * MOUSE_SENSITIVITY))
}
```

{% hint style="warning" %}
**Nota:** `screenDelta` es solo para escritorio. En móvil siempre informa `0`. Si tu escena está orientada a móvil, diseña un fallback táctil.
{% endhint %}

### Implementación completa de referencia

El [`33,20-modo-espectador`](https://github.com/decentraland/sdk7-test-scenes/tree/main/scenes/33,20-spectate-mode) la test scene contiene un módulo de espectador autocontenido en `src/spectate.ts`. Admite modos free-cam y follow-cam, controles WASD + mouse-look, cambio cíclico de jugadores, zoom de distancia orbital, recorte de límites y un HUD en pantalla que muestra los controles y el objetivo actual a seguir.

Para usarlo en tu propio proyecto:

1. Copia `src/spectate.ts` en tu escena.
2. Actualiza `PIVOT`, `BOUNDS_MIN`, y `BOUNDS_MAX` en la parte superior del archivo para que coincidan con las parcelas de tu escena. Este es el error de integración más común.
3. Conecta `toggleSpectate()` a cualquier trigger: un Entity clicable, un Button de UI o una pulsación de tecla.

{% hint style="info" %}
**💡 Consejo**: Para ver ejemplos funcionales de control de cámara, consulta la [`2,22-virtual-cameras`](https://github.com/decentraland/sdk7-test-scenes/tree/main/scenes/2,22-virtual-cameras) Scene de prueba, que alterna varias `VirtualCamera` entities a través de `MainCamera` incluyendo `lookAtEntity` apuntadas al player y una cámara tweened; [`32,20-virtual-camera-mouse-look`](https://github.com/decentraland/sdk7-test-scenes/tree/main/scenes/32,20-virtual-camera-mouse-look), que controla una cámara de mouselook mientras el pointer está bloqueado; [`33,20-modo-espectador`](https://github.com/decentraland/sdk7-test-scenes/tree/main/scenes/33,20-spectate-mode), que implementa una cámara completa de spectate/observer con modos follow-cam y free-cam; y [`9,99-modifier-areas`](https://github.com/decentraland/sdk7-test-scenes/tree/main/scenes/9,99-modifier-areas), que fuerza un camera mode dentro de un volumen con `CameraModeArea`.
{% endhint %}


---

# 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 dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.decentraland.org/creator/content-creator-es/escenas-sdk7/fundamentos-del-contenido-3d/camera.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
