> 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/scenes-sdk7/interactividad/user-data.md).

# Datos del usuario

Obtén datos de los jugadores a medida que interactúan con tu escena.

## Posición y rotación del jugador

Usa el `PlayerEntity` y la `CameraEntity` para conocer la posición y rotación del jugador, comprobando su `Transform` components.

```ts
function getPlayerPosition() {
	if (!Transform.has(engine.PlayerEntity)) return
	if (!Transform.has(engine.CameraEntity)) return

	//posición del jugador
	const playerPos = Transform.get(engine.PlayerEntity).position

	//rotación del jugador
	const playerRot = Transform.get(engine.PlayerEntity).rotation

	//posición de la cámara
	const CameraPos = Transform.get(engine.CameraEntity).position

	//rotación de la cámara
	const CameraRot = Transform.get(engine.CameraEntity).rotation

	console.log('playerPos: ', playerPos)
	console.log('playerRot: ', playerRot)
	console.log('cameraPos: ', CameraPos)
	console.log('cameraRot: ', CameraRot)
}

engine.addSystem(getPlayerPosition)
```

* **Posición de PlayerEntity**: La posición del avatar, a la altura del pecho. Aproximadamente a 0,88 metros sobre el suelo.
* **Rotación de PlayerEntity**: La dirección hacia la que mira el avatar, expresada como un quaternion.
* **Posición de CameraEntity**:
  * En 1.ª persona: Igual a la posición del avatar, pero a la altura de los ojos. Aproximadamente a 1,75 metros sobre el suelo.
  * En 3.ª persona: Puede variar según los movimientos de la cámara.
* **Rotación de PlayerEntity**:
  * En 1.ª persona: Similar a la dirección hacia la que mira el avatar, expresada como un quaternion. Puede redondearse de forma ligeramente distinta a la rotación del jugador.
  * En 3.ª persona: Puede variar según los movimientos de la cámara.

