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

# Dados do usuário

## Posição e rotação do jogador

Usa o `PlayerEntity` e o `CameraEntity` para saber a posição e a rotação do jogador, verificando os seus `Transform` components.

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

	//posição do jogador
	const playerPos = Transform.get(engine.PlayerEntity).position

	//rotação do jogador
	const playerRot = Transform.get(engine.PlayerEntity).rotation

	//posição da câmera
	const CameraPos = Transform.get(engine.CameraEntity).position

	//rotação da câmera
	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)
```

* **posição do PlayerEntity**: A posição do avatar, à altura do peito. Aproximadamente a 0,88 cm acima do chão.
* **rotação do PlayerEntity**: A direção para a qual o avatar está virado, expressa como um quaternion.
* **posição do CameraEntity**:
  * Em 1.ª pessoa: Igual à posição do avatar, mas ao nível dos olhos. Aproximadamente a 1,75 cm acima do chão.
  * Em 3.ª pessoa: Pode variar consoante os movimentos da câmera.
* **rotação do PlayerEntity**:
  * Em 1.ª pessoa: Semelhante à direção para a qual o avatar está virado, expressa como um quaternion. Pode estar ligeiramente arredondada de forma diferente da rotação do jogador.
  * Em 3.ª pessoa: Pode variar consoante os movimentos da câmera.

{% hint style="warning" %}
**📔 Nota**: Evita referir o `engine.PlayerEntity` ou o `engine.CameraEntity` no carregamento inicial da scene, porque isso pode resultar em erros se as entities ainda não estiverem inicializadas. Para evitar este problema, usa-os dentro da `main()` função, ou numa função chamada indiretamente por `main()`. Também podes encapsular o comportamento num bloco assíncrono [`executeTask` Outro](/creator/content-creator-pt/scenes-sdk7/padroes-de-programacao/async-functions.md#the-executetask-function).

é referir estas entities dentro de um system. Aí estarão sempre disponíveis, porque a primeira execução do system é chamada assim que a scene já estiver devidamente inicializada.
{% endhint %}

## Obter todos os jogadores

Todos os jogadores na scene têm um `Transform` component. Este component é apenas de leitura nos avatars. Para obter as posições de todos os jogadores, [itera por todas as entities com](/creator/content-creator-pt/scenes-sdk7/interatividade/user-data.md) um `PlayerIdentityData` component.

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

for (const [entity, data, transform] of engine.getEntitiesWith(
	PlayerIdentityData,
	Transform
)) {
	console.log('Dados do jogador: ', { entity, data, transform })
}
```

O código acima itera por todas as entities com um `Transform` e um `PlayerIdentityData` component, e regista os respetivos dados. Podes usar este mesmo método para obter qualquer um dos dados disponíveis de todos os jogadores.

