Enhanced Input
Enhanced Input é um plugin original criado pela Epic Games que utilizamos no Parrot. Se você estiver utilizando a versão mais recente da Unreal Engine 5, ele deve estar habilitado por padrão. Você pode verificar se ele está habilitado acessando Editar, Plugins e marcando a caixa de seleção.
O Enhanced Input (entrada aprimorada) substitui o sistema de entrada padrão da Unreal Engine e é o padrão para o tratamento complexo de entradas ou remapeamento de controles em tempo de execução. A documentação oficial da Epic Games apresenta uma excelente visão geral do sistema, além de instruções sobre como configurar seus ativos de entrada.
Conceitos fundamentais
Para reiterar a documentação oficial, os conceitos fundamentais do Enhanced Input que você precisa entender são os seguintes:
Ações de entrada
Contextos de mapeamento de entrada (IMCs)
Modificadores de entrada
Gatilhos de entrada
Se você já utilizou o novo sistema de entrada do Unity, esses conceitos devem ser familiares.
As ações de entrada podem ser melhor compreendidas como "o que a ação que será realizada no jogo faz" em um contexto específico do jogo. Por exemplo, se o seu personagem estivesse em um carro, seria desejável ter ações como "Acelerar" ou "Frear".
Contextos de mapeamento de entrada também funcionam com esse exemplo. Se o jogador entrar ou sair do carro, talvez seja necessário alterar a função de determinadas teclas ou botões do controle.
Gatilhos de entrada impedirão que as ações sejam acionadas, a menos que todas as condições de gatilho sejam atendidas. Por exemplo, você pode querer que o jogador mantenha um botão pressionado por um determinado período de tempo para disparar uma ação.
Modificadores de entrada alteram o valor da própria entrada. Zonas mortas são um modificador de entrada comum usado para suavizar valores de entrada brutos. O Enhanced Input resolve todos esses problemas para você com algumas configurações.
Vejamos um exemplo no Parrot. Em Content/Input/Gameplay, você encontrará uma pasta Actions e um arquivo de ativo IMC_Gameplay. Na pasta Actions, localize o ativo IA_Jump.
O tipo de valor aqui é Digital (bool), que indica o tipo de saída dessa ação. Em gatilhos, existem os seguintes tipos:
Pressionado
Liberado
Observando essa ação de entrada, é possível perceber que qualquer tecla ou botão mapeado deve ser acionado por meio de um toque e ter um estado de saída booleano. Liberar o botão aciona o término da ação. Outro detalhe importante aqui é que tanto os gatilhos quanto os modificadores podem ser substituídos por um contexto de mapeamento de entrada. Vamos examinar o contexto de mapeamento de entradas da jogabilidade para observar a substituição de modificadores na prática.
IA_MoveAxis não possui nenhum gatilho definido, portanto, o valor do Controle Direcional Analógico Esquerdo no Eixo X aqui será lido imediatamente quando uma alteração for detectada. Para facilitar os valores de entrada brutos, utilizamos um modificador de Zona morta para definir os limites superior e inferior de entrada.
Um exemplo em que não fornecemos uma substituição no IMC é o mapeamento de saltos.
Aqui, você notará que o gatilho vem da própria ação de entrada e, portanto, não é necessário definir um gatilho no mapeamento. As configurações também são herdadas da ação, mas você pode ignorar esse assunto por enquanto, pois ele será abordado na seção sobre remapeamento.
Ouvintes de eventos de Enhanced Input
Agora que os seus ativos estão configurados, é necessário realizar algumas configurações para uso em tempo de execução. No Parrot, vinculamos ao Subsistema de jogador local do Enhanced Input para configurar nossos ouvintes de eventos em BP_ParrotPlayerController. A partir do nó BeginPlay, adicionamos o contexto de mapeamento para IMC_Gameplay.
O parâmetro de prioridade é importante aqui. Contextos de mapeamento de entrada são avaliados por sua prioridade. Portanto, considere isso ao criar camadas de contextos. Por enquanto, você utilizará apenas o contexto do jogo.
Observe o parâmetro Notificar configurações do usuário definido como verdadeiro aqui: isso será necessário para o Remapeamento de entrada em tempo de execução posteriormente.
Com o contexto de mapeamento pronto, basta adicionar os nós de evento de entrada aprimorados nas ações de seu interesse. Aqui está um exemplo de salto:
A ação começa quando o jogador pressiona o botão e é concluída quando o jogador solta o botão. Observe as demais ações de entrada em BP_ParrotPlayerController para verificar como outros tipos de entrada são processados. Você também pode vincular eventos de entrada em C++, se preferir, conforme descrito na documentação oficial.
Remapeamento de entrada em tempo de execução
O Enhanced Input possui a capacidade de remapear teclas vinculadas a ações de entrada em tempo de execução. É importante observar que, embora essa funcionalidade esteja operacional, ela ainda está em fase experimental. Portanto, tenha cuidado ao tentar fazer envios com ela. No Parrot, temos uma tela Vinculações de teclas que permite ao jogador remapear suas teclas. Para isso, combinamos o Enhanced Input com o plugin Common UI da Epic Games para fornecer os metadados corretos aos widgets da tela. A configuração do Common UI é abordada na documentação sobre a interface de usuário. É recomendado ler essa seção antes de prosseguir. Com esse plugin configurado, você também pode exibir elementos da interface de usuário específicos da plataforma.
Para iniciar, habilite as Configurações do usuário para o Enhanced Input nas configurações do nosso projeto. Elas ficam em Editar, Configurações do projeto, Engine, Enhanced Input. Defina suas configurações da seguinte forma:
Em seguida, navegue até um ativo de Ação de entrada e ajuste as Configurações de teclas mapeáveis pelo jogador. O campo Nome deve ser único em todas as suas ações de entrada. O Nome de exibição e a Categoria são localizados no Parrot.
Também é possível substituir as configurações de teclas mapeáveis pelo jogador ao definir uma tecla em um IMC. Para a ação de salto no IMC de jogabilidade, deixamos essa configuração como "Herdar configurações da ação", para que não seja necessário realizar nenhuma ação especial.
Verifique se, ao adicionar o contexto de mapeamento de entrada no Blueprint do controle do jogador, o parâmetro Notificar configurações do usuário está definido como verdadeiro.
A próxima parte abordará como podemos vincular as ações do Enhanced Input ao Common UI. Abordaremos o que é necessário para o remapeamento de entradas no Parrot, mas esta documentação é complementar ao Guia oficial de início rápido do Common UI.
Para o próximo passo, criamos um novo IMC: IMC_UI_Generic em Content/Input/UI.
É necessário definir o campo "Configurações de teclas mapeáveis pelo jogador" em cada ação de entrada e direcioná-lo para o ativo de dados de metadados da interface de usuário apropriado. Aqui está um exemplo da ação genérica de Aceitar entrada e do próprio ativo de metadados.
Essas ações de IMC e de entrada são necessárias para que o Common UI reconheça as ações invocadas pela navegação da interface de usuário. As ações genéricas Aceitar e Voltar são exemplos primários disso, pois o jogador sempre desejará invocá-las ao navegar pelas telas da interface de usuário. Definimos esses mapeamentos em um Blueprint de dados específico do CommonUI que é uma subclasse de CommonUIInputData.
Em seguida, em Editar, Configurações do projeto, Configurações comuns de entrada, defina os dados de entrada para o seu Blueprint de dados de entrada genérico.
Após definir os campos importantes, é possível prosseguir com a configuração das telas do widget. Inicie com uma classe de tela básica do Parrot para telas estáticas e uma ativável para as demais. As telas estáticas seriam semelhantes ao HUD, em que não é necessário se preocupar com a navegação da interface de usuário. Um exemplo ativável seria o Menu Pausa, uma vez que ele precisa saber quando o botão Voltar é pressionado e existe na camada Menu no layout do jogo.
A hierarquia da tela é abordada na documentação sobre a interface de usuário, mas, para referência, ela é repetida aqui:
Nas configurações padrão das telas do BP, definimos um contexto de mapeamento de entrada opcional. Ele é aplicado na ativação/desativação do widget e pode ser substituído para cada classe.
UParrotActivatableScreen possui uma implementação para lidar com ações de voltar. O ouvinte de evento IA_UI_GenericBack é definido no gráfico de eventos dos Blueprints derivados que fazem uso dele. Também é necessário habilitar a caixa de seleção É manipulador de retorno no painel Detalhes.
Consulte os comentários na classe C++ e no BP para ver como o padrão Voltar é utilizado em diferentes widgets de tela.
Após abordar as classes básicas, observe a tela de atalhos de teclado. WBP_KeyBindingsScreen fica em Content/UI/Widgets/Screens. Recomenda-se revisar o gráfico de eventos por conta própria para verificar como as Configurações do usuário e o Perfil de teclas são consultados para extrair os tipos de Mapeamento de teclas do jogador no Enhanced Input. Os dados são utilizados para adicionar e preencher os widgets WBP_InputSelectorBox. Dentro do widget WBP_InputSelectorBox, você encontrará dois widgets W_ParrotInputSelector.
Um é utilizado para entradas do controle de videogame e outro para entradas do teclado. O Seletor de entrada do Parrot é um widget personalizado inspirado no widget Seletor de entrada integrado. Ambos os widgets entram em um estado de seleção, aguardam uma entrada e, em seguida, atualizam a exibição:
Para o mouse e o teclado, trabalhamos com o texto retornado do subsistema Enhanced Input e atualizamos a exibição.
A implementação do gamepad depende da interface de usuário comum para consultar imagens específicas do controlador. Neste caso, criamos uma para imagens do Xbox chamada
CommonInput_Gamepad_XboxemContent/Input/UI/Platform. Essa classe deriva deUCommonInputBaseControllerData.
A partir desta classe, é possível mapear chaves de entrada para pincéis com imagens. Em seguida, configure os dados do controle em Editar, Configurações do projeto, Configurações de entrada comuns e navegue até a plataforma.
Com esses dados conectados, o restante do trabalho ocorre nos widgets. Vale a pena examinar o código e os comentários em UParrotInputSelector e WBP_InputSelectorBox para entender exatamente como a funcionalidade de remapeamento funciona usando os subsistemas Enhanced Input e Common UI.
A última funcionalidade importante a ser destacada é como as teclas mapeadas são salvas. Isso acontece em SaveKeyMappings em WBP_KeyBindingsScreen. Essa função itera sobre todos os widgets da caixa seletora e, em seguida, utiliza as funções integradas nas configurações do usuário Aplicar configurações e Salvar configurações. Salvar configurações grava um arquivo de jogo salvo, EnhancedInputUserSettings.sav, no disco. Ele fica em Diretório do projeto, Parrot, Jogos salvos.
Se tudo foi configurado corretamente, você deverá ter uma tela de atalhos de teclado em funcionamento.
Você pode observar que, no canto inferior direito, há um widget de ação que é atualizado quando a tecla é remapeada. Esse widget é WBP_ParrotGamepadActionWidget e fica em Content/UI/Widgets/Common. Ele utiliza intensamente a classe UCommonActionWidget do Common UI, que foi criada para exibir ícones específicos da plataforma a partir de uma ação de entrada, utilizando os dados de entrada comuns que criamos anteriormente. Aproveitando o Common UI, é fácil criar novos widgets conforme necessário, que fazem referência às ações do Enhanced Input do seu jogo.