Transcrições
1. Introdução: Bem-vindo ao meu curso sobre sistemas de diálogo e eventos em Gado. Este curso é uma continuação dos fundamentos do desenvolvimento de jogos
em Gado, mas pode ser seguido e aplicado a qualquer projeto que envolva um personagem que
o jogador possa controlar para interagir com NPCs ou objetos pressionando um botão e
exibindo um diálogo Você está convidado a se juntar ao
nosso servidor de discórdia para trabalhar neste curso
ao lado de seus colegas Neste curso,
abordaremos a criação de caixas de diálogo, eventos
e interações. Em seguida, junte-os
com bandeiras de progresso, controles de
câmera e animações de
personagens Quando terminar, você terá um sistema
abrangente de diálogos
e eventos para seu jogo que pode
ser usado para produzir cenas cortadas de
alta qualidade e narrativas ramificadas
complexas que reagem às escolhas dos jogadores e permitem que eles
progridam no Você também aprenderá habilidades úteis para trabalhar com o motor de
jogo Gada, organizando e projetando seus projetos para
serem mais escaláveis Você
aprenderá a codificar com script
GD com tudo
explicado em detalhes Aplicaremos princípios de design
orientado a objetos em nossos scripts,
herança, encapsulamento
e abstração,
juntamente com outros padrões de design de
engenharia de software, juntamente com outros padrões de design de
engenharia de software como o padrão Singleton e
Composite,
para mantê-los organizados, personalizáveis e reutilizáveis para personalizáveis Todos os arquivos do projeto
também estão disponíveis no Github, se você precisar revisar
o projeto como estava depois de concluir
cada lição Esses vídeos foram gravados
usando o Gadot versão 4.2 0.2. O projeto começa
com ativos dos pacotes remasterizados
K Kits Character and
Dungeon
feitos por K L auberg e do pacote
Guy básico feito por Penzla feitos por K L auberg e do pacote
Guy básico feito por Todos estão disponíveis para
download gratuito no dot IO.
2. Caixa de diálogo: Olá, amigos. Antes de
começarmos, você deve ter visto um jogo
em seu projeto que contenha um personagem que o jogador possa controlar e um nível em que ele
possa andar. Você deve ter outros
personagens para atuar como NPCs ou objetos com os quais o
personagem possa interagir Ao longo deste curso,
adicionaremos a capacidade de o jogador interagir com o ambiente
pressionando um botão, seja para iniciar
um diálogo com outro personagem ou
interagir com um objeto Essas interações incluirão o progresso do jogador no
jogo, a decisões e a criação cenas
básicas com comportamentos e animações de
câmera personalizados comportamentos e animações de
câmera Você pode usar seu próprio projeto para acompanhar este
curso ou baixar um projeto inicial
do meu Github intitulado
Godo Dialog Course Seu projeto pode ser
dois D ou três D e quase qualquer
gênero de jogo que envolva a interação do jogador com o ambiente ou com
os NBCs Vamos começar adicionando uma caixa
de diálogo à cena do jogo. Dependendo dos
ativos que você está usando, talvez
você queira transformar
o nó raiz da caixa de diálogo em um painel
ou em um contêiner de painéis. Mas esses ativos são tão grandes que eu
quero reduzi-los, que exigirá que
o nó
do painel não tenha filhos, já que a escala
seria herdada, e eu não quero isso Talvez você queira que a caixa de
diálogo fique visível no FAD
por motivos artísticos Realmente depende de
como você deseja usá-lo. Vou desenhar o meu primeiro atrás de todo o
resto na interface do usuário. Com o nó raiz dos meus diálogos,
apenas um nó de controle
simples que,
na verdade, não representa
nada desenhado na tela Vou ancorar a caixa de diálogo
na parte inferior da tela, cobrindo toda a
largura, e colocarei a âncora superior em dois terços abaixo da parte superior da A caixa de diálogo cobrirá o terço
inferior da tela, que com o tamanho da minha janela
é de cerca de 240 pixels. Em seguida, adicionarei um nó secundário, um painel para desenhar a caixa
real na tela e definirei suas âncoras como totalmente destruídas, de
forma que corresponda
à forma que corresponda Dando ao nó
do grupo de diálogo um novo tema. Podemos adicionar um painel ao tema e dar
a ele uma nova
textura de caixa de estilo para desenhá-lo. Vou usar a caixa laranja arredondada
como a textura da minha caixa de diálogo com margens de
textura de 256
pixels em todos os lados Essa imagem é enorme,
com 1522 pixels. Vou reduzir o tamanho do
nó até a metade. Em seguida, use o encaixe de grade e defina suas dimensões para corresponder ao nó pai
da caixa de diálogo A maioria das caixas de diálogo
conterá pelo menos
o nome da pessoa que está falando e uma linha de diálogo
organizada verticalmente Vamos adicionar um
contêiner de caixa vertical e, dentro dele, também adicionar dois rótulos. Um para o nome do orador e outro para uma
linha de diálogo. Mas para a linha de diálogo, talvez
você queira usar
um rótulo de rich text em vez de um rótulo normal. rótulos de texto rico
permitem o uso do código
BB para fazer todos os tipos de truques
de formatação no texto do diálogo, como negrito, itálico ou até cores e Você pode expressar o
tom do palestrante, associar temas
relacionados a cores exclusivas ou destacar palavras-chave importantes para ajudar o jogador a
se lembrar delas. Vou redimensionar a caixa
vertical para caber dentro dos limites
da caixa de diálogo Costumo usar a
grafia americana de diálogo ao referir a uma interface de
interface de usuário que exibe texto Mas vou usar a
grafia tradicional do diálogo ao referir a uma conversa entre personagens em uma cena Vamos preenchê-los com um texto de
espaço reservado para que possamos ver como ficam Alguém está falando, e
eles estão dizendo um pouco de oram Ipsum. Ativar o ajuste de
conteúdo forçará o
nó do rótulo de rich text a se expandir para caber em seu conteúdo, como faria um nó de rótulo
normal. Vamos definir a fonte padrão
e o tamanho da fonte para o tema, usando a
fonte mais legível como padrão, com um tamanho razoável e
fácil de ler. Vou usar 32. Adicionando um
rótulo de rich text ao tema, podemos definir a cor padrão para a linha de diálogo e não o nome do locutor,
pois são tipos de nós diferentes. Vou usar preto para me
destacar melhor contra
a caixa laranja. Em seguida, podemos adicionar o nó do
rótulo ao tema e usar uma fonte diferente para
exibir o nome do palestrante. Também darei aos
rótulos uma
cor e uma sombra diferentes, para que se destaquem ainda mais. Vou usar uma fonte mais sofisticada para a etiqueta com
o nome do palestrante. Antes de escrever qualquer
diálogo para seu jogo, é uma boa ideia obter
uma estimativa aproximada da
quantidade de texto que
cabe confortavelmente na tela do seu jogo Certifique-se de que sua caixa de diálogo
seja capaz de exibir uma quantidade razoável de texto ao mesmo tempo, ser
facilmente legível. Usando
textos de espaço reservado falsos como esse, podemos criar o
pior cenário possível de quanto texto podemos exibir e usar isso como um limite rígido ao escrever
diálogos para o jogo Também deve
haver alguma indicação para o jogador de que o
diálogo terminou e que o jogo está aguardando a entrada
deles para continuar. Vamos adicionar um botão
à caixa de diálogo. Como quero que a textura dos
botões
corresponda à escala
da textura da caixa, vou usá-la como filha
da caixa e fixá-la no canto inferior
direito Esse é um botão exclusivo,
então, em vez de definir sua caixa de
estilo no tema, usarei a seção de
substituição do tema para adicionar uma nova
caixa de estilo de textura que se aplicará somente a esse botão
específico Vou usar o ícone de seta. Use as dimensões em pixels
da imagem para definir
o tamanho do botão e posicioná-lo
em um local com boa aparência. Vou criar mais caixas de estilo para os outros estados de botão
usando o mesmo ícone de seta. Em seguida, aplique a modulação de cores
para cada estado. Cinza desbotado para pessoas com deficiência, cores
verde e amarelo para os outros. O tema dos botões
ainda está disponível se
quisermos usá-lo
posteriormente para adicionar botões temáticos
à caixa de diálogo sem
afetar esse Certifique-se de verificar
como sua caixa de diálogo aparece no
contexto do jogo e
fazer os ajustes
necessários até ficar
satisfeito com a aparência. Quando estiver satisfeito
com sua caixa de diálogo, podemos ocultá-la por
padrão clicando no ícone ao lado dela
na árvore da cena. Em seguida, vamos adicionar um script a ele
e salvá-lo na pasta de scripts de
interface do usuário. Vamos pegar uma referência ao alto-falante e ao rótulo de rich text
da caixa de diálogo, atribuindo-os a variáveis
privadas Nosso script precisa ser
capaz de exibir qualquer linha de diálogo falada por
qualquer palestrante em nosso jogo, o que significa que
precisará de uma função pública aceite dois parâmetros, quem está falando
e o que está dizendo. Ambos como cordas. Ambos podem ser definidos acessando
a propriedade text, atribuindo-a ao parâmetro
passado para a função Nas versões mais antigas do Godot, o rótulo de rich text terá propriedades
separadas para
texto e texto de código BB Certifique-se de usar
a propriedade de texto do código BB se quiser que seu código
BB funcione. Podemos tornar isso mais funcional fazendo com que o
alto-falante seja opcional, definindo a propriedade visível
do rótulo do alto-falante para
depender de o nome
do alto-falante ser ou não uma string vazia. Se trocarmos a ordem
dos parâmetros, também
podemos tornar o
parâmetro opcional
atribuindo um valor
padrão a uma string vazia Os parâmetros opcionais sempre
devem ser listados após os obrigatórios
ao definir uma função. Também devemos definir a
propriedade visível da caixa de diálogo. Vamos fazer isso em uma função
pública separada chamada open. E também uma função fechada
para configurá-la como falsa. Também pegando uma referência ao botão
continuar. Depois que o texto
for exibido, devemos dizer ao botão de
continuação que capture o
foco para que ele possa ser acessado
com um controlador. Vamos conectar o sinal do botão
pressionado ao script e usá-lo para fechar a caixa de
diálogo por enquanto. No script do gerenciador de jogos, podemos pegar uma referência
à caixa de diálogo. Quando o jogo começa, podemos fazer com que a caixa de
diálogo exiba uma mensagem. Olá, mundo. Como o
nome do palestrante é opcional, vamos ver como
funciona sem ele. Desta vez, vamos adicionar um nome de
orador, fantasma. O fantasma dirá: Boo, eu sou um fantasma assustador, mas ele terá um código
BB aplicado a ele, para que o jogador
tenha uma ideia melhor de como a linha
deve ser lida Se suas etiquetas
saírem dos limites da área,
elas serão cortadas. Mas podemos mudar
esse comportamento nas propriedades de controle,
desmarcando
o conteúdo do clipe Existem várias tags de código BB
diferentes que fornecem uma grande
variedade de efeitos, e você pode até mesmo
criar suas próprias usando um script personalizado herdado
do efeito rich text Para obter uma lista completa das tags de código BB, consulte o Google Docs. Agora podemos exibir
uma caixa de diálogo para fornecer informações ao jogador. Na próxima lição, adicionaremos uma animação de digitação e exibiremos
sequências de Te vejo na próxima aula.
3. Monólogo: Olá, amigos.
Na lição anterior, adicionamos uma
caixa de diálogo à cena do jogo. Nesta lição,
animaremos a digitação para que o texto apareça
gradualmente e permita que
a caixa exiba
sequências de Para fins de demonstração, voltei a usar o Guram Ipsum nesta lição e tornarei a caixa de
diálogo visível Com o nó do rótulo de
texto rico em diálogo selecionado, expanda a seção de
texto exibida. Podemos ver que o número
de caracteres visíveis é uma propriedade facilmente editável com um valor padrão
de menos um Menos um
caractere visível é obviamente impossível e está sendo
usado para significar ilimitado. Mas se ajustarmos esse número
clicando e
arrastando-o lentamente para a direita, podemos ver o texto desaparecer
e ser preenchido gradualmente à medida o número de caracteres visíveis aumenta de zero para
o comprimento da string Em nosso script de diálogo, quando definimos o texto que
está sendo exibido, também
podemos definir os
caracteres visíveis como zero. Em seguida, queremos aumentar o
número de caracteres visíveis gradualmente ao longo do tempo até que todos
estejam visíveis. Como não sabemos
quantos caracteres existem, podemos usar um loop wile para continuar repetindo o mesmo código,
desde que a condição seja A condição, nesse caso,
será desde que o número de caracteres
visíveis seja
menor que o número total
de caracteres. Verificando a documentação
do nó do rótulo de rich text. Podemos ver que
existe uma função chamada get total de
caracteres, que retorna convenientemente o número total de
caracteres, excluindo
as tags de código
BB Embora o número de caracteres
visíveis seja menor que a contagem total de
caracteres, podemos adicionar um aos caracteres
visíveis. Mas esse loop e
toda a função serão executados no
espaço de um único quadro. O texto inteiro ainda
será exibido instantaneamente. Precisamos fazer com que o loop faça uma
breve
pausa a cada iteração Podemos dizer ao loop que aguarde um sinal emitido
pela árvore de cenas, um sinal que é emitido uma
vez a cada quadro do processo, 60 vezes por segundo com as configurações
padrão do projeto Esse loop agora
exibirá os caracteres a uma
taxa de 60 caracteres por segundo e
se ajustará automaticamente à
configuração da taxa de quadros do projeto. Mas e se não quisermos
usar a taxa de quadros do projeto? Em vez disso, vamos adicionar uma variável de velocidade de
digitação
ao recurso de configurações e atribuir a ela um valor padrão de
90 caracteres por segundo Na cena do menu de configurações, podemos adicionar um rótulo e um controle deslizante para permitir que o jogador
altere a velocidade de digitação E dê a ele um alcance razoável. Vou configurá-lo para
30 a 120 caracteres por segundo com um valor de
etapa de dez Conecte seu
sinal de valor alterado ao script. E altere o recurso de
configurações para corresponder e inicializar o
valor na função pronta Consulte o curso
básico sobre desenvolvimento de jogos desta série para
obter mais informações sobre as configurações do jogo De volta ao script da caixa de diálogo, precisaremos de uma variável para conter quanto tempo
passou desde o início da digitação e defini-la como zero
antes do
início do ciclo de digitação Então, em cada iteração do loop, podemos adicionar a
quantidade de tempo que passou acessando
a função, obtendo o processo Delta T. Como sabemos quantos
segundos se passaram desde o início da digitação e
quantos caracteres queremos digitar por segundo, só
precisamos multiplicar
esses
dois números para obter o número Vamos ver como fica. Podemos até mesmo alterar a
velocidade de digitação nas configurações do jogo. O registro de depuração nos diz que
estamos reduzindo a precisão, convertendo um float em um inteiro Poderíamos fazer com que
a velocidade de digitação
flutuasse ou ignorar
esse aviso, pois
sabemos que o controle deslizante foi
configurado para
usar apenas números inteiros de qualquer flutuasse ou ignorar esse aviso, pois
sabemos que o controle deslizante foi configurado para
usar apenas Então, adicionarei uma
tag de aviso para ignorar antes dessa linha. Godo sabe ignorar o aviso de precisão
reduzida. Isso também acontece no script
do menu de configurações
pelo mesmo motivo. Agora, a velocidade de digitação
é um pouco mais rápida, mas alguns jogadores ainda podem querer pular a animação de
digitação Então, vamos mudar o comportamento
do botão de continuação. Se o jogador pressionar o botão
Continuar
e o número de caracteres
visíveis for
menor que a contagem total de personagens, podemos
definir instantaneamente o número de caracteres
visíveis igual
à contagem total de personagens Isso exibirá o texto
inteiro e forçará a quebra do loop pois sua condição não
é mais atendida Se o número de caracteres
visíveis
não for menor que a contagem
total de caracteres, isso significa que a digitação já
foi concluída Nesse caso, devemos
fechar a caixa de diálogo. Para que isso funcione
com um controle, o botão continuar precisará
capturar o foco antes
do início da digitação Quando a
animação de digitação começa e o jogador
pressiona o botão continuar, ele pula a animação de digitação
ou fecha
a caixa de
diálogo, não as
duas ou fecha
a caixa de
diálogo, não as Ignorar a
animação de digitação ainda dará
ao jogador a oportunidade de
lê-la antes de prosseguir Mas e se quisermos que
um personagem diga mais de uma linha de diálogo e mantenha a caixa de diálogo aberta? Para isso, podemos adicionar
outra função pública para exibir diálogos. Desta vez, aceitando uma matriz de strings como
primeiro argumento Vamos começar chamando nossa outra função para
exibir a primeira linha, usando o Índice zero na matriz, transmitindo-o e o nome
do
locutor para que seja
digitado na caixa de diálogo Para continuar na segunda linha quando
o botão
continuar for pressionado, precisaremos que o script
lembre quais são
as linhas e qual linha
está sendo exibida atualmente. Como o escopo dessa matriz está somente dentro do contexto dessa chamada
de função, ela não pode ser acessada
de outra função. Assim, declarando uma nova
variável de linhas, uma matriz de strings, podemos atribuir seu valor
na parte superior da nova função e outra variável
para lembrar qual linha é
exibida atualmente como Também podemos defini-lo como zero
na parte superior da chamada da
função e usá-lo para indexar a matriz. Então, quando o
botão continuar é pressionado, podemos adicionar um a ele verificar se ele ainda é menor que o tamanho da matriz. Se for, então
há mais diálogo, para que possamos chamar a
primeira função novamente. Alterando isso para ser
a variável privada, que declaramos acima
e usamos para armazenar uma matriz de strings
passadas para a função pública de
várias linhas Se quiser que o nome
do locutor continue sendo exibido, você também precisará armazená-lo
em uma variável. E se não, o
diálogo está concluído e podemos ocultar
a caixa de diálogo. Mas agora o
botão de continuação não funcionará conforme esperado se exibirmos apenas
uma única linha de diálogo. Precisaremos separar
a funcionalidade pública de exibir uma linha
de diálogo dos detalhes de como ela é realizada criando um método
privado que faça o. As funções públicas, aceitando uma linha
ou várias linhas, agora
podem chamar
a função privada para atingir seus
objetivos internamente A primeira função pode
armazenar a única linha
na matriz como seu único conteúdo e definir a
linha atual como zero, e agora ela se comporta exatamente
como a função de várias Mas se é
você ou outra pessoa escrevendo os
scripts de diálogo para o seu jogo, agora
existem
várias opções para exibir uma única linha ou
várias linhas de diálogo. Abrir a caixa de diálogo
e capturar o foco só precisa ser feito uma vez para que cada conjunto de diálogos seja
exibido E o
botão de continuação também
precisa chamar a
função da próxima linha. Normalmente, gosto de organizar funções em meus scripts
para ter públicas na parte superior e privadas na parte inferior e manter
as funções relacionadas juntas. Isso segue dois
princípios orientados a objetos: abstração, ocultando os detalhes de como as coisas são feitas de forma privada
dentro do script,
e encapsulamento, expondo
publicamente apenas as funções que você
deseja que outras pessoas vejam Vamos tentar simular um personagem falando várias
linhas de diálogo Primeiro, declararemos
uma variável para manter uma sequência de diálogo
em
uma matriz de strings e passá-la para a chamada da função
como o primeiro argumento, que preencheremos
abrindo um colchete Mas como a sequência de várias cordas longas
ocupará muito espaço,
prefiro ter cada uma delas em sua própria linha, e ajuda usar o recuo
para mantê-las Em seguida, o
colchete de fechamento pode ser usado para marcar claramente
onde essa matriz termina Executando a cena, podemos ver que a primeira
linha é exibida. Clicar no
botão continuar exibe a próxima linha, clicando no botão continuado enquanto a linha ainda está digitando, pularemos a animação de digitação e exibiremos a Quando todas as quatro linhas
forem exibidas, clicar no
botão Continuar fecha a caixa de diálogo Mas eu não quero ter que
declarar uma variável, preenchê-la e chamar
uma função toda vez Eu preferiria fazer
tudo isso em uma linha de código. Seguindo um formato semelhante, podemos substituir a declaração da
variável chamada
da função.
Os parênteses adicionam outra camada Nossa matriz é declarada
e preenchida na chamada de função junto
com
a especificação do nome do
locutor No entanto, a matriz agora não
tem um tipo especificado, mas como o Godo Script é uma
linguagem de digitação vaga, tudo Na verdade, podemos remover
os requisitos de tipo dos nossos parâmetros de
função de script de diálogo. Mas tenha cuidado para passar apenas argumentos
válidos ou
você receberá erros. Agora podemos exibir sequências
mais longas de diálogo com
digitação e salto animados Na próxima lição, criaremos scripts de eventos
personalizados que podem exibir
sequências complexas de diálogos Te vejo na próxima aula.
4. Gerente de eventos: Olá, amigos.
Na lição anterior, aprimoramos o
sistema de diálogo digitando, pulando e várias linhas Nesta lição, criaremos
um gerenciador de eventos para gerenciar nossos diálogos de jogos e
sincronizá-los com outros sistemas Começando na cena do jogo, vamos adicionar um novo nó básico e chamá-lo de gerente de eventos. O script do gerenciador de jogos pode obter uma referência a esse nó
usando addon ready, junto com o nó do jogador. Pensando na árvore de cenários como uma organização, normalmente, se filiais diferentes quiserem solicitar algo uma
da outra, elas precisam enviar a solicitação por meio de um gerente
acima de ambas. Nesse caso, algo no nível vai
direto para o topo do
gerenciador de cenas
do jogo para solicitar permissão para usar o
gerente de eventos para realizar um evento. Se alguma coisa em nossa cena de jogo quiser fazer com
que um
evento aconteça, basta pedir ao
gerente de jogo que inicie um evento, passando o evento
como argumento, e talvez também queiramos
encerrar os eventos com uma função
comum. O gerente do jogo pode
desativar o nó do jogador, para que o jogador não possa controlar o personagem durante um evento. E quando o evento terminar,
podemos restaurar o controle do
jogador. Depois que todos os preparativos
tiverem sido feitos, diga ao evento que
eles estão prontos para serem realizados, passando pela referência do
gerente do evento. Pode tornar isso mais
flexível adicionando também um parâmetro booleano opcional à chamada
da função com o valor
padrão verdadeiro Agora é possível escrever alguns eventos que não
removem o controle do jogador. No script do player, vamos adicionar uma variável pública para ativar e desativar o controle
do player Nas mesmas linhas em que
estamos verificando se o jogo está pausado
antes de processar a entrada, podemos adicionar uma condição usando o operador lógico ou
representado por dois canais Se o jogo estiver pausado ou o
jogador tiver sido desativado, retornamos e ignoramos a entrada Mas se o personagem estiver se movendo quando o
nó do jogador estiver desativado, ele continuará correndo
na mesma direção até que o
controle seja reativado. Podemos definir como
uma variável é definida, bem
como adicionar
funcionalidade automática com um setter Depois de uma
declaração de variável com dois pontos, podemos escrever um bloco
de código para
restringir melhor a forma como essa
variável é Criando uma função definida, aceitando um novo valor
como parâmetro, podemos atribuir o novo
valor à nossa variável. Mas também queremos garantir que se o nó do jogador não
estiver ativado, digamos ao
personagem
que pare de se mover. Esse comportamento se torna automático sempre que a
variável ativada é definida como falsa Semelhante a um gerente de cena, o
trabalho do gerente de eventos será
facilitar a comunicação entre diferentes
partes da cena. Mas esse script não tem as
mesmas responsabilidades de um gerente de cena, então não herdará
dessa classe Ele pode simplesmente herdar do nó. ainda vou salvá-lo
na pasta do gerente No entanto, ainda vou salvá-lo
na pasta do gerente, pois ele ainda é
considerado um gerente. Na parte superior do roteiro, precisaremos de referências
a qualquer coisa que possa estar comumente
envolvida em um evento. O personagem, a caixa de diálogo e o FAD, tudo são variáveis
públicas Você também pode
adicionar funções extras ao gerenciador de eventos para agrupar comportamentos
comumente usados, criar uma fila de eventos ou até mesmo agrupar eventos em outros
eventos Agora, qualquer script em nossa
cena de jogo precisará apenas fazer
referência ao gerente do jogo para poder iniciar um evento, apresentar diálogos,
entrar e sair
e até mesmo controlar o personagem Vamos mudar para a cena de
nível e configurar um cenário básico em que, quando
o jogador entra nesta sala, recebe uma mensagem. Para isso, precisaremos de
um nó D de área três com forma de colisão Vou fazer dela uma caixa que cubra toda
a
entrada da sala, então não há como
o jogador entrar na sala sem
colidir com essa Lembre-se de que esses
tipos de
eventos acionados por proximidade podem atrapalhar
alguns jogadores e devem
ser usados com moderação A maioria dos jogadores prefere
participar de eventos que removam seu controle voluntariamente
pressionando um botão Não precisa existir
em nenhuma camada de colisão, mascarando colisões apenas
com o Ele só precisa
ser monitorado
pelo jogador e não
monitorável por nada Podemos anexar um script e criar uma nova pasta restaurando
todos os nossos scripts de eventos O nome T é entrar na sala, conectando o
sinal inserido pelo corpo ao script Podemos escrever o que
acontecerá quando o personagem do jogador
entrar nessa área. Podemos encontrar o gerente do jogo usando uma notação de cifrão, começando pelo nó raiz Podemos dizer ao
gerente do jogo que inicie um evento, passando a si mesmo
como argumento como o evento
a ser iniciado. Talvez você queira fazer
isso usando o ad on ready, mas eu recomendaria fazer isso quando o evento for acionado. Como nem todos os eventos
serão acionados toda vez que um nível for
carregado em seu jogo, não é necessário que eles pesquisem a
árvore de cenas de uma só vez, pois seria mais eficiente fazer isso somente se precisassem. Como não precisamos
da referência da carroceria, vamos prefixá-la
com um sublinhado para comercializar o motor Antes de iniciar o evento, também
podemos
verificar se
o que foi passado como
argumento não é nulo E se não for nulo, verifique
também se ele tem
um método chamado run event Invertendo a lógica,
podemos verificar se isso é nulo ou se não tem
o método run event Se alguma dessas
condições for verdadeira, podemos retornar
ignorando a solicitação Eu prefiro usar se
não for evento aqui, que significa a mesma coisa. Também vamos imprimir
uma mensagem de aviso para o desenvolvedor sobre isso, informando que eles cometeram um erro que precisam ser corrigidos. aviso push exibirá uma mensagem de aviso amarela
no registro sem
interromper o jogo O script de eventos agora pode definir essa função de execução de eventos
como uma série de instruções
passadas pelo gerenciador de eventos para qualquer um dos outros
componentes da cena, conforme necessário, e tudo pode
ser sincronizado por meio do uso de sinais Para criar nosso cenário, precisamos apenas passar pelo gerente
do evento para acessar
a caixa de diálogo e pedir
que ele exiba uma mensagem. Em seguida, diga ao gerente do jogo
que o evento acabou. Adicionando um peso à
frente de qualquer função, podemos retornar um sinal dela, para que o evento saiba quando
essa tarefa está concluída. Passando para o script da caixa de
diálogo, vamos fazer com que a função de
linha de exibição retorne um sinal para quando
o diálogo terminar. E também faça o mesmo com
a função de várias linhas. Na parte superior do script, podemos dar uma definição ao
sinal e emiti-la ao fechar
a caixa de diálogo O principal objetivo de toda
essa infraestrutura é
criar roteiros
parecidos com um roteiro, dando instruções claras sobre
quem está dizendo, como está agindo,
onde está, o que a câmera está
olhando, etc Se o jogador entrar nesta sala
, agora ele
receberá uma mensagem. O controle foi
temporariamente
retirado do player enquanto
a mensagem era exibida. Ao pressionar o botão
Continuar, a caixa de diálogo emite o sinal de que o
diálogo foi concluído, permitindo que o
script do evento avance, encerrando o evento e restaurando o
controle para o jogador Agora temos um
gerenciador de eventos que desativa controle
do jogador enquanto um evento
acontece envolvendo diálogos Na próxima lição, criaremos um componente interativo com
o qual o jogador poderá
interagir para acionar eventos Te vejo na próxima aula.
5. Interagir: Olá, amigos.
Na lição anterior, adicionamos um gerenciador de eventos
que pode executar um script de eventos. Nesta lição, adicionaremos interações para o
jogador iniciar. Uma forma mais popular de
iniciar eventos é quando o jogador pressiona um botão para interagir com
algo ou alguém Abrindo as configurações do projeto, alternando para a guia do mapa de entrada. Vamos adicionar um botão de interação. Vou usar E no teclado
ou Y no meu controlador. Em seguida, no script do jogador, podemos verificar se o
botão de interação foi pressionado
e, em caso afirmativo, mandar o personagem interagir com o que ou com
quem estiver na frente dele. Para descobrir quem ou o
que seria, podemos usar a. Na cena do personagem, vamos adicionar um nó secundário ao
equipamento do tipo três D. Queremos que o raio aponte
para a frente do personagem, uma distância razoável para poder interagir
com algo, vou configurá-lo para 2 metros Como a plataforma é a coisa
que realmente está girando,
quando criança, o raycast
girará A máscara de colisão determina o que o raio pode colidir Queremos que esse raio
encontre interações. Devemos dar às interações
sua própria camada de colisão. Abrindo as configurações do
projeto
na guia geral,
abaixo dos nomes das camadas, três camadas de física D, definirei a camada cinco para ser
específica para interações. O raio lançado
colidirá com a camada cinco, mas também será obstruído
pela camada um, impedindo que o jogador interaja
com algo
do outro lado da parede Expandindo a seção de
largura de colisão, procuraremos áreas, nossas interações e
corpos semelhantes ao terreno Posicionando a altura
do raio, faz mais
sentido
colocá-lo em algum lugar
próximo ao nível dos ombros, ou pelo menos em algum lugar
entre o nível do peito e dos olhos. Mas também podemos usar isso
como uma oportunidade para implementar certas
restrições de alcance em nossas interações. Vamos posicionar a caixa CSG na
frente do personagem e imaginar que nosso objeto
interativo ou NPC esteja em cima Qual pode
ser a altura da caixa antes que a pessoa ou coisa em cima dela
não seja mais interativa Já que o raio colidiria com a caixa e não com a
coisa em cima dela Acho razoável permitir
a interação com algo que seja 1 metro
mais alto que o personagem, mas não 1,5 metro Então, vou posicioná-lo em
algum lugar intermediário. 1,3 metro parece bom, o que é metade da altura
do colisor do personagem No
script do personagem, podemos obter uma referência ao
nó do elenco usando addon ready. Mas observe que fazer
isso dessa forma
exigirá que cada personagem tenha
o nó de lançamento. Ao alterar a anotação
do cifrão para uma função, obtenha node ou null Podemos passar o caminho do nó
como um argumento de string, que podemos copiar clicando com o botão
direito do mouse no nó
e selecionando copiar caminho, ou clicando e arrastando o nó diretamente para as
aspas Agora, para qualquer personagem
sem um nó de conversão, essa variável será definida
apenas nula em vez de
gerar um erro Vamos adicionar uma função ao script
do personagem
chamada interact, que chamamos do script do player
quando
o botão de interação foi pressionado. Primeiro, verificando se
o nó de conversão existe, podemos então verificar se ele está
colidindo com alguma coisa Podemos então verificar se
o objeto com o qual o raio colidiu tem um
método chamado interact
e, em caso afirmativo, chamá-lo Se o raio não
existir, nada acontecerá. Se o raio emitido não atingir nada,
nada acontecerá Se o raio lançado atingir o
terreno como uma parede, o terreno
não terá um método
chamado interact , então
nada Se o raycast estiver atingindo
algo na camada cinco, que tem um método
chamado interact, ele chamará esse método, acionando Mas pensando em todas
as coisas diferentes em um jogo com as quais o jogador
pode interagir, um NPC e uma porta interagir
pressionando um botão, mas não têm
muito mais em comum Um NPC pode querer herdar
as mesmas propriedades e comportamentos usados por um personagem jogável para
andar por aí Embora uma porta precise de propriedades
como
se está trancada ou não e comportamentos
como abrir ou fechar. Usando uma estrutura de herança. Você pode transformar todas as portas em NPCs que simplesmente
não se movem ou transformar todos os personagens em portas sem que
seus
comportamentos e
propriedades parecidos com portas seus
comportamentos e
propriedades parecidos sejam ignorados Usar o
comportamento
interativo como pai abstrato de
portas e NPCs é melhor, mas ainda implica que todos os NPCs e todas as portas
devem ser interativos, o
que geralmente não é o caso na que geralmente não é Talvez você queira
ter uma classe de NPC que herde do personagem, mas também
herde de outra classe para obter funções adicionais
de Mas Godot não permite herança
múltipla. Seria melhor que
o comportamento interativo de portas, NPCs e qualquer outra coisa fosse independente
da natureza da coisa com a qual
você está Em vez disso, podemos aplicar o padrão composto para fazer isso com
mais eficiência Criando um nó filho para
representar a interação, podemos então associar um comportamento de
interação
a qualquer coisa que quisermos. Em nosso nível, temos
alguns personagens diferentes. Vamos escolher um e anexar um nó
filho a ele para representar o componente de interação desse NPC como um nó D
da área três Essa área não
monitorará nada, mas será monitorável
pela emissão de raios que
criamos anteriormente Portanto, sua
camada de colisão será cinco, então ela pode ser detectada
pelo raio emitido e sua máscara pode ser zero
, pois não está procurando nada Ele precisará de uma forma de colisão. Vou usar uma cápsula e
tê-la maior que o personagem. O raio não
precisa estar exatamente apontando diretamente para eles. Quanto à altura
da cápsula, podemos aplicar a
mesma lógica que fizemos antes ao contrário. Desta vez, imagine que nosso personagem
está de pé na caixa. Qual pode ser a altura da caixa
antes que nosso personagem não possa mais interagir com o NPC que está
no chão Vou definir as mesmas
restrições e deixar o jogador interagir com
algo 1 metro abaixo delas, mas não 1,5 metro. Sabendo que o raio
está sendo lançado 1,3 metros acima do solo em que
o personagem do jogador
está parado, então a forma
de
colisão das interações t mais 1 metro Torná-lo com 2,6 metros de
altura parece razoável, o
que também a mesma altura do colisor do
personagem Mas observe que mesmo um objeto minúsculo como uma chave no chão, precisará ter um colisor dessa altura para ser
atingido pela reformulação Podemos anexar um script
a essa interação. Vamos chamá-lo de diálogo de imagem. E salve-o na pasta de scripts de
eventos. Esse script
precisará de duas funções: interagir e executar evento. A função de interação será praticamente a mesma da lição
anterior, solicitando que o gerente do jogo
execute esse script como um evento. Para a função run event, podemos fazer com que o mago
diga o que quisermos. E termine o evento depois
que eles terminarem de falar. Agora vamos duplicar
esse nó de interação e anexá-lo à porta Em seguida, duplique também o script de diálogo do
Mage e chame-o de porta da cela Substituindo o script anexado
a essa interação e editando-o para dizer algo
como se a porta estivesse trancada. Em apenas algumas etapas simples, podemos criar qualquer tipo de interação que o jogador possa iniciar pressionando
o botão de interação com qualquer objeto ou NPC Como modifiquei a escala de uma parede comum para
criar a porta, a forma
da colisão está
herdando sua propriedade de escala Mas depois de
centralizá-lo dentro da porta, ele ainda faz um bom trabalho ao
cercar Vamos experimentá-lo. Pressionar
o botão de interação quando não estamos enfrentando
nada não adianta. Mas se caminharmos até o mago, podemos pressionar o
botão de interação para iniciar um diálogo Da mesma forma, também podemos caminhar até a porta
e interagir com ela. Agora temos uma porta, o
jogador ainda não consegue abrir
e, no NPC, o jogador pode
falar com ela pressionando um botão Na próxima lição, adicionaremos opções de
diálogo e árvores de
conversação ao sistema de diálogo. Te vejo na próxima aula.
6. Escolha: Olá, amigos.
Na lição anterior, criamos um componente de
interação que pode ser anexado a
qualquer coisa em nosso jogo. Nesta lição,
adicionaremos opções de
diálogo ramificadas ao sistema de caixas de diálogo Primeiro, precisaremos adicionar mais botões
à caixa de diálogo. Depende de você como
e onde deseja posicionar seus botões de opção de
diálogo. Estejam eles
na mesma
caixa de diálogo , em uma caixa separada, flutuando no
centro da tela, acompanhada de diálogo ou não. Para o meu jogo, vou colocar meus botões dentro
da caixa de diálogo. Adicionar outro contêiner de caixa
vertical à caixa de diálogo. Vamos chamá-lo de opções, e ele conterá três
botões chamados opção zero, opção um e opção dois. Vou dar a cada um deles
um texto padrão e definir o texto para
ser alinhado à esquerda Se eu ocultar o nome do locutor e restringir o diálogo
a no máximo duas linhas, tudo deve
caber dentro da caixa. Vou apenas ancorá-lo
no canto inferior direito
da caixa de diálogo e movê-lo para uma posição
em que fique bem Manter pressionada a tecla alt ou
options ao clicar e arrastar moverá somente o nó
selecionado e seus filhos Editando a caixa de diálogo deles, podemos adicionar quatro botões. Eu terei a cor da
fonte padrão preta. Desativado, cinza desbotado. foco foi coberto e
pressionado em branco e adicione um contorno preto para que o texto em branco ainda
fique legível Na guia Constance, definirei o
contorno em dois Em seguida, substituirei todas as caixas de estilo dos
botões por caixas de estilo vazias, para que elas sejam exibidas apenas
como texto normal. Ao selecionar o contêiner da caixa
vertical Opções, usarei a seção de
substituição do tema para adicionar 12 pixels de separação entre cada um dos
botões de opção para espaçá-los Reserve um tempo para organizar
o layout da caixa de diálogo e usar texto de espaço reservado
falso para testar os limites da
quantidade de informações podem ser exibidas de uma vez, incluindo quantas opções você gostaria de
apresentar ao jogador Quando estiver satisfeito com a forma como
tudo é exibido, lembre-se de ocultar a caixa de diálogo. Precisaremos alterar
o script para
poder exibir
tudo de forma adequada. Vamos pegar uma referência
às opções como uma matriz de seus nós filhos usando o método Get children. E em uma função pública
chamada Opções de exibição, aceitando uma linha de
diálogo como uma string e uma matriz de strings para as opções que o
jogador escolherá Como na função de linha de exibição, atribuiremos que a
matriz de linhas seja apenas a única linha
que foi passada como parâmetro e a
definiremos entre
colchetes e definiremos
a linha atual como zero Ao exibir as opções de diálogo, quero que o
nome do locutor fique oculto, então vou configurá-lo
como uma string vazia. Podemos então pedir à
caixa de diálogo que a abra, se ainda
não estiver, e comece a
digitar a próxima linha Onde isso
difere de exibir uma simples linha de
diálogo, no entanto, é exibir os botões de
opção, que eu não quero que aconteça
até que a linha
termine de digitar Para isso, precisaremos de
outro sinal, emitido pela próxima função de
linha Vamos dizer que acabou de digitar. E aguarde esse sinal
após a próxima chamada. Também precisaremos definir esse sinal na
parte superior do script. Depois que a digitação for
concluída, o botão Continuar
não será mais relevante Portanto, devemos definir sua
propriedade visible como falls para ocultá-la. Em seguida, podemos usar quatro loops para percorrer a
matriz de botões de opção Mas como precisamos
combinar os índices da matriz de botões com
os
índices da matriz de strings, podemos usar um tipo
diferente de quatro Usando o alias I, que na programação é universalmente
usado para índice, seguido pela palavra-chave,
podemos iterar o tamanho
das matrizes O valor de I começará
em zero e aumentará um
até atingir o
tamanho da matriz de botões, neste caso, três e parar. Agora podemos usar o valor de i para verificar se ele é menor que o tamanho da matriz de
string que foi passada como parâmetro
para essa função. Caso o diálogo tenha menos do que o
número máximo de opções. Se isso for verdade, podemos definir a propriedade
de texto do botão no índice para o
valor da string do mesmo índice e também definir o
botão para ficar visível. Se o índice do botão for
maior que o número de opções
, o botão
não deverá estar visível. Finalmente, podemos dizer
ao botão superior para capturar o foco para que ele possa ser
acessado com um controlador. Para que isso funcione
perfeitamente com nossas outras funções de
exibição de diálogo, precisaremos alternar a visibilidade
do botão Continuar
e
dos botões de opção
ao digitar as linhas ao digitar Também moverei a linha dizendo
ao botão de continuação para capturar o
foco para estar aqui também. Com tudo sendo
exibido corretamente
, basta
informar ao script do evento qual opção o
jogador selecionou. O tipo de retorno dessa
função será um número inteiro. O índice do botão que
o jogador pressionou, que corresponde ao índice
da escolha que ele selecionou. Cada um dos nossos botões, ao
ser clicado, chamará uma função. Vamos chamá-lo na opção pressionada, com um
parâmetro inteiro chamado index Essa função, assim como
pressionar o botão de continuação, pode fechar a
caixa de diálogo e emitir um sinal Vamos chamar o sinal selecionado e passar o índice pelo sinal
como argumento. Na parte superior do script, podemos dar uma definição a esse
sinal
e, desta vez, também dar
ao sinal um
argumento inteiro chamado choice A
função de opções de exibição agora pode retornar um peso selecionado, que fará com que
ela espere até o jogador pressione
um dos botões, depois receba o índice
inteiro do botão que foi
pressionado e
o retorne A última coisa a fazer é conectar os
sinais pressionados pelo botão a essa função. Certifique-se de que seu script tenha sido salvo para que o mecanismo possa
encontrar essa nova função. Selecionando cada um dos botões, conectando o sinal pressionado, selecione o
nó da caixa de diálogo na lista. Ignore o método de
receptor sugerido e clique no botão de seleção. Isso apresenta uma lista
de funções
no script de diálogo
cujos parâmetros correspondem aos argumentos dos sinais. Como o sinal pressionado não
tem argumentos, somente funções sem
parâmetros são compatíveis. Clique no botão Somente
métodos compatíveis para ver uma lista completa de funções e
selecionar as opções pressionadas Para corrigir o problema de compatibilidade, precisamos adicionar nossos próprios argumentos ao sinal na seção
avançada. Usando o menu suspenso, podemos selecionar qualquer
tipo incorporado para o argumento. O que queremos
usar é um número inteiro. Adicionando um
argumento inteiro ao sinal, podemos definir seu valor como o índice da
matriz do botão botão de opção zero é o índice
zero. Clique e conecte-se. Em seguida, podemos repetir esse processo com o restante dos
botões de opção, alterando o valor do argumento de
cada um para corresponder ao
índice na matriz. O argumento agora será passado para a função on option
pressed, emitida pelo
sinal selecionado e retornada pela
função de opções de exibição de volta ao
script do evento, que a chamou Para testar as opções de
diálogo, vamos modificar o script do evento de
diálogo Maj Semelhante à exibição de uma
única linha de diálogo. Podemos aguardar em uma caixa de diálogo Opções de
exibição, fornecendo uma pequena
linha de diálogo, seguida por uma série de opções Essa declaração retorna
um número inteiro entre zero e o número de opções
na matriz exclusivamente Atribuindo o
número inteiro retornado a uma variável, podemos então ramificar nosso
diálogo com base em seu Você pode usar uma
instrução if para isso, mas acho as declarações de correspondência muito mais claras para esse propósito. A correspondência de palavras-chave funciona forma semelhante à alternância
em outros idiomas. No bloco de código após
a instrução match, podemos fornecer uma opção
seguida por dois pontos e, dentro desse bloco de código, continuar com o que
acontecerá nesse caso E forneça
casos diferentes para cada uma de nossas opções de diálogo.
Vamos experimentá-lo. Eu tenho a velocidade de digitação de texto definida como mínima para testar
o botão continuar Se falarmos com o
mago, ele dirá uma linha de diálogo,
que podemos pular Depois de pular, são
apresentadas três opções,
que capturaram o foco, e o botão continuar não
está mais disponível Selecionando qualquer uma das opções, o diálogo continua
com base na seleção que fizemos. Se fizermos isso de novo, podemos
selecionar uma opção diferente. O mago diz
algo diferente. Podemos simplificar ainda mais esse
script
substituindo a declaração da
variável pela instrução match. Agora temos opções de diálogo para o jogador escolher, resultando em árvores de
diálogo ramificadas Na próxima lição,
podemos permitir que o jogador progrida no
jogo durante esses eventos. Te vejo na próxima aula.
7. Bandeiras: Olá, amigos.
Na lição anterior, permitimos que o jogador
escolhesse entre uma lista de opções e usamos sua seleção para
criar um diálogo ramificado Nesta lição, usaremos marcadores de
progressão para
mudar a forma como os eventos se desenrolam Vamos começar fazendo com que o diálogo de um
NPC mude cada vez que o jogador
interage com Em qualquer script que você esteja usando
para salvar o arquivo de seus jogos, neste projeto, estamos usando um recurso personalizado
chamado progress. Podemos adicionar uma variável exportada para rastrear quantas vezes o jogador interagiu
com o maj como um número inteiro, que naturalmente assumirá o
valor zero No meu projeto, o salvamento
e o carregamento
reais do arquivo foram removidos. Lembre-se de que
minhas demonstrações sempre
começarão com
os valores padrão Para obter mais informações sobre como salvar informações de
progresso
e recursos personalizados, consulte o curso anterior desta série, Fundamentos do
desenvolvimento de jogos No script do Mage Dialogue, podemos iniciar nossa função run
event combinando primeiro o
valor dessa variável. Então, com base no número de vezes que o jogador
falou com o Mago, podemos fornecer diferentes
linhas de diálogo. Faria sentido
que, se o jogador nunca tivesse falado com o Mago, o primeiro começasse
com uma introdução. Podemos então acessar
a mesma variável e incrementar seu valor em um E na próxima vez que o jogador
falar com o mago, ele dirá
algo diferente e também aumentará
o valor em um. Adicionando uma
opção padrão, no script Gado, isso é identificado com um
sublinhado em vez de um valor Podemos fornecer uma
linha de diálogo repetida para depois que o jogador tiver esgotado
todas as opções anteriores Na terceira vez,
falando com o mago, e toda vez depois disso, produziremos essa
linha de diálogo. Vamos experimentar. Na primeira vez que falamos com o mago,
eles se apresentam. Na segunda vez, eles passam
a ser anfitriões hospitaleiros. Na terceira vez e
todas as vezes depois disso, eles simplesmente nos
dirão que estão ocupados demais para conversar agora. Como alternativa, em vez de
ter diálogos repetidos, poderíamos fazer essa interação após o esgotamento do diálogo
, para que esse NPC não seja
mais Também podemos criar ciclos
de repetição de diálogos redefinindo o valor para um número menor após
a última Então, agora o made dirá
algo diferente a cada vez, repetindo as mesmas três
linhas em ordem sequencial Em vez de criar uma
variável separada para cada MPC, talvez
você queira considerar o
uso de uma matriz de números inteiros Precisaremos inicializar essa matriz para conter
um zero para cada MPC Como tenho três NPCs, adicionarei três
zeros à matriz Em seguida, cada MPC
do seu jogo pode receber um número começando do zero,
usado para indexar a matriz Podemos tornar esse erro mais fácil
e menos propenso usando uma enumeração,
uma Gosto de manter todas as
minhas enumerações do meu projeto em um único
script Começando com
o nome de classe Enums. Ele não precisa
herdar nenhuma das propriedades
do node,
pois não será anexado a nenhuma O único conteúdo
desse script será declarar as enumerações a serem
usadas Nosso primeiro número será uma lista
de todos os NPCs do jogo,
Night, Mage e Rogue A convenção para Enums é
usar estojo superior de cobra,
às vezes chamado de estojo de cobra
gritando O
script de diálogo do Mage agora pode acessar a matriz e indexá-la
com a enumeração F. Essas são práticas comuns
para diálogos de NPCs em jogos, mas na verdade não permitem que o jogador
progrida no Vamos usar a porta como
exemplo de progresso e que o jogador possa abrir
a porta durante um evento de
interação, mas somente se
souber a senha. conhecimento da
senha deve ser fornecido ao
personagem do jogador pelo mago meio de um evento de
diálogo separado antes que ele
possa usá-la para abrir a porta. No recurso de progresso, podemos adicionar uma variável
booleana exportada para determinar se o
jogador sabe ou não a senha, que naturalmente será falsa
como padrão As variáveis booleanas
usadas para controlar a progressão
do jogo são comumente
chamadas de bandeiras Ao falar com o mago, o personagem
terá a opção pedir
para ver o prisioneiro. Ao selecionar essa opção, o major informará ao
jogador a senha. Nesse ponto, podemos definir a variável no recurso de
progresso como verdadeira, já que o personagem do jogador
agora sabe a senha. Anexando um script à porta, podemos adicionar uma
variável exportada informando se a porta está aberta no momento e adicionar três funções públicas, verificando se a porta está aberta, abrindo a porta e
fechando a porta Retornando um booleano. Apenas retornaremos o valor
da variável is open, para que outros scripts possam facilmente obter seu valor, mas não defini-lo. Aplicação do encapsulamento. Também declararei
uma variável para manter
a posição y da porta
quando ela for fechada como um flutuador E defina seu valor durante
a função pronta para ser sua posição y atual ou sua posição y atual
mais 4 metros, com base no valor de está aberto. Cada uma dessas funções
pode definir a variável is open e chamar uma função privada
para mover a porta. Para abrir uma porta,
moverei sua posição y para baixo 4 metros e, para fechá-la, redefinirei sua posição
para o valor fechado. Com uma variável de interpolação. Depois de verificar se a
interpolação ainda não existe e não está execução no
momento,
crie uma nova Quero que o nó da porta permaneça interativo enquanto
a porta estiver aberta Eu permanecerei
na mesma posição
e, em vez disso, abrirei
apenas as portas para mim. Abrindo esta cena, ignorando o aviso, pois
não estou fazendo nenhuma edição Podemos ver que o nó da malha dessa porta está na metade da parede. Vou usar isso como o
nó que está sendo tweed e interpolando seu valor de
posição y. Como a posição
é a propriedade, podemos acessar a propriedade y
da estrutura vetorial três com dois pontos no caminho
da propriedade para nos movermos para
a nova posição por um
período de 1 segundo Retornando o sinal
finalizado de interpolação por meio das chamadas de função, caso algum outro script
queira aguardá-lo Isso é um pouco exagerado
para esta demonstração, mas esse script agora é
flexível o suficiente para funcionar com abertura
e o fechamento portas
semelhantes em
qualquer lugar do meu jogo No script do
evento de interação de portas, precisaremos de uma referência
ao nó raiz das portas. Para simplificar, vou usar
apenas get parent. Podemos primeiro verificar se a
porta está aberta no momento. Nesse caso, podemos encerrar o evento para
devolver o controle ao jogador, depois mandar a porta fechar e retornar para evitar que mais
desse script seja executado. O jogador não precisará esperar
até que a porta feche e poderá continuar jogando Se a porta estiver
fechada, podemos verificar se o jogador sabe
a senha ou não. Se o jogador ainda não
souber a senha. Podemos apresentar um
diálogo simples sobre a porta estar fechada
e encerrar o evento. Mas se o jogador
souber a senha, farei com que os bárbaros digam a senha na
linha de diálogo, encerrem o evento e mandem
a porta se abrir Eu gostaria
de
evitar que o jogador interaja
com a porta enquanto ela está abrindo ou fechando,
caso corresponda ao botão Em ambos os casos, definirei a camada de colisão do nó de
interação como zero,
impedindo que o
rec de interação a detecte Em seguida, adicione um peso
e ajuste-o de volta ao valor
original depois a porta terminar de
abrir ou fechar Podemos ver o valor
cobrindo o mouse
sobre a máscara de bits. Cada camada é representada
por um único bit, um zero ou
um na memória. E cada bit é numerado a
partir de zero. A camada cinco é o bit número quatro. Seu valor representado
como um inteiro é então dois elevado
a quatro, que é 16 Então, podemos reativar
esse colisor ajustando sua
camada de colisão de volta para 16 Se estiver usando várias camadas de
colisão, somar seus
valores de bits
gerará o
valor inteiro da máscara de Qualquer número inteiro pode ser usado como
máscara de bits dessa forma e é
uma maneira extremamente eficiente
de armazenar até 32 sinalizadores booleanos em um único inteiro
. A porta precisa
ser configurada usando at on ready. Vamos experimentar. Ao tentar interagir primeiro
com a porta, a porta é selada. Mas depois de falar com o mago e adquirir conhecimento
da senha, interagindo com a porta novamente, a interação acontece de
forma diferente e a porta se abre Quando a porta estiver
completamente aberta, podemos interagir com
ela novamente para fechá-la. Agora temos
bandeiras de progresso que permitem ao jogador
progredir no jogo usando eventos Na próxima lição,
mudaremos o que a câmera está
vendo durante os eventos. Te vejo na próxima aula.
8. Câmera : Olá, amigos.
Na lição anterior, permitimos que o jogador
progredisse no jogo colocando e lendo
bandeiras durante os eventos Nesta lição, adicionaremos uma câmera cinematográfica ao sistema de gerenciamento de
eventos Vamos começar na cena do
jogo adicionando uma câmera de três nós D
ao gerenciador de eventos. E defina uma referência a ela no script
do gerenciador de eventos. Então, no nível sn, usando o
evento de diálogo make como exemplo, podemos adicionar outro modo D de três
câmeras como filho ao evento de
interação Em seguida, mova a câmera e use o
botão de visualização da câmera para posicionar ou girar a câmera para
onde achamos que ela ficará boa como perspectiva
para nosso evento Quando estiver satisfeito
com a aparência, altere o tipo do nó para Marker three D e renomeie-o para algo
mais apropriado Mantendo suas propriedades
transformadas de posição e rotação
dentro da cena Agora podemos usar esse
marcador para posicionar a câmera cinematográfica
durante
o evento de diálogo Adicionando um roteiro
à câmera cinematográfica, vou colocá-lo na pasta de
eventos Precisaremos de uma função pública para mover a câmera até um marcador, definindo a posição
e a rotação da câmera para coincidir com
as do marcador e tornando-a
a câmera atual Mas, como as posições
e rotações dos filhos são relativas
aos pais, precisaremos usar a posição
global e rotação
global para
garantir que estamos obtendo
os valores corretos Em seguida, no script do evento do
diálogo Maj, podemos pegar uma referência a esse nó marcador e pedir ao gerente do evento que
mova a câmera cinematográfica Quando o evento
terminar, precisaremos que o gerente do jogo
volte para a câmera do jogador. No script do gerenciador de jogos, precisaremos de uma referência à câmera principal
do jogador para
que, quando os eventos terminarem, possamos transformar a câmera do jogador na
câmera atual antes de permitir que o
jogador comece a jogar novamente. Vamos experimentá-lo. Ao
falar com o mago, a câmera cinematográfica se move até
o marcador e assume Então, quando o evento termina, a câmera do jogador
retoma o controle. Também podemos atenuar a transição entre as câmeras com bastante facilidade Adicionando uma função ao script do gerenciador de
eventos, vamos chamá-la de fade to marker, aceitando o marcador três D e retornando Podemos esperar que desapareça para preto depois enviar o marcador para a câmera cinematográfica Em seguida, retorne fade para c. O gerenciador de jogo também
pode entrar
e desaparecer ao
voltar para a câmera do jogador Mas só faria
sentido fazer isso se o evento estivesse usando
a câmera cinematográfica Também podemos tornar esse comportamento opcional adicionando um parâmetro booleano
opcional à função e usar
o fade somente se solicitado especificamente
pelo evento Adicionando true à chamada da função do
evento final e aguardando a marcação de Fay
no início do script A câmera agora
entra e desaparece à medida que muda de perspectiva no
início e no final do evento Se seus eventos tiverem
mais de um marcador, talvez
você queira
classificá-los em um nó principal Vamos chamá-lo de marcadores de câmera. E no roteiro do evento, pegue uma referência a ele como
uma matriz de seus filhos. O script do evento pode solicitar que a câmera passe para
o marcador zero,
um, dois, etc., mais
parecido com um set de filmagem Mas e se quisermos que
a câmera faça uma panorâmica? Vamos adicionar mais algumas funções ao script
da câmera, Direção
panorâmica, para mover a câmera usando
um vetor e panorâmica para marcador para mover gradualmente a câmera diretamente para
um local específico Ambos aceitarão um período de tempo para o pan e retornarão um sinal para informar o evento quando eles terminarão, caso
queiramos aguardá-lo Para mudar
algo gradualmente ao longo do tempo, precisaremos de uma variável de interpolação Ambas as funções podem ser simplificadas em uma função
privada Vamos chamá-la de câmera interpolada, aceitando o destino
alvo, a duração do tempo e
retornando o mesmo sinal Como o pan to marker já
sabe seu destino, simplesmente
passamos essas informações para a função de interpolação da
câmera, acessando a
posição global do E a
função de direção panorâmica pode calcular seu destino alvo
adicionando a direção à sua posição global
atual. Depois de verificar se a interpolação já existe e está em execução, em caso afirmativo, mate-a e
crie uma nova Em seguida, podemos ajustar a posição
global da câmera para ser o destino alvo durante
a duração solicitada Na função panorâmica para o marcador
, também faria
sentido combinar a rotação
e
a posição dos marcadores, mas talvez não sempre Vamos adicionar um
parâmetro booleano opcional para permitir
esse comportamento Poderíamos duplicar a função de câmera de
interpolação para adicionar outra com rotação, mas eu preferiria adicionar
a rotação no parâmetro booleano
a essa função,
dando à rotação um valor
padrão do Se o evento quiser que a câmera corresponda
à rotação dos marcadores
, interpole também a rotação global da
câmera para
corresponder à rotação alvo ao
longo da duração Por padrão, várias interpolações
ocorrerão em sequência, mas queremos intervir
simultaneamente Podemos adicionar outra chamada de função aqui paralela para conseguir isso. Se mudarmos esses tipos de
argumentos de um marcador três D para um nó
genérico três D, então qualquer nó três D
pode ser usado como marcador, incluindo a câmera do jogador Eles também precisarão
defini-la como a câmera ativa, caso ainda não esteja. No script do gerenciador de eventos, também
podemos alterar esse tipo de
marcador três D para um nó três D. Obter uma referência
ao nó da câmera do jogador o
marcará como privado, para
que outros scripts não Em seguida, podemos adicionar uma
função que move a câmera cinematográfica para a posição da câmera do
jogador No roteiro de diálogo do Mage. Em vez de usar o Fade, vamos tentar colocar
a câmera cinematográfica na posição da
câmera do jogador e
movê-la para o marcador durante nosso evento antes da
primeira Em seguida,
desloque a câmera para cima e volte para a câmera do
player
no final . Vamos experimentá-lo. Esse diálogo agora
parece mais uma cena cortada com a
câmera se movendo. Mas podemos levar
isso ainda mais longe criando trilhas de câmera que guiarão
a câmera
pela cena em um movimento suave de
varredura Comece adicionando um nó D do
caminho três
ao nó do evento de interação. Esse nó tem uma propriedade, um recurso de curva de três D. Clicando nele para
expandi-lo, ele contém uma matriz de pontos. Adicionando um ponto, cada ponto contém uma posição vetorial de
três. Começando com o primeiro ponto
na localização original dos marcadores, podemos adicionar mais
pontos à matriz Para mover a câmera
pelas portas, depois para a janela dos guardas até
a cela da prisão As outras propriedades dos pontos são
âncoras que adicionam peso
ao cálculo dos pontos antes e depois deles
ao longo da curva O primeiro ponto
tem apenas uma âncora externa, o último ponto
tem apenas uma âncora interna, mas cada ponto
intermediário tem ambas ajuste dessas âncoras
suavizará a curva seguindo a fórmula da curva de
Bezier Agora que temos um caminho que
gostaríamos que a câmera seguisse, precisamos adicionar outro
nó ao caminho. O caminho segue três nós D. A segunda propriedade
do nó de acompanhamento do caminho, a taxa de progresso, o
moverá ao longo do caminho
em uma porcentagem. Adicionando uma câmera com três nós D
ao nó de acompanhamento do caminho e dando sua rotação original
voltada para o mago. Em seguida, podemos clicar
no botão de visualização para ver da perspectiva da
câmera Em seguida, ajuste o valor do progresso e veja a câmera
percorrer a cena Agora podemos excluir os três nós D da
câmera. Para fazer isso em nossos scripts, precisamos apenas
obter uma referência ao nó de acompanhamento
do caminho
no script do evento. Vou dividir
o diálogo em linhas
separadas para sincronizar
melhor
com os movimentos da câmera Também podemos usar isso como
um marcador para posicionar
a câmera, se quisermos, antes de
iniciar o movimento Podemos então dizer à
câmera que siga um caminho, passando o
nó de acompanhamento do caminho como argumento, junto com a duração do tempo. Vamos definir essa função
no script da câmera. Aceitando um caminho a seguir e uma duração de
tempo como parâmetros. A primeira coisa que
precisaremos fazer é reposicionar a câmera
para o nó de acompanhamento
do caminho e, em
seguida, redefinir sua posição
e rotação para coincidir com ela. Fazendo todas as interpolações usuais e retornando o
sinal ao terminar Podemos então intercalar a propriedade de
progresso
do nó de acompanhamento para atingir o valor de um ao longo
do tempo E faça dessa a câmera
atual. Finalmente, o
gerente do jogo pode devolver
a câmera cinematográfica ao gerente
do evento e, se necessário, encerrar
o evento Então, vamos experimentá-lo. Depois de
mencionar o prisioneiro, a câmera varre a cena para olhar para
eles pela janela. Se você quiser restringir a forma como a câmera gira enquanto
segue o caminho, é fácil
limitá-la a
girar apenas em torno do eixo y
ou a não girar Agora temos uma
câmera cinematográfica que pode pegar nossos eventos de diálogo simples e
transformá-los em cenas cortadas Na próxima lição, também
adicionaremos animações de personagens. Te vejo na próxima aula.
9. Animação: Olá, amigos.
Na lição anterior, adicionamos uma câmera cinematográfica
ao sistema de eventos E esta lição animará os personagens
durante nossos eventos Vamos começar com uma cena de
personagem. Ao selecionar o
nó da árvore de animação, o painel da árvore se abre na parte inferior
do editor, exibindo a máquina de
estado que controla a mecânica de
movimento dos personagens Para obter mais informações
sobre os conceitos básicos de animação de personagens
e máquinas de estado, consulte a introdução a três cursos de desenvolvimento de jogos em
D. Para evitar confusas
redes emaranhadas de transições de estado, podemos manter diferentes tipos de
animações separados em diferentes máquinas de animações separados em diferentes máquinas Clicando com o botão direito do mouse no espaço vazio, vamos adicionar uma nova
máquina de estado a esta. Por falta de um nome melhor, vou chamá-lo de diverso Usando a ferramenta Connect, adicione conexões da locomoção à nova
máquina de estado e vice-versa Usando a ferramenta de seleção, selecione a transição da locomoção para a
nova máquina de estado Expanda a seção avançada e
altere o modo avançado
de automático para ativado. Isso nos permitirá acionar as animações por meio de um script em vez de esperar que
a árvore de animação gerencie automaticamente a transição, como acontece com
a mecânica do movimento Selecionando a outra transição, expanda a seção de comutação e altere seu
modo de comutação para no final, permitindo que qualquer uma das
animações dentro da nova máquina de estado termine antes de retornar
à locomoção Selecionando a nova máquina de
estado em si, altere o
tipo da máquina de estado de raiz para agrupada a mecânica de movimento é Atualmente, a mecânica de movimento é a máquina de
estado raiz, e essa nova
máquina de estado conterá animações
semelhantes que serão agrupadas para ajudar a
manter Em seguida, clique no ícone do lápis para editar essa nova máquina de estado. Podemos retornar à raiz da máquina de estado usando
os botões de migalhas de pão na parte superior
do painel da árvore de
animação Nessa
máquina de estado, podemos adicionar qualquer animação que comece e termine com
a pose ociosa, que deve ser
reproduzida uma vez e não Neste pacote de recursos, as animações de torcer, interagir e pegar se
encaixam nessa descrição Para que a máquina de
estado funcione conforme o esperado, o número de transições
desde o início deve corresponder ao número de transições que entram
na máquina de estado Da mesma forma, o número
de transições que saem da máquina de estados deve corresponder ao número de transições que
levam ao Como há apenas
uma transição para dentro e para fora
da máquina de estado, só pode
haver uma transição conectando-se do início ao fim. Precisamos de um
estado intermediário, o estado que
inicia e termina todas essas animações, a pose ociosa Infelizmente, esse pacote de ativos não contém uma pose ociosa, mas podemos criar uma facilmente Alterne para o painel de animação na parte inferior do editor. E selecione a
animação inativa no menu suspenso. Clique no
botão de animação ao lado da lista suspensa e
selecione duplicar Renomeie a nova pose ociosa da
animação. Altere a duração
da
animação da pose ociosa para zero e
desative o loop De volta ao painel da
árvore de animação, dentro da máquina de
estados diversos, podemos adicionar duas cópias da animação de Vamos chamá-los de Idle Post
start e Idle Pose End. Em seguida, conecte-se do início à pose de
inatividade e, em seguida, um ao
outro estado a partir daí E cada uma delas até
a segunda pose ociosa
e, finalmente, o estado final Selecionando cada uma das transições
do início da pose ociosa, altere o
modo avançado para ativado E as transições para a extremidade da
pose ociosa podem alternar na extremidade. Agora, o número de
transições para dentro e para fora
da máquina de estado
corresponde ao número de transições do
início e do fim ao fim Não há possibilidade de ambiguidade para que a
árvore de animação navegue sem problemas Podemos visualizar a
aparência
dessas animações clicando no botão
play ao lado delas. E podemos adicionar uma
curta duração de
cross fade às transições
de entrada e saída da máquina de
estado para melhor combiná-las com
os estados de locomoção Quando você estiver satisfeito
com a máquina de estado, podemos salvá-la como um recurso
dentro do projeto. Depois de criar as animações de
pose ociosa para
os outros personagens, essa máquina de estado
pode ser carregada nos nós da árvore de animação pois todos eles têm
as mesmas No script do personagem, podemos adicionar uma função pública para acionar a
transição para qualquer uma
dessas animações simplesmente
passando o nome da
animação como uma string Só precisamos fazer com que a reprodução da
máquina de estado viaje até a animação
adicionando o nome
da máquina de estados agrupada que a
contém na frente, junto com um Mas precisaremos
restringir manualmente apenas permitindo que
isso aconteça a partir do estado de locomoção, verificando
primeiro
o nó atual da
máquina de estado Se o nó atual não
for locomoção, devemos ignorar essa solicitação Isso evitará iniciar essas animações no
meio do salto Talvez também não queiramos que
o personagem
consiga se mover enquanto essas
animações estão sendo reproduzidas Vamos adicionar um parâmetro
booleano opcional chamado locked com o valor
padrão true E também declare uma variável
privada para o script indicando se o personagem se move
simultaneamente ou Adicionando um setter a essa variável
após definir seu valor Se o personagem não puder se mover, também
devemos definir o
valor da direção de entrada como
zero para parar o caractere se ele já
estiver se movendo Então, em qualquer função
que se move ou pula, podemos adicionar uma
declaração condicional verificando se o personagem pode se mover
antes de permitir que isso aconteça Quando instruídos a realizar
uma animação, se a animação bloquear o movimento
, podemos definir a variável
can move como falsa e
retorná-la como verdadeira após o término da
animação Mas não podemos simplesmente esperar o sinal de finalização da
animação, pois ele será emitido quando a animação atual terminar, que está inativa, não
aquela que queremos Colocando o comando wait dentro um loop while e apenas
continuando o loop, podemos aguardar cada sinal finalizado da
animação
repetidamente até que o sinal específico
que queremos seja emitido Segurando o controle ou comando
e clicando no sinal. Podemos ver que ele passa um argumento do
nome da animação que acabou de terminar. O. Só precisamos comparar esse valor com
o nome da animação,
que, quando recebido, quebrará
o ciclo de espera e definirá a variável can
move de volta para verdadeira Por fim, para usar isso como parte do sistema de
gerenciamento de eventos, devemos ter um sinal de
retorno, caso
queiramos aguardar Vamos chamar essa
animação de sinal de finalizada. Podemos emitir e
retornar o sinal
se a animação
foi cancelada e fornecer um
parâmetro booleano para determinar se solicitação de animação foi bem-sucedida
ou não Falsar falso é o argumento. E no final da
função com true. Definindo o sinal e seu parâmetro na
parte superior do script. Como nosso gerente de eventos já tem uma referência
ao personagem do jogador, mandar ele realizar essas
animações agora é trivial No script de
interação da porta do celular, vamos aguardar e interagir com animação antes que qualquer
diálogo aconteça No script de diálogo de Maj, precisaremos de uma referência
ao personagem Maj para podermos solicitar
animações dele, que pode ser feito facilmente usando addon ready
e get parent, já que essa nota de interação
é infância para Se você quiser incluir
vários caracteres, basta exportar uma variável para cada um incluído
no diálogo. Vou fazer com que o mago aplauda enquanto fala excluindo
a palavra-chave await, mas finja que a
animação Observe que também podemos
dar aos personagens outros comandos
, como iniciar o salto ou a direção do rosto.
Vamos experimentá-lo. Ao falar com o mago, eles se agitam furiosamente enquanto
gritam para o personagem do jogador
no diálogo Se interagirmos com a porta, o personagem do jogador
estenderá a mão e tocará nela antes de iniciar
o resto do evento Agora temos a capacidade de
animar personagens
durante nossos eventos Na próxima lição, moveremos
os personagens para. Te vejo na próxima aula.
10. Direção: Olá, amigos.
Na lição anterior, adicionamos animações de personagens
ao sistema de eventos Nesta lição,
diremos aos personagens que andem
e corram em torno de dois. Vamos montar uma cena básica. Ao falar com o mago, faça com que ele
volte até a parede, pegue algo da prateleira, volte para o jogador
e entregue a ele. Como fizemos com a câmera, podemos adicionar marcadores de três nós D que informam ao personagem para
onde se mover Muito parecido com as direções de palco. Podemos adicionar um como
filho do mago para copiar
facilmente sua posição
atual exata. Em seguida, duplique-o e mova o novo para ficar perto
das prateleiras na parede Certifique-se de deixar espaço
suficiente para que o colisor do personagem
não colida com a parede antes de
chegar ao destino Se você tiver vários
marcadores em um evento, ajudaria
classificá-los em um nó principal Clicando e
arrastando-os para serem reconfigurados. Mas se o personagem
andar por aí, já que todos esses
nós são filhos do nó do personagem, todos
eles se moverão para lá. Podemos selecionar os
nós principais que contêm nossos marcadores,
expandir a seção de transformação
e clicar no botão de alternância de nível superior, o que impedirá
que as
propriedades da transformação sejam herdadas expandir a seção de transformação e clicar no botão de alternância de nível superior, o impedirá
que as
propriedades da transformação propriedades da Os marcadores
permanecerão estacionários enquanto o feito anda por aí Então, no script do evento, podemos pegar uma referência a esse nó como uma matriz
de seus filhos. Depois de uma linha de diálogo, podemos dizer ao mago que caminhe
até o marcador de personagem um,
interaja, depois retorne ao marcador de
personagem
zero e interaja novamente antes de exibir
outra linha de No script do personagem,
podemos adicionar a função que diz ao jogador que vá até um marcador. Aceitando três D como marcador
e uma distância permitida até o destino como
flutuador Isso permitirá que
a função termine quando o personagem chegar perto o suficiente do marcador sem precisar ficar
diretamente em cima dele Vamos atribuir a ele um
valor padrão de um quarto de metro. Em seguida, retorne um sinal
quando estiver pronto. Vamos adicionar um sinal
chamado destino alcançado, emiti-lo e devolvê-lo no
final da função Subtrair a posição global
atual do personagem
do destino
nos dará um vetor apontando para ele, um vetor com
direção e distância Nossos controles de caracteres assumem
um comprimento vetorial de um, pois é isso que é fornecido
pelo singleton de entrada Ao usar essa direção
para mover um caractere, teremos que
normalizá-lo primeiro, definindo o
comprimento do vetor como um Simplesmente definindo a variável de
direção, o processo físico
moverá o personagem. Se envolvermos tudo
isso em um loop selvagem, podemos continuar executando esse
código enquanto o caractere estiver mais longe do destino do
que a distância permitida Aguardando o próximo quadro físico Este código será executado junto com o processo físico para mover o personagem de onde
está para onde está indo Quando o destino for alcançado, podemos definir sua
direção para o vetor
30 para interromper seu movimento, mas o personagem ainda assim
desacelerará para frente Se quisermos que o personagem pare no marcador com
mais precisão, ele precisará começar a
desacelerar antes de alcançá-lo Então, podemos
dividir isso em duas fases antes e depois do ponto em que o personagem começa a
desacelerar, chamado Podemos calcular a distância de
parada
tomando sua velocidade atual
x z, calculando a
média com uma
velocidade de zero,
que pode ser simplificada
para dividi-la por dois e, em
seguida, dividi-la também por sua desaceleração A distância de parada será maior quanto mais rápido o
personagem se mover e também dependerá
da taxa de desaceleração Até que o personagem alcance
a distância de parada
, ele acelerará
até sua velocidade máxima. Ao atingir a distância de
parada, eles começarão a
desacelerar e pararão completamente mais ou menos diretamente no
destino Se a distância permitida for alcançada antes da distância de
parada
, o personagem ainda
parará Tudo isso pode ser feito usando uma declaração turn rey
em uma linha. Desde que o
personagem do jogador interaja com o mago pela
frente, isso funciona bem Mas se o
personagem do jogador estiver no caminho de onde o
mago quer andar, isso pode fazer com que o mago
não consiga chegar ao
seu destino. Embora a navegação em um ambiente estático
seja bastante simples, encontrar caminhos
dinâmicos em torno de obstáculos em movimento é um problema
difícil de resolver. Muitos jogos mais antigos costumavam fazer com que os
personagens
se cruzassem ou fossem bloqueados por um
período limitado de tempo e depois chegassem ao
destino como último recurso Nenhum deles parece muito bom. A maioria dos jogos modernos, incluindo AA, optará por fazer com que
suas cenas sejam executadas em um
ambiente totalmente controlado e eliminem qualquer possibilidade
de obstrução do caminho Para conseguir isso,
qualquer cena cortada que desenvolva personagens
andando por aí começará ficando preta Então, cada personagem na
cena pode ser reposicionado,
se necessário, antes de
começar a Então, quando a cena volta
, cada movimento é
cuidadosamente coreografado Podemos adicionar outro
marcador de personagem para especificar onde o personagem do jogador deve ficar durante essa interação Mas com o
nível superior ativado, os marcadores
dos personagens parecem ter se movido
para a origem
da cena, mas ainda mantêm suas posições
globais Isso dificulta a adição de
mais marcadores. Vamos desligar o botão de nível
superior e
editar a posição de transformação
para forçá-la a ser atualizada e, em
seguida, redefini-la para zero Agora ele aparece na posição
correta. Vamos adicionar mais um
e movê-lo para onde o bárbaro
deveria estar Definindo sua rotação para ficar
voltada para a idade. Em seguida, ligue novamente o nível superior. No script do personagem,
precisaremos de uma função que em vez de colocar
o caractere em um marcador,
simplesmente defina sua posição e,
possivelmente, rotacione
diretamente para
ele simplesmente defina sua posição e possivelmente, rotacione
diretamente Aceitando um nó três
D como parâmetro e um parâmetro opcional para corresponder à rotação y com um valor
padrão verdadeiro. Não precisamos retornar um sinal pois isso acontecerá
instantaneamente. Definir a posição
global do personagem para corresponder e, se corresponder
à rotação, defina
também a rotação y
do equipamento para corresponder a isso Quando a cena começa, primeiro
ficamos pretos Em seguida, posicione o personagem do
jogador no marcador dois, igualando também sua rotação, antes de voltar e retomar o
resto do evento Agora, mesmo se
ficarmos deliberadamente no caminho do major, a cena cortada ficará preta
para corrigir isso antes de jogar o evento de uma forma mais
controlada para evitar possíveis problemas Vamos tornar
a
função de caminhada do personagem ainda mais
flexível adicionando a opção de
fazer com que o personagem corra. Vamos tornar a
função de caminhada do personagem ainda mais flexível adicionando a opção de
fazer com que o personagem corra. Adicionar um parâmetro booleano chamado running com o valor
padrão false Podemos dizer ao personagem para ser executado no início da função e caminhar no final da função se esse parâmetro
for definido como verdadeiro. Também podemos adicionar outra
função que permitirá ao personagem seguir um caminho com vários pontos
em vez de apenas um. Começando com a mesma
definição de função de move to maker, vamos renomeá-la para seguir o caminho Altere o primeiro parâmetro
para path e remova o tipo. Vamos apenas supor que é uma matriz do nó três D
sem forçá-la Em seguida, emita e retorne o sinal de
destino alcançado. Declarando uma nova variável para o ponto atual no
caminho para o qual estamos caminhando, que começará do zero Desde que esse número seja menor que o tamanho da matriz, devemos aguardar a mudança
para esse marcador E podemos transmitir a mesma distância permitida
e valores de corrida Na cena da masmorra, eu
fui em frente e
posicionei um marcador para o bárbaro caminhar
depois de abrir a porta, e três marcadores que formam
um caminho pelo qual o Como o
nó de interação da porta não se move, também não
há necessidade de se preocupar com
o movimento dos marcadores A interação entre a porta da cela , então, precisa de uma referência
a esses marcadores, bem
como ao personagem invasor Enquanto a porta
se abre, o bárbaro pode sair do
caminho para o marcador zero. Então, o ladino agradecerá ao sair
da cela da prisão Vou adicionar mais leniência de
distância permitida e fazer com que o personagem corra Vou deixar o jogador
recuperar o controle
assim que terminar de usar a caixa
de diálogo, que ele não precise
ficar ocioso enquanto o ladino corre para que ele não precise
ficar ocioso enquanto o ladino corre
. Vamos experimentá-lo. Interagindo com
a cela, a porta se abre e o bárbaro
caminha para o lado Então o ladino atira,
agradece e foge. Agora temos personagens capazes de andar e correr durante os eventos. E a próxima lição melhorará o design modular
de nossos eventos. Te vejo na próxima aula.
11. Modularidade: Olá, amigos.
Na lição anterior, tínhamos personagens andando e
correndo por aí durante os eventos. Nesta lição,
encerraremos com algumas melhorias nos scripts
do evento. Ao longo deste curso,
criamos uma variedade de eventos
diferentes. Alguns são acionados quando o jogador
entra em uma área específica, outros ao pressionar um botão. Observando esses dois roteiros, podemos começar a ver
a semelhança
da função run event com
algo como um roteiro, dando instruções para personagens e câmeras em um set de filmagem Você pode imaginar
fazer um jogo inteiro. Haverá
centenas ou possivelmente milhares
desses scripts, possivelmente escritos por
várias pessoas. Queremos que eles sejam tão fáceis de
escrever e editar quanto possível para reduzir o tempo
necessário para produzi-los, bem
como padronizados
para reduzir possíveis bugs Vamos começar adicionando uma declaração de nome de
classe ao script do gerenciador de eventos. Então, em nossos scripts de eventos, especificando o tipo
do gerenciador de eventos, o mecanismo agora produzirá sugestões de
preenchimento automático ao acessar variáveis ou funções dentro do gerenciador de eventos Um recurso útil para reduzir bugs em qualquer script que o use. Em seguida, seria
útil separar como um evento é acionado
de como ele foi executado. Vamos criar um novo script
dentro da pasta de eventos. Embora Godot não tenha
realmente uma implementação de
uma classe abstrata, ainda
podemos fingir que
é uma classe abstrata, que nunca foi feita para ser
instanciada de
forma alguma,
apenas instanciada de
forma alguma Herdado de Aa three D e atribua a ele um evento de interação com
o nome da classe Ao mover o
método de interação para essa classe, qualquer script de evento de interação no jogo pode
então herdar do evento de interação para
ocultar a função de interação
por meio de herança Também podemos limpar o código da camada de
colisão
chamando métodos herdados
com nomes apropriados Como set interactable, passando verdadeiro ou falso
como argumento Então, a classe de evento de interação pode ocultar os detalhes de como isso é feito e
padronizá-los para todos os
eventos interativos no jogo Definir a
camada de colisão para 16 se ela for
interativa ou então zero
para Seria uma boa
ideia
herdar ainda mais do
evento de interação para criar uma classe comum que
possa ser aplicada a todas as interações similares
em seu jogo, como ter um
script para todas as portas ou um script para todas as
captadores, por As únicas diferenças entre
suas interações semelhantes variáveis
exportadas ou
referências a outros nós Muitos eventos em jogos só são acionados sob
certas condições, e muitos se tornam irrelevantes
depois de terem acontecido uma vez Qualquer um dos nossos scripts de
eventos de interação pode facilmente substituir o
método de interação para adicionar condições, verificando o progresso do jogador em
busca de sinalizadores, se necessário, antes de chamar a definição
de
superclasse de interação para iniciar OK. Colocando a mesma
bandeira dentro do evento. Também podemos tornar esse evento ininterativo para evitar que o mesmo evento aconteça Outra opção popular é usar o método ready para verificar se as condições
desse evento foram
atendidas e configurá-lo para ser interativo ou não quando carregado
pela primeira vez no Geralmente, esse é o caso sempre acionamento de um evento
exige o zoneamento e o retorno ao
nível para reiniciá-lo antes de falar com uma
NBC As condições do evento estão sendo verificadas somente
quando carregadas pela primeira vez. Vamos duplicar o script do evento de
interação
e também criar um script do evento de
proximidade Alterando o
nome da classe para corresponder. Podemos trocar o
método de interação com nenhum corpo inserido, aceitando o corpo como
um parâmetro de três D. Essa colisão
acionará o evento, mas o sinal inserido pelo corpo
não está inerentemente conectado Na função ready,
podemos
conectar manualmente o sinal
ao método chamável Vamos também configurar a
máscara de colisão para detectar o jogador, que é a camada nove, bit oito, dois elevado
a oito é 256 Agora, qualquer script de evento pode herdar
do evento de proximidade e suas
condições de acionamento, bem como o mascaramento de
colisão Neste projeto, coloquei todos os personagens na
mesma camada de colisão, então qualquer um deles
acionará eventos de proximidade Abrindo as configurações do projeto, sob os nomes das camadas,
três físicos D. Vamos adicionar uma
camada separada para NPCs. Então, em cada cena de NPC, podemos mudar sua
camada de colisão de jogador para
NPC e fazer com que os
dois se mascarem Agora, somente o
personagem do jogador será detectado por eventos de proximidade. Vamos também criar
outro tipo de evento, que não seja acionado
pelo jogador, mas que possa ser acionado
por meio de outros scripts. O gerente do jogo provavelmente
iniciará um evento de
introdução na primeira
vez que o jogo for carregado Um nível também pode querer acionar eventos quando
o jogador entra nele, ou eventos podem querer
acionar outros eventos. Criando um novo script
na pasta de eventos, vamos chamá-lo de evento com script Desta vez,
ele herdará do nó, já que não
precisa de nenhum comportamento da classe de nós Aa de três D. Como um evento com script
não precisa ser acionado, o único propósito
do script será garantir que haja
uma função de execução do evento e também fornecer um sinal que será emitido quando
o evento for concluído, que pode ser emitido Qualquer script herdado
dessa classe agora pode retornar o evento super dot run
para automatizar esse comportamento Adicionando uma variável
ao arquivo seguro do player, vamos chamá-la de introdução
de Ablean, que naturalmente usará
como padrão quedas Vamos criar um
evento de introdução que só será acionado uma vez quando o jogo for carregado pela
primeira vez Para simplificar,
vou fazer com que desapareça já que o
estado atual do destino é preto quando o
jogo carrega pela primeira vez Em seguida, diga olá mundo e
defina a bandeira como verdadeira. Em seguida, retorne o evento Spot Run, que emite e retorna
o sinal finalizado E também diga ao
gerente do jogo que encerre o evento. Adicionando uma nova nota
à cena do jogo para realizar o evento programado O gerente do jogo pode obter uma referência a ela
usando o complemento pronto. Na função pronta. Agora
podemos verificar essa bandeira. Em seguida, inicie o evento de introdução e
aguarde o sinal final. Se o sinalizador tiver sido definido como verdadeiro, ele
será ignorado Comandando a cena,
o evento de introdução ps. Se o jogador salvar
e recarregar o jogo,
o evento com script de introdução
não será acionado pela Vou demonstrar padronizando a variável no arquivo
sa como True Vamos adicionar outro nó para
conter um evento secundário, que será acionado
por um evento primário. Adicionar um script a esse nó herdado
do evento com script ele apenas dirá evento
secundário e retornará o evento Super dot run Qualquer script de evento no
jogo agora pode aguardar a execução desse evento secundário
e ele será executado antes de retornar ao evento que
o chamou Isso pode ajudar a dividir eventos
extra longos em partes maiores,
dividir narrativas ramificadas em scripts separados
ou reciclar o mesmo evento
para ser usado
em vários contextos dividir narrativas ramificadas em scripts separados
ou reciclar o mesmo evento
para ser usado
em vários contextos em partes maiores,
dividir narrativas ramificadas em scripts separados
ou reciclar o mesmo evento
para ser usado
em vários contextos. Agora temos um sistema
de
gerenciamento de eventos e
diálogos muito abrangente sistema
de
gerenciamento de eventos e
diálogos que pode ser usado para criar narrativas
ramificadas complexas, cenas
envolventes e dar ao jogador
a escolha de como ele deseja
progredir O sistema também é
otimizado para tornar a produção dos
scripts de eventos bastante simples.
12. O que vem a seguir?: Bem-vindo ao meu curso sobre
inventário e lojas em Gado. Este curso é uma continuação de diálogos e eventos em Gado, mas pode ser seguido e aplicado a qualquer projeto que envolva
pegar itens, adicioná-los a um
inventário, soltar, usar ou equipar itens de um menu
de inventário
e trocar itens com um e trocar itens Você está convidado a se juntar ao
nosso servidor de discórdia para trabalhar neste curso
ao lado de seus colegas Neste curso, abordaremos diferentes métodos de
pegar itens, gerenciar os dados de
inventário dos jogadores, exibir seu inventário
na interface de usuário em um menu, permitir que o jogador interaja com seu inventário de
maneiras diferentes e trocar itens com NPCs Quando terminar,
você terá um sistema de
inventário simples para seu jogo que é facilmente personalizável em sua apresentação
e função Você também aprenderá habilidades úteis para trabalhar com o motor de
jogo Gada, organizando e projetando seus projetos para
serem mais escaláveis Você
aprenderá a codificar com script
GD com tudo
explicado em detalhes Aplicaremos princípios de design
orientado a objetos em nossos scripts,
herança, encapsulamento,
abstração e polimorfismo,
para mantê-los organizados,
personalizáveis e reutilizáveis para personalizáveis Todos os arquivos do projeto
também estão disponíveis no GitHub, se você precisar revisar
o projeto como estava depois de concluir
cada lição Esses vídeos foram gravados
usando o Gdoersion 4.2 0.2. O projeto começa com
ativos de K Kits, pacotes remasterizados de
personagens e Dungeon feitos por K Lauberg Pacote Basic Guy
feito pela Penzilla
e ícones feitos por Shakahi e ícones feitos Todos estão disponíveis para
download gratuito nele. Os efeitos sonoros feitos por
Valensbyer também estão
incluídos e estão disponíveis