# Dados do Utilizador

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

Use o `PlayerEntity` quanto a `CameraEntity` saber a posição e a rotação do jogador, checando seu `Transform` componentes.

```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, na altura do peito. Aproximadamente 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 1,75 cm acima do chão.
  * Em 3ª pessoa: Pode variar dependendo dos movimentos da câmera.
* **Rotação do PlayerEntity**:
  * Em 1ª pessoa: Similar à direção para a qual o avatar está virado, expressa como um quaternion. Pode ser arredondada de forma ligeiramente diferente da rotação do jogador.
  * Em 3ª pessoa: Pode variar dependendo dos movimentos da câmera.

{% hint style="warning" %}
**📔 Nota**: Evite referir-se ao `engine.PlayerEntity` ou o `O exemplo a seguir traça um raio a partir da posição da câmera do jogador para frente, usando a` no carregamento inicial da cena, porque isso pode resultar em erros se as entidades ainda não estiverem inicializadas. Para evitar esse problema, use estes dentro do `main()` function, or on a function indirectly called by `main()`. You can also encapsulate the behavior in an async [`executeTask` block](https://docs.decentraland.org/creator/content-creator-pt/padroes-de-programacao/async-functions#the-executetask-function).

Outra opção é referir-se a essas entidades dentro de um sistema. Lá elas estarão sempre disponíveis, porque a primeira execução do sistema é chamada uma vez que a cena já está devidamente inicializada.
{% endhint %}

## Buscar todos os jogadores

Todos os jogadores na cena têm um `Transform` component. Este componente é somente leitura em avatares. Para obter as posições de todos os jogadores, [itera sobre todas as entidades com](https://docs.decentraland.org/creator/content-creator-pt/scenes-sdk7/interatividade/user-data) a `PlayerIdentityData` component.

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

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

O código acima itera sobre todas as entidades com um `Transform` e um `PlayerIdentityData` component, e registra seus dados. Você pode usar esse mesmo método para obter qualquer um dos dados disponíveis de todos os jogadores.

Veja [Listeners de eventos](https://docs.decentraland.org/creator/content-creator-pt/scenes-sdk7/event-listeners#player-locks-or-unlocks-cursor) para aprender como detectar e reagir quando novos jogadores entram na cena.

## Obter dados do jogador

Use `getPlayer()` para buscar dados sobre o jogador atual, ou qualquer outro jogador na cena.

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

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

	let myPlayer = getPlayer()

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

`getPlayer()` retorna o seguinte:

* `campo name`: *(string)* O nome de usuário do jogador, como os outros veem no mundo
* `userId`: *(string)* Uma string UUID que identifica o jogador. Se o jogador tiver uma chave pública, este campo terá o mesmo valor que a chave pública.
* `isGuest`: *(boolean)* Indica se o jogador tem uma chave pública. *True* se o jogador for uma conta guest sem chave pública.
* `position`: *(Vector3)* A posição do avatar na cena.
* `avatar`: Um objeto aninhado com dados sobre o avatar base do jogador e aparência.
* `wearables`: Um array de identificadores para cada um dos wearables que o jogador está usando atualmente. Por exemplo `urn:decentraland:off-chain:base-avatars:green_hoodie`. Todos os wearables têm um identificador similar, mesmo que sejam NFTs.
* `emotes`: Um array de identificadores para cada um dos emotes que o jogador tem equipado na roda de acesso rápido.
* `entidade`: Uma referência à entidade do jogador. Isso pode ser útil para passar para outras funções, ou para adicionar componentes personalizados a ela.

O `avatar` o objeto tem as seguintes informações aninhadas:

* `bodyShapeUrn`: Um identificador para a forma corporal geral do avatar. Either `urn:decentraland:off-chain:base-avatars:BaseFemale` for female or `urn:decentraland:off-chain:base-avatars:BaseMale` for male.
* `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`
* `campo name`: O nome do jogador.

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

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

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

	let myPlayer = getPlayer()

	if (myPlayer) {
		console.log('Is Guest: ', myPlayer.isGuest)
		console.log('Name : ', myPlayer.name)
		console.log('UserId : ', myPlayer.userId)
		console.log('Avatar shape : ', myPlayer.position)
		console.log('Avatar shape : ', myPlayer.avatar?.bodyShapeUrn)
		console.log('Avatar eyes color : ', myPlayer.avatar?.eyesColor)
		console.log('Avatar hair color : ', myPlayer.avatar?.hairColor)
		console.log('Wearables on : ', myPlayer.wearables)
		console.log('Emotes available : ', myPlayer.emotes)
	}
}
```

{% hint style="info" %}
**💡 Tip**: Ao testar em preview com o editor web legado, para evitar usar um avatar aleatório, execute a cena no navegador conectado com sua carteira Metamask.
{% endhint %}

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

```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)
}
```

O trecho acima itera sobre todas as entidades com um `PlayerIdentityData` component, significando todas as entidades de avatar na cena. Em seguida, executa o `getPlayer()` para essa entidade.

`getPlayer()` só pode buscar dados de jogadores que estejam atualmente na mesma cena; eles não precisam necessariamente estar em alcance visual, mas devem estar conectados à mesma ilha de comms. Para testar isso em preview, abra uma segunda aba e faça login com uma conta diferente, e faça ambos os jogadores ficarem dentro da cena.

{% hint style="warning" %}
**📔 Nota**: Os IDs de usuário devem sempre estar em letras minúsculas. Se copiar um endereço de carteira, certifique-se de que todos os caracteres estejam em minúsculas.
{% endhint %}

## Dados de qualquer jogador

Para obter informações de qualquer jogador, faça um [REST API call](https://docs.decentraland.org/creator/content-creator-pt/networking/network-connections#call-a-rest-api) aos servidores de conteúdo.

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

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

{% hint style="info" %}
**💡 Tip**: Experimente a URL em um navegador para ver como a resposta é estruturada.
{% endhint %}

As seguintes informações estão disponíveis a partir desta API:

* `displayName`: *(string)* O nome de usuário do jogador, como os outros veem no mundo
* `userId`: *(string)* Uma string UUID que identifica o jogador. Se o jogador tiver uma chave pública, este campo terá o mesmo valor que a chave pública.
* `hasConnectedWeb3`: *(boolean)* Indica se o jogador tem uma chave pública. *True* se o jogador tiver uma.
* `publicKey`: *(string)* A chave pública da carteira Ethereum do jogador. Se o jogador entrar como guest, sem carteira vinculada, 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 a cada vez que o jogador altera alguma de suas configurações. Use isto se você encontrar dados conflitantes, para saber qual versão é mais recente.

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

O `avatar` o objeto tem as seguintes informações aninhadas:

* `wearables`: `WearableId[]` Um array de identificadores para cada um dos wearables que o jogador está usando atualmente. Por exemplo `urn:decentraland:off-chain:base-avatars:green_hoodie`. Todos os wearables têm um identificador similar, mesmo que sejam NFTs.
* `bodyShape`: Um identificador para a forma corporal geral do avatar. Either `urn:decentraland:off-chain:base-avatars:BaseFemale` for female or `urn:decentraland:off-chain:base-avatars:BaseMale` for male.
* `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 em 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 em pé, com 512x1024 pixels.

{% hint style="danger" %}
**❗Aviso** As snapshots do avatar serão descontinuadas no futuro e não serão mais retornadas como parte dos dados do avatar. A abordagem recomendada é usar `AvatarTexture` em vez disso, veja [Retratos de Avatar](https://docs.decentraland.org/creator/content-creator-pt/essenciais-de-conteudo-3d/materials#avatar-portraits).
{% endhint %}

Ao contrário de `getPlayer()`, esta opção não está limitada apenas aos jogadores que estão atualmente na mesma cena, ou mesmo no mesmo servidor. Com esta abordagem você pode buscar dados de qualquer jogador que tenha feito login nos servidores no passado.

Se você souber em qual servidor o jogador que você quer consultar está conectado, pode obter dados mais atualizados enviando suas requisições para esse servidor específico. Por exemplo, se o jogador trocar de roupa, essa informação estará disponível instantaneamente no servidor do jogador, mas provavelmente levará alguns minutos para propagar-se ao `peer.decentraland.org` server.

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

{% hint style="info" %}
**💡 Tip**: Você pode obter o servidor do jogador atual buscando `getRealm().domain`.
{% endhint %}

Este exemplo combina `myProfile.userId` e `getRealm()` para obter os dados do jogador diretamente do servidor em que o jogador está:

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

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

		console.log('full response: ', json)
		console.log(
			'player is wearing :',
			json[0].metadata.avatars[0].avatar.wearables
		)
		console.log('player owns :', json[0].metadata.avatars[0].inventory)
	} catch {
		console.log('an error occurred while reaching for player data')
	}
}

fetchPlayerData()
```

## Componentes de dados do jogador

Ao invés de usar `getPlayer()`, você pode ler dados diretamente de uma série de componentes que armazenam os dados em cada entidade de jogador. Os seguintes componentes existem:

* `PlayerIdentityData`: Armazena o endereço do jogador e uma `isGuest` propriedade para sinalizar contas guest.
* `AvatarBase`: Armazena dados sobre o avatar base, incluindo:
  * `campo 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 equipado atualmente.
  * `emoteUrns`: A lista de emotes que o jogador tem equipado na roda de acesso rápido.
* `AvatarEmoteCommand`: Info sobre emotes que o jogador está reproduzindo no momento. Inclui:
  * `emoteUrn`: A URN do último emote reproduzido pelo jogador, desde que entrou na cena
  * `loop`: True se o emote está em loop
  * `timestamp`: O horário em que esse emote foi acionado

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

{% hint style="warning" %}
**📔 Nota**: Todos esses componentes são somente leitura. Você não pode alterar seus valores a partir da cena.
{% endhint %}

## Obter Portable Experiences

Portable experiences são essencialmente cenas que não estão restritas a parcelas de terra. Os jogadores podem levar essas experiências consigo para qualquer lugar em Decentraland, adicionando uma nova camada de conteúdo sobre o mundo. Smart Wearables são exemplos de portable experiences. Você pode querer saber se um jogador está usando um desses, já que um smart wearable pode permitir que jogadores tenham habilidades que poderiam ser consideradas trapaça em um jogo competitivo. Por exemplo, em um jogo de plataforma, um jogador que usa um jetpack tem uma vantagem muito injusta sobre os outros.

Como criador de cena, você pode querer limitar o que jogadores usando portable experiences podem fazer em sua cena. Use `getPortableExperiencesLoaded()` para verificar se o jogador tem alguma portable experience atualmente ativada.

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

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

`getPortableExperiencesLoaded()` retorna um array de objetos, cada um desses objetos inclui um atributo `id` . No caso de wearables, o id é a URN do wearable.

## Obter informações detalhadas sobre os wearables de um jogador

O `getPlayer()` A função retorna apenas uma lista de ids de wearables, sem informações sobre cada wearable. Talvez você queira verificar qualquer wearable de uma categoria específica (ex: chapéus), ou qualquer wearable de uma raridade específica (ex: Mythic); para isso você precisará buscar informações mais detalhadas sobre os wearables do jogador.

Faça um [REST API call](https://docs.decentraland.org/creator/content-creator-pt/networking/network-connections#call-a-rest-api) para a 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 esta URL, você deve obter o realm (provavelmente com `getRealm()`) e o id do jogador (provavelmente com `getPlayer()`)
{% endhint %}

Este recurso pode ser usado junto com a busca de informações sobre o jogador, para por exemplo permitir que jogadores entrem em um lugar somente se estiverem usando algum wearable da coleção de halloween, ou qualquer wearable que seja de *legendary* raridade.

{% hint style="info" %}
**💡 Tip**: Experimente a URL em um navegador para ver como a resposta é 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('using URL: ', url)

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

		console.log('full response: ', json)
	} catch {
		console.log('an error occurred while reaching for wearables data')
	}
}

executeTask(fetchWearablesData)
```

{% hint style="info" %}
**💡 Tip**: Você pode buscar ainda mais informações sobre wearables específicos a partir da [seguinte API](https://decentraland.github.io/catalyst-api-specs/#tag/Lambdas/operation/searchWearables).
{% endhint %}

## Verificar o modo de câmera do jogador

Os jogadores podem estar usando uma câmera em 1ª ou 3ª pessoa ao explorar Decentraland. Verifique qual desses o jogador está usando checando o valor do `CameraMode` componente do `O exemplo a seguir traça um raio a partir da posição da câmera do jogador para frente, usando a` entidade engine.CameraEntity

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

	let cameraEntity = CameraMode.get(engine.CameraEntity)

	if (cameraEntity.mode == CameraType.CT_THIRD_PERSON) {
		console.log('The player is using the 3rd person camera')
	} else {
		console.log('The player is using the 1st person camera')
	}
}

engine.addSystem(checkCameraMode)
```

{% hint style="warning" %}
**📔 Nota**: As informações da câmera estão disponíveis apenas para o jogador atual executando a cena. Você não pode consultar os dados da câmera de qualquer outro jogador.
{% endhint %}

O modo de 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` componente do `O exemplo a seguir traça um raio a partir da posição da câmera do jogador para frente, usando a` é somente leitura, você não pode forçar o jogador a mudar o modo de câmera através disso.

{% hint style="info" %}
**💡 Tip**: Para mudar o modo de câmera do jogador, use uma [Camera modifier area](https://docs.decentraland.org/creator/content-creator-pt/essenciais-de-conteudo-3d/camera#1st-and-3rd-person-camera-modes).
{% endhint %}

Saber o modo de câmera pode ser muito útil para ajustar finamente as mecânicas da sua cena para se adequarem melhor ao que é mais confortável nesse modo. Por exemplo, alvos pequenos são mais difíceis de clicar quando em 3ª pessoa.

{% hint style="warning" %}
**📔 Nota**: Evite referir-se ao `O exemplo a seguir traça um raio a partir da posição da câmera do jogador para frente, usando a` no carregamento inicial da cena, porque isso pode resultar em erros se as entidades ainda não estiverem inicializadas. Para evitar esse problema, use estes dentro do `main()` function, or on a function indirectly called by `main()`. You can also encapsulate the behavior in an async [`executeTask` block](https://docs.decentraland.org/creator/content-creator-pt/padroes-de-programacao/async-functions#the-executetask-function).

Outra opção é referir-se a esta entidade dentro de um sistema. Ela estará sempre disponível, porque a primeira execução do sistema é chamada uma vez que a cena já está devidamente inicializada.
{% endhint %}

## Verificar se o jogador tem o cursor bloqueado

Jogadores podem alternar entre dois modos de cursor: *cursor travado* modo para controlar a câmera ou *cursor destravado* modo para mover o cursor livremente sobre a UI.

Jogadores destravam o cursor clicando o *Botão direito do mouse* ou pressionando a tecla *Esc* e travam o cursor de volta clicando em qualquer lugar na tela.

Marque a `PointerLock` componente da [entidade da câmera](https://docs.decentraland.org/creator/content-creator-pt/arquitetura/entities-components#reserved-entities) para descobrir qual é o modo atual do cursor.

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

Veja [Listeners de eventos](https://docs.decentraland.org/creator/content-creator-pt/scenes-sdk7/event-listeners#player-locks-or-unlocks-cursor) para ver como reagir facilmente às mudanças no estado do cursor.

O `PointerLock` componente do `O exemplo a seguir traça um raio a partir da posição da câmera do jogador para frente, usando a` é somente leitura, você não pode forçar o jogador a bloquear ou desbloquear o cursor.

{% hint style="warning" %}
**📔 Nota**: Evite referir-se ao `O exemplo a seguir traça um raio a partir da posição da câmera do jogador para frente, usando a` no carregamento inicial da cena, porque isso pode resultar em erros se as entidades ainda não estiverem inicializadas. Para evitar esse problema, use estes dentro do `main()` function, or on a function indirectly called by `main()`. You can also encapsulate the behavior in an async [`executeTask` block](https://docs.decentraland.org/creator/content-creator-pt/padroes-de-programacao/async-functions#the-executetask-function).

Outra opção é referir-se à entidade dentro de um sistema. Ela estará sempre disponível, porque a primeira execução do sistema é chamada uma vez que a cena já está devidamente inicializada.
{% endhint %}

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

Use o `primaryPointerInfo` componente no `engine.RootEntity` para obter a posição do cursor do jogador. Isso pode ser usado para mecânicas como interações de arrastar e soltar, gestos de swipe, etc.

```ts
import { engine, Entity, InputAction, inputSystem, PointerEventType, RaycastQueryType, raycastSystem, TextShape, Transform } from '@dcl/sdk/ecs'

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

engine.addSystem(CursorSystem)
```

{% hint style="warning" %}
**📔 Nota**: Evite referir-se ao `engine.RootEntity` no carregamento inicial da cena, porque isso pode resultar em erros se as entidades não estiverem inicializadas ainda. Para evitar esse problema, sempre refira-se à entidade dentro de um sistema. Ela estará sempre disponível, porque a primeira execução do sistema é chamada uma vez que a cena já está devidamente inicializada.
{% endhint %}

O `primaryPointerInfo` o componente retorna um objeto com as seguintes propriedades:

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

{% hint style="info" %}
**💡 Tip**: Para reagir a eventos simples de hover em elementos de UI, pode ser mais fácil usar os `onMouseEnter` e `onMouseLeave` events, see [UI Button Events](https://docs.decentraland.org/creator/content-creator-pt/ui-2d/ui_button_events#hover-feedback).
{% endhint %}

O `primaryPointerInfo` o componente é somente leitura, você não pode forçar o jogador a mudar a posição do cursor.

O exemplo a seguir mostra como exibir a posição do cursor em um elemento de UI.

***arquivo 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) }}
  />
)
```

***arquivo 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)
```

Você pode usar o `worldRayDirection` para definir o campo `campo` de um raycast para saber se uma entidade está na linha de visão do cursor. Veja [Raycasting](https://docs.decentraland.org/creator/content-creator-pt/scenes-sdk7/interatividade/raycasting) para mais detalhes.
