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

# Datos del usuario

## Posición y rotación del jugador

Usa el `PlayerEntity` y el `CameraEntity` para conocer la posición y la rotación del jugador, comprobando sus `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('posiciónJugador: ', playerPos)
	console.log('rotaciónJugador: ', playerRot)
	console.log('posiciónCámara: ', CameraPos)
	console.log('rotaciónCámara: ', 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 ligeramente de forma distinta de 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 la `engine.CameraEntity` en la carga inicial de la scene, porque eso puede provocar errores si las entities aún no se han inicializado. Para evitar este problema, usa estas 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/escenas-sdk7/patrones-de-programacion/async-functions.md#the-executetask-function).

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

## Obtener todos los players

Todos los players en la scene tienen un `Transform` component. Este component es de solo lectura en los avatars. Para obtener las posiciones de todos los players, [itera sobre todas las entities con](/creator/content-creator-es/escenas-sdk7/interactividad/user-data.md) un `PlayerIdentityData` component.

```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 entities con un `Transform` y un `PlayerIdentityData` component, y registra sus datos. Puedes usar este mismo método para obtener cualquiera de los datos disponibles de todos los players.

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

## Obtener datos del jugador

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

```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('Id de usuario : ', myPlayer.userId)
	}
}
```

`getPlayer()` devuelve lo siguiente:

* `name`: *(string)* El nombre de usuario del jugador, tal como otros lo ven en el mundo
* `userId`: *(string)* Una cadena que identifica al jugador. Para jugadores conectados con una wallet, esta es la dirección de la wallet, escrita en minúsculas. Para 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.
* `position`: *(Vector3)* La posición del avatar en la scene.
* `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 lleva 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.
* `entity`: Una referencia a la entity del jugador. Esto puede ser útil para pasarlo a otras functions, o para añadirle components personalizados.

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

* `bodyShapeUrn`: Un identificador para la forma general del cuerpo del avatar. Puede ser `urn:decentraland:off-chain:base-avatars:BaseFemale` para femenino o `urn:decentraland:off-chain:base-avatars:BaseMale` para masculino.
* `skinColor`: Color de piel del jugador como un `Color3`
* `eyesColor`: Color de ojos del jugador como un `Color3`
* `hairColor`: Color de pelo del jugador como un `Color3`
* `name`: El nombre del jugador.

{% hint style="warning" %}
**📔 Nota**: Los datos del jugador pueden no estar disponibles en el primer frame de la scene, dependiendo de los tiempos de carga. Debes verificar que los datos se devolvieron y, si no, intentarlo de nuevo unos milisegundos más tarde.
{% 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('Id de usuario : ', myPlayer.userId)
		console.log('Forma del avatar : ', myPlayer.position)
		console.log('Forma del avatar : ', myPlayer.avatar?.bodyShapeUrn)
		console.log('Color de ojos del avatar : ', myPlayer.avatar?.eyesColor)
		console.log('Color de pelo 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 scene, diferente del jugador actual, ejecuta `getPlayer()` con un objeto con una `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 entities con un `PlayerIdentityData` component, es decir, todas las entities de avatar en la scene. Luego ejecuta el `getPlayer()` para esa entity.

`getPlayer()` solo puede obtener datos de players que actualmente están en la misma scene, no necesariamente tienen que estar en rango visual, pero sí deben estar conectados a la misma comms island. Para probarlo en Preview, abre una segunda pestaña e inicia sesión con una cuenta diferente, y haz que ambos players estén dentro de la scene.

{% hint style="warning" %}
**📔 Nota**: Los User IDs deben estar siempre 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 player

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

Esta información se expone en la siguiente URL, añadiendo el user id del player 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 en esta API:

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

