Buscar

Aula 10 - Interface de Usuário e HUD


Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 16 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 16 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 16 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Continue navegando


Prévia do material em texto

Desenvolvimento de Jogos Digitais II
Aula 10: Interface de Usuário e HUD
Apresentação
No projeto de um jogo, é comum a necessidade de menus para con�gurações gerais e acesso às fases, construídos a
partir de componentes padronizados para interfaces de usuário, como caixas de marcação e seletores deslizantes. Os
elementos de HUD, ou Head Up Display, são criados com os mesmos componentes, e servem para o acompanhamento
de informações no decorrer do jogo, onde também podemos utilizar recursos de depuração visual.
Objetivo
Construir menus de con�guração, com os componentes de interface de usuário;
Construir elementos de HUD, para acompanhamento das informações do jogo;
Usar os recursos de depuração visual como elementos de HUD.
Menus de con�guração
Os pesquisadores da Xerox foram pioneiros na construção de interfaces grá�cas, de�nindo conceitos que persistem até os
dias atuais, como janelas, menus, caixas de opção, caixas de seleção e ícones. As ideias foram seguidas pela Apple, com o
lançamento do Macintosh, no ano de 1984, e pela Microsoft, com o sistema Windows, que se popularizou somente a partir de
1990, já na versão 3.0.
Outras plataformas também passaram a disponibilizar ambientes baseados em janelas, como XWindow no UNIX e Linux,
Workbench no Commodore Amiga, e GEM nos computadores da marca Atari. Algo em comum entre as plataformas é a
presença de um conjunto padrão de componentes visuais denominado WIMP (Window, Icon, Menu, Pointer), ou seja, é um
ambiente composto de janelas, ícones, menus e ponteiros.
Quando trabalhamos com jogos é comum a necessidade de menus para con�gurações gerais, seleção de fases, gerência de
jogos salvos, entre outras tarefas comuns. Como esperado, os componentes oferecidos pela Game Engine, para a construção
de interfaces grá�cas, seguem os mesmos padrões estabelecidos para ambientes desktop.
Comentário
Na Unreal Engine, as interfaces grá�cas, normalmente na forma de menus, são criadas a partir de componentes próprios, com o
processo iniciado por meio do clique em Add New, e escolha de Widget Blueprint, no grupo User Interface.
Atenção! Aqui existe uma videoaula, acesso pelo conteúdo online
O componente do tipo Widget Blueprint exige um editor próprio, devido à especi�cidade do processo de construção,
ocorrendo a divisão em cinco áreas principais:
 Fonte: O autor.
1. Toolbar, com as opções globais, destacando-se a
alternância entre Designer e Graph;
2. Pallete e Hierarchy, onde a primeira contém os
componentes disponíveis para criação das interfaces,
e a segunda apresenta a hierarquia dos componentes
instanciados;
3. Work Space, de�nindo uma área para edição da
interface grá�ca de forma visual, no modo Designer,
ou para a organização dos �uxos de execução, no
modo Graph;
4. Details, apresentando os detalhes do componente
selecionado;
5. Animation e Timeline, para a gerência de animações e
suas linhas de tempo, sempre no contexto da
interface grá�ca.
Para demonstrar o uso de menus vamos criar um projeto no modelo Blank, com a utilização do modo de Blueprints. Após a
criação, vamos adicionar os pacotes Starter Content, do grupo Content Packs, e First Person, do grupo Blueprint Feature,
sempre a partir do clique no botão Add New, seguido da opção Add Feature or Content Pack.
Em seguida, devemos excluir todos os componentes da cena, o que pode ser feito de forma rápida por meio do painel World
Outliner, salvando a cena com o nome CenaEntrada, e vamos criar a interface grá�ca com o clique em Add New, escolhendo
a opção User Interface, seguido de Widget Blueprint. Adotaremos o nome MenuPrincipal para a nossa interface grá�ca,
além de adicionar uma imagem para ser utilizada no fundo em passo posterior.
 Figura: Configuração inicial do projeto e aspecto do World Outliner para a cena. Fonte: O autor.
