Os obstáculos do ambiente desempenham um papel importante na formação do jogo. Ao usar perigos e armadilhas, você adiciona consequências para o jogador e aumenta a dificuldade e a tensão conforme ele avança no quebra-cabeça ou no nível.
Nesta parte da série de tutoriais, você criará uma armadilha de estacas e uma armadilha de fogo que podem causar dano ao jogador. Em seguida, você conectará a armadilha de fogo e trocará os objetos de jogabilidade para criar uma nova jogabilidade e um quebra-cabeça.
Agora que o jogador pode receber dano e perder toda a vida, você também vai configurar uma condição de falha que encerrará e reiniciará o jogo, dando aos jogadores a chance de tentar novamente.
Antes de começar
Você deve compreender os tópicos abordados nas seções anteriores de Como projetar uma aventura de quebra-cabeça:
Noções básicas de Blueprints, como variáveis, funções, gráficos de evento e adição de nós.
Usar eventos de interface de Blueprint para ativar um interruptor em outro objeto de jogabilidade.
Você precisará dos seguintes ativos de Criar uma chave e Quebra-cabeças: interruptores e cubos:
Material
M_BasicColore instância de materialM_BasicColor_RedInterface de Blueprint de
BPI_InteractionClasse de Blueprint
BP_Switch
Criar um conjunto de classes de Blueprint relacionadas
Ao longo desta série de tutoriais, você encontrou ativos da Unreal Engine que usam relações pai-filho e herança. Herança significa criar uma classe-filho que reutiliza e estende as funcionalidades de uma classe-pai existente. A classe-filho pode expandir essas funcionalidades sem alterar a classe-pai. A herança economiza seu tempo reutilizando funcionalidades úteis em muitos ativos, em vez de adicioná-las manualmente a cada novo ativo.
Os ativos de instância de material herdam funcionalidades dos materiais-pai. Em muitos de seus Blueprints, você criou componentes que herdam dados de transformação de um componente-pai.
Os jogos usam diferentes tipos de perigos, mas geralmente compartilham as mesmas funcionalidades principais. Um Blueprint-pai de armadilha pode definir essas funcionalidades compartilhadas, enquanto cada Blueprint-filho de armadilha estende essas funcionalidades, adicionando elementos visuais e comportamentos diferentes.
A armadilha-base (pai) precisa detectar a sobreposição de jogador e usar a mecânica de jogo de dano para reduzir a vida do jogador ao longo do tempo. Em seguida, você criará (ou subclassificará) armadilhas-filho para estender as funcionalidades da armadilha-base e adicionar elementos visuais ou comportamentos adicionais. A armadilha de estacas adiciona malhas estáticas à sua aparência, e a armadilha de fogo adiciona um efeito de fogo e o comportamento que faz com que ela seja ativada e desativada.
Seu nível ainda está na fase de esboço, então concentre-se em criar uma versão simplificada de cada armadilha que ainda informe o design visual futuro.
Criar o Blueprint da armadilha-base
Primeiro, crie a classe de Blueprint da armadilha-base como pai e base das armadilhas especializadas.
Para criar um Blueprint que defina funcionalidades de armadilhas comuns, siga estas etapas:
No Navegador de Conteúdo, vá para a pasta Conteúdo > AdventureGame > Designer > Blueprints e crie uma nova pasta chamada
Armadilhas.Clique com o botão direito na pasta Armadilhas, ou clique em "Adicionar" e crie uma classe de Blueprint.
Na janela
Escolha a classe pai, clique em Ator.Dê o nome
BP_TrapBasepara esta classe e abra-a.
Adicionar componentes
Para a armadilha-base, você criará uma malha estática como rascunho para mostrar os limites da armadilha. Todas as armadilhas também precisam de um volume de colisão para saber quando o jogador pisa nelas.
Para criar os componentes físicos da armadilha base, siga estas etapas:
Na aba Componentes, clique em Adicionar, pesquise uma forma de malha estática de Cubo e adicione-a.
Dê o nome
TrapBasepara o componente de malha.No painel Detalhes, em Transformação, altere a Escala do cubo para
2,2,0,1para criar uma base de quadrado plana.Na aba Componentes, com TrapBase selecionada, clique em Adicionar, pesquise um componente de colisão e selecione-o.
Dê nome
TrapTriggerpara o componente de colisão. É o volume de colisão usado para detectar quando o jogador está sobre a armadilha.Assim como no caso do
BP_Switch, você anexa o componente de colisão à malha. Se quiser alterar o tamanho da armadilha, a área de gatilhos se ajustará automaticamente.No painel Detalhes, em Transformação, altere as seguintes propriedades para criar uma grande caixa de colisão acima da malha base:
Defina Posição como
0,0,400.Defina Escala como
1,5,1,5,12.
Adicionar Variáveis
Todas as armadilhas também precisam de propriedades editáveis que permitem personalização:
Se o perigo está ativo ou inativo.
O dano que a armadilha causa ao jogador.
O intervalo de dano, ou tempo de incidência.
E a armadilha precisa saber quem colidiu com ela.
Para adicionar propriedades comuns à armadilha-base, siga estas etapas:
Na aba Meu Blueprint, crie as variáveis a seguir:
Nome da variável
Tipo
Categoria
Valor padrão
Ativo
Booleano
Configuração
True
BaseDamage
Float
Configuração
5.0
DamageInterval
Float
Configuração
1,0
Depois de criar uma variável, compile seu Blueprint para adicionar um valor padrão.
Clique no ícone de olho de cada variável para que o olho seja aberto, tornando todas as três variáveis editáveis e públicas.
Adicione uma variável chamada
OtherActore mude o tipo para Actor (Object Reference).
Criar uma função para causar dano
Agora que a armadilha tem as propriedades-base, você pode começar a criar o comportamento dela. Todas as armadilhas devem diminuir os pontos de vida (PV) do jogador em um intervalo regular quando o jogador se sobrepõe ao volume de colisão.
A Unreal Engine tem soluções integradas para muitas mecânicas de jogabilidade comuns, incluindo aplicar e receber dano.
Para a armadilha, você usará o nó da função Apply Damage integrado. Para organizar a lógica de gerenciamento de dano, você criará sua própria função que chama Apply Damage em todos os personagens que tocam a armadilha se ela estiver ativa.
Para criar uma função que aplica o dano de armadilha ao jogador, siga estas etapas:
Na seção Funções, clique em Adicionar. Dê o nome
fnApplyDamageToTargetspara a função e abra o gráfico dela.Você que causar dano apenas quando a armadilha estiver ativada. Portanto, adicione um nó Branch onde Condição é uma referência (Get) à variável Ativa.
Mais adiante neste tutorial, você adicionará alguns inimigos PNJ, de modo que é possível que muitos atores estejam na armadilha ao mesmo tempo. Portanto, quando a armadilha estiver ativa, faça um loop em uma matriz com todos os atores que encostarem na armadilha:
Conecte o pin True do nó Branch a um nó For Each Loop.
Para a entrada Matriz do loop, você precisará criar uma matriz de todos os atores sobrepostos. A Unreal Engine faz isso para você: adicione um nó Get Overlapping Actors (TrapTrigger). O nó tem uma referência a TrapTrigger como Destino.
No nó Get Overlapping Actors, altere o filtro de classe para personagem para que personagens do jogador e PNJ possam ser adicionados à matriz.
Para cada elemento da matriz, ou cada iteração do loop, aplique a quantidade de dano definida na variável BaseDamage ao ator nesse elemento da matriz. Para isso, conecte um nó Apply Damage ao nó Loop Body.
A função Apply Damage vem da biblioteca Game Statics da Unreal Engine. O ícone no canto superior direito significa que a função pode ser usada em jogos de rede e executada no servidor.
Configure o nó Apply Damage:
Para o pin Ator que recebeu dano, conecte o elemento da matriz do loop.
Para o pin Dano-base, conecte uma referência à variável Dano-base.
6. Salve e compile seu blueprint.
A função fnApplyDamageToTarget completa deve ficar assim:
Se você copiar e colar esse trecho de código no gráfico correspondente que está no seu projeto, conecte o nó de entrada da função ao nó Branch.
Crie um temporizador que causa dano ao longo do tempo
Em seguida, faça a armadilha chamar a função de causar dano em intervalos regulares. Para fazer isso, você usará uma das funções de temporizador da Unreal Engine para criar um temporizador.
Neste Blueprint, você usará Set Timer by Function Name:
Esse nó cria um temporizador e vincula uma função a ele. Assim, quando o temporizador expirar, o nó chama a função, executando todas as ações nela.
Para definir um temporizador quando o jogo iniciar, siga estas etapas:
Vá para a aba
EventGraphde BP_TrapBase. Exclua os nós Event ActorBeginOverlap e Event Tick fornecidos.Antes de a armadilha realizar qualquer ação, verifique se ela está ativa. No nó Event BeginPlay , adicione um nó Branch em que a Condição faz referência à variável Ativa.
No pin Verdadeiro do nó Branch, crie um nó Set Timer by Function Name.
Configure o nó de temporizador:
Para o pin Time, conecte uma referência à variável DamageInterval.
Clique na caixa de texto perto do nome da função e insira
fnApplyDamageToTarget.Verifique se você digitou o nome da função corretamente, senão a lógica será executada da forma incorreta.
Habilite Looping.
Os nós Set Timer geram um valor de retorno chamado Manipulador de temporizador, que funciona como um número de rastreio ou controle para o temporizador. Para interromper, pausar ou retomar o temporizador, você deve referenciar esse manipulador de temporizador. Salve-o em uma nova variável:
No painel Meu Blueprint, crie uma nova variável chamada
TimerHandler. Mude o tipo para Timer Handle (Manipulador de temporizador).Adicione um nó Set Timer Handler e conecte-o ao valor de retorno e aos pins de execução do nó Set Timer by Event.
Quando a Unreal Engine cria um temporizador, ele começa a ser executado imediatamente, portanto você precisa pausar o temporizador até que um personagem pise na armadilha. Conecte um nó Pause Timer by Handle e passe o seu TimerHandler para ele.
Salve e compile seu blueprint.
Você também pode criar temporizadores com um nó Set Timer by Event. Aqui, você usaria a lista de ações do nó para Add Custom Event e o usaria como um delegate para vincular ações ao temporizador.
Eventos personalizados são reutilizáveis, blocos nomeados de lógica semelhantes a funções. Ao contrário das funções, eles podem conter atrasos, nós da linha do tempo e outras ações latentes. Portanto, talvez seja necessário usar esse método à medida que o jogo fica mais complexo.
Conecte um pin delegate quadrado de evento para passar uma referência desse evento ao nó de temporizador. Isso não aciona o evento, mas armazena o evento e suas ações para uso posterior (quando o intervalo de tempo expirar).
Iniciar e interromper dano
Você criou e pausou o temporizador de dano. Ele está pronto e aguardando. Agora, faça o dano ser retomado quando um personagem pisar no volume de colisão da armadilha e pause o dano quando o personagem parar de se sobrepor ao volume.
Para adicionar uma lógica que inicia o dano, siga estas etapas:
No painel Componentes, clique com o botão direito do mouse no componente TrapTrigger, vá para Adicionar evento e selecione Adicionar OnComponentBeginOverlap.
Após o evento, conecte um nó Set Other Actor para salvar na variável o ator sobreposto.
Conecte o evento e Defina os pins do nó Other Actor.
Conecte um nó fnApplyDamageToTarget para que o personagem receba dano imediatamente ao tocar na armadilha.
Conecte um nó Unpause Timer by Handle para retomar o temporizador e os intervalos do dano. Para a entrada do manipulador, conecte uma referência à variável TimerHandler.
Para adicionar uma lógica que interrompe o dano ao longo do tempo, siga estas etapas:
Clique com o botão direito no componente TrapTrigger, vá para Adicionar evento > On Component End Overlap.
Após o evento, conecte um nó Pause Timer by Handle, passando uma referência a TimerHandler para ele.
Salve e compile seu blueprint.
Agora a armadilha cria, inicia e interrompe um temporizador de dano.
O gráfico de evento BP_TrapBase deve ficar assim:
Para obter mais informações sobre temporizadores e gerenciamento de temporizador, confira Gameplay Timers.
Teste a armadilha-base
Para testar a armadilha, adicione uma mensagem Print String que seja exibida na tela quando a armadilha causar dano.
Para imprimir uma mensagem na tela que mostra se a armadilha funciona como esperado, siga estas etapas:
Em
BP_TrapBase, vá para a aba fnApplyDamageToTarget.No gráfico da função, conecte um nó Print String após o nó Apply Damage.
Altere In String para
Jogador atingido!Clique na seta que está na parte inferior do nó Print String para mostrar mais opções e altere Duration para
5. Isso facilita a visualização do dano causado ao longo do tempo.Compile e Salve o Blueprint. No Navegador de Conteúdo, arraste uma instância de
BP_TrapBasepara o seu nível.Jogue o nível e pise na armadilha. Uma nova mensagem "Jogador atingido!" deverá aparecer a cada segundo.
Criar subclasse da armadilha de estacas
Agora que você concluiu sua classe-pai, é hora de começar a criar subclasses!
Primeiro, você criará uma armadilha de estacas que modifica a aparência da armadilha-base, adicionando uma linguagem de forma. Uma armadilha plana não parece perigosa, mas o jogador interpretará um objeto pontiagudo como algo que pode machucá-lo.
Para criar uma armadilha de estacas, siga estas etapas:
No Navegador de Conteúdo, na pasta Traps, clique com o botão direito em
BP_TrapBasee selecione Criar classe de Blueprint-filho.Dê o nome
BP_TrapSpikespara a classe de Blueprint e abra-a.Na aba Componentes, com DefaultSceneRoot selecionada, clique em Adicionar, pesquise Cone e selecione-o.
Você redimensionará e posicionará os cones para que caibam em quatro linhas de quatro cones cada (ou 16 no total).
No painel Detalhes do cone, na seção Transformação, altere as seguintes propriedades:
Altere a Posição para
-75,-75,25.Altere a Escala para
0,5,0,5,0,4.
Agora há uma estaca menor no canto da malha-base.
Para ter um contraste visual, na seção Materiais, use o menu suspenso para alterar a cor do material para
M_BasicColor_Red.Selecione o cone e duplique-o (Ctrl + D) três vezes, transladando cada cone em 50 unidades para que eles se alinhem em uma linha, em um lado da malha-base.
Segure CTRL para selecionar os quatro cones e duplicá-los. No painel Componentes, selecione os quatro cones novos (eles terão o maior número de sufixos) e mova-os em 50 unidades. Repita isso mais duas vezes para criar uma grade de cones 4x4.
As inclinações e os ângulos das estacas podem dificultar o movimento do jogador para fora da armadilha. Para evitar que o jogador caia entre as estacas, adicione um piso invisível no topo delas:
Na aba Componentes, duplique a malha TrapBase e dê o nome de
InvisFloorpara ela.Mova o chão para cima de modo que apenas as pontas da estacas fiquem visíveis acima do chão.
No painel Detalhes, na seção Colisão, verifique se Predefinições de colisão está definida como BlockAllDynamic. Isso bloqueia a passagem de todos os atores pela malha.
Na seção Renderização, desabilite Visível. Isso oculta a malha nas janelas de visualização e durante a jogabilidade.
Na aba Componentes, selecione a malha TrapBase. No painel Detalhes, na seção Renderização, habilite Oculto no jogo. Isso mantém a malha visível nas janelas de visualização, mas a oculta durante o jogo, para que você veja apenas as estacas.
Salve e compile seu blueprint.
A subclasse da armadilha de estacas tem todo o comportamento da armadilha-base, então ela também exibe a mensagem "Jogador atingido!" quando a armadilha está funcionando. Arraste uma instância de BP_TrapSpikes para o nível e teste-a!
Subclasse de armadilha de fogo
Em seguida, você criará uma armadilha que estende o comportamento da armadilha-base. Uma armadilha de fogo adiciona um perigo que o jogador pode desligar com um interruptor, que é uma mecânica de jogabilidade que pode ser transformada em um novo quebra-cabeça.
Em Quebra-cabeças: interruptores e cubos, você criou a interface de Blueprint BPI_Interaction que um interruptor pode usar para ligar e desligar outros objetos do jogo. Você também pode usar essa interface em um Blueprint de armadilha para que um interruptor possa alterar a variável Ativa da armadilha durante o jogo.
Primeiro, você precisará de um novo material para usar quando a armadilha for desativada.
Para criar um material preto para a armadilha de fogo, siga estas etapas:
No Navegador de Conteúdo, vá para a pasta AdventureGame > Designer > Materials.
Clique com o botão direito
M_BasicColore selecione Criar instância de material.Dê o nome
M_BasicColor_Blackpara a instância de material de abra-a.Expanda Valores de parâmetro vetorial globais, habilite Cor e clique na amostra de cores para mudar para cinza-escuro (Hex sRGB =
3D3B3BFF). Fica melhor no jogo do que preto total.Salve e feche a instância de material.
Para criar uma subclasse de uma armadilha de fogo, siga estas etapas:
No Navegador de Conteúdo, clique com o botão direito em
BP_TrapBasee selecione Criar classe de Blueprint-filho.Dê o nome
BP_TrapFirepara o Blueprint e abra-o.Altere a cor da malha-base para que ela represente uma armadilha de fogo. Selecione o componente TrapBase e, no painel Detalhes, na seção Materiais, altere o material para
M_BasicColor_Red.Acima da janela de visualização, clique em Configurações de Classe.
No painel Detalhes, na seção Interfaces, perto de Interfaces implementadas, clique em Adicionar, pesquise
BPI_Interactione selecione-o.No painel Meu Blueprint , as funções de evento fnBPISwitchOff e fnBPISwitchOn são mostradas na seção Interfaces.
Assim como com
BP_Switch,configure os materiais personalizáveis para a armadilha de fogo:Na seção Variáveis do painel Meu Blueprint, crie duas variáveis com os nomes de
OffMaterialeOnMaterial.Mude o tipo para Material Interface (Object Reference).
Clique nos ícones de olho para torná-los públicos e editáveis.
Mude a categoria para Configuração.
Compile e defina os seguintes valores padrão:
OffMaterial:
M_BaseColor_BlackOnMaterial:
M_BaseColor_Red
Salve e compile o Blueprint para poder usar os eventos da interface no gráfico de evento da armadilha.
Estender o comportamento da armadilha
Assim como quando você criou a plataforma móvel em Quebra-cabeças: plataformas móveis, você precisa definir o gráfico de evento da armadilha para executar as seguintes ações quando um interruptor chamar fnBPISwitchOn e fnBPISwitchOff:
Ative ou desative a armadilha.
Mude o material da armadilha.
Com a plataforma móvel, você precisava que a plataforma começasse a se mover quando o jogador ativasse o interruptor. Para a armadilha, você precisa do oposto: a armadilha está ativa quando o nível começa e deve desligar quando o jogador ativa o interruptor.
Para adicionar uma lógica que desativa armadilhas de fogo quando o jogador pressiona um interruptor, siga estas etapas:
Vá para a aba EventGraph da armadilha de fogo. No painel Meu Blueprint, na lista Interfaces, clique duas vezes em fnBPIButtonOn para adicionar um nó de evento ao gráfico.
As variáveis
BP_TrapBasenão são exibidas no painel Meu Blueprint, mas você pode acessá-las na lista de ações do nó. Arraste o pin de execução do nó Event fnBPISwitchOn, pesquise avariável ativae selecione Set Active. Mantenha Ativa desabilitada.Após o nó Set, conecte um nó Set Material (TrapBase) (na seção Renderização > Material da lista de ações).
No nó Set Material, conecte uma referência à variável OffMaterial ao pin Material.
Para adicionar uma lógica que ativa armadilhas de fogo se um interruptor for desativado, siga estas etapas:
Na seção Interfaces, clique duas vezes em Event fnBPISwitchOff para adicionar esse nó.
Após o evento, conecte um nó de variável Set Active, mas desta vez habilite Ativa.
Após o nó Set, conecte um nó Set Material (TrapBase) e uma referência a OnMaterial.
Salve e compile seu blueprint.
O gráfico de evento completo da armadilha de fogo deve ficar assim:
Adicione uma instância de BP_TrapFire ao seu nível e experimente!
Atualizar o HUD com os PV do jogador
É hora de substituir os nós Print String por feedback real para o jogador. Você alterará o HUD para informar os PV do jogador em tempo real.
Adicionar uma variável PV ao HUD
Para adicionar vida dinâmica do jogador ao HUD, siga estas etapas:
No Navegador de Conteúdo, abra o Blueprint de widget
WBP_PlayerHUD. É preciso estar na visualização do Designer.Em Hierarquia, clique no widget txtHP. No painel Detalhes, habilite É variável e exclua 100 da propriedade Texto.
Vá até a visualização Gráfico e configure uma nova função que define o valor de "txtHP:
Na seção Funções, adicione uma nova função chamada fnSetHP.
Com a função selecionada, no painel Detalhes, clique em + perto de Entradas.
Dê o nome
NewHPpara a entrada e mude o tipo dela para Float.Depois, você mudará o personagem jogável para fazer uma chamada a essa função quando receber dano.
No gráfico da função fnSetHP, após o nó de entrada da função, conecte um nó SetText (Text).
Se não encontrar um nó na lista de ações do nó, desabilite Sensível ao contexto.
Configure o nó SetText (Text):
Para o Alvo, conecte uma referência à variável txtHP. Este é o widget de texto que exibe a vida do jogador.
Para In Text, conecte o pin de entrada de New HP do nó de entrada da função. A Unreal Engine adiciona automaticamente um nó To Text (Float) para converter o valor.
Salve e compile o Blueprint de widget.
O gráfico completo da função fnSetHP deve ficar assim:
Se você copiar esse trecho de Blueprint para o gráfico, precisará conectar o nó de entrada da função aos nós SetText e To Text.
Exibir os PV iniciais do jogador
Configure variáveis de HUD disponíveis antes de exibi-las. Nesse caso, você sabe os PV iniciais do jogador e pode exibir essas informações quando o jogo iniciar.
Para atualizar o Blueprints do personagem jogável e exibir os PV no HUD, siga estas etapas:
No Navegador de Conteúdo, abra o Blueprint
BP_AdventureCharacter. No gráfico de evento, procure a lógica Event Possessed.No painel Meu Blueprint, expanda Gráficos > EventGraph e clique duas vezes em Event Possessed para focalizar nele dentro do gráfico.
Entre o nó Set e o nó Add to Viewport, conecte um nó fnSetHP:
Para o Alvo, use o pin de saída do nó Set para tornar o HUD o Alvo.
Para New HP, conecte uma referência à variável Vida do jogador.
Certifique-se de que o pin Alvo do nó Add to Viewport também está conectado a um nó de variável do HUD.
No painel Meu Blueprint, clique na variável Vida. No painel Detalhes, mude (ou mantenha) o valor padrão. Este tutorial usa 100 pontos de vida iniciais.
Salve e compile.
A nova lógica de Event Possessed do jogador deve ser semelhante a esta:
Se estiver copiando essa lógica para o seu projeto, primeiro exclua o grupo de lógica de Event Possessed existente.
Agora, o HUD exibe a vida do jogador quando o jogo é iniciado. A última parte da lógica necessária é atualizar o HUD quando o jogador receber dano. Para fazer isso, você modificará a lógica de gerenciamento de dano do personagem para que ela funcione com o HUD.
Atualize a vida do jogador após receber dano
Para lidar com o dano no jogador, siga estas etapas:
No canto inferior esquerdo do gráfico de evento de
BP_AdventureCharacterprocure a seção de lógica chamada Manipulação de dano e morte, que inicia com um nó Event AnyDamage. Você deve modificar esta seção para executar sua própria lógica.Exclua todos os nós que estão depois do nó Branch. Mantenha o nó Branch.
Esta seção da lógica usa nós de operador para realizar cálculos. Quando o personagem recebe dano, o nó Event AnyDamage é acionado, passando informações sobre o dano causado, o tipo de dano, o controle e o ator que causou o dano. Em seguida, o dano é subtraído da variável Vida do personagem. Após a subtração da vida, o nó Branch verifica se a vida do jogador chegou a 0.
Por enquanto, você quer criar uma lógica que atualizará o HUD quando a vida do jogador for maior que 0. Portanto, no pin Falso, conecte um nó FnSetHP para enviar o novo valor de vida ao HUD.
Configure o nó fnSetHP:
Para o Alvo, conecte uma referência à variável HUD do personagem.
Para a entrada de New HP, conecte uma referência à variável Vida.
Salve e compile seu blueprint.
Agora o HUD exibe a vida atual do jogador e atualiza o valor de vida quando o jogador receber dano.
Volte ao Blueprint BP_TrapBase e exclua os nós Print String adicionados ao gráfico de evento da armadilha-base.
Jogue o jogo de novo e faça testes!
Criar uma condição de falha e de ressurgimento
Quando o jogador ficar sem vida e for eliminado, interrompa o jogo e dê a ele a chance de tentar novamente. Neste tutorial, você desabilitará os controles do jogador, comunicará ao jogador que ele perdeu o jogo e carregará o nível.
Primeiro, você criará um Blueprint de widget de fim de jogo que informa ao jogador que ele foi eliminado.
Adicionar uma tela de fim de jogo
Para criar um Blueprint de widget para a tela de fim de jogo, siga estas etapas:
No Navegador de Conteúdo, na pasta AdventureGame > Designer > Blueprints > Widgets, clique com o botão direito, vá para Interface do usuário e selecione Blueprint de Widget.
Na janela Escolha a classe-pai, clique em Widget de usuário.
Dê o nome
WBP_EliminatedScreenpara o Blueprint de widget e abra-o.
Para definir a interface de fim de jogo, siga estas etapas:
Na aba Paleta, procure a tela e arraste um painel de tela para [WBP_EliminatedScreen] na Hierarquia. Assim como no HUD, a tela é o widget-raiz.
A tela apresentará uma mensagem de fim de jogo sobreposta por um efeito de desfoque que facilita a leitura do texto. Na aba Paleta, arraste uma Sobreposição para ser filho da tela.
Com a sobreposição selecionada, no painel Detalhes, na seção Espaço (Espaço de Painel de Tela, expanda Âncoras e altere ambos os valores máximos (X e Y) para
1.As outras propriedades de espaço (abaixo de Âncoras) mudam para configurações de Deslocamento.
Ao compilar o HUD, você manteve todos os pontos de ancoragem em um canto. Assim, se o tamanho da tela mudasse, esses objetos permaneceriam ancorados no ponto de ancoragem. Agora, a sobreposição está ancorada em toda a caixa delimitadora da tela e encolhe ou estica para corresponder ao tamanho dela.
Quando você altera as configurações de âncora, o editor altera alguns valores de deslocamento para manter a forma padrão do painel de sobreposição. Para remover isso, altere Deslocamento direito e Deslocamento inferior para
0. Agora a sobreposição preenche a tela.Na aba Paleta, arraste um widget Desfoque de Segundo Plano para se tornar filho do painel Sobreposição.
Com o efeito de desfoque selecionado, no painel Detalhes, na seção Espaço (Espaço de sobreposição), altere:
Alinhamento Horizontal para Preenchimento Horizontal.
Alinhamento Vertical para Preenchimento Vertical.
Na seção Aparência, altere Intensidade do Desfoque para
5.Na aba Paleta, adicione um widget Texto como filho de Sobreposição.
Com o widget Texto selecionado, no painel Detalhes, na seção Espaço (Espaço de substituição), altere:
Alinhamento Horizontal para Alinhar ao Centro na Horizontal.
Alinhamento Vertical para Alinhar ao Centro na Vertical.
Na seção Conteúdo, altere o Texto para
Você foi eliminado… reiniciando nível.Na seção Appearance (Aparência), deixe o texto maior e mais fácil de ler configurando as seguintes propriedades:
Clique na amostra de cores perto de Cor e opacidade e escolha uma cor para seu texto. Este tutorial usa rosa (Color Hex sRGB =
FF4D7AFF).Expanda o cabeçalho Font (Fonte) e altere Size (Tamanho) para
60.Expanda Fonte > Configurações de contorno e altere o tamanho do Contorno para
1.
12. Salve e compile seu blueprint.
Lógica de compilação para uma condição de falha
Agora que você tem uma tela de fim de jogo, você pode modificar a classe do personagem para exibi-la quando o jogador ficar sem vida. Quando isso acontece, a execução passa pela etapa Verdadeiro do nó Branch com a qual você estava trabalhando antes.
Para lidar com a derrota do jogador, você precisará:
Desabilitar a entrada do jogador para que o jogador não possa se mover.
Exibir a tela de fim de jogo.
Reiniciar o nível após um período de tempo determinado.
Para interromper e carregar o jogo quando o jogador for eliminado, siga estas etapas:
Em
BP_AdventurePlayer, volte à lógica de tratamento de dano (começando com o evento AnyDamage) no Blueprints do personagem.Após o pin de execução Verdadeiro do nó Branch, conecte um nó Do Once e um nó Disable Input.
O jogador pode continuar sendo atingido depois de ficar sem vida. Portanto, o nó Do Once garante que a lógica será executada apenas uma vez.
Conecte o pin Controle do Jogador no nó Disable Input, conecte um nó Get Player Controller (na seção Jogo > Jogador da lista de ações do nó).
Há alguns nós chamados Get Player Controller. Certifique-se de que o nó tem um pin de entrada Índice do Jogador. Um índice de 0 é o índice padrão para o primeiro personagem jogável que surge no nível.
Após desabilitar o controle do jogador, crie e exiba a tela de fim de jogo:
Conecte um nó Create Widget. No nó, altere a Classe para
WBP_EliminatedScreen.Conecte os pins Valor de retorno e Execução do nó do widget a um nó Add to Viewport.
Adicione um atraso, obtenha o nome do nível atual e carregue-o:
Após o nó Add to Viewport, conecte um nó Delay e mude a Duração para
5segundos.Após Delay, conecte um nó Get Current Level Name.
Após Get Current Level Name, conecte um nó Open Level (by Name).
Conecte o pin Valor de retorno ao pin Nome do nível. O editor adiciona automaticamente um nó de conversão de string em nome.
Salve e compile seu Blueprint de jogador.
Esta seção do gráfico de evento BP_AdventureCharacter deve ficar assim:
Se estiver copiando esta lógica para seu projeto, exclua o grupo de nós de manipulação de dano (incluindo as lógicas de Event AnyDamage e Event Destroyed) primeiro.
Jogue seu nível para testá-lo. Pise em uma armadilha, faça seu personagem perder toda a vida e certifique-se de que o jogo será restaurado como planejado.
Adicionar perigos aos seus quebra-cabeças
Em Quebra-cabeças: interruptores e cubos, você aprendeu a projetar mecânicas de jogabilidade que adicionam dificuldade, tensão, consequências e decisões de risco e recompensa. Desastres de ambiente que causam dano ao jogador são uma das mecânicas que introduzem essas consequências. Você pode usar as armadilhas de estacas para adicionar perigo e consequências adicionais a quebra-cabeças anteriores e obstáculos no nível, e as armadilhas de fogo acionadas por interruptor podem criar quebra-cabeças mais dinâmicos que fazem o jogador interagir com o ambiente para revelar caminhos seguros.
Ao projetar jogos, uma parte importante para reduzir a sobrecarga e melhorar a velocidade de desenvolvimento é encontrar várias maneiras diferentes de usar e combinar objetos de jogabilidade. Em uma seção anterior desta série de tutoriais, falamos sobre as plataformas com tecnologia de interruptor para criar uma forma de avançar. Aqui, o mesmo interruptor pode desabilitar armadilhas de fogo para revelar um caminho para o jogador. Isso adiciona variedade ao nível sem precisar de um número infinito de sistemas únicos.
De forma semelhante à mecânica de jogo de porta e chave que você criou no início desta série de tutoriais, a armadilha de fogo se torna outra mecânica para gerenciar o ritmo do jogo e o acesso ao ambiente.
Criar um quebra-cabeça de labirinto com armadilhas de fogo
Na Sala 2, você combinará interruptores e armadilhas de fogo para criar um quebra-cabeça de labirinto onde o jogador deve desativar cuidadosamente os perigos para descobrir e coletar a última chave.
Esboçar o quebra-cabeça no papel ajuda muito. Como as armadilhas têm 1 m x 1 m, a amostra "Sala 2" pode acomodar uma grade de 7 x 9 de armadilhas. Comece traçando um caminho pela grade que termina na chave. Em seguida, divida o caminho em segmentos e coloque interruptores para controlar cada segmento.
Para aumentar a dificuldade e criar mais revelações e surpresas, adicione funcionalidades arquitetônicas que bloqueiem as linhas de visão. Por exemplo, coloque interruptores atrás de paredes ou pilares para que o jogador tenha que descobri-los ao longo do caminho.
Esse caminho em loop dá ao jogador um vislumbre da chave, para que ele descubra o objetivo enquanto percorre o primeiro segmento do caminho.
Com seu plano concluído, comece a montar o quebra-cabeça no Editor de Níveis.
Depois de criar o caminho para a chave e novas formas de rascunho, preencha o resto da sala com armadilhas de fogo para obscurecer a rota correta.
Renomeie os objetos de nível no Organizador para que fique claro quais armadilhas de fogo cada interruptor controla. Por exemplo, se BP_Switch1 desativar três armadilhas, nomeie-as como BP_FireTrap_S1_0, BP_FireTrap_S1_1 e BP_FireTrap_S1_2. Renomeie as armadilhas de fogo adicionais como BP_FireTrap_Extra para mostrar que elas não fazem parte do quebra-cabeça.
Se quiser, você pode ajudar o jogador a sair depois de concluído o quebra-cabeça adicionando um último interruptor sob a chave que desabilita algumas armadilhas no caminho.
Teste o quebra-cabeça com frequência, prestando atenção às linhas de visão, aos pontos de frustração e aos possíveis atalhos. Recrute um amigo para ajudar; ele pode encontrar brechas inesperadas. Durante o teste de jogo, você pode perceber que precisa fazer ajustes para interromper o jogador de pular partes do quebra-cabeça.
Se você descobrir uma brecha que pode ser explorada, há algumas opções:
Reorganize o caminho ou o quebra-cabeça.
Adicione mais bloqueadores arquitetônicos.
Aumente o dano de fogo para que desviar do caminho tenha consequências mais duras.
Deixe uma brecha que pode ser explorada, mas aumente o custo, dando ao jogador uma escolha e autonomia. Ele pode escolher entre gastar mais tempo para revelar o caminho seguro ou sacrificar seus PV para pegar a chave logo.
No quebra-cabeça do nível de amostra, adicionamos alguns escombros sob o arco que leva até a chave para que o jogador possa vê-la, mas não possa ir direto para ela. Também ocultamos os interruptores não apenas para algumas revelações recompensadoras, mas também para evitar pular essa parte do caminho.
Adicionar estacas aos obstáculos anteriores
Vamos adicionar estacas aos quebra-cabeças anteriores para criar consequências em caso de queda
Comece com o quebra-cabeça da Sala 1. Para a primeira plataforma móvel, mantenha as estacas baixas para que, se o jogador cair, ele possa apenas subir novamente e tentar outra vez. Ao introduzir uma nova mecânica, dê ao jogador um espaço seguro para que ele possa se concentrar no aprendizado.
Da mesma forma, na Sala Inicial, você pode adicionar algumas estacas ao fosso sob a primeira chave. O jogador pode praticar o salto nas duas primeiras plataformas para se preparar para o salto final e mais arriscado até a chave. Agora, pegar a primeira chave sem se ferir vai ficar ainda mais emocionante.
Quando o jogador entender o básico e tiver alguma prática em mover blocos em plataformas e interruptores, é hora de adicionar consequências. Abaixo da segunda plataforma, ou terceiro botão, coloque algumas armadilhas de estacas. Você aumentou a tensão, pois o jogador recebe dano se cair, mas pode se mover rapidamente para fora da armadilha para minimizar os estragos e continuar.
Por fim, para a última plataforma e o interruptor, continue aumentando o nível de perigo. Cubra a área abaixo com estacas para que o jogador tenha que correr mais para escapar delas e receber mais dano. A essa altura, o jogador já deve ser mais hábil com a mecânica, e a consequência para os erros parece mais justa porque ele já praticou.
Esse design segue esta estrutura popular para apresentar mecânicas de jogabilidade aos jogadores:
Introdução: a primeira plataforma ensina a mecânica do jogo com segurança.
Desenvolvimento: a segunda plataforma e cubo testa a habilidade de crescimento do jogador com riscos moderados.
Reviravolta: a última plataforma aumenta o perigo e adiciona uma nova direção de movimento, transformando a mecânica em um desafio tenso.
Como você aprendeu na aula de criação de jogo em Quebra-cabeças: plataformas móveis, ao intensificar as consequências em um quebra-cabeça, você equilibra imparcialidade e emoção.
Alterar o dano de uma armadilha
Você pode aumentar ou diminuir o dano de um tipo de armadilha para alterar o nível de dificuldade. Você pode fazer isso de duas maneiras:
No Organizador, pesquise "estacas" ou "fogo" e selecione todas as armadilhas desse tipo. No painel Detalhes, altere Configurações > Dano-base como quiser. Com esse método, lembre-se de alterar o Dano-base de todas as novas instâncias da armadilha que você adicionar ao seu nível. Ou adicione novas instâncias de armadilhas ao nível duplicando as armadilhas existentes para evitar a edição de cada nova instância.
OU
Abra um dos Blueprints de armadilha-filho e vá até a aba Script de Construção correspondente. Você não pode editar variáveis herdadas no painel Meu Blueprint, mas pode definir variáveis no gráfico. Conecte um nó Set Base Damage após os dois nós Script de Construção. No nó, altere o valor de Dano-base como quiser.
Para garantir que os objetos do jogabilidade sejam previsíveis para o jogador, certifique-se de que todas as armadilhas do mesmo tipo causam o mesmo dano.
No nível de amostra do tutorial, armadilhas de fogo causam 5 de dano por segundo, e instâncias de armadilhas de estacas são modificadas para causar 10 de dano por segundo.
Experimente o nível de amostra
Se quiser usar partes do cômodo projetado nesta parte do tutorial em vez de criar o seu próprio, copie os trechos de código a seguir.
Rascunho da Sala 2
Este trecho de código contém o chão, as paredes e as novas formas de rascunho adicionadas à Sala 2 para criar o quebra-cabeça da sala. No Organizador, todas as formas estão em uma pasta chamada Room2.
Begin Map
Begin Level
Begin Actor Class=/Script/Engine.TextRenderActor Name=TextRenderActor_19 Archetype="/Script/Engine.TextRenderActor'/Script/Engine.Default__TextRenderActor'" ExportPath="/Script/Engine.TextRenderActor'/Game/AdventureGame/Designer/Lvl_Adventure.Lvl_Adventure:PersistentLevel.TextRenderActor_19'"
Begin Object Class=/Script/Engine.TextRenderComponent Name="NewTextRenderComponent" Archetype="/Script/Engine.TextRenderComponent'/Script/Engine.Default__TextRenderActor:NewTextRenderComponent'" ExportPath="/Script/Engine.TextRenderComponent'/Game/AdventureGame/Designer/Lvl_Adventure.Lvl_Adventure:PersistentLevel.TextRenderActor_19.NewTextRenderComponent'"
End Object
Begin Object Class=/Script/Engine.BillboardComponent Name="Sprite" Archetype="/Script/Engine.BillboardComponent'/Script/Engine.Default__TextRenderActor:Sprite'" ExportPath="/Script/Engine.BillboardComponent'/Game/AdventureGame/Designer/Lvl_Adventure.Lvl_Adventure:PersistentLevel.TextRenderActor_19.Sprite'"
End Object
Begin Object Name="NewTextRenderComponent" ExportPath="/Script/Engine.TextRenderComponent'/Game/AdventureGame/Designer/Lvl_Adventure.Lvl_Adventure:PersistentLevel.TextRenderActor_19.NewTextRenderComponent'"
Text=NSLOCTEXT("[3C535F7772EB3B3657484B5E2D5B925D]", "2347F80B407C68C27836E990A20143CF", "Room 2")
HorizontalAlignment=EHTA_Center
Para copiar todo o rascunho da Sala 2, siga estas etapas:
Remova tudo que já estiver na Sala 2 (ou algo no final do Corredor 2):
Use o Organizador para selecionar os conteúdos existentes da Sala 2: clique com o botão direito na pasta
Room2e selecione Selecionar > Filhos imediatos. Pressione Excluir.Ou, mude a janela de visualização para a visualização ortogonal superior para selecionar e excluir manualmente o ambiente existente.
Clique em Copiar trecho de código completo.
No Unreal Editor, certifique-se de que a janela de visualização seja o painel ativo (clique em qualquer lugar da janela de visualização ou do Organizador e pressione Esc e, em seguida, pressione Ctrl + V.
O nível e o Organizador devem ficar assim:
Chave, armadilhas e interruptores da Sala 2
Esse trecho de texto contém os interruptores, as armadilhas e a chave vermelha do quebra-cabeça. No Organizador, todos os objetos estão em uma pasta chamada Room2.
Para copiar instâncias de Blueprints entre projetos, os ativos-pai de Blueprints devem ser totalmente idênticos e ter o mesmo nome e locais de arquivo. Se você alterou componentes, nomes de variável ou propriedades do Blueprints no projeto, o trecho de código pode não ser copiado como o esperado e você precisará definir esses objetos de nível manualmente.
Begin Map
Begin Level
Begin Actor Class=/Game/AdventureGame/Designer/Blueprints/Traps/BP_TrapFire.BP_TrapFire_C Name=BP_FireTrap_C_261 Archetype="/Game/AdventureGame/Designer/Blueprints/Traps/BP_TrapFire.BP_TrapFire_C'/Game/AdventureGame/Designer/Blueprints/Traps/BP_TrapFire.Default__BP_TrapFire_C'" ExportPath="/Game/AdventureGame/Designer/Blueprints/Traps/BP_TrapFire.BP_TrapFire_C'/Game/AdventureGame/Designer/Lvl_Adventure.Lvl_Adventure:PersistentLevel.BP_FireTrap_C_261'"
Begin Object Class=/Script/Engine.SceneComponent Name="DefaultSceneRoot" Archetype="/Script/Engine.SceneComponent'/Game/AdventureGame/Designer/Blueprints/Traps/BP_TrapFire.BP_TrapFire_C:ICH-DefaultSceneRoot_GEN_VARIABLE'" ExportPath="/Script/Engine.SceneComponent'/Game/AdventureGame/Designer/Lvl_Adventure.Lvl_Adventure:PersistentLevel.BP_FireTrap_C_261.DefaultSceneRoot'"
End Object
Begin Object Class=/Script/Engine.StaticMeshComponent Name="TrapBase" Archetype="/Script/Engine.StaticMeshComponent'/Game/AdventureGame/Designer/Blueprints/Traps/BP_TrapFire.BP_TrapFire_C:TrapBase_GEN_VARIABLE'" ExportPath="/Script/Engine.StaticMeshComponent'/Game/AdventureGame/Designer/Lvl_Adventure.Lvl_Adventure:PersistentLevel.BP_FireTrap_C_261.TrapBase'"
End Object
Begin Object Class=/Script/Engine.BoxComponent Name="TrapTrigger" Archetype="/Script/Engine.BoxComponent'/Game/AdventureGame/Designer/Blueprints/Traps/BP_TrapFire.BP_TrapFire_C:TrapTrigger_GEN_VARIABLE'" ExportPath="/Script/Engine.BoxComponent'/Game/AdventureGame/Designer/Lvl_Adventure.Lvl_Adventure:PersistentLevel.BP_FireTrap_C_261.TrapTrigger'"
End Object
Begin Object Name="DefaultSceneRoot" ExportPath="/Script/Engine.SceneComponent'/Game/AdventureGame/Designer/Lvl_Adventure.Lvl_Adventure:PersistentLevel.BP_FireTrap_C_261.DefaultSceneRoot'"
Para definir as peças de Blueprints do quebra-cabeça, siga estas etapas:
Clique em Copiar trecho de código completo.
No Unreal Editor, confirme que a janela de visualização ou o Organizador é o painel ativo e pressione CTRL+V.
Verifique as propriedades de configuração de cada interruptor e, se necessário, reconecte cada interruptor às armadilhas de fogo:
No Organizador, na pasta
Room2, clique emBP_Switch4.No painel Detalhes, na seção Configurações, expanda a Lista de objetos de interação.
Para cada elemento na lista, clique no menu suspenso, pesquise
S4e selecione uma das armadilhas de fogo marcadas comS4.Repita estas etapas para cada interruptor:
BP_Switch5acionaBP_FireTrap_S5_0-7BP_Switch6acionaBP_FireTrap_S6_0-3BP_Switch7acionaBP_FireTrap_S7_0-4BP_Switch8acionaBP_FireTrap_S8_0-3BP_Switch9, abaixo da chave, acionaBP_FireTrap_S9_0-4
O nível e o Organizador devem ficar assim:
Próxima
Em seguida, você aprenderá a adicionar outro perigo popular ao seu jogo: os PNJs inimigos! Aprenda a criar um inimigo de IA e adicione uma malha de navegação ao nível para que os inimigos encontrem o jogador e causem dano a ele.