Vê [Event listeners](/creator/content-creator-pt/scenes-sdk7/interatividade/event-listeners.md#player-locks-or-unlocks-cursor) para aprender a detetar e reagir quando novos jogadores entram na scene.

## Obter dados do jogador

Usa `getPlayer()` para obter dados do jogador atual, ou de qualquer outro jogador na scene.

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

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

	let myPlayer = getPlayer()

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

`getPlayer()` devolve o seguinte:

* `name`: *(string)* O nome de utilizador do jogador, tal como os outros veem no mundo
* `userId`: *(string)* Uma string UUID que identifica o jogador. Se o jogador tiver uma public key, este campo terá o mesmo valor que a public key.
* `isGuest`: *(boolean)* Indica se o jogador tem uma public key. *True* se o jogador for uma conta de convidado sem public key.
* `position`: *(Vector3)* A posição do avatar na scene.
* `avatar`: Um objeto aninhado com dados sobre o avatar base e a aparência do jogador.
* `wearables`: Um array de identificadores para cada um dos wearables que o jogador está a usar atualmente. Por exemplo `urn:decentraland:off-chain:base-avatars:green_hoodie`. Todos os wearables têm um identificador semelhante, mesmo que sejam NFTs.
* `emotes`: Um array de identificadores para cada um dos emotes que o jogador tem atualmente equipados na roda de acesso rápido.
* `entity`: Uma referência para a entity do jogador. Isto pode ser útil para passar para outras funções ou para lhe adicionar components personalizados.

O `avatar` object tem a seguinte informação aninhada:

* `bodyShapeUrn`: Um identificador para a forma corporal geral do avatar. Seja `urn:decentraland:off-chain:base-avatars:BaseFemale` para feminino ou `urn:decentraland:off-chain:base-avatars:BaseMale` para masculino.
* `skinColor`: Cor da pele do jogador como um `Color4`
* `eyesColor`: Cor dos olhos do jogador como um `Color4`
* `hairColor`: Cor do cabelo do jogador como um `Color4`
* `name`: O nome do jogador.

{% hint style="warning" %}
**📔 Nota**: Os dados do jogador podem não estar disponíveis no primeiro frame da scene, dependendo dos tempos de carregamento. Deves verificar se os dados foram devolvidos e, caso contrário, tentar novamente alguns milissegundos mais tarde.
{% endhint %}

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

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

	let myPlayer = getPlayer()

	if (myPlayer) {
		console.log('É Convidado: ', myPlayer.isGuest)
		console.log('Nome : ', myPlayer.name)
		console.log('UserId : ', myPlayer.userId)
		console.log('Forma do avatar : ', myPlayer.position)
		console.log('Forma do avatar : ', myPlayer.avatar?.bodyShapeUrn)
		console.log('Cor dos olhos do avatar : ', myPlayer.avatar?.eyesColor)
		console.log('Cor do cabelo do avatar : ', myPlayer.avatar?.hairColor)
		console.log('Wearables ativos : ', myPlayer.wearables)
		console.log('Emotes disponíveis : ', myPlayer.emotes)
	}
}
```

{% hint style="info" %}
**💡 Dica**: Ao testar em preview com o editor web legado, para evitar usar um avatar aleatório, executa a scene no browser ligada à tua wallet Metamask.
{% endhint %}

Para obter os dados de um jogador específico na scene, diferente do jogador atual, executa `getPlayer()` com um objeto com uma propriedade `userId` .

```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('JOGADOR : ', player?.name)
}
```

O trecho acima itera por todas as entities com um `PlayerIdentityData` component, ou seja, todas as entities de avatar na scene. Depois executa o `getPlayer()` para essa entity.

`getPlayer()` só consegue obter dados de jogadores que estejam atualmente na mesma scene; não precisam de estar necessariamente dentro do alcance visual, mas devem estar ligados à mesma ilha de coms. Para testar isto em preview, abre um segundo separador e inicia sessão com uma conta diferente, e faz com que ambos os jogadores estejam dentro da scene.

{% hint style="warning" %}
**📔 Nota**: Os IDs de utilizador devem estar sempre em minúsculas. Se copiares um endereço de wallet, certifica-te de que todos os caracteres estão em minúsculas.
{% endhint %}

## Dados de qualquer jogador

Para obter informação de qualquer jogador, faz uma chamada [REST API](/creator/content-creator-pt/scenes-sdk7/networking/network-connections.md#call-a-rest-api) aos content servers.

Esta informação é exposta no seguinte URL, acrescentando o user id do jogador ao parâmetro da URL.

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

{% hint style="info" %}
**💡 Dica**: Experimenta o URL num browser para veres como a resposta está estruturada.
{% endhint %}

A seguinte informação está disponível nesta API:

* `displayName`: *(string)* O nome de utilizador do jogador, tal como os outros veem no mundo
* `userId`: *(string)* Uma string UUID que identifica o jogador. Se o jogador tiver uma public key, este campo terá o mesmo valor que a public key.
* `hasConnectedWeb3`: *(boolean)* Indica se o jogador tem uma public key. *True* se o jogador tiver um.
* `publicKey`: *(string)* A public key da wallet Ethereum do jogador. Se o jogador iniciar sessão como convidado, sem wallet ligada, este campo será `null`.
* `avatar`: Um objeto aninhado com dados sobre a aparência do jogador.
* `version`: *(number)* Um número de versão que aumenta em um sempre que o jogador altera qualquer uma das suas definições. Usa isto se encontrares dados em conflito, para saber qual a versão mais recente.

{% hint style="warning" %}
**📔 Nota**: Para quaisquer transações Ethereum com o jogador, usa sempre o `publicKey` campo, em vez do `userId`, para evitar lidar com wallets inexistentes.
{% endhint %}

O `avatar` object tem a seguinte informação aninhada:

* `wearables`: `WearableId[]` Um array de identificadores para cada um dos wearables que o jogador está atualmente a usar. Por exemplo `urn:decentraland:off-chain:base-avatars:green_hoodie`. Todos os wearables têm um identificador semelhante, mesmo que sejam NFTs.
* `bodyShape`: Um identificador para a forma corporal geral do avatar. Seja `urn:decentraland:off-chain:base-avatars:BaseFemale` para feminino ou `urn:decentraland:off-chain:base-avatars:BaseMale` para masculino.
* `skinColor`: *ColorString* Um valor hex para a cor da pele do jogador.
* `hairColor`: *ColorString* Um valor hex para a cor do cabelo do jogador.
* `eyeColor`: *ColorString* Um valor hex para a cor dos olhos do jogador.
* `snapshots`: Um objeto aninhado com representações base64 de imagens .jpg do jogador em várias resoluções.
  * `face256`: *string* O rosto do jogador como uma imagem de 256x256 pixels.
  * `body`: *string* A imagem em resolução total do jogador de pé direito, com 512x1024 pixels.

{% hint style="danger" %}
**❗Aviso** Os snapshots do avatar serão descontinuados no futuro e deixarão de ser devolvidos como parte dos dados de um avatar. A abordagem recomendada é usar `AvatarTexture` em vez disso, vê [Avatar Portraits](/creator/content-creator-pt/scenes-sdk7/essenciais-de-conteudo-3d/materials.md#avatar-portraits).
{% endhint %}

Ao contrário de `getPlayer()`, esta opção não está limitada apenas aos jogadores que estão atualmente na mesma scene, ou mesmo no mesmo server. Com esta abordagem podes obter dados de qualquer jogador que tenha iniciado sessão nos servers no passado.

Se souberes a que server o jogador que queres consultar está ligado, podes obter dados mais atualizados enviando os teus pedidos para esse server específico. Por exemplo, se o jogador mudar de roupa, esta informação estará disponível instantaneamente no server do jogador, mas provavelmente demorará alguns minutos a propagar-se para o `peer.decentraland.org` server.

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

{% hint style="info" %}
**💡 Dica**: Podes obter o server do jogador atual ao obter `getRealm().domain`.
{% endhint %}

Este exemplo combina `myProfile.userId` e `getRealm()` para obter os dados do jogador diretamente a partir do server em que o jogador se encontra:

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

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

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

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

		console.log('resposta completa: ', json)
		console.log(
			'jogador está a usar :',
			json[0].metadata.avatars[0].avatar.wearables
		)
		console.log('jogador possui :', json[0].metadata.avatars[0].inventory)
	} catch {
		console.log('ocorreu um erro ao tentar obter os dados do jogador')
	}
}

fetchPlayerData()
```

