Diálogo e eventos em Godot! | Thomas Yanuziello | Skillshare
Pesquisar

Velocidade de reprodução


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

Diálogo e eventos em Godot!

teacher avatar Thomas Yanuziello, Indie Game Developer

Assista a este curso e milhares de outros

Tenha acesso ilimitado a todos os cursos
Oferecidos por líderes do setor e profissionais do mercado
Os temas incluem ilustração, design, fotografia e muito mais

Assista a este curso e milhares de outros

Tenha acesso ilimitado a todos os cursos
Oferecidos por líderes do setor e profissionais do mercado
Os temas incluem ilustração, design, fotografia e muito mais

Aulas neste curso

    • 1.

      Introdução

      1:40

    • 2.

      Caixa de diálogo

      11:53

    • 3.

      Monólogo

      13:12

    • 4.

      Gerente de eventos

      10:31

    • 5.

      Interagir

      11:21

    • 6.

      Escolha

      12:33

    • 7.

      Bandeiras

      12:11

    • 8.

      Câmera 

      15:00

    • 9.

      Animação

      11:49

    • 10.

      Direção

      11:53

    • 11.

      Modularidade

      10:56

    • 12.

      O que vem a seguir?

      1:38

  • --
  • Nível iniciante
  • Nível intermediário
  • Nível avançado
  • Todos os níveis

Gerado pela comunidade

O nível é determinado pela opinião da maioria dos estudantes que avaliaram este curso. Mostramos a recomendação do professor até que sejam coletadas as respostas de pelo menos 5 estudantes.

22

Estudantes

--

Projeto

Sobre este curso

Este curso é uma continuação dos fundamentos do desenvolvimento de jogos em Godot.

Clique no link do meu site no meu perfil para participar do nosso servidor de discord!

Neste curso, vamos abordar a criação de caixas de diálogo, eventos e interações e depois amarrá-los com sinalizadores de progresso, controles de câmera e animações de personagens.

Você também vai aprender habilidades úteis para trabalhar com o motor de jogo Godot, organizar e projetar seus projetos para serem mais escaláveis.  Você vai aprender como codificar com GDscript, com tudo explicado em detalhes.  Nossos scripts serão escritos para serem altamente personalizáveis e reutilizáveis.  Todos os arquivos do projeto também estarão disponíveis no GitHub se você precisar revisar o projeto como estava depois de concluir cada aula.  Esses vídeos foram gravados usando a versão Godot 4.2.2.

Este curso vai fazer parte de uma série projetada para ensinar pedaços de desenvolvimento de jogos do tamanho de uma mordida que podem ser usados ​​de forma intercambiável uns com os outros.  Então, deixe-me saber quais tipos de jogos você é interessante em aprender como fazer e vou tentar incluí-los em futuros cursos desta série.

Conheça seu professor

Teacher Profile Image

Thomas Yanuziello

Indie Game Developer

Professor
Level: Beginner

Nota do curso

As expectativas foram atingidas?
    Superou!
  • 0%
  • Sim
  • 0%
  • Um pouco
  • 0%
  • Não
  • 0%

Por que fazer parte da Skillshare?

Faça cursos premiados Skillshare Original

Cada curso possui aulas curtas e projetos práticos

Sua assinatura apoia os professores da Skillshare

Aprenda em qualquer lugar

Faça cursos em qualquer lugar com o aplicativo da Skillshare. Assista no avião, no metrô ou em qualquer lugar que funcione melhor para você, por streaming ou download.

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