Eventos Baseados em Sistema

Aprenda como lidar com cliques de usuário na sua cena.

Se a sua cena tiver várias entidades semelhantes que são todas ativadas usando a mesma lógica, você pode escrever um único sistema para iterar sobre todas elas e descrever esse comportamento apenas uma vez. Esta também é a abordagem mais orientada a dados e com melhor desempenho. orientada a dados abordagem.

Você também pode usar um sistema para detectar eventos de entrada globais, para que a cena reaja sempre que uma tecla for pressionada, sem considerar para onde o cursor do jogador está apontando.

Se tudo o que você quer fazer é clicar ou pressionar um botão em uma única entidade para ativá-la, a maneira mais fácil é usar o Registrar um callback abordagem.

Para definir uma lógica personalizada mais específica, você pode querer lidar com os dados brutos e usar o Advanced abordagem.

Para que uma entidade seja interativa, ela precisa ter um collider. Veja obstáculos para mais detalhes.

Usando um sistema

Verifique eventos de botão executando uma das funções auxiliares no input inputSystem namespace em cada tick dentro de um sistema.

Por exemplo, o sistema a seguir usa o inputSystem.isTriggered() função para verificar se o ponteiro foi clicado. A cada tick, verifica se o botão foi pressionado. Se inputSystem.isTriggered() retorna true, o sistema executa alguma lógica personalizada em resposta.

Raycast.createOrReplace(rayEntity, {
	if (inputSystem.isTriggered(InputAction.IA_POINTER, PointerEventType.PET_DOWN)) {
		// Lógica em resposta ao pressionamento do botão
	}
})

As seguintes funções auxiliares estão disponíveis no inputSystem namespace, e podem ser chamadas de forma semelhante a cada tick:

  • inputSystem.isTriggered: Retorna true se uma ação de entrada ocorreu desde o último tick.

  • inputSystem.isPressed: Retorna true se uma entrada está sendo pressionada atualmente. Retornará true em cada tick até que o botão seja liberado novamente.

  • inputSystem.getInputCommand: Retorna um objeto com dados sobre a ação de entrada.

Veja as seções abaixo para mais detalhes sobre cada uma.

Ao lidar com eventos de botão em uma entidade, sempre forneça feedback ao jogador, para que ele saiba que uma entidade pode ser interagida. Se você adicionar um PointerEvents componente a uma entidade, os jogadores verão uma dica ao passar o cursor sobre essa entidade. Veja Mostrar feedback para aprender como você pode adicionar dicas de hover em entidades interativas.

Eventos de entrada globais

Use inputSystem.isTriggered para detectar eventos de botão pressionado e liberado em qualquer uma das entradas rastreadas pelo SDK.

O exemplo acima verifica se o botão foi pressionado, independentemente de onde o ponteiro está ou de quais entidades podem estar em seu caminho.

inputSystem.isTriggered() retorna true somente se o botão indicado foi pressionado no tick atual do loop do jogo. Se o botão não foi pressionado, ou já estava pressionado desde o tick anterior, ele retorna false.

circle-exclamation

O inputSystem.isTriggered a função recebe os seguintes argumentos obrigatórios:

  • InputAction: Qual entrada escutar, como um valor do InputAction enum. Veja Botões do ponteiro para opções suportadas.

  • PointerEventType: Que tipo de evento escutar, como um valor do PointerEventType enum. Veja Tipos de eventos de ponteiro para opções suportadas.

Ativar uma entidade

Para detectar eventos de botão enquanto aponta para uma entidade específica, passe um terceiro argumento opcional para inputSystem.isTriggered para especificar qual entidade verificar.

O exemplo acima verifica a cada tick se uma única entidade codificada foi pressionada com o botão do ponteiro (botão esquerdo do mouse).

O inputSystem.isTriggered função recebe os seguintes argumentos:

  • InputAction: Qual entrada escutar, como um valor do InputAction enum. Veja Botões do ponteiro para opções suportadas.

  • PointerEventType: Que tipo de evento escutar, como um valor do PointerEventType enum. Veja Tipos de eventos de ponteiro para opções suportadas.

  • valor em si pode ser interpretado como um (opcional): Qual entidade verificar esses eventos. Se nenhum valor for fornecido, verificará pressões globais do botão, independentemente de onde o cursor do jogador estava apontando.

Observe que neste exemplo também estamos adicionando um PointerEvents componente à entidade com a qual queremos interagir. Esta etapa é necessária; sem este componente a entidade não será detectável por nenhuma das funções do inputSystem. veja Mostrar feedback para mais detalhes sobre o PointerEvents component.

circle-exclamation

Se houver várias entidades com as quais o jogador pode interagir da mesma forma, considere usar inputSystem.getInputCommand. Este comando retorna informações sobre um comando de clique global, incluindo o ID da entidade; você pode usar isso para executar uma única função que lide com todas elas.

circle-exclamation

Veja Dados da ação de entrada para mais informações. Este método também fornece dados mais detalhados sobre o acerto do evento do ponteiro.

Botão de entrada liberado

Você também pode verificar eventos de liberação do ponteiro de maneira muito semelhante, usando PointerEventType.PET_UP.