Agora vamos dar um duplo clique sobre MenuPrincipal, abrindo o editor, e construir a nossa interface grá�ca. Vamos
arrastar os componentes necessários, a partir de Pallete para a área de Work Space, no modo Designer.
Nossa interface terá uma imagem à esquerda e um painel à direita, sobrepondo levemente a imagem, com dois botões e um
seletor deslizante no painel. O painel é de�nido a partir de um Vertical Box, e os botões são componentes Button, com
elementos Text sobrepostos.
 Figura: Hierarquia de componentes e desenho da interface gráfica. Fonte: O autor.
Para de�nir a ordem de apresentação, controlando a sobreposição de componentes que estão no mesmo nível hierárquico,
precisamos alterar o valor de ZOrder, no grupo Slot, a partir do painel Details, quando adotaremos os valores 0 para a
imagem e 1 para o painel. Efetuando a mudança, iremos garantir que o painel �cará acima da �gura de fundo.
O componente para exibição da imagem é do tipo Image, sendo associado ao Asset de imagem por meio do atributo Image,
oferecido por Brush, no grupo Appearance. Uma forma simples de efetuar a associação é deixar a �gura selecionada no
Content Browser, voltar para o editor, e clicar na seta apontando para a esquerda, próxima ao atributo.
Adicionaremos ao painel, com o nome pnlMenu, dois componentes Button, com os nomes btnCena1 e btnCena2. Algo
evidente nos botões é que não apresentam qualquer indicação visual de suas funções, o que será feito com a adição de
componentes Text a cada um deles, quando utilizaremos os textos "Cena 1" e "Cena 2", de�nidos no atributo Text, do grupo
Content.
Quanto aos aspectos visuais dos botões e textos associados, efetuaremos mudanças ao nível do grupo Appearance de cada
componente, utilizando fonte com tamanho 36 para os textos, a partir do atributo Size, de Font, e transparência de 50% para
os botões, obtida por meio do atributo A (Alpha), de Background Color, com valor igual a 0.5.
 Figura: Modificações em Appearance para cada Button e Text associado. Fonte: O autor.
Após con�gurar os botões e textos associados, vamos acrescentar um componente Spacer, para de�nir um espaço vertical
até o trecho seguinte, onde utilizaremos um componente do tipo Text, com o texto "Volume", e um componente Slider, com o
nome sldVolume. Devemos con�gurar sldVolume com valor 2 para o atributo Max Value, no grupo Appearance, e valor 2
para a dimensão Y de Scale, no grupo Render Transform. 
 Figura: Configurações da instância de Slider. Fonte: O autor.
Para ativar a interface con�gurada vamos alterar o Event Graph do Level Blueprint, no �uxo do evento Begin Play,
adicionando um nó do tipo Create Widget, com a seleção do Blueprint MenuPrincipal para o conector Class, o que vai gerar
uma instância de nosso menu. Para que seja apresentado na tela, precisamos de um nó do tipo Add to Viewport, na
sequência, com o conector Target conectado a Result do primeiro nó.
Ainda precisamos do controle do mouse, que é obtido com mais um nó na sequência, do tipo Set Show Mouse Cursor, com
valor True, e tendo como Target um nó GetPlayerController.
 Figura: Alteração do Level Blueprint para apresentação da interface gráfica. Fonte: O autor.
Atenção
Para podermos encontrar o nó de controle do mouse é necessário desmarcar a opção Context Sensitive na busca.
Com todas as con�gurações efetuadas até este ponto já será possível observar o menu com a execução do jogo e testar as
características visuais, mesmo que as funcionalidades para os botões e o seletor deslizante não tenham sido de�nidas.
 Figura: Menu principal na execução do jogo. Fonte: O autor.