{% hint style="warning" %}
**📔 Nota**: Evita referirte a la `engine.PlayerEntity` o `engine.CameraEntity` durante la carga inicial de la escena, porque eso puede provocar errores si las entidades aún no se han inicializado. Para evitar este problema, úsalo dentro de la `main()` función, o en una función llamada indirectamente por `main()`. También puedes encapsular el comportamiento en un async [`executeTask` bloque](/creator/content-creator-es/scenes-sdk7/patrones-de-programacion/async-functions.md#the-executetask-function).

Otra opción es referirse a estas entidades dentro de un sistema. Allí siempre estarán disponibles, porque la primera ejecución del sistema se llama una vez que la escena ya está correctamente inicializada.
{% endhint %}

## Obtener todos los jugadores

Todos los jugadores en la escena tienen un `Transform` componente. Este componente es de solo lectura en los avatares. Para obtener las posiciones de todos los jugadores, [itera sobre todas las entidades con](/creator/content-creator-es/scenes-sdk7/interactividad/user-data.md) un `PlayerIdentityData` componente.

```ts
import { PlayerIdentityData } from '@dcl/sdk/ecs'

for (const [entity, data, transform] of engine.getEntitiesWith(
	PlayerIdentityData,
	Transform
)) {
	console.log('Datos del jugador: ', { entity, data, transform })
}
```

El código anterior itera sobre todas las entidades con un `Transform` y una `PlayerIdentityData` componente, y registra sus datos. Puedes usar este mismo método para obtener cualquiera de los datos disponibles de todos los jugadores.

Consulta [Listeners de eventos](/creator/content-creator-es/scenes-sdk7/interactividad/event-listeners.md#player-locks-or-unlocks-cursor) para aprender a detectar y reaccionar cuando nuevos jugadores se unan a la escena.

## Obtener datos del jugador

Usa `getPlayer()` para obtener datos del jugador actual, o de cualquier otro jugador en la escena.

```ts
import { getPlayer } from '@dcl/sdk/src/players'

export function main() {
	createCube(5, 1, 5)

	let myPlayer = getPlayer()

	if (myPlayer) {
		console.log('Nombre: ', myPlayer.name)
		console.log('UserId: ', myPlayer.userId)
	}
}
```

`getPlayer()` devuelve lo siguiente:

* `name`: *(string)* El nombre de usuario del jugador, tal como lo ven los demás en el mundo
* `userId`: *(string)* Una cadena que identifica al jugador. Para los jugadores conectados con una wallet, esta es la dirección de la wallet, escrita en minúsculas. Para las cuentas de invitado, es un identificador generado localmente.
* `isGuest`: *(boolean)* Indica si el jugador tiene una clave pública. *Verdadero* si el jugador es una cuenta de invitado sin una clave pública.
* `posición`: *(Vector3)* La posición del avatar en la escena.
* `avatar`: Un objeto anidado con datos sobre el avatar base y la apariencia del jugador.
* `wearables`: Un array de identificadores para cada uno de los wearables que el jugador está usando actualmente. Por ejemplo `urn:decentraland:off-chain:base-avatars:green_hoodie`. Todos los wearables tienen un identificador similar, incluso si son NFTs.
* `emotes`: Un array de identificadores para cada uno de los emotes que el jugador tiene equipados actualmente en la rueda de acceso rápido.
* `entidad`: Una referencia a la entidad del jugador. Esto puede ser útil para pasarla a otras funciones, o para añadirle componentes personalizados.

El `avatar` el objeto tiene la siguiente información anidada:

* `bodyShapeUrn`: Un identificador para la forma corporal general del avatar. Ya sea `urn:decentraland:off-chain:base-avatars:BaseFemale` para femenino o `urn:decentraland:off-chain:base-avatars:BaseMale` para masculino.
* `skinColor`: El color de la piel del jugador como un `Color3`
* `eyesColor`: El color de los ojos del jugador como un `Color3`
* `hairColor`: El color del cabello del jugador como un `Color3`
* `name`: El nombre del jugador.

{% hint style="warning" %}
**📔 Nota**: Es posible que los datos del jugador no estén disponibles en el primer frame de la escena, según los tiempos de carga. Debes verificar que se hayan devuelto los datos y, de lo contrario, intentarlo de nuevo unos milisegundos después.
{% endhint %}

```ts
import { getPlayer } from '@dcl/sdk/src/players'

export function main() {
	createCube(5, 1, 5)

	let myPlayer = getPlayer()

	if (myPlayer) {
		console.log('Es invitado: ', myPlayer.isGuest)
		console.log('Nombre: ', myPlayer.name)
		console.log('UserId: ', myPlayer.userId)
		console.log('Forma del avatar: ', myPlayer.position)
		console.log('Forma del avatar: ', myPlayer.avatar?.bodyShapeUrn)
		console.log('Color de los ojos del avatar: ', myPlayer.avatar?.eyesColor)
		console.log('Color del cabello del avatar: ', myPlayer.avatar?.hairColor)
		console.log('Wearables equipados: ', myPlayer.wearables)
		console.log('Emotes disponibles: ', myPlayer.emotes)
	}
}
```

Para obtener los datos de un jugador específico en la escena, distinto del jugador actual, ejecuta `getPlayer()` con un objeto con un `userId` propiedad.

```ts
import { getPlayer } from '@dcl/sdk/src/players'

for (const [entity, data, transform] of engine.getEntitiesWith(
	PlayerIdentityData,
	Transform
)) {
	let player = getPlayer({ userId: data.address })
	console.log('JUGADOR: ', player?.name)
}
```

El fragmento anterior itera sobre todas las entidades con un `PlayerIdentityData` componente, lo que significa todas las entidades avatar de la escena. Luego ejecuta el `getPlayer()` para esa entidad.

`getPlayer()` solo puede obtener datos de jugadores que se encuentran actualmente en la misma escena; no es necesario que estén dentro del rango visual, pero sí deben estar conectados a la misma isla de comunicaciones. Para probar esto en Preview, abre una segunda pestaña e inicia sesión con una cuenta diferente, y haz que ambos jugadores estén dentro de la escena.

{% hint style="warning" %}
**📔 Nota**: Los User IDs siempre deben estar en minúsculas. Si copias una dirección de wallet, asegúrate de que todos los caracteres estén en minúsculas.
{% endhint %}

## Datos de cualquier jugador

Para obtener información de cualquier jugador, realiza una [llamada REST API](/creator/content-creator-es/scenes-sdk7/networking/network-connections.md#call-a-rest-api) a los servidores de contenido.

Esta información se expone en la siguiente URL, añadiendo el user id del jugador al parámetro de la url.

`https://peer.decentraland.org/lambdas/profile/<player user id>`

{% hint style="info" %}
**💡 Consejo**: Prueba la URL en un navegador para ver cómo está estructurada la respuesta.
{% endhint %}

La siguiente información está disponible desde esta API:

* `displayName`: *(string)* El nombre de usuario del jugador, tal como lo ven los demás en el mundo
* `userId`: *(string)* Una cadena UUID que identifica al jugador. Si el jugador tiene una clave pública, este campo tendrá el mismo valor que la clave pública.
* `hasConnectedWeb3`: *(boolean)* Indica si el jugador tiene una clave pública. *Verdadero* si el jugador tiene una.
* `publicKey`: *(string)* La clave pública de la wallet Ethereum del jugador. Si el jugador inicia sesión como invitado, sin una wallet vinculada, este campo será `null`.
* `avatar`: Un objeto anidado con datos sobre la apariencia del jugador.
* `version`: *(number)* Un número de versión que aumenta en uno cada vez que el jugador cambia cualquiera de sus ajustes. Usa esto si encuentras datos conflictivos, para saber qué versión es la más reciente.

{% hint style="warning" %}
**📔 Nota**: Para cualquier transacción de Ethereum con el jugador, usa siempre el `publicKey` campo, en lugar del `userId`, para evitar tratar con wallets inexistentes.
{% endhint %}

El `avatar` el objeto tiene la siguiente información anidada:

* `wearables`: `WearableId[]` Un array de identificadores para cada uno de los wearables que el jugador está usando actualmente. Por ejemplo `urn:decentraland:off-chain:base-avatars:green_hoodie`. Todos los wearables tienen un identificador similar, incluso si son NFTs.
* `bodyShape`: Un identificador para la forma corporal general del avatar. Ya sea `urn:decentraland:off-chain:base-avatars:BaseFemale` para femenino o `urn:decentraland:off-chain:base-avatars:BaseMale` para masculino.
* `skin`: Un objeto con un `color` campo, que contiene el color de piel del jugador como `{ r, g, b, a }` números del 0 al 1.
* `hair`: Un objeto con un `color` campo, que contiene el color del cabello del jugador como `{ r, g, b, a }` números del 0 al 1.
* `eyes`: Un objeto con un `color` campo, que contiene el color de los ojos del jugador como `{ r, g, b, a }` números del 0 al 1.
* `snapshots`: Un objeto anidado con representaciones en base64 de imágenes .jpg del jugador en varias resoluciones.
  * `face256`: *string* El rostro del jugador como una imagen de 256x256 píxeles.
  * `body`: *string* La imagen a resolución completa del jugador de pie, con 512x1024 píxeles.

{% hint style="danger" %}
**❗Advertencia** Las snapshots del avatar quedarán obsoletas en el futuro y dejarán de devolverse como parte de los datos de un avatar. El enfoque recomendado es usar `AvatarTexture` en su lugar, consulta [Retratos de Avatar](/creator/content-creator-es/scenes-sdk7/fundamentos-del-contenido-3d/materials.md#avatar-portraits).
{% endhint %}

A diferencia de `getPlayer()`, esta opción no se limita solo a los jugadores que están actualmente en la misma escena, o incluso en el mismo servidor. Con este enfoque puedes obtener datos de cualquier jugador que haya iniciado sesión en los servidores en el pasado.

Si sabes a qué servidor está conectado el jugador que quieres consultar, puedes obtener datos más actualizados enviando tus solicitudes a ese servidor específico. Por ejemplo, si el jugador cambia de ropa, esta información estará disponible al instante en el servidor del jugador, pero probablemente tardará un par de minutos en propagarse al `peer.decentraland.org` servidor.

`https://<player server>/lambdas/profile/<player user id>`

{% hint style="info" %}
**💡 Consejo**: Puedes obtener el servidor del jugador actual llamando a `getRealm()` y leyendo el `realmInfo.baseUrl` campo de la respuesta.
{% endhint %}

Este ejemplo combina `myProfile.userId` y `getRealm()` para obtener los datos del jugador directamente desde el servidor en el que se encuentra el jugador:

```ts
import { getRealm } from '~system/Runtime'
import { myProfile } from '@dcl/sdk/network'

async function fetchPlayerData() {
	const { realmInfo } = await getRealm({})
	if (!realmInfo) return

	const url = `${realmInfo.baseUrl}/lambdas/profile/${myProfile.userId}`
	console.log('usando la URL: ', url)

	try {
		const response = await fetch(url)
		const json = await response.json()

		console.log('respuesta completa: ', json)
		console.log('el jugador lleva puestos: ', json.avatars[0].avatar.wearables)
	} catch {
		console.log('ocurrió un error al intentar obtener los datos del jugador')
	}
}

fetchPlayerData()
```

## Componentes de datos del jugador

En lugar de usar `getPlayer()`, puedes leer los datos directamente desde una serie de componentes que almacenan los datos de cada entidad jugador. Existen los siguientes componentes:

* `PlayerIdentityData`: Almacena la dirección del jugador y una `isGuest` propiedad para marcar las cuentas de invitado.
* `AvatarBase`: Almacena datos sobre el avatar base, incluyendo:
  * `name`: El nombre del jugador.
  * `bodyShapeUrn`: Los ids correspondientes al tipo de cuerpo masculino o femenino.
  * `skinColor`: El color de la piel del jugador como un `Color3`
  * `eyesColor`: El color de los ojos del jugador como un `Color3`
  * `hairColor`: El color del cabello del jugador como un `Color3`
* `AvatarEquippedData`: La lista de wearables y emotes equipados.
  * `wearableUrns`: La lista de wearables que el jugador tiene equipados actualmente.
  * `emoteUrns`: La lista de emotes que el jugador tiene equipados actualmente en la rueda de acceso rápido.
* `AvatarEmoteCommand`: Información sobre los emotes que el jugador está reproduciendo actualmente. Incluye:
  * `emoteUrn`: El URN del último emote reproducido por el jugador, desde que entró en la escena
  * `loop`: Verdadero si el emote se está reproduciendo en bucle
  * `marca de tiempo`: El momento en que se activó este emote

```ts
for (const [entity, data, base, attach, transform] of engine.getEntitiesWith(
	PlayerIdentityData,
	AvatarBase,
	AvatarEquippedData,
	Transform
)) {
	console.log('DATOS DEL JUGADOR: ', { entity, data, transform, base, attach })
}
```

{% hint style="warning" %}
**📔 Nota**: Todos estos componentes son de solo lectura. No puedes cambiar sus valores desde la escena.
{% endhint %}

## Obtener experiencias portables

Las experiencias portables son, esencialmente, escenas que no están restringidas a parcelas de tierra. Los jugadores pueden llevarlas consigo a cualquier lugar al que vayan en Decentraland, añadiendo una nueva capa de contenido sobre el mundo. Los Smart Wearables son ejemplos de experiencias portables. Puede que quieras saber si un jugador lleva uno de estos, ya que un Smart Wearable puede permitir que los jugadores tengan habilidades que podrían considerarse trampas en un juego competitivo. Por ejemplo, en un juego de plataformas, un jugador que lleva un jetpack tiene una ventaja muy injusta sobre los demás.

Como creador de escenas, puede que quieras limitar lo que pueden hacer en tu escena los jugadores que lleven experiencias portables. Usa `getPortableExperiencesLoaded()` para comprobar si el jugador tiene alguna experiencia portable activada actualmente.

```ts
import { getPortableExperiencesLoaded } from '~system/PortableExperiences'

executeTask(async () => {
	let portableExperiences = await getPortableExperiencesLoaded({})
	console.log(portableExperiences.loaded)
})
```

`getPortableExperiencesLoaded()` devuelve un array de objetos; cada uno de estos objetos incluye un `id` atributo id. En el caso de los wearables, el id es el URN del wearable.

## Obtener información detallada sobre los wearables de un jugador

El `getPlayer()` La función solo devuelve una lista de ids de wearables, sin información sobre cada wearable. Quizá quieras comprobar cualquier wearable de una categoría específica (por ejemplo: hats), o cualquier wearable de una rareza específica (por ejemplo: Mythic); para eso tendrás que obtener información más detallada sobre los wearables del jugador.

Haz una [llamada REST API](/creator/content-creator-es/scenes-sdk7/networking/network-connections.md#call-a-rest-api) a la siguiente URL, para obtener una lista completa y actualizada de todos los wearables que se pueden usar actualmente, con detalles de cada uno.

`${playerRealm.realmInfo.baseUrl}/lambdas/collections/wearables-by-owner/${userData.userId}?includeDefinitions`

{% hint style="warning" %}
**📔 Nota**: Para construir esta URL, debes obtener el realm (probablemente con `getRealm()`) y el id del jugador (probablemente con `getPlayer()`)
{% endhint %}

Esta función podría usarse junto con la obtención de información sobre el jugador, para por ejemplo permitir que los jugadores entren en un lugar solo si llevan puesto cualquier wearable de la colección de Halloween, o cualquier wearable que tenga rareza *legendaria* rareza.

{% hint style="info" %}
**💡 Consejo**: Prueba la URL en un navegador para ver cómo está estructurada la respuesta.
{% endhint %}

```ts
import { getPlayer } from '@dcl/sdk/src/players'
import { getRealm } from '~system/Runtime'

async function fetchWearablesData() {
	try {
		let userData = getPlayer()
		const realm = await getRealm({})
		if (!userData || !realm.realmInfo) return

		const url =
			`${realm.realmInfo?.baseUrl}/lambdas/collections/wearables-by-owner/${userData.userId}?includeDefinitions`.toString()
		console.log('usando la URL: ', url)

		let response = await fetch(url)
		let json = await response.json()

		console.log('respuesta completa: ', json)
	} catch {
		console.log('ocurrió un error al intentar obtener los datos de los wearables')
	}
}

executeTask(fetchWearablesData)
```

{% hint style="info" %}
**💡 Consejo**: Puedes obtener aún más información sobre wearables específicos desde la [siguiente API](https://decentraland.github.io/catalyst-api-specs/#tag/Lambdas/operation/searchWearables).
{% endhint %}

## Comprobar el modo de cámara del jugador

Los jugadores pueden usar una cámara en primera o en tercera persona al explorar Decentraland. Comprueba cuál de estas está usando el jugador revisando el valor `CameraMode` componente de la `engine.CameraEntity` entidad.

```ts
function checkCameraMode() {
	if (!CameraMode.has(engine.CameraEntity)) return

	let cameraEntity = CameraMode.get(engine.CameraEntity)

	if (cameraEntity.mode == CameraType.CT_THIRD_PERSON) {
		console.log('El jugador está usando la cámara en 3ª persona')
	} else {
		console.log('El jugador está usando la cámara en 1ª persona')
	}
}

engine.addSystem(checkCameraMode)
```

{% hint style="warning" %}
**📔 Nota**: La información de la cámara solo está disponible para el jugador actual que ejecuta la escena. No puedes consultar los datos de cámara de ningún otro jugador.
{% endhint %}

El modo de cámara usa un valor del `CameraType` enum. Los siguientes valores son posibles:

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

El `CameraMode` componente de la `engine.CameraEntity` es de solo lectura; no puedes obligar al jugador a cambiar el modo de cámara a través de esto.

{% hint style="info" %}
**💡 Consejo**: Para cambiar el modo de cámara del jugador, usa una [área de modificación de cámara](/creator/content-creator-es/scenes-sdk7/fundamentos-del-contenido-3d/camera.md#1st-and-3rd-person-camera-modes).
{% endhint %}

Conocer el modo de cámara puede ser muy útil para ajustar con precisión la mecánica de tu escena y adaptarla mejor a lo que resulta más cómodo con este modo. Por ejemplo, los objetivos pequeños son más difíciles de clicar en tercera persona.

{% hint style="warning" %}
**📔 Nota**: Evita referirte a la `engine.CameraEntity` durante la carga inicial de la escena, porque eso puede provocar errores si las entidades aún no se han inicializado. Para evitar este problema, úsalo dentro de la `main()` función, o en una función llamada indirectamente por `main()`. También puedes encapsular el comportamiento en un async [`executeTask` bloque](/creator/content-creator-es/scenes-sdk7/patrones-de-programacion/async-functions.md#the-executetask-function).

Otra opción es referirse a esta entidad dentro de un sistema. Siempre estará disponible, porque la primera ejecución del sistema se llama una vez que la escena ya está correctamente inicializada.
{% endhint %}

## Comprobar si el jugador tiene el cursor bloqueado

Los jugadores pueden alternar entre dos modos de cursor: *cursor bloqueado* modo para controlar la cámara o *cursor desbloqueado* modo para mover el cursor libremente sobre la UI.

Los jugadores desbloquean el cursor haciendo clic en el *botón derecho del mouse* o presionando la *Esc* tecla, y vuelven a bloquear el cursor haciendo clic en cualquier parte de la pantalla.

Consulta la `PointerLock` componente de la [entidad de cámara de la escena](/creator/content-creator-es/scenes-sdk7/arquitectura/entities-components.md#reserved-entities) para averiguar cuál es el modo actual del cursor.

```ts
export function main() {
	const isLocked = PointerLock.get(engine.CameraEntity).isPointerLocked
	console.log(isLocked)
}
```

Consulta [Listeners de eventos](/creator/content-creator-es/scenes-sdk7/interactividad/event-listeners.md#player-locks-or-unlocks-cursor) para ver cómo reaccionar fácilmente a los cambios en el estado del cursor.

También puedes forzar el estado del cursor del jugador escribiendo en el `isPointerLocked` campo del `PointerLock` componente en `engine.CameraEntity`. Consulta [Bloquear o desbloquear el cursor](/creator/content-creator-es/scenes-sdk7/interactividad/eventos-de-button/click-events.md#lock-or-unlock-the-cursor) para ver ejemplos.

{% hint style="warning" %}
**📔 Nota**: Evita referirte a la `engine.CameraEntity` durante la carga inicial de la escena, porque eso puede provocar errores si las entidades aún no se han inicializado. Para evitar este problema, úsalo dentro de la `main()` función, o en una función llamada indirectamente por `main()`. También puedes encapsular el comportamiento en un async [`executeTask` bloque](/creator/content-creator-es/scenes-sdk7/patrones-de-programacion/async-functions.md#the-executetask-function).

Otra opción es referirse a la entidad dentro de un sistema. Siempre estará disponible, porque la primera ejecución del sistema se llama una vez que la escena ya está correctamente inicializada.
{% endhint %}

## Comprobar la posición del cursor del jugador

Usa el `PrimaryPointerInfo` componente en el `engine.RootEntity` para obtener la posición del cursor del jugador. Esto puede usarse para mecánicas como interacciones de arrastrar y soltar, gestos de deslizamiento, etc.

```ts
import { PrimaryPointerInfo } from '@dcl/sdk/ecs'

function CursorSystem() {
	const pointerInfo = PrimaryPointerInfo.get(engine.RootEntity)
	console.log(pointerInfo)
}

engine.addSystem(CursorSystem)
```

{% hint style="warning" %}
**📔 Nota**: Evita referirte a la `engine.RootEntity` durante la carga inicial de la escena, porque eso puede provocar errores si las entidades aún no se han inicializado. Para evitar este problema, refiérete siempre a la entidad dentro de un sistema. Siempre estará disponible, porque la primera ejecución del sistema se llama una vez que la escena ya está correctamente inicializada.
{% endhint %}

El `PrimaryPointerInfo` El componente devuelve un objeto con las siguientes propiedades:

* `screenCoordinates`: *(Vector2)* La posición del cursor en la escena, expresada en píxeles. El origen está en la esquina superior izquierda de la pantalla, con `y` creciendo hacia abajo — el mismo espacio de coordenadas que `UiTransform` y `UiCanvasInformation`. Cuando el cursor está bloqueado, esto informa del centro de la pantalla.
* `screenDelta`: *(Vector2)* El cambio en la posición del cursor desde el último frame, expresado en píxeles. [Movimiento del ratón](/creator/content-creator-es/scenes-sdk7/interactividad/mouse-movement.md) para obtener detalles y ejemplos.
* `worldRayDirection`: *(Vector3)* Un vector que representa la dirección del rayo desde la cámara hasta el cursor. El origen es la posición de la cámara. Úsalo para calcular la posición del cursor en el mundo.
* `pointerType`: 0 para `none`, 1 para `mouse`

{% hint style="info" %}
**💡 Consejo**: A diferencia de las otras propiedades, `screenDelta` sigue informando del movimiento del mouse incluso cuando el cursor está [bloqueado](/creator/content-creator-es/scenes-sdk7/interactividad/eventos-de-button/click-events.md#lock-or-unlock-the-cursor). Esto lo hace ideal para interacciones en tiempo real como gestos de arrastre y controles de cámara personalizados, consulta [Movimiento del ratón](/creator/content-creator-es/scenes-sdk7/interactividad/mouse-movement.md).
{% endhint %}

{% hint style="info" %}
**Consejo:** Para reaccionar a eventos simples de hover en elementos de la UI, puede que te resulte más fácil usar los `onMouseEnter` y `onMouseLeave` eventos, consulta [Eventos de botones de UI](/creator/content-creator-es/scenes-sdk7/ui-2d/ui_button_events.md#hover-feedback).
{% endhint %}

El `PrimaryPointerInfo` el componente es de solo lectura; no puedes obligar al jugador a cambiar la posición del cursor.

El siguiente ejemplo muestra cómo mostrar la posición del cursor en un elemento de UI.

***Archivo ui.tsx:***

```tsx
import { UiEntity, ReactEcs } from '@dcl/sdk/react-ecs'
import { Color4 } from '@dcl/sdk/math'
import {cursorXpos, cursorYpos} from './index'

export const uiMenu = () => (
  <UiEntity
    uiTransform={{
			width: '100%',
			height: '100px',
			justifyContent: 'center',
			alignItems: 'center',
    }}
    uiText={{ value: `Posición del cursor: `+  cursorXpos + `,` + cursorYpos, fontSize: 40 }}
    uiBackground={{ color: Color4.create(0.5, 0.8, 0.1, 0.6) }}
  />
)
```

***Archivo index.ts:***

```ts
import { engine, PrimaryPointerInfo } from '@dcl/sdk/ecs'
import { ReactEcsRenderer } from '@dcl/sdk/react-ecs'
import { uiMenu } from './ui'

export function main() {
  ReactEcsRenderer.setUiRenderer(uiMenu)
}

export let cursorXpos: number | undefined = undefined
export let cursorYpos: number | undefined = undefined

function CursorSystem() {
  const pointerInfo = PrimaryPointerInfo.get(engine.RootEntity)
  console.log(pointerInfo)

  cursorXpos = pointerInfo.screenCoordinates?.x
  cursorYpos = pointerInfo.screenCoordinates?.y
}

engine.addSystem(CursorSystem)
```

Puedes usar la `worldRayDirection` para establecer el `dirección` campo de un raycast para saber si una entidad está en la línea de visión del cursor. Consulta [Raycasting](/creator/content-creator-es/scenes-sdk7/interactividad/raycasting.md) para más detalles.


---

# 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-es/scenes-sdk7/interactividad/user-data.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.