## Componentes dos dados do jogador

Em vez de usar `getPlayer()`, podes ler dados diretamente de uma série de components que guardam os dados em cada entity de jogador. Existem os seguintes components:

* `PlayerIdentityData`: Guarda o endereço do jogador e uma propriedade `isGuest` para assinalar contas de convidado.
* `AvatarBase`: Guarda dados sobre o avatar base, incluindo:
  * `name`: O nome do jogador.
  * `bodyShapeUrn`: Os ids correspondentes ao tipo de corpo masculino ou feminino.
  * `skinColor`: Cor da pele do jogador como um `Color4`
  * `eyeColor`: Cor dos olhos do jogador como um `Color4`
  * `hairColor`: Cor do cabelo do jogador como um `Color4`
* `AvatarEquippedData`: A lista de wearables e emotes equipados.
  * `wearableUrns`: A lista de wearables que o jogador tem atualmente equipados.
  * `emoteUrns`: A lista de emotes que o jogador tem atualmente equipados na roda de acesso rápido.
* `AvatarEmoteCommand`: Informação sobre os emotes que o jogador está atualmente a reproduzir. Inclui:
  * `emoteUrn`: O URN do último emote reproduzido pelo jogador, desde que entrou na scene
  * `loop`: True se o emote estiver em loop
  * `timestamp`: A hora em que este emote foi acionado

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

{% hint style="warning" %}
**📔 Nota**: Todos estes components são apenas de leitura. Não podes alterar os seus valores a partir da scene.
{% endhint %}

## Obter Portable Experiences

As portable experiences são, essencialmente, scenes que não estão limitadas a parcels de terra. Os jogadores podem levá-las consigo para qualquer lugar em que vão em Decentraland, adicionando uma nova camada de conteúdo sobre o mundo. Smart Wearables são exemplos de portable experiences. Podes querer saber se um jogador está a usar uma destas, uma vez que um smart wearable pode permitir aos jogadores ter habilidades que poderiam ser consideradas batota num jogo competitivo. Por exemplo, num jogo de plataforma, um jogador que usa um jetpack tem uma vantagem muito injusta sobre os outros.

