> 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 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('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 está mirando 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 está mirando el avatar, expresada como un quaternion. Puede redondearse ligeramente de forma 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 `engine.PlayerEntity` o a `engine.CameraEntity` durante la carga inicial de la scene, porque eso puede provocar errores si las entities aún no están inicializadas. Para evitar este problema, usa esto dentro de la `main()` función, o en una función llamada indirectamente por `main()`. También puedes encapsular el comportamiento en un bloque async [`executeTask` block](/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 avatares. 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 player: ', { 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 [Event listeners](/creator/content-creator-es/escenas-sdk7/interactividad/event-listeners.md#player-locks-or-unlocks-cursor) para aprender cómo detectar y reaccionar cuando nuevos players se unan a la scene.

## Obtener datos del player

Usa `getPlayer()` para obtener datos del player actual, o de cualquier otro player 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('UserId : ', myPlayer.userId)
	}
}
```

`getPlayer()` devuelve lo siguiente:

* `name`: *(string)* El nombre de usuario del player, tal como otros lo ven en el mundo
* `userId`: *(string)* Una string que identifica al player. Para players 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 player tiene una clave pública. *True* si el player 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 player.
* `wearables`: Un array de identificadores para cada uno de los wearables que el player lleva puestos 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 player tiene equipados actualmente en la rueda de acceso rápido.
* `entity`: Una referencia a la entity del player. Esto puede ser útil para pasarla a otras funciones, o para añadirle components personalizados.

El `avatar` object tiene la siguiente información anidada:

* `bodyShapeUrn`: Un identificador para la forma corporal general 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 player como un `Color3`
* `eyesColor`: Color de ojos del player como un `Color3`
* `hairColor`: Color de pelo del player como un `Color3`
* `name`: El nombre del player.

{% hint style="warning" %}
**📔 Nota**: Es posible que los datos del player no estén disponibles en el primer frame de la scene, dependiendo de los tiempos de carga. Debes verificar que los datos se hayan devuelto 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('UserId : ', 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)
	}
}
```

{% hint style="info" %}
**💡 Consejo**: Al probar en preview con el editor web heredado, para evitar usar un avatar aleatorio, ejecuta la scene en el navegador conectado con tu wallet de Metamask.
{% endhint %}

Para obtener los datos de un player específico en la scene, diferente del player 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('PLAYER : ', player?.name)
}
```

El snippet anterior itera sobre todas las entities con un `PlayerIdentityData` component, lo que significa todas las avatar entities en la scene. Luego ejecuta el `getPlayer()` para esa entity.

`getPlayer()` solo puede obtener datos de players que estén actualmente dentro de la misma scene, no hace falta que estén necesariamente dentro del rango visual, pero sí deben estar conectados a la misma comms island. Para probar esto 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, haz una [llamada a la REST API](/creator/content-creator-es/escenas-sdk7/redes/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 browser para ver cómo está estructurada la response.
{% endhint %}

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

* `displayName`: *(string)* El nombre de usuario del player, tal como otros lo ven en el mundo
* `userId`: *(string)* Una string 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 player tiene una clave pública. *True* si el player tiene una.
* `publicKey`: *(string)* La clave pública de la wallet 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 en conflicto, 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` campo, en lugar del `userId`, para evitar lidiar con wallets inexistentes.
{% endhint %}

El `avatar` object tiene la siguiente información anidada:

* `wearables`: `WearableId[]` Un array de identificadores para cada uno de los wearables que el player lleva puestos 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. 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` campo, 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` campo, 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` campo, 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 en base64 de imágenes .jpg del player en varias resoluciones.
  * `face256`: *string* La cara del player como una imagen de 256x256 píxeles.
  * `body`: *string* La imagen a 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 dejarán de devolverse 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/conceptos-basicos-de-contenido-3d/materials.md#avatar-portraits).
{% endhint %}

A diferencia de `getPlayer()`, esta opción no se limita solo a los players que están actualmente 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 response.
{% endhint %}

Este ejemplo combina `myProfile.userId` y `getRealm()` para obtener los datos del player directamente desde el server en el que está 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('response completa: ', json)
		console.log('el player lleva puesto :', json.avatars[0].avatar.wearables)
	} catch {
		console.log('se produjo un error al intentar obtener datos del player')
	}
}

fetchPlayerData()
```

## Componentes de datos del player

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