circle-exclamation

Verificar botões pressionados

Verifique se um botão está sendo pressionado atualmente usando inputSystem.isPressed() dentro de um sistema.

inputSystem.isPressed() retorna true se o botão estiver sendo mantido pressionado no momento, não importa quando o botão foi pressionado, e não importa para onde o cursor do jogador está apontando. Caso contrário, retorna false.

O inputSystem.isPressed a função recebe um único argumento:

  • InputAction: Qual entrada escutar, como um valor do InputAction enum. Veja Botões do ponteiro para opções suportadas.

Lidar com múltiplas entidades

Se a sua cena tiver múltiplas entidades que são afetadas por eventos de ponteiro da mesma forma, faz sentido escrever um sistema que itere sobre todas elas.

Este exemplo usa um componentes de todas as entidades na cena, usando uma para iterar sobre todas as entidades com um PointerEvents componente. Em seguida, verifica cada uma dessas entidades com inputSystem.isTriggered, iterando sobre elas uma por uma. Se uma ação de entrada for detectada em qualquer uma dessas entidades, executa a lógica personalizada.

Em vez de iterar sobre todos as entidades com um PointerEvents componente em um único sistema, você pode querer escrever sistemas diferentes para lidar com entidades que deveriam se comportar de maneiras diferentes. A abordagem recomendada é marcar diferentes tipos de entidades com componentes personalizados, e iterar sobre eles em sistemas separados.

Este exemplo tem um sistema que itera sobre todas as entidades que têm um componente personalizado chamado IsDoor e outro que itera sobre todas as entidades que têm um componente personalizado chamado isGem. Em ambos os sistemas, verifica cada entidade correspondente para ver se foram ativadas com o botão do ponteiro.

Esta forma de organizar o código da sua cena é muito orientada a dados e deve resultar em um uso muito eficiente dos recursos de memória.

Mostrar feedback

Para exibir dicas de UI enquanto aponta para uma entidade, use as propriedades no PointerEvents component.

// dar à entidade um componente PointerEvents

circle-exclamation

O PointerEvents Usando-um-sistema

  • eventType: Que tipo de evento escutar, como um valor do PointerEventType enum. Veja Tipos de eventos de ponteiro para opções suportadas.

  • o componente requer pelo menos uma definição de evento de ponteiro. Cada definição de evento de ponteiro pode ser configurada com o seguinte:eventInfo

    • botão (obrigatório: Um objeto que pode conter os seguintes campos: InputAction enum. Veja Botões do ponteiro para opções suportadas.

    • ): Qual entrada escutar, como um valor do (opcional)hoverText

    • : Qual string exibir na dica de feedback de hover. "Interact" por padrão. (opcional)hideFeedback false por padrão.

    • : Se true, oculta tanto a dica de hover quanto o destaque de borda para esta entidade. (opcional)showHighlight true : Se true, os jogadores verão o destaque de borda ao passar o cursor sobre a entidade. : Qual string exibir na dica de feedback de hover. "Interact" por padrão. is false.

    • Os seguintes campos opcionais estão disponíveis ao criar um raio com qualquer um dos métodos acima: (opcional)por padrão. Este valor só é considerado se : Só mostrar feedback quando o jogador estiver mais próximo do que uma certa distância da entidade. O padrão é.

10 metros PointerEvents Um único um PointerEvents componente pode conter múltiplas definições de eventos de ponteiro, que podem detectar eventos diferentes para botões diferentes. Cada entidade só pode ter um componente, mas este componente pode incluir vários objetos em seu pointerEvents

hoverText: 'Give gem',

Os jogadores verão múltiplos rótulos, um para cada evento de ponteiro, exibidos radialmente ao redor do cursor. PointerEvents O exemplo abaixo combina o uso de

Feedback ao passar o cursor

// Lógica personalizada em resposta a uma ação de entrada PointerEvents Quando um jogador passa o cursor sobre um item com um

  • componente, ele vê:

  • Um destaque de borda na entidade

Uma dica de hover perto do cursor com um ícone para o botão que precisa ser pressionado e uma string que diz "Interact".

Esses elementos podem ser alternados e personalizados. botão O feedback de hover na UI exibe um ícone diferente dependendo de qual entrada você seleciona no E campo. No PC, ele exibe um ícone com um paraInputAction.IA_PRIMARY F campo. No PC, ele exibe um ícone com um , umInputAction.IA_SECONDARY , e um mouse para.

InputAction.IA_POINTER ): Qual entrada escutar, como um valor do Altere a string mudando o valor de

PointerEvents.create(chest, { ): Qual entrada escutar, como um valor doNo exemplo acima, o evento do ponteiro inclui um valor para . Este campo define a string a exibir na UI enquanto o jogador aponta para a entidade. Por padrão, essa string soletra.

circle-info

💡 Tip: O ): Qual entrada escutar, como um valor do Interact Open, Activate, A string deve descrever a ação que acontece ao interagir. Por exemplo, SelecioneGrab

. Essas strings devem ser tão curtas quanto possível, para evitar roubar muita atenção do jogador.