Para de�nir a resposta de um botão devemos acessar o grupo Events, ao �nal de Details, com o componente selecionado, e
clicar no sinal de adição ao lado de On Clicked. Alternando para o modo Graph adicionamos um nó do tipo Open Level,
utilizando FirstPersonExampleMap, incluído no pacote First Person, como valor do conector Level Name.
 Figura: Configuração do clique sobre o primeiro botão. Fonte: O autor.
Executando novamente o jogo poderemos observar que o clique sobre o primeiro botão ativará a cena de exemplo do pacote
First Person.
Enquanto a abertura da cena mostrou-se um processo muito simples,o controle de volume do áudio será um pouco mais
complexo. O primeiro fator a ser considerado é a classe de áudio, onde temos como padrão a classe Master, mas que pode
assumir valores como Music ou SFX, além de classes customizadas, e serve para permitir o controle independentemente de
elementos como música e efeitos sonoros.
Para o controle dinâmico do volume precisaremos de um componente do tipo Sound Mix, que funciona como um gestor
global de volume e efeitos, criado com o clique em Add New, seguido da escolha de Sounds, Classes e Sound Class Mix.
Também vamos utilizar um arquivo de áudio, mantendo a classe Master e marcando a opção Looping para o Sound Wave, o
qual será arrastado para a cena, com a geração de um Ambient Sound servindo de referência sonora para o ajuste de
volume.
 Figura: Projeto com os componentes Sound Mix e Sound Wave adicionados. Fonte: O autor.
O direcionamento da gestão de áudio para o Sound Mix ocorrerá ao nível do Level Blueprint, onde adicionaremos um nó do
tipo Set Base Sound Mix com a escolha do componente criado anteriormente no conector In Sound Mix.
Na sequência iremos zerar o volume do áudio com um nó do tipo Set Sound Mix Class Override, atribuindo os valores 0 para
o conector Volume e Master para In Sound Class, além de associar, no conetor In Sound Mix Modi�er, o nosso componente
para gestão de áudio.
 Figura: Modificação do fluxo, no Level Blueprint, para adição do Sound Mix. Fonte: O autor.
Quanto à modi�cação do volume a partir do seletor deslizante, vamos adicionar o tratamento para o evento On Value
Changed com a adição de nó do tipo Set Sound Mix Class Override, escolha da classe de áudio Master para In Sound Class,
associação de nosso gestor de áudio para o conector In Sound Mix Modi�er e ligação entre o conector Volume com a saída
Value do evento gerado para o seletor.
 Figura: Configuração para controle do volume a partir do seletor deslizante. Fonte: O autor.
Executando novamente o jogo poderemos experimentar o controle de volume, voltado para a classe de áudio Master. Vale
lembrar que poderíamos ter outros seletores deslizantes para controlar elementos especí�cos, como as classes Music e SFX.
Atenção! Aqui existe uma videoaula, acesso pelo conteúdo online
Head Up Display (HUD)
Classi�camos como HUD qualquer tipo de informação apresentada para o jogador durante a execução do jogo, desde uma
simples mira até velocímetros e minimapas. Uma regra básica acerca dos componentes para HUD é a de que não devem
diminuir a visibilidade da cena, pois iria interferir diretamente na jogabilidade.
Vamos criar outro Widget Blueprint com o nome Cena1HUD, que terá um Text no canto superior esquerdo, adotando o nome
txtPontos e apresenta o texto "Pontos: 0", além de um Progress Bar, que será chamado de pgbMunicao, ancorado à direita.
 Figura: Blueprint com barra de progresso ancorada à direita. Fonte: O autor.
Precisaremos adicionar uma imagem com uma sequência de projéteis de forma a expressar a quantidade de tiros
remanescentes durante a execução do jogo.
 Figura: Execução do jogo, com a quantidade de tiros remanescentes. Fonte: O autor.
A imagem servirá de fundo para a barra de progresso, sendo associada ao atributo Image, de Fill Image, no grupo Style, e
utilizaremos o valor 0 para o campo A (Alpha) de Tint, no grupo Background Image. Também precisamos dos valores 1,1,1
para R,G,B, em Fill Color, no grupo Appearance, além da opção Right to Left em Bar Fill Type e 0.5 para o valor de Percent,
ambos no grupo Progress.
 Figura: Configuração dos aspectos visuais da barra de progresso. Fonte: O autor.
