Neste tutorial, você criará um quebra-cabeça de plataforma com dois objetos de jogabilidade comuns:
Um interruptor com placa de pressão.
Um cubo de física que reage ao jogador.
Você usará design de nível e mecânicas de jogo, como tempo, física e dano, para ajustar a dificuldade do quebra-cabeça e introduzir consequências para as ações do jogador.
Antes de começar
Este tutorial pressupõe que você já entenda os seguintes tópicos, abordados nas seções anteriores de Como projetar uma aventura de quebra-cabeça:
Materiais
Blueprints
Variáveis
Interfaces de Blueprint
Modo de Jogar no Editor (JNE)
Você precisará dos seguintes ativos criados em Criar uma chave.
M_BasicColor_Blue
Uma abordagem ao design de jogos
Independentemente do gênero, jogos envolventes fazem os jogadores sentirem algo; a emoção da competição entre jogadores ou o conforto de um simulador de fazenda. Essa resposta emocional contribui para o engajamento do jogador. Se o jogo não for envolvente, é menos provável que os jogadores continuem jogando, o que pode afetar o sucesso do projeto.
Como designer de jogos, o seu trabalho é projetar a jogabilidade por meio do design de nível e da mecânica do jogo. Você pode criar um nível intuitivamente, mas, neste tutorial, usaremos fórmulas para visualizar o processo.
Design de níveis
Por meio do design de nível, você pode aumentar ou diminuir a dificuldade de uma tarefa. Por exemplo, em um jogo de plataforma, pular para uma plataforma é uma tarefa. Se você colocar uma plataforma no limite superior da distância de salto de um personagem, estará aumentando a dificuldade de alcançar a plataforma e concluir a tarefa.
No entanto, se não houver consequências para a falha, mesmo uma tarefa de alta dificuldade provavelmente fará o jogador se sentir seguro.
Uma sensação de segurança é útil em seções de tutorial do jogo, em que o jogador pode aprender os controles sem consequências.
No entanto, uma sensação constante de segurança pode não ser útil para o seu jogo. Por exemplo, sem tensão, uma luta com um chefe pode parecer entediante, resultando na falta de engajamento do jogador.
Para deixar o jogador tenso, você pode introduzir consequências usando a mecânica de jogo dano.
Mecânicas de Jogo
O dano representa as chances de o jogador perder algo valioso, como:
Equipamento
Poderes
Progresso de nível
Um personagem jogável ou um mascote não jogável.
A dificuldade da tarefa, combinada com a gravidade das consequências, pode afetar o nível de tensão que o jogador sente:
Tarefas desnecessariamente difíceis com poucas consequências ou recompensas podem causar frustração no jogador.
A quantidade de tensão ao realizar uma tarefa pode afetar a quantidade de satisfação que o jogador sente quando atinge uma condição de vitória. A satisfação, especialmente quando combinada com uma recompensa, cria motivação para continuar jogando.
Uma condição de vitória é uma condição que o jogador deve cumprir para concluir uma tarefa com sucesso.
Criar um interruptor
Um interruptor é um objeto de jogabilidade que produz um efeito quando algo interage com ele.
Aprendendo a criar um interruptor, você pode criar uma funcionalidade de jogabilidade, como pressionar um botão para abrir uma porta. Nesse caso, você usará o interruptor para mudar a cor das colisões com atores no jogo.
Criar com lógica
O interruptor será ativado quando um objeto ou jogador fizer sobreposição a ele. Antes de começar a criar, vamos esboçar a lógica por trás dessa interação respondendo às seguintes perguntas: o que precisa acontecer com quem e quando?
Este é um resumo da lógica do interruptor:
No tempo de execução, o interruptor está desligado.
Se o jogador pisar no interruptor, este será ligado.
Se o jogador sair do interruptor, este será desligado.
Como o interruptor tem dois estados (ligado e desligado), você pode usar materiais para visualizar cada estado no tempo de execução. Durante o teste, isso verificará rapidamente se a lógica está funcionando corretamente.
Criar materiais
Para o estado desligado do interruptor, use M_BasicColor_Blue. Para o estado ligado, crie um material emissivo.
Um material emissivo emite luz.
Para criar o material emissivo, siga estas etapas:
No Navegador de Conteúdo, em AdventureGame > Designer > Materiais, clique com o botão direito e selecione Material.
Dê o nome de
M_EmissiveColorpara o material novo e clique duas vezes nele para abrir o Editor de Material.No gráfico de material, clique com o botão direito e pesquise Parâmetro vetorial. Clique nele para preenchê-lo no gráfico e dê o nome de
Cor. Isso controla a cor da luz do material.No nó Color, clique com o botão direito na amostra de cores para abrir o Seletor de Cores.
Escolha sua própria cor ou defina-a como Hex sRGB
27F774FFpara continuar.Clique com o botão direito e procure mais dois nós: um nó de constante e um de multiplicação.
Conecte o nó Color ao pin A do nó Multiply. Em seguida, conecte a Constante ao pin B do nó Multiply. Por fim, conecte o nó Multiply ao pin Cor emissiva do nó M_EmissiveColor.
O valor da constante controla o poder emissivo ou o brilho do material. Ajuste como preferir ou defina como
25para continuar.Salve e feche o material.
A pasta Materials deve ficar assim:
Como M_EmissiveColor é o único material emissivo neste tutorial, você não precisa criar instâncias. No entanto, as instâncias de material são uma maneira elegante de manter seu projeto modular e funcionando de forma eficiente em um ambiente de desenvolvimento.
Em seguida, você criará o interruptor.
Configurar uma classe de Blueprint
O interruptor será um Blueprint que consiste em uma malha estática e uma caixa de colisão. A caixa de colisão detecta o contato com o jogador, o que aciona os estados de ligado e desligado do interruptor.
A colisão é a detecção de dois objetos que entram em contato no tempo de execução. Caixas de colisão, assim como esferas e cápsulas, são volumes usados para fazer essas detecções. Por exemplo, hitboxes são um exemplo de uso de formas de colisão para detectar um ataque bem-sucedido.
Para começar, siga estas etapas:
No Navegador de Conteúdo, em AdventureGame > Designer > Blueprints, crie uma nova pasta chamada
Activation(Ativação).Dentro de Activation (Ativação), clique com o botão direito para criar uma classe de Blueprint.
Na caixa de diálogo Escolher classe pai, selecione Ator.
Dê o nome de
BP_Switchpara o novo Blueprint e clique duas vezes nele para abrir oBP_Switchno Editor de Blueprint.Na aba Componentes, crie uma malha estática ao clicar em Adicionar, pesquise o
cuboe selecione-o.Dê o nome de
Interruptorpara o cubo.No painel Detalhes, em Transformação, ajuste a escala do Interruptor para
2,0,2,0,0,1.Na aba Componentes, crie uma caixa de colisão ao clicar em Adicionar e pesquise
caixa de colisão.Dê o nome de
Gatilho.No painel Detalhes, em Posição, a juste o valor Z da colisão da caixa para
200.Em Escala, ajuste a escala para
1,5,1,5,5,0. Essa caixa de colisão é mais grossa que a malha estática para capturar colisões facilmente.Salve e compile o Blueprint.
A pasta Blueprints deve ficar assim:
Para evitar perder o trabalho se a compilação falhar, salve e então compile o Blueprint após qualquer alteração significativa.
Em seguida, você criará variáveis para controlar o comportamento do interruptor.
Criar variáveis
Por meio de variáveis, o BP_Switch pode referenciar o material que você acabou de criar. Em vez de codificar um material específico no interruptor, você pode trocar os materiais em tempo real, o que será feito mais adiante neste tutorial.
Por ora, crie as seguintes variáveis em BP_Switch:
Nome da variável | Tipo | Valor padrão | Explicação |
OnMaterial | Interface do material |
| A cor do interruptor quando ligado. |
OffMaterial | Interface do material |
| A cor do interruptor quando desligado. |
Na aba MyBlueprint, em VARIABLES, crie duas variáveis novas ao clicar no botão + duas vezes.
Chame uma de
OnMateriale a outra deOffMaterial.Defina o tipo de pin como interface de material (referência de objeto).
Selecione OnMaterial. No painel Detalhes, perto de Categoria, crie uma nova categoria chamada
Configurações.Clique em Compilar para acessar o Valor padrão. No Valor padrão, selecione
M_EmissiveColor. Esta variável está pronta por enquanto.Selecione OffMaterial. No painel Detalhes, adicione-o à categoria Configurações.
No Valor padrão, selecione
M_BasicColor_Blue.Salve e compile.
Agora que o Blueprint pode fazer referência aos materiais, você usará a lógica para instruir o interruptor quando usá-los.
Implementar sua lógica
Você deve ter uma caixa de colisão, uma malha estática e dois materiais. A lógica do interruptor pode ser escrita como:
No tempo de execução, o Interruptor deve exibir OffMaterial.
Se o Gatilho detectar uma colisão, defina o material do Interruptor para OnMaterial.
Se o Gatilho parar de detectar uma colisão, defina o material do Interruptor como OffMaterial.
Para criar essa lógica, use um script de construção para instruir o BP_Switch a usar OffMaterial no tempo de execução:
Na aba Script de Construção, arraste o pin Execução no nó Construction Script e pesquise Definir material (Interruptor). Clique para criá-lo.
No nó Set Material, arraste o pin Material e pesquise Get OffMaterial. Selecione-o.
Salve e compile.
Você lidará com a lógica restante no EventGraph. Para instruir o interruptor a ligar e desligar em caso de sobreposição, siga as etapas abaixo:
No EventGraph, exclua os nós Event BeginPlay, Event ActorBeginOverlap e Event Tick. Você não precisará deles.
Na aba Meu Blueprint, no cabeçalho Componentes, clique com o botão direito em Gatilho e selecione Adicionar evento > Adicionar OnComponentBeginOverlap.
Repita o processo para adicionar um nó OnComponentEndOverlap também.
No pin Execução do nó OnComponentBeginOverlap(Trigger), arraste e procure o SetMaterial (Switch).
No pin Material do nó Set Material, arraste e pesquise Get OnMaterial.
No pin Execução do nó OnComponentEndOverlap(Trigger), arraste e pesquise Set Material (Switch).
No pin Material do nó Set Material, arraste e pesquise Get OffMaterial.
O interruptor está pronto. Salve e compile.
O gráfico do Script de Construção deve ficar assim:
O EventGraph deve ficar assim:
Agora você pode testar seu projeto para conferir se o interruptor funciona corretamente.
Arraste uma instância de BP_Switch no Navegador de Conteúdo para a Sala 1. Clique no menu de três pontos, na barra de ferramentas Playmode, e selecione Posição da câmera atual. Isso garante que você entrará no modo JNE a partir da sua posição atual na janela de visualização em vez de percorrer todo o nível para testar uma funcionalidade.
No modo JNE, quando você pisa no interruptor, ele deverá acender. Quando você sair, ele deverá voltar a ser azul.
Os benefícios do desenvolvimento modular
Digamos que você queira dois interruptores em vez de um, mas queira que o segundo acenda uma luz vermelha em vez de verde. Você poderia criar um interruptor com a mesma lógica e atribuir um material vermelho, mas isso consumiria tempo de desenvolvimento e criaria mais sobrecarga para o projeto.
A sobrecarga refere-se ao consumo de recursos (poder de processamento, tempo, quantidades de armazenamento e assim por diante).
Como as plataformas (computadores e consoles) têm poder de processamento finito, os desenvolvedores de jogos geralmente preferem trabalhar de forma modular para reduzir a sobrecarga.
Como você usou Blueprints e variáveis para criar o interruptor, você já está trabalhando de forma modular. Vejamos seu trabalho em ação:
Abra
BP_Switchno Editor de Blueprint ao clicar duas vezes no Navegador de Conteúdo.Em Variáveis, selecione OnMaterial e clique no ícone do olho para abri-lo.
Selecione OffMaterial para fazermos a mesma coisa de uma maneira diferente. No painel Detalhes, habilite Instância editável. Você notará que o ícone do olho abriu, tornando a variável global.
Salve, compile e feche.
Você já deve ter uma instância de BP_Switch no nível, então arraste uma segunda instância. Com um dos interruptores selecionados na janela de visualização, o painel Detalhes exibirá uma nova categoria de interface chamada configuração. Essa é a categoria de variável que você criou em Como criar variáveis. A configuração exibe as variáveis globais como parâmetros que você pode alterar em tempo real na janela de visualização.
Experimente alterar os materiais para o que quiser e teste como os interruptores reagem no modo JNE. Você perceberá que cada instância do interruptor pode conter materiais de ativação e desativação exclusivos, sem a necessidade de criar interruptores do zero, acelerando o desenvolvimento e reduzindo a sobrecarga.
Se quiser uma janela de visualização igual à nossa, exclua a segunda instância do interruptor antes de continuar este tutorial.
Criar ativações únicas e múltiplas
O interruptor liga e desliga indefinidamente. Em certos casos, é importante ativá-lo apenas uma vez. Por exemplo, em um corredor que leva a um espólio, você pode usar um interruptor para ativar uma armadilha que o jogador deverá evitar. Se o jogador conseguir evitar a armadilha e coletar o espólio, o interruptor não ativará a armadilha novamente.
Em vez de descartar o que já foi criado, adicione um booleano para permitir apenas um uso do interruptor.
Nome da variável | Tipo | Valor padrão | Explicação |
ActivateOnce | Booleano | False | Determina se o interruptor deve poder ser ativado várias vezes ou apenas uma vez. |
Para fazer isso, siga estas etapas:
No Editor de Blueprint para
BP_Switch, em Variáveis, clique no botão + para adicionar uma nova variável.Dê o nome de
ActivateOncee defina o tipo de pin como Boolean (Booleano).No painel Detalhes, marque a caixa Instância editável.
Clique no menu suspenso ao lado de Categoria e selecione Configuração.
Clique em Compilar para acessar o valor padrão da variável e verifique se ela está desmarcada. Isso significa que ActivateOnce não estará habilitado por padrão para esse Blueprint.
No EventGraph, clique com o botão direito e pesquise um nó Branch.
No pin Condição, no nó Branch, arraste e pesquise Get ActivateOnce.
Arraste o pin Execução do nó On Component End Overlap (Trigger) para o pin Execução do nó Branch. Ele deve se desconectar do nó SetMaterial.
Conecte o pin Falso do nó Branch ao pin Execução do nó Set Material. Isso significa que, quando o objeto se afasta do interruptor, uma decisão é tomada: se ActivateOnce for alternado para verdadeiro, o interruptor para de detectar colisões. Se ActivateOnce for alternado para Falso, o interruptor funciona indefinidamente.
Salve, compile e feche o Blueprint.
Selecione
BP_Switchna janela de visualização. No painel Detalhes, ActivateOnce deve ser uma caixa de seleção alternável para essa instância. Habilite-o para ver como funciona.
O EventGraph deve ficar assim:
Clique em Jogar para testar a variável no modo JNE. Com ActivateOnce habilitado, o interruptor deve permanecer aceso mesmo depois de sair dele.
Ativar interruptores com física
Mais adiante neste tutorial, o jogador precisará manter o interruptor pressionado enquanto explora o restante do nível. Para isso, você criará o segundo objeto de jogabilidade desse quebra-cabeça, o cubo de física. Isso incorpora a mecânica do jogo, física, no quebra-cabeça que você está criando.
Para criar um cubo de física usando Blueprints, siga estas etapas:
No Navegador de Conteúdo, vá para AdventureGame > Designer > Blueprints > Ativação, clique com o botão direito e crie uma nova Classe de Blueprint.
Na caixa de diálogo Escolher classe pai, selecione Ator.
Chame o novo Blueprint de
BP_Cube.Clique duas vezes nele para abrir
BP_Cubeno Editor de Blueprint.Na aba Componentes, crie uma malha estática ao clicar em Adicionar, pesquise o
cuboe selecione-o.Chame a malha de
Cubo.No painel Detalhes, em Malha estática, pesquise e selecione SM_ChamferCube.
Defina a posição Z como
50,0.Em Materiais, defina o Elemento 0 como
M_BasicColor_Blue.Em Física, habilite Simular física. Essa configuração habilita o uso da engine de física do Chaos da UE, permitindo que o cubo reaja ao empurrão do jogador.
Salve e compile.
Para testar a funcionalidade, arraste uma instância de BP_Cube para o nível, perto do interruptor. Pressione Jogar para entrar no modo JNE e use as teclas de letras WASD para empurrar o BP_Cube até um interruptor e ligá-lo.
Depuração
Se você empurrar o cubo até o interruptor, este será ligado, mas você poderá notar um problema. Se você se afastar do interruptor, ele será desligado mesmo que o cubo ainda esteja sobreposto a ele.
Examine a lógica atual para encontrar o erro:
Se o Gatilho parar de detectar uma colisão, defina o material do Interruptor como OffMaterial.
Para resolver esse problema, instrua o Gatilho a verificar se há atores sobrepostos antes de continuar:
Se o Gatilho parar de detectar e se não houver nenhum ator sobreposto a ele, defina o material do Interruptor como OffMaterial.
Para fazer esse ajuste nos Blueprints, siga estas etapas:
No Editor de Blueprint para o
BP_Switch, clique com o botão direito e crie um nó Branch.Arraste o pin Condição, pesquise e crie um nó Is Empty (Array).
No pin Matriz de destino do nó Is Empty, pesquise e crie Obter atores sobrepostos (Trigger).
Defina o filtro de classe como Ator.
Conecte essa lógica aos nós existentes ao arrastá-lo do pin Falso do primeiro nó Branch e conecte-o ao pin Execução do segundo nó Branch.
Conecte o pin Verdadeiro do segundo nó Branch ao pin Execução do nó Set Material.
Salve e compile.
O EventGraph deve ficar assim:
Para ajustar as configurações de colisão do Gatilho, siga estas etapas:
Na aba Componentes, selecione Gatilho.
No painel Detalhes, no cabeçalho Predefinições de colisão, defina o menu suspenso como Personalizado.
No menu suspenso Colisão habilitada, selecione Colisão habilitada (consulta e física).
No menu suspenso Tipo de objeto, selecione WorldDynamic.
Ao lado de WorldDynamic, marque Ignorar.
Salve e compile.
Entre no modo JNE para testar sua solução. O interruptor deve permanecer aceso enquanto houver algum ator em sobreposição a ele, mesmo que um deles se afaste.
Criar funcionalidade adicional
Até agora, você criou um interruptor que liga e desliga. Isso é excelente para ver se o interruptor está funcionando corretamente, mas pode ser mais útil. Em seguida, você usará o interruptor para ativar outros objetos no nível.
Primeiro, você criará uma interface de Blueprint com duas funções, cada um representando o estado ativado e desativado do interruptor. Essas funções são usadas como eventos sinalizados entre objetos.
No Navegador de Conteúdo, vá para AdventureGame > Designer > Blueprints > Ativação, clique com o botão direito e destaque o Blueprint. Em seguida, selecione Interface de Blueprint.
Chame a interface
BPI_Interaction. Clique duas vezes para abrir a janela Interface de Blueprint.No painel MyBlueprint, já deve existir uma nova função. Dê o nome de
fnBPISwitchOn.Clique em Adicionar e, em seguida, na função para criar uma segunda função. Dê o nome de
fnBPISwitchOff.Sua interface está concluída. Salve, compile e feche.
Em seguida, você criará uma matriz que contém todos os objetos que deseja ativar com o interruptor. Neste tutorial, você usará uma matriz para gerenciar quais objetos o interruptor ativará, em vez de criar uma lógica única para cada novo objeto.
Nome da variável | Tipo | Valor padrão | Explicação |
InteractObjectList | Matriz do ator | Nenhum | A matriz de atores que o interruptor ativa. |
Na aba Meu Blueprint de
BP_Switch, em VARIÁVEIS, clique no botão + para criar uma variável nova.Dê o nome de
InteractObjectListe defina o tipo de pin como Ator (referência de objeto).No painel Detalhes, perto do Tipo de variável, defina o tipo de contêiner como Matriz.
Para torná-lo um parâmetro de interface, marque Instância editável e adicione-o à categoria Configuração.
Salve e compile.
Usando a lógica, você instruirá o interruptor a iterar cada objeto na matriz (que está vazia no momento) e sinalizá-lo usando a interface BPI_Interaction criada anteriormente. Para isso, use um For Each Loop.
Para fazer isso, siga estas etapas:
No EventGraph, arraste do pin de Execução do nó Set Material (do nó On Component Begin Overlap) e pesquise For Each Loop.
Para instruir quais objetos devem realizar o evento, arraste do pin de Matriz em For Each Loop e pesquise Get InteractObjectList.
Por fim, arraste do pin Loop Body no For Each Loop e procure fnBPISwitchOn. Este é o evento que você está chamando.
Conecte o pin Elemento de matriz no For Each Loop ao pin de Alvo no nó fnBPISwitchOn.
Isso também deve ser feito para On Component End Overlap (Trigger). Para acelerar o processo, selecione o For Each Loop e o nó Interact Object List e copie-o ao clicar com o botão direito > Copiar ou Ctrl + C. Pressione CTRL + P para colá-lo no gráfico.
Conecte o pin de Execução do nó Set Material ao pin de Execução do For Each Loop.
No pin de Loop Body do For Each Loop, arraste e pesquise fnBPISwitchOff. Conecte o pin Elemento da matriz ao pin Alvo.
O interruptor está pronto. Salve, compile e feche.
O EventGraph deve ficar assim:
Você criou a base para ativar uma lista única de objetos em seu nível para cada instância do seu interruptor. No próximo tutorial, você criará o terceiro objeto de jogabilidade deste desafio: uma plataforma móvel.