* `PlayerIdentityData`: Almacena la dirección del player y una `isGuest` propiedad para marcar cuentas de invitado.
* `AvatarBase`: Almacena datos sobre el avatar base, incluyendo:
  * `name`: El nombre del player.
  * `bodyShapeUrn`: Los ids correspondientes al tipo de cuerpo masculino o femenino.
  * `skinColor`: Color de piel del player como un `Color3`
  * `eyesColor`: Color de ojos del player como un `Color3`
  * `hairColor`: Color de pelo del player como un `Color3`
* `AvatarEquippedData`: La lista de wearables y emotes equipados.
  * `wearableUrns`: La lista de wearables que el player tiene equipados actualmente.
  * `emoteUrns`: La lista de emotes que el player 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`: True si el emote se está reproduciendo en loop
  * `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 experiencias portátiles

Las experiencias portátiles son, esencialmente, scenes que no están restringidas a parcels de land. Los players pueden llevarlas consigo a donde vayan en Decentraland, añadiendo una nueva capa de contenido sobre el World. Smart Wearables son ejemplos de experiencias portátiles. Quizá quieras saber si un player lleva una de estas, ya que un smart wearable puede permitir que los players tengan habilidades que podrían considerarse trampa en un juego competitivo. Por ejemplo, en un juego de plataformas, un player que lleva un jetpack tiene una ventaja muy injusta sobre los demás.

Como creador de una scene, quizá quieras limitar lo que los players que llevan experiencias portátiles pueden hacer en tu scene. Usa `getPortableExperiencesLoaded()` para comprobar si el player tiene alguna experiencia portátil activada actualmente.

```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()` 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 (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 a la REST API](/creator/content-creator-es/escenas-sdk7/redes/network-connections.md#call-a-rest-api) llamada a la siguiente URL, para obtener una lista completa y actualizada de todos los wearables que se pueden usar actualmente, 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, por ejemplo para permitir que los players entren en un lugar solo si llevan cualquier wearable de la colección de halloween, o cualquier wearable que sea de *legendary* rareza.

{% hint style="info" %}
**💡 Consejo**: Prueba la URL en un browser para ver cómo está estructurada la response.
{% 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('response completa: ', json)
	} catch {
		console.log('se produjo un error al intentar obtener 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 de la `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 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 de la `engine.CameraEntity` es de solo lectura, no puedes obligar 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 una [Camera modifier area](/creator/content-creator-es/escenas-sdk7/conceptos-basicos-de-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 scene y adaptarla mejor a lo que resulte más cómodo usando este modo. Por ejemplo, los objetivos pequeños son más difíciles de pulsar en 3.ª persona.

{% hint style="warning" %}
**📔 Nota**: Evita referirte a `engine.CameraEntity` durante la carga inicial de la scene, porque eso puede provocar errores si las entities aún no están inicializadas. Para evitar este problema, usa esto dentro de la `main()` función, o en una función llamada indirectamente por `main()`. También puedes encapsular el comportamiento en un bloque async [`executeTask` block](/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 players pueden alternar entre dos modos de cursor: *cursor bloqueado* modo para controlar la camera 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 el `PointerLock` componente de la [entidad de cámara](/creator/content-creator-es/escenas-sdk7/arquitectura/entities-components.md#reserved-entities) de la escena 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 [Event listeners](/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 jugador escribiendo en el `isPointerLocked` campo del `PointerLock` componente 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 `engine.CameraEntity` durante la carga inicial de la scene, porque eso puede provocar errores si las entities aún no están inicializadas. Para evitar este problema, usa esto dentro de la `main()` función, o en una función llamada indirectamente por `main()`. También puedes encapsular el comportamiento en un bloque async [`executeTask` block](/creator/content-creator-es/escenas-sdk7/patrones-de-programacion/async-functions.md#the-executetask-function).

Otra opción es hacer referencia 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 %}

## Consulta 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 se puede usar 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 `engine.RootEntity` en la carga inicial de la escena, porque eso puede generar errores si las entidades aún no están inicializadas. Para evitar este problema, haz siempre referencia 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 es la esquina inferior izquierda de la pantalla. Cuando el cursor está bloqueado, esto muestra el 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 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 mientras el cursor está [bloqueado](/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 arrastrar 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 simples de hover en elementos de la UI, puede que te resulte más fácil usar los eventos `onMouseEnter` y `onMouseLeave` ; consulta [UI Button Events](/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 la 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 el `worldRayDirection` para establecer el `direction` 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/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.