Para um controle mais simples da barra de progresso vamos inicialmente criar duas variáveis inteiras em Cena1HUD,
acessando a área Graph e clicando em Add New, seguido da opção Variable. Ambas as variáveis serão do tipo Integer,
visíveis externamente, e com valor Default equivalente à quantidade de projéteis da imagem, sendo utilizado 18 no exemplo,
adotando os nomes qtdTiros e maxTiros.
Em seguida devemos alimentar o percentual de progresso por meio de uma função de ligação. Para tal devemos selecionar o
componente pgbMunicao na área Designer. Com a barra de progresso selecionada, clicamos em Bind, ao lado do atributo
Percent, no grupo Progress, e utilizamos a opção Create Binding, gerando a função para a área Graph.
 Figura: Criação da função de ligação para a barra de progresso. Fonte: O autor.
Na área Graph vamos de�nir o �uxo de execução para Get_pgbMunicao_Percent_0, a função criada no passo anterior,
adicionando os nós do tipo Get para as duas variáveis de�nidas, o que pode ser feito com base em arraste a partir de
MyBlueprint, e um nó de divisão entre elementos Float.
O valor de qtdTiros será dividido por maxTiros, gerando o valor percentual que será aplicado ao retorno da função, no
conector Return Value, mas chamando a atenção para o uso de divisão Float, mesmo com elementos inteiros, para evitar
resultados truncados.
 Figura: Fluxo de execução da função de ligação para o atributo Percent. Fonte: O autor.
Ainda falta instanciar o HUD, o que faremos ao nível do Blueprint de First Person Character, visando minimizar a quantidade
total de nós necessária. Vamos criar a variável MeuHUD, do tipo Cena1HUD, de�nir o evento Begin Play, da mesma forma
que �zemos para o menu da cena inicial, porém baseado em Cena1HUD, e atribuir a instância em MeuHUD ao �nal.
 Figura: Adição do HUD ao Blueprint de First Person Character. Fonte: O autor.
Embora o HUD já seja exibido ele ainda não estará funcional, sendo necessário implementar a lógica, segundo a qual temos a
diminuição da quantidade de projéteis a cada vez que ocorre um disparo, e o disparo é liberado apenas quando há projéteis
disponíveis.
A interferência deve ocorrer ao nível do evento Input Action Fire, que encontra-se no grupo Spawn Projectile, onde o disparo
só deverá ocorrer caso a quantidade de projéteis seja maior do que zero.
Para obter o nó de referência para MeuHUD arrastamos a variável, a partir da área My Blueprint até o Event Graph, com a
escolha do modo Get, e arrastando a partir da saída da referência, geramos um nó do tipo Get para qtdTiros.
A comparação é efetuada a partir de um nó do tipo maior que, tendo no primeiro parâmetro qtdTiros e no segundo
parâmetro o valor zero, e adicionaremos um nó do tipo Branch, recebendo o resultado da comparação em Condition, de
forma a liberar a continuidade do �uxo apenas se a condição for True.
Comentário
Ao sair do Branch, a primeira ação deverá ser a diminuição da quantidade de projéteis, o que será feito a partir de um nó de
subtração, recebendo qtdTiros no primeiro parâmetro e o valor 1 no segundo, com o resultado direcionado para uma ação Set
sobre qtdTiros.
O nó do tipo Set é obtido com o arraste a partir da referência para MeuHUD, que também deverá ser associado ao conector
Target do novo nó. Quanto ao �uxo de execução, ele virá do Branch, seguindo para Montage Play, no grupo Spawn
Projectile, que era o destino original do evento Input Action Fire, voltando com isso ao �uxo inicial, apenas com a
interferência necessária para a manutenção da quantidade de projéteis.
 Figura: Manutenção da quantidade de projéteis disponíveis. Fonte: O autor.