Como criador de uma scene, podes querer limitar o que os jogadores que usam portable experiences podem fazer na tua scene. Usa `getPortableExperiencesLoaded()` para verificar se o jogador tem atualmente alguma portable experience ativada.

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

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

`getPortableExperiencesLoaded()` devolve um array de objetos, e cada um destes objetos inclui um atributo `id` . No caso dos wearables, o id é o URN do wearable.

## Obter informação detalhada sobre os wearables de um jogador

O `getPlayer()` a função devolve apenas uma lista de ids de wearables, sem informação sobre cada wearable. Talvez queiras verificar qualquer wearable de uma categoria específica (por exemplo: hats), ou qualquer wearable de uma raridade específica (por exemplo: Mythic); para isso vais precisar de obter informação mais detalhada sobre os wearables do jogador.

Faz uma [REST API](/creator/content-creator-pt/scenes-sdk7/networking/network-connections.md#call-a-rest-api) para o seguinte URL, para obter uma lista completa e atualizada de todos os wearables que estão atualmente utilizáveis, com detalhes sobre cada um.

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

{% hint style="warning" %}
**📔 Nota**: Para construir este URL, tens de obter o realm (provavelmente com `getRealm()`e o id do jogador (provavelmente com `getPlayer()`)
{% endhint %}

Esta funcionalidade pode ser usada em conjunto com a obtenção de informação sobre o jogador, para, por exemplo, só permitir que os jogadores entrem num local se estiverem a usar qualquer wearable da coleção de halloween, ou qualquer wearable de raridade *legendary* .

{% hint style="info" %}
**💡 Dica**: Experimenta o URL num browser para veres como a resposta está estruturada.
{% 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({})

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

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

		console.log('resposta completa: ', json)
	} catch {
		console.log('ocorreu um erro ao tentar obter os dados dos wearables')
	}
}

executeTask(fetchWearablesData)
```

{% hint style="info" %}
**💡 Dica**: Podes obter ainda mais informação sobre wearables específicos a partir da [seguinte API](https://decentraland.github.io/catalyst-api-specs/#tag/Lambdas/operation/searchWearables).
{% endhint %}

## Verifica o modo de câmera do jogador

Os jogadores podem usar uma câmera em 1.ª ou 3.ª pessoa quando exploram Decentraland. Verifica qual destas o jogador está a usar verificando o valor `CameraMode` component da `engine.CameraEntity` entity.

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

	let cameraEntity = CameraMode.get(engine.CameraEntity)

	if (cameraEntity.mode == CameraType.CT_THIRD_PERSON) {
		console.log('O jogador está a usar a câmera em 3.ª pessoa')
	} else {
		console.log('O jogador está a usar a câmera em 1.ª pessoa')
	}
}

engine.addSystem(checkCameraMode)
```

{% hint style="warning" %}
**📔 Nota**: A informação da câmera só está disponível para o jogador atual que está a executar a scene. Não podes consultar os dados da câmera de qualquer outro jogador.
{% endhint %}

O modo da câmera usa um valor do `CameraType` enum. Os seguintes valores são possíveis:

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

O `CameraMode` component da `engine.CameraEntity` é apenas de leitura, não podes forçar o jogador a mudar o modo da câmera através disto.

{% hint style="info" %}
**💡 Dica**: Para mudar o modo da câmera do jogador, usa uma [Área de modificador de câmera](/creator/content-creator-pt/scenes-sdk7/essenciais-de-conteudo-3d/camera.md#1st-and-3rd-person-camera-modes).
{% endhint %}

Saber o modo da câmera pode ser muito útil para afinar os mecanismos da tua scene e ajustá-los melhor ao que é mais confortável ao usar este modo. Por exemplo, alvos pequenos são mais difíceis de clicar em 3.ª pessoa.

{% hint style="warning" %}
**📔 Nota**: Evita referir o `engine.CameraEntity` no carregamento inicial da scene, porque isso pode resultar em erros se as entities ainda não estiverem inicializadas. Para evitar este problema, usa-os dentro da `main()` função, ou numa função chamada indiretamente por `main()`. Também podes encapsular o comportamento num bloco assíncrono [`executeTask` Outro](/creator/content-creator-pt/scenes-sdk7/padroes-de-programacao/async-functions.md#the-executetask-function).

Outra opção é referir esta entity dentro de um system. Ela estará sempre disponível, porque a primeira execução do system é chamada assim que a scene já estiver devidamente inicializada.
{% endhint %}

## Verifica se o cursor do jogador está bloqueado

Os jogadores podem alternar entre dois modos de cursor: *cursor bloqueado* para controlar a câmera ou *cursor desbloqueado* para mover o cursor livremente sobre a UI.

Os jogadores desbloqueiam o cursor ao clicar no *botão direito do rato* ou ao premir a tecla *Esc* , e bloqueiam o cursor novamente ao clicar em qualquer parte do ecrã.

Verifica o `PointerLock` component da [entity da câmera](/creator/content-creator-pt/scenes-sdk7/arquitetura/entities-components.md#reserved-entities) da scene para descobrir qual é o modo atual do cursor.

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

Vê [Event listeners](/creator/content-creator-pt/scenes-sdk7/interatividade/event-listeners.md#player-locks-or-unlocks-cursor) para ver como reagir facilmente a alterações no estado do cursor.

Também podes forçar o estado do cursor do jogador escrevendo no `isPointerLocked` campo do `PointerLock` component em `engine.CameraEntity`. Vê [Bloquear ou desbloquear o cursor](/creator/content-creator-pt/scenes-sdk7/interatividade/eventos-de-botao/click-events.md#lock-or-unlock-the-cursor) para exemplos.

{% hint style="warning" %}
**📔 Nota**: Evita referir o `engine.CameraEntity` no carregamento inicial da scene, porque isso pode resultar em erros se as entities ainda não estiverem inicializadas. Para evitar este problema, usa-os dentro da `main()` função, ou numa função chamada indiretamente por `main()`. Também podes encapsular o comportamento num bloco assíncrono [`executeTask` Outro](/creator/content-creator-pt/scenes-sdk7/padroes-de-programacao/async-functions.md#the-executetask-function).

Outra opção é referir a entity dentro de um system. Ela estará sempre disponível, porque a primeira execução do system é chamada assim que a scene já estiver devidamente inicializada.
{% endhint %}

## Verifica a posição do cursor do jogador

Usa o `primaryPointerInfo` component na `engine.RootEntity` para obter a posição do cursor do jogador. Isto pode ser usado para mecânicas como interações de drag and drop, gestos de swipe, 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 referir o `engine.RootEntity` no carregamento inicial da scene, porque isso pode resultar em erros se as entities ainda não estiverem inicializadas. Para evitar este problema, refere sempre a entity dentro de um system. Ela estará sempre disponível, porque a primeira execução do system é chamada assim que a scene já estiver devidamente inicializada.
{% endhint %}

O `primaryPointerInfo` component devolve um objeto com as seguintes propriedades:

* `screenCoordinates`: *(Vector2)* A posição do cursor na scene, expressa em pixels. A origem é o canto superior esquerdo do ecrã.
* `screenDelta`: *(Vector2)* A variação na posição do cursor desde o frame anterior, expressa em pixels.
* `worldRayDirection`: *(Vector3)* Um vetor que representa a direção do raio da câmera até ao cursor. A origem é a posição da câmera. Usa isto para calcular a posição do cursor no mundo.
* `pointerType`: 0 para `none`, 1 para `mouse`

{% hint style="info" %}
**💡 Dica**: Para reagir a eventos simples de hover em elementos da UI, pode ser mais fácil usar os eventos `onMouseEnter` e `onMouseLeave` , vê [UI Button Events](/creator/content-creator-pt/scenes-sdk7/ui-2d/ui_button_events.md#hover-feedback).
{% endhint %}

O `primaryPointerInfo` component é apenas de leitura, não podes forçar o jogador a alterar a posição do cursor.

O exemplo seguinte mostra como apresentar a posição do cursor num elemento da UI.

***ficheiro 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: `Cursor pos: `+  cursorXpos + `,` + cursorYpos, fontSize: 40 }}
    uiBackground={{ color: Color4.create(0.5, 0.8, 0.1, 0.6) }}
  />
)
```

***ficheiro index.ts:***

```ts
import { engine } 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)
```

Podes usar o `worldRayDirection` para definir o `direction` campo de um raycast para saber se uma entity está na linha de visão do cursor. Vê [Raycasting](/creator/content-creator-pt/scenes-sdk7/interatividade/raycasting.md) para mais detalhes.


---

# 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-pt/scenes-sdk7/interatividade/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.