O ): Qual entrada escutar, como um valor do Se uma entidade tiver múltiplos eventos de ponteiro, as dicas de hover para cada um deles são exibidas radialmente ao redor do cursor. de um .UP

componente com o evento de ponteiro é exibido apenas enquanto o jogador já estiver segurando a tecla correspondente e apontando para a entidade. DOWN evento de ponteiro e um .UP o evento de ponteiro é exibido apenas enquanto o jogador já estiver segurando a tecla correspondente e apontando para a entidade. evento de ponteiro, a dica para a evento de ponteiro e um ação é mostrada enquanto o botão não está sendo pressionado. A dica muda para aquela do

hoverText: 'Drop', ): Qual entrada escutar, como um valor do Para ocultar a dica de hover, mas deixar o destaque de borda, defina o valor de

hoverText: '', : Se true, oculta tanto a dica de hover quanto o destaque de borda para esta entidade. para false.

showHighlight: false, : Qual string exibir na dica de feedback de hover. "Interact" por padrão. Para ocultar tanto a dica de hover quanto o destaque de borda, defina o PointerEvents para true. Ao fazer isso, o cursor não mostra ícones, texto ou qualquer destaque de borda. Você também pode simplesmente remover o

hideFeedback: true,

Distância máxima

Algumas entidades podem ser intencionalmente interativas apenas a curta distância. Se um jogador estiver longe demais de uma entidade, a dica de hover não será exibida ao lado do cursor. : Só mostrar feedback quando o jogador estiver mais próximo do que uma certa distância da entidade. O padrão éPor padrão, entidades só são clicáveis quando o jogador está dentro de uma curta distância da entidade, em uma distância máxima de Os seguintes campos opcionais estão disponíveis ao criar um raio com qualquer um dos métodos acima: Você pode alterar a distância máxima definindo a

if (cmd.hit.length < 6) { O exemplo acima define a distância máxima para dicas de hover como6 metros Dados da ação de entrada . Certifique-se de que a lógica para lidar com as ações de entrada também siga as mesmas regras. Veja

circle-exclamation

é medida em metros a partir da câmera do jogador. Tenha em mente que em terceira pessoa a câmera está um pouco mais afastada, então certifique-se de que a distância que você define funciona bem em ambos os modos.

O PointerEvents Dicas personalizadas avançadas

Use o inputSystem.isTriggered() o componente adiciona facilmente dicas de UI quando o cursor do jogador começa a pairar sobre uma entidade. Geralmente é bom que as dicas se comportem de forma consistente com o que os jogadores estão acostumados a ver em outras cenas do Decentraland. No entanto, em alguns casos você pode querer sinalizar que algo é interativo de maneira personalizada. Por exemplo, você poderia reproduzir um som sutil quando o jogador começa a pairar sobre a entidade. Você também poderia mostrar um destaque brilhante ao redor da entidade enquanto estiver pairando, e ocultá-lo quando não estiver mais pairando. Também pode ser usado para mecânicas de jogabilidade específicas. PointerEventType.PET_HOVER_ENTER e PointerEventType.PET_HOVER_LEAVE função junto com os

eventos para executar comportamentos personalizados sempre que o cursor do jogador começar a apontar para o collider da entidade e sempre que o cursor parar de apontar para ele. 1.5 O exemplo abaixo amplia entidades para um tamanho de 1 quando o cursor começa a apontar para seus colliders, e as define de volta para um tamanho de

circle-exclamation

Dados da ação de entrada

Transform.getMutable(entity).scale = Vector3.create(1, 1, 1)Ver documentaçãoarrow-up-rightRecupere dados de uma ação de entrada, como o botão que foi pressionado, a entidade que foi atingida, a direção e comprimento do raio, etc. Veja (

) para uma descrição de todos os dados disponíveis. inputSystem.getInputCommandPara buscar esses dados, use

console.log(cmd.hit.entityId) inputSystem.getInputCommand Se não houver uma ação de entrada que corresponda à consulta, então

retorna undefined. Certifique-se de tratar esse cenário em sua lógica.

Distância máxima de clique Para impor uma distância máxima, de modo que uma entidade só seja clicável a curta distância, recupere a hit.length

circle-exclamation

componente para se comportar de maneira consistente.

Malhas diferentes dentro de um modelo .glTF Frequentemente,

modelos 3D são compostos de múltiplas malhas, que cada uma tem um nome interno individual. Todos os eventos de botão incluem a informação de qual malha específica foi clicada, assim você pode usar essa informação para acionar diferentes comportamentos de clique em cada caso. Blenderarrow-up-right Para ver como as malhas dentro do modelo são nomeadas, você deve abrir o modelo 3D com uma ferramenta de edição, como


circle-info

💡 Tippor exemplo.

: Você também pode descobrir o nome da malha clicada registrando-o e lendo no console. : Número de Id da entidade que foi atingida pelo raio. Você acessa a hit propriedade como parte do

objeto, que é retornado pelo evento de clique. No exemplo abaixo temos um modelo de casa que inclui uma malha chamadafirePlace

circle-exclamation

Atualizado