O próximo passo será o controle da quantidade de pontos do jogador, segundo um processo bastante semelhante, iniciando
com a edição de Cena1HUD. Na área Designer vamos marcar a opção isVariable para txtPontos, em Details,
transformando o componente em uma variável disponível para o modo Graph.
Ainda na área Designer vamos ativar o Bind para o atributo Text de txtPontos, oferecido no grupo Content, gerando a função
Get_txtPontos_Text_0, e direcionado de forma automática para o modo Graph, onde iremos acrescentar uma variável
pública do tipo Integer, adotando o nome qtdPontos e atribuindo 0 para o valor Default.
Para a implementação da função de ligação vamos adicionar um nó do tipo Append, tendo a expressão "Pontos: " no
conector A, e o Get para qtdPontos, obtido com o arrastea partir de My Blueprint, no conector B. O resultado será uma
String, que será associada a Return Value com a conversão a partir de um nó ToText, mas observando que os nós de
conversão serão gerados de forma automática. 
 Figura: Fluxo de execução da função de ligação para o atributo Text. Fonte: O autor.
A atualização da pontuação deverá ocorrer no Blueprint de First Person Character após o nó Add Impulse at Location,
pertencente ao grupo Deal With Impact, já que o impulso é gerado apenas quando um alvo válido é detectado.
Quanto ao incremento da pontuação, devemos obter uma referência para MeuHUD, de forma a gerar um nó do tipo Get para
qtdPontos, seguindo para um nó de adição de inteiros, em que o segundo parâmetro terá valor 10, com o resultado da soma
alimentando o nó do tipo Set para qtdPontos. Com o nó Set alimentado, ele deve ser incorporado ao �uxo de execução após
o nó Add Impulse at Location.
 Figura: Manutenção dos pontos do jogador. Fonte: O autor.
Já podemos executar nosso projeto e veri�car nosso HUD em funcionamento, mas seria interessante de�nir uma área de
recarga. Vamos abrir First Person Example Map adicionando um Trigger Volume, presente no painel Place Actor, no grupo
Volumes, e um Point Light na mesma posição da cena.
Para o Trigger Volume, adicionaremos um Component Tag, no grupo Tags, do painel Details, com o valor RECARGA,
enquanto o Point Light terá Light Color com valor 1,0,0 para R,G,B, assumindo uma tonalidade vermelha, e 50 para Intensity,
ambos os atributos no grupo Light.
Voltando ao Blueprint de First Person Character, adicionamos o evento Actor Begin Overlap, quando teremos a comparação
da Tag e reposição do valor máximo de projéteis. Acrescentamos um nó do tipo Component Has Tag, sem marcar Context
Sensitive, recebendo Other Actor de Begin Overlap, em Target, e RECARGA em Tag, com a saída direcionada para um Branch
que, para o valor True, libera o �uxo até o nó Set de qtdTiros, recebendo valor �xo, no caso 18.
 Figura: Trigger Volume e fluxo para reconhecimento do gatilho a partir da Tag. Fonte: O autor.
Recursos de depuração visual
Em aulas anteriores já utilizamos um dos vários recursos de depuração visual oferecidos pela Unreal Engine, quando foram
emitidas mensagens texto para a tela durante o jogo. Embora seja útil, trata do modelo mais simples para apresentação das
informações. É possível utilizar marcadores grá�cos nos pontos que serão atingidos por um projétil, ou desenhar uma linha
para expressar a rota que será traçada até o alvo.
Atenção! Aqui existe uma videoaula, acesso pelo conteúdo online
Vamos criar outra cena, com o nome Cena2Map, contendo um conjunto de cubos com a física habilitada, uma malha que
possa representar um canhão, e modo de jogo con�gurado para First Person Game Mode. O canhão deverá rotacionar e
reconhecer os cubos, de�agrando os projéteis sobre eles, enquanto apresenta marcadores visuais.
 Figura: Configuração inicial da segunda cena. Fonte: O autor.