{% hint style="warning" %}
**📔 Nota**: Para cualquier transacción de Ethereum con el player, usa siempre el `publicKey` field, 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 player lleva 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 general del cuerpo del avatar. Puede ser `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` field, que contiene el color de piel del player como `{ r, g, b, a }` números de 0 a 1.
* `hair`: Un objeto con un `color` field, que contiene el color de pelo del player como `{ r, g, b, a }` números de 0 a 1.
* `eyes`: Un objeto con un `color` field, que contiene el color de ojos del player como `{ r, g, b, a }` números de 0 a 1.
* `snapshots`: Un objeto anidado con representaciones base64 de imágenes .jpg del player en varias resoluciones.
  * `face256`: *string* El rostro del player como una imagen de 256x256 píxeles.
  * `body`: *string* La imagen en resolución completa del player de pie, con 512x1024 píxeles.

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

A diferencia de `getPlayer()`, esta opción no se limita solo a los players que actualmente están en la misma scene, ni siquiera en el mismo server. Con este enfoque puedes obtener datos de cualquier player que haya iniciado sesión en los servers en el pasado.

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

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

{% hint style="info" %}
**💡 Consejo**: Puedes obtener el server del player 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 player directamente desde el server en el que se encuentra el player:

```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 URL: ', url)

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

		console.log('respuesta completa: ', json)
		console.log('el player lleva puesto :', json.avatars[0].avatar.wearables)
	} catch {
		console.log('se produjo un error al acceder a los datos del player')
	}
}

fetchPlayerData()
```

## Components de datos del player

En lugar de usar `getPlayer()`, puedes leer datos directamente de una serie de components que almacenan los datos en cada player entity. Los siguientes components existen:

* `PlayerIdentityData`: Almacena la dirección del player y un `isGuest` propiedad para marcar 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`: Color de piel del jugador como un `Color3`
  * `eyesColor`: Color de ojos del jugador como un `Color3`
  * `hairColor`: Color de pelo 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 player está reproduciendo actualmente. Incluye:
  * `emoteUrn`: El URN del último emote reproducido por el player desde que entró en la scene
  * `loop`: Verdadero si el emote se está reproduciendo en bucle
  * `timestamp`: 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 PLAYER: ', { entity, data, transform, base, attach })
}
```

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

## Obtener Portable Experiences

Portable experiences son esencialmente scenes que no están limitadas a parcelas de land. Los players pueden llevarlas consigo a dondequiera que vayan en Decentraland, añadiendo una nueva capa de contenido sobre el world. Smart Wearables son ejemplos de portable experiences. Puede que quieras saber si un player lleva una de estas, ya que un smart wearable puede permitir a los players tener abilities que podrían considerarse cheating en un juego competitive. Por ejemplo, en un platform game, un player que lleva un jetpack tiene una ventaja muy injusta sobre los demás.

Como creador de scenes, quizá quieras limitar lo que pueden hacer en tu scene los players que llevan portable experiences. Usa `getPortableExperiencesLoaded()` para comprobar si el player tiene alguna portable experience actualmente activada.

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

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

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

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

El `getPlayer()` function devuelve solo una lista de ids de wearables, sin información sobre cada wearable. Tal vez quieras comprobar cualquier wearable de una categoría específica (p. ej., hats), o cualquier wearable de una rareza específica (p. ej., Mythic); para eso necesitarás obtener información más detallada sobre los wearables del player.

Haz una [llamada REST API](/creator/content-creator-es/escenas-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 actualmente se pueden usar, con detalles sobre 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 player (probablemente con `getPlayer()`)
{% endhint %}

Esta función podría usarse junto con la obtención de información sobre el player, para por ejemplo permitir que los players entren en un lugar solo si llevan puesto cualquier wearable de la colección de Halloween, o cualquier wearable que sea de *legendary* rarity.

{% 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 URL: ', url)

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

		console.log('respuesta completa: ', json)
	} catch {
		console.log('se produjo un error al acceder a los datos de 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 player

Los players pueden estar usando una cámara en 1.ª o 3.ª persona al explorar Decentraland. Comprueba cuál de estas está usando el player verificando el valor `CameraMode` component del `engine.CameraEntity` entity.

```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 player está usando la cámara en 3.ª persona')
	} else {
		console.log('El player 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 player actual que ejecuta la scene. No puedes consultar los datos de la cámara de ningún otro player.
{% 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` component del `engine.CameraEntity` es de solo lectura; no puedes forzar al player a cambiar el modo de cámara a través de esto.

{% hint style="info" %}
**💡 Consejo**: Para cambiar el modo de cámara del player, usa un [Camera modifier area](/creator/content-creator-es/escenas-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 finamente la mecánica de tu scene y adaptarla mejor a lo que resulte más cómodo al usar este modo. Por ejemplo, los objetivos pequeños son más difíciles de hacer clic en 3.ª persona.

{% hint style="warning" %}
**📔 Nota**: Evita referirte a la `engine.CameraEntity` en la carga inicial de la scene, porque eso puede provocar errores si las entities aún no se han inicializado. Para evitar este problema, usa estas 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/escenas-sdk7/patrones-de-programacion/async-functions.md#the-executetask-function).

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

## Comprobar si el player tiene el cursor bloqueado

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

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

Comprueba el `PointerLock` component de la [camera entity](/creator/content-creator-es/escenas-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 [Escuchadores de eventos](/creator/content-creator-es/escenas-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 player escribiendo en el `isPointerLocked` campo del `PointerLock` component en `engine.CameraEntity`. Consulta [Bloquear o desbloquear el cursor](/creator/content-creator-es/escenas-sdk7/interactividad/eventos-de-boton/click-events.md#lock-or-unlock-the-cursor) para ver ejemplos.

{% hint style="warning" %}
**📔 Nota**: Evita referirte a la `engine.CameraEntity` en la carga inicial de la scene, porque eso puede provocar errores si las entities aún no se han inicializado. Para evitar este problema, usa estas 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/escenas-sdk7/patrones-de-programacion/async-functions.md#the-executetask-function).

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

## Comprobar la posición del cursor del player

Usa el `PrimaryPointerInfo` component en el `engine.RootEntity` para obtener la posición del cursor del player. Esto puede usarse para mecánicas como interacciones de drag and drop, 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` en la carga inicial de la scene, porque eso puede provocar errores si las entities aún no se han inicializado. Para evitar este problema, refiérete siempre a la entity dentro de un system. Siempre estará disponible, porque la primera ejecución del system se llama una vez que la scene ya está correctamente inicializada.
{% endhint %}

El `PrimaryPointerInfo` el component devuelve un objeto con las siguientes propiedades:

* `screenCoordinates`: *(Vector2)* La posición del cursor en la scene, expresada en píxeles. El origen está en la esquina inferior izquierda de la pantalla. 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. Consulta [Mouse Movement](/creator/content-creator-es/escenas-sdk7/interactividad/mouse-movement.md) para más detalles y ejemplos.
* `worldRayDirection`: *(Vector3)* Un vector que representa la dirección del ray desde la cámara hasta el cursor. El origen es la posición de la cámara. Usa esto para calcular la posición del cursor en el world.
* `pointerType`: 0 para `none`, 1 para `mouse`

{% hint style="info" %}
**💡 Consejo**: A diferencia de las otras properties, `screenDelta` sigue informando del movimiento del mouse incluso cuando el cursor está [locked](/creator/content-creator-es/escenas-sdk7/interactividad/eventos-de-boton/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 [Mouse Movement](/creator/content-creator-es/escenas-sdk7/interactividad/mouse-movement.md).
{% endhint %}

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

El `PrimaryPointerInfo` el componente es de solo lectura, no puedes forzar 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 la `dirección` campo de un raycast para saber si una Entity está en la línea de visión del cursor. Ver [Raycasting](/creator/content-creator-es/escenas-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 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/interactividad/user-data.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.
