Quais são as partes de um personagem na Unreal Engine?
Conforme mencionado na seção Modo de Jogo/Estado do Jogo, o Framework de jogabilidade da Unreal Engine ajuda a entender como os personagens funcionam na Unreal Engine. Conceitualmente, um jogador consiste em um pawn que representa a presença física no mundo do jogo, e um controle determina o comportamento. Esse desacoplamento é útil tanto para IA quanto para replicação de rede. Para referência, a hierarquia se parece com isso:
Vamos começar importando os ativos, criando o pawn e trabalhando até chegar no controle do jogador. Para Parrot, nosso herói controlado pelo jogador será o Capitão Barbarossa (visite o site da Quaternius para obter o Kit Pirata fornecido pela Quaternius).
Importando ativos de arte
Em uma ferramenta de modelagem 3D de sua escolha, exporte sua malha/animações para um formato compatível com a engine. Neste caso, os desenvolvedores usaram .fbx. Os ativos de Barbarossa estão em "Content/Assets/Quaternius/PirateKit/Characters/Barbarossa". Você pode importar seu .fbx clicando com o botão direito do mouse no menu de contexto ou arrastando e soltando no Navegador de Conteúdo. Você receberá uma janela .fbx de configurações de importação. Escolha as opções apropriadas para sua importação. Neste caso, certifique-se de que nenhum esqueleto existente esteja selecionado e que a opção importar animações esteja marcada. Também é necessário criar um novo material de atlas que possa ser indexado pela sua malha. Este material pode ser reutilizado nos ativos do Kit Pirata. Agora você deve ter esses 3 arquivos e todas as animações incluídas em seu .fbx.
Para oferecer maior organização, os arquivos de sequência de animação ficam na pasta Animações, adjacente a 3 arquivos:
Esqueleto, malha do esqueleto e ativos de física
Um esqueleto é uma hierarquia usada para definir ossos (às vezes chamados de articulações) em uma malha do esqueleto. Esses ossos devem corresponder ao equipamento na sua ferramenta de modelagem 3D. Esqueletos podem ser reutilizados em malhas do esqueleto, desde que os equipamentos sejam compatíveis. Você também notará um ativo de física criado. Os ativos de física definem a física e a colisão usadas por uma malha do esqueleto. Eles contêm corpos rígidos e restrições para simulação. Você só pode ter um ativo de física por malha do esqueleto e eles podem ser ativados ou desativados condicionalmente. Você pode ajustar os ativos de física conforme eles são importados ou criar novos ativos a partir de uma malha do esqueleto.
Blueprint de animação
Agora que você tem uma malha do esqueleto para trabalhar, você pode começar a animá-la com o Blueprint de animação. O Blueprint de animação é semelhante ao sistema de animação de mecanismo da Unity. O Gráfico de animação em Blueprints de animação deve parecer familiar e funcionar de maneira semelhante. Ambos os sistemas têm fluxo lógico condicional que pode fazer a transição de estados de animação para uma pose de saída final. Na sua pasta, crie um novo Blueprint de animação no menu de contexto e selecione seu esqueleto. Nosso Blueprint de animação será chamado de ABP_Captain_Barbarossa em Content/Blueprints/Player.
No lado esquerdo do Blueprint Inspector, você notará que há dois gráficos: Event Graph e Animation Graph. O gráfico de animação é a máquina de estados que controla sua pose de saída final. O gráfico de eventos é onde você pode definir qualquer lógica relacionada à animação. Ao contrário do Unity, onde você precisa passar dados para o componente Mecanim, os Blueprints de animação podem extrair o que precisam de um determinado evento. Por exemplo, você pode querer consultar a velocidade do personagem e conduzir sua animação com base nesse valor. Uma maneira organizada de fazer isso é usar o Nó Event Blueprint Initialize Animation no gráfico de eventos, Obter o ator proprietário, e armazenar o seu componente de movimento em uma variável. A partir daí, a cada marca de BlueprintThreadSafeUpdateAnimation, você pode consultar a velocidade diretamente do seu componente de movimento. Variáveis também podem ser compartilhadas entre o gráfico de eventos e o gráfico de animação.
Vale a pena explorar mais por conta própria o Blueprint de animação configurado para Barbarossa. Ao clicar duas vezes nos nós, você pode ver como as máquinas de estado, os estados e as regras de estado são configuradas para a pose de saída final. Há também exemplos de uso de um reprodutor de sequência e de um espaço de mesclagem. Da mesma forma, o gráfico de eventos mostra como a animação é controlada pelos dados dos personagens. Essa relação ficará mais clara à medida que este artigo avança.
Pawn
Agora que há uma malha do esqueleto que pode ser animada, você pode começar a criar seu pawn que será usado pelo Modo de Jogo. Os desenvolvedores escolheram construir no Personagem padrão da Unreal Engine, que é uma classe filha da classe padrão Pawn C++. A classe Personagem tem um componente Movimento do personagem que é especialmente útil para este jogo e é outra classe a ser desenvolvida.
Tanto o jogador quanto os pawns inimigos têm algumas funcionalidades compartilhadas, como pontos de vida, ser atingido e morrer. Essa funcionalidade é compartilhada pela criação de uma classe C++ AParrotCharacterBase que herda deACharacter. Esta classe fornece uma boa base para construir, já que os pawns inimigos e jogadores divergem em comportamento.
Em seguida, crie um AParrotPlayerCharacter C++ para manipular a lógica específica do jogador. Por fim, você criará um Blueprint para lidar com a representação visual do seu personagem. O Blueprint do Parrot é BP_ParrotPlayerCharacter em Content/Blueprints/Player. A hierarquia da herança tem o seguinte visual:
Ao abrir o BP_ParrotPlayerCharacter, você deverá ver alguns componentes no inspetor de componentes à esquerda da janela do editor. O componente de malha é onde você pode definir seu ativo de malha do esqueleto, bem como o Blueprint de animação em Classe de animação. Se a malha não estiver posicionada corretamente, você pode ajustar os valores de transformação para alinhá-la ao seu componente de cápsula. Você deve ver algo com o seguinte visual:
Em seguida, você pode atribuir a classe de pawn padrão ao Blueprint no ativo do modo de jogo.
Agora, existe um pawn animado que pode ser usado no jogo!
Controle do jogador
Com um pawn utilizável, agora você pode criar o controle do jogador. Os controles do jogador representam essencialmente a vontade do jogador humano. Algo a considerar ao criar seu jogo é onde definir eventos de entrada. Para jogos simples, onde os pawns não mudam, o pawn é adequado para isso. Entretanto, quando o comportamento começa a ficar complexo demais, o controle do jogador se torna uma opção melhor. Os pawns são transitórios e podem ser possuídos ou não pelos controles dos jogadores. Os pawns podem ser gerados ou destruídos enquanto os controles dos jogadores persistem durante o jogo.
Você não precisará de nenhuma lógica C++ no controle do jogador, então basta criar um Blueprint para fazer o que é necessário. BP_ParrotPlayerController fica em "Content/Blueprints/Player". A hierarquia da herança tem o seguinte visual:
Dentro do Blueprint, observe que há nós de eventos de entrada que levam a alguma lógica básica de jogo. Esses eventos de entrada estão relacionados especificamente à Entrada aprimorada. Você pode aprender mais sobre como isso é configurado na documentação de Entrada aprimorada. Armazenando em cache o pawn do personagem do Parrot Player no início do jogo, podemos usá-lo para chamar funções de movimento base mais tarde. Como Adicionar entrada de movimento, Jump e StopJump.
Hora de testar! No Blueprint de modo de jogo, defina a nova classe do controle do jogador e verifique se você pode usar o controle no jogo:
Nesta lista suspensa no editor de níveis, verifique se o modo de jogo correto está selecionado:
Por fim, certifique-se de que seu mapa tenha um ator PlayerStart e uma câmera que você possa visualizar. Ao clicar no botão de reprodução, você deverá ver seu personagem se movendo e sendo animado:
Componente de movimento do personagem Parrot
A classe base ACharacter tem muitas funcionalidades excelentes incorporadas. Um exemplo disso é o componente de ator UCharacterMovement. O componente de movimento do personagem controla toda a lógica de como um personagem se move pelo mundo. Ele suporta modos de caminhada, corrida, queda, natação, voo e movimento personalizado. Definitivamente vale a pena explorar por conta própria para ter uma ideia de como funciona o movimento básico dos personagens e também de quão poderosos são os componentes do ator.
Para Parrot, o componente de movimento do personagem base não forneceu a sensação de jogo que os desenvolvedores estavam procurando. Porém, forneceu uma base sólida para construir. A classe C++ UParrotCharacterMovementComponent deriva de UCharacterMovementComponent. Podemos então definir o componente de movimento no componente de movimento CDO em BP_ParrotPlayerCharacter, assim:
Mas o que o componente de movimento do Parrot realmente faz? Em essência, o componente permite que você defina um salto no estilo "plataforma", substituindo funções do componente de movimento base relacionadas ao salto. Usando alguns valores ajustáveis pelo design, quando ocorre um salto, você pode modificar a escala de gravidade e a velocidade do salto do personagem do jogador para atingir uma altura máxima em um período de tempo fixo. Ao atingir o ápice, você pode começar a aplicar uma escala de gravidade decrescente. Se o jogador liberar o comando de salto antes do tempo, você pode aplicar um multiplicador para aumentar a gravidade.
O resultado é um salto que "parece" mais com o que você esperaria de um jogo de plataforma, em vez de apenas aplicar um impulso no eixo Z.
A partir do trabalho pesado do componente de movimento do personagem base, você pode focar a lógica do componente de movimento do Parrot apenas no pulo. Também vale a pena analisar os valores no inspetor para BP_ParrotPlayerCharacter no componente de movimento, para obter uma visão completa de como todas as partes do componente de movimento funcionam juntas. A lógica do movimento pode ser expandida para se adequar a qualquer variedade de casos de uso.