Dados do usuário
Obtenha dados dos players conforme interagem com sua cena.
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.
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.
📔 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.
é 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.
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 um PlayerIdentityData component.
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 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.
getPlayer() devolve o seguinte:
name: (string) O nome de utilizador do jogador, tal como os outros veem no mundouserId: (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 exemplourn: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. Sejaurn:decentraland:off-chain:base-avatars:BaseFemalepara feminino ouurn:decentraland:off-chain:base-avatars:BaseMalepara masculino.skinColor: Cor da pele do jogador como umColor4eyesColor: Cor dos olhos do jogador como umColor4hairColor: Cor do cabelo do jogador como umColor4name: O nome do jogador.
📔 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.
💡 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.
Para obter os dados de um jogador específico na scene, diferente do jogador atual, executa getPlayer() com um objeto com uma propriedade userId .
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.
📔 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.
Dados de qualquer jogador
Para obter informação de qualquer jogador, faz uma chamada 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>
💡 Dica: Experimenta o URL num browser para veres como a resposta está estruturada.
A seguinte informação está disponível nesta API:
displayName: (string) O nome de utilizador do jogador, tal como os outros veem no mundouserId: (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.
📔 Nota: Para quaisquer transações Ethereum com o jogador, usa sempre o publicKey campo, em vez do userId, para evitar lidar com wallets inexistentes.
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 exemplourn: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. Sejaurn:decentraland:off-chain:base-avatars:BaseFemalepara feminino ouurn:decentraland:off-chain:base-avatars:BaseMalepara 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.
❗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.
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>
💡 Dica: Podes obter o server do jogador atual ao obter getRealm().domain.
Este exemplo combina myProfile.userId e getRealm() para obter os dados do jogador diretamente a partir do server em que o jogador se encontra:
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 propriedadeisGuestpara 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 umColor4eyeColor: Cor dos olhos do jogador como umColor4hairColor: Cor do cabelo do jogador como umColor4
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 sceneloop: True se o emote estiver em looptimestamp: A hora em que este emote foi acionado
📔 Nota: Todos estes components são apenas de leitura. Não podes alterar os seus valores a partir da scene.
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.
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 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
📔 Nota: Para construir este URL, tens de obter o realm (provavelmente com getRealm()e o id do jogador (provavelmente com getPlayer())
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 .
💡 Dica: Experimenta o URL num browser para veres como a resposta está estruturada.
💡 Dica: Podes obter ainda mais informação sobre wearables específicos a partir da seguinte API.
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.
📔 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.
O modo da câmera usa um valor do CameraType enum. Os seguintes valores são possíveis:
CameraType.CT_FIRST_PERSONCameraType.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.
💡 Dica: Para mudar o modo da câmera do jogador, usa uma Área de modificador de câmera.
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.
📔 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.
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.
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 da scene para descobrir qual é o modo atual do cursor.
Vê Event listeners 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 para exemplos.
📔 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.
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.
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.
📔 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.
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 paranone, 1 paramouse
💡 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.
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:
ficheiro index.ts:
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 para mais detalhes.
Atualizado