Uma forma simples de reconhecer elementos pertencentes a determinado grupo é o uso de Tags — etiquetas de texto que
podem ser anexadas a componentes ou atores —, permitindo que sejam testadas na colisão. Além de ativar a física nos
cubos, vamos acrescentar uma Tag com o texto ALVO para cada um deles, sempre no grupo Actor, opção Tags, do painel
Details, sendo possível selecionar todos os objetos e efetuar a alteração com apenas um acréscimo.
 Figura: Acréscimo da Tag com o texto ALVO nos cubos. Fonte: O autor.
Qualquer ator ou componente permite o acréscimo de múltiplas
Tags, algo que viabiliza subclassi�cações , durante o processo de
reconhecimento, na colisão.
Como o canhão será rotacionado devemos alterar sua mobilidade para Movable por meio do atributo Mobility, do grupo
Transform. Também será interessante aumentar a área de jogo, com alteração da escala do chão (Floor) nas dimensões X e
Y.
Como próximo passo, vamos criar uma classe C++ derivada de Actor Component, com o nome CanhaoMove, que deverá ser
associada ao objeto de canhão da cena. A associação é feita com o clique sobre o botão Add Component, no painel Details, e
escolha da classe.
O arquivo header de UCanhaoMove terá um atributo interno inteiro, com o nome lastTiro, voltado para a criação de um
contador de tempo entre tiros, além do construtor padrão e o método de atualização TickComponent.
Também serão necessários os atributos TiroOffset de�nindo a distância do pivot até a saída do cano, Velocidade,
representando a velocidade de rotação utilizada, e ProjetilActorClass, para a escolha do Blueprint do projétil.
 
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class JOGOMENU_API UCanhaoMove : public UActorComponent
{
GENERATED_BODY()
int lastTiro = 0;
public:
UCanhaoMove();
UPROPERTY(EditAnywhere)
float TiroOffset = 300.0f;
UPROPERTY(EditAnyWhere)
float Velocidade = 5;
UPROPERTY(EditAnyWhere)
UClass* ProjetilActorClass;
virtual void TickComponent(float DeltaTime, ELevelTick TickType,
FActorComponentTickFunction* ThisTickFunction) override;
};
 Listagem: Arquivo header de UCanhaoMove. Fonte: O autor.
Quanto ao arquivo de implementação devemos começar com a importação dos arquivos de cabeçalho Engine para os
métodos visuais de depuração e SkeletalMeshActor para de�nir a funcionalidade da classe parcial, que faz referência ao
ator (Actor). Na sequência, teremos o construtor, onde serão ativadas duas propriedades, uma para a inicialização
automática do objeto e outra para ativar a execução do método TickComponent a cada quadro.
 
#include "CanhaoMove.h"
#include "Animation/SkeletalMeshActor.h"
#include "Engine.h"
UCanhaoMove::UCanhaoMove()
{
bWantsInitializeComponent = true;
PrimaryComponentTick.bCanEverTick = true;
}
 Listagem: Arquivo header de UCanhaoMove. Fonte: O autor.
O método TickComponent tem dois objetivos: o primeiro é rotacionar o canhão e o outro é reconhecer os alvos, indicando
visualmente a direção e de�agrando os projéteis.
 
void UCanhaoMove::TickComponent(float DeltaTime, ELevelTick TickType,
FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
AActor* Owner = GetOwner();
FRotator novaRotacao = FRotator(0, Velocidade*DeltaTime, 0);
FQuat quat1 = FQuat(novaRotacao);
Owner->AddActorLocalRotation(quat1,false,0,ETeleportType::None);
if (--lastTiro > 0) return;
FHitResult* resultado = new FHitResult();
FVector direcaoTiro = Owner->GetActorRightVector();
FVector pontoInicial = Owner->GetActorLocation()+
(direcaoTiro * TiroOffset);
FVector pontoFinal = pontoInicial + (direcaoTiro * 1000.0f);
FCollisionQueryParams* parametros = new FCollisionQueryParams();
if (Owner->GetWorld()->LineTraceSingleByChannel(*resultado,
pontoInicial, pontoFinal, ECC_Visibility, *parametros)) {
DrawDebugBox(GetWorld(), resultado->ImpactPoint,
FVector(2.f, 2.f, 2.f), FColor::Blue, false, 5.f,
ECC_WorldStatic, 1.f);
if (resultado->Actor->ActorHasTag(TEXT("ALVO"))) {
DrawDebugLine(GetWorld(), pontoInicial, pontoFinal,
FColor::Purple, false, 5.f,
ECC_WorldStatic, 1.f);
FTransform* geracao = new FTransform(Owner->GetTransform());
geracao->SetLocation(pontoInicial);
GetWorld()->SpawnActor(ProjetilActorClass, geracao);
lastTiro = 15;
}
}
}
 Listagem: Método TickComponent, na segunda parte do arquivo de implementação. Fonte: O autor.
01
No início do método podemos observar a captura do ator por meio de GetOwner e a de�nição de um FRotator com a
rotação necessária para o quadro, de acordo com a velocidade, sendo transformada em um Quaternion, para que
possa ser aplicada ao ator, o que é feito a partir do método AddActorLocalRotation.
02
Na linha seguinte temos o decréscimo de lastTiro, junto ao teste no qual um valor maior do que zero irá desprezar o
resto do método a partir do uso de return. Como a variável assume o valor 15 após um tiro, isso garante um espaço
mínimo, em termos de quadros, entre dois tiros consecutivos.
03
Nas linhas seguintes preparamos os requisitospara a veri�cação da existência de um alvo na direção apontada pelo
canhão, sendo de�nidos os pontos inicial e �nal do rastreio. Para obter a posição do ator utilizamos
GetActorLocation, enquanto a direção apontada pelo canhão será recuperada a partir de GetActorRightVector.
04
Com base nos dois valores de�nimos qual será o ponto inicial, com o deslocamento de magnitude igual ao valor de
TiroOffset, a partir do centro, e do ponto �nal, mil unidades após o inicial, sempre na direção recuperada.
Além dos parâmetros que foram calculados temos as instâncias de FHitResult para obter o resultado do rastreio, e
FCollisionQueryParams, obrigatório na chamada para o método de rastreio, sendo mantida a con�guração padrão no
exemplo.
Comentário
Embora existam várias formas de rastreio disponíveis, aqui utilizamos o modelo linear a partir de LineTraceSingleByChannel,
que veri�ca a ocorrência de colisão sobre uma linha, de�nida entre os pontos inicial e �nal, com o retorno da primeira colisão
encontrada no ponteiro para FHitResult.
Se o método de rastreio retornar alguma colisão desenhamos uma caixa de cor azul no ponto de impacto, ou ImpactPoint, a
partir de DrawDebugBox, e se a Tag do objeto onde ocorreu a colisão for ALVO, a linha de rastreio é desenhada com a
chamada para DrawDebugLine. Nas linhas seguintes temos a geração do projétil por meio de SpawnActor utilizando a
posição de início do rastreio e a reinicialização do contador lastTiro com o valor 15.
Para de�nir o projétil precisamos adicionar o pacote Twin Stick Shooter e criar uma cópia de TwinStickProjectile no diretório
Blueprints de TwinStickBP, com o nome TiroCanhao, onde algumas mudanças devem ser efetuadas. Abrindo o Blueprint da
cópia vamos acessar o nível de ProjectileMovement, modi�car a direção da velocidade para o eixo Y, no grupo Velocity, e
adotar o modelo espacial, desmarcando Constrain to Plane no grupo Planar Movement.
Após efetuar as mudanças associamos o projétil ao atributo Projectil Actor Class, ao nível de CanhaoMove, para o canhão, e
con�guramos os atributos Velocidade e Tiro Offset com os valores que mais se adequarem ao jogo. É claro que nossa
classe deve ser compilada antes da con�guração dos atributos no painel Details.
 Figura: Configurações efetuadas para TiroCanhao e CanhaoMove. Fonte: O autor.
Caso queira som no tiro do canhão você precisará de um ponteiro para USoundBase, editável ao nível do painel Details, para
que seja associado a um SoundWave ou SoundCue, além de uma chamada para PlaySoundAtLocation, na mesma posição
da geração do projétil.
 
FAudioDevice* soundPlayer = GetWorld()->GetAudioDevice();
soundPlayer->PlaySoundAtLocation(SomTiro, GetWorld(),
1.0f, 1.0f, 0.0f, geracao->GetLocation(), geracao->Rotator());
 Listagem: Comando para execução do áudio durante o tiro do canhão. Fonte: O autor.
Com tudo �nalizado, lembrando que o som do tiro é opcional, podemos alterar a resposta ao clique do segundo botão do
menu, com a abertura de Cena2Map, da mesma forma que �zemos na chamada para o exemplo de First Person, e invocar a
nova cena na execução.
 Figura: Execução do jogo, com a presença de marcadores e linhas de traçado. Fonte: O autor.
A segunda cena, embora simples, demonstra muito bem a utilização dos recursos visuais de depuração, com as linhas de
traçado púrpuras e os cubos azuis nos pontos de colisão. Note que as modi�cações efetuadas em First Person Character
serão mantidas para a nova cena.
Atividade
1. A maioria dos jogos precisa de menus para con�gurações gerais e carregamento de fases, entre outras tarefas, e na Unreal
Engine é possível criá-los a partir de Blueprints, como quase tudo no ambiente. Qual tipo de componente deve ser utilizado na
criação de menus?
a) Animation Blueprint
b) Character Blueprint
c) Actor Class Blueprint
d) Material Blueprint
e) Widget Blueprint
2. Na construção do HUD as informações mais simples são aquelas apresentadas na forma de texto, como pontuação e
diálogos curtos. Claro que a informação apresentada evolui durante a execução do jogo e, para automatizar seu preenchimento,
podemos vincular o campo a uma função, segundo um processo iniciado com o clique no botão:
a) Add Component
b) Bind
c) Auto Key
d) Anchors
e) Return Node
3. Os indicadores para depuração visual podem proporcionar informações de boa qualidade na composição do HUD, como o
traçado de linhas e a marcação de pontos, algo que facilita, por exemplo, a identi�cação da direção para tiro e do ponto de
contato com o alvo. Para exibir o caminho que será percorrido pelo projétil podemos utilizar:
a) DrawDebugLine
b) DrawDebugSphere
c) AddOnScreenDebugMessage
d) DrawDebugBox
e) PrintText
Notas
Bones1
São criadas as chaves de animação, ao longo da linha de tempo, para os diversos componentes da hierarquia, e a malha é
aplicada sobre ela, adequando-se ao movimento esperado — como ocorre para nós, quando nossos esqueletos se movem e a
pele segue o movimento que foi imposto.
Referências
CARNALL, B. Unreal Engine 4.X By Example. Birmingham: Packt Publishing, 2016.
COPLE, D. Desenvolvimento de Jogos II. Rio de Janeiro: SESES, 2019.
MONIEM, M. Mastering Unreal Engine 4.X. Birmingham: Packt Publishing, 2016.
SATHEESH, P. Unreal Engine 4 Game Development Essentials. Birmingham: Packt Publishing, 2016.
SHERIF, W.; WHITTLE, S. Unreal Engine 4 Scripting with C++ Cookbook. Birmingham: Packt Publishing, 2016.
Próxima aula
Explore mais
No site raywenderlich leia o artigo sobre a criação de interfaces de usuário na Unreal Engine.
Em Unreal Engine veja a referência do fabricante para os componentes utilizados em Widget Blueprints.d
Em Tom Looman leia o artigo sobre a informações integradas ao ambiente 3D, com base em UMG.
javascript:void(0);
javascript:void(0);
javascript:void(0);