Godot, 1000 pequenas coisas

Recentemente, descobriu o mecanismo Godot, um mecanismo de jogos de código aberto. Compartilho alguns truques e notas, principalmente da área de 3d, código ou pontos gerais.





Godot, em geral, tem uma reputação de se parecer mais com um mecanismo 2D, que foi bem trabalhado, mas não há muito tempo, os recursos 3D nos permitem fazer jogos em 3D. Especialmente se você conseguir otimizar algumas coisas por conta própria, não faça um jogo muito pesado e complexo e também ficará satisfeito com as opções de renderização atuais. Ou você pode esperar por otimizações futuras e pela aparência do vulkan.



Fora da caixa, o motor possui alguma física, incluindo juntas e veículos com rodas. Não há editor de terreno embutido, mas você pode usar um plug-in, importar de programas especializados ou apenas como uma malha de um pacote 3D. Neste último caso, por uma questão de desempenho, você terá que cortar a paisagem de forma independente em fragmentos de pedaços e, provavelmente, torná-los malhas separadas para colisões. Quanto às malhas para o formato da colisão da paisagem - para que não haja inconsistências visuais, é necessário triangular o modelo durante a exportação do pacote 3D. Por exemplo, uma das maneiras mais simples de fazer isso no Blender é exportar a malha no formato collada (.dae); há uma caixa de seleção triangular por padrão.

Às vezes, um modelo do Blender precisa ser girado 180 graus dentro de Godot; portanto, não se surpreenda se o terreno não estiver visível - provavelmente ele será girado pelos normais na direção errada.



Godot pratica a abordagem "tudo é uma cena" e é adaptado à estrutura de árvore dos elementos. Na prática, isso significa que novos objetos são adicionados ao nível como ramificações para os nós já existentes nele, eles podem ser transformados em pré-fabricados e abertos separadamente, como se fosse seu pequeno mundo local separado. Portanto, é muito conveniente editar todos os tipos de objetos compostos salvos, a única coisa é que, se a luz foi exposta no seu nível, então, por exemplo, entrando no personagem, na cena local, você não verá essa iluminação e, configurando seus materiais, não entenderá como eles se parecem. a luz. Esse problema pode ser resolvido de diferentes maneiras, por exemplo, mudando para a janela de nível e avaliando as mudanças em andamento com o personagem, depois de salvar sua cena lá. Ou apenas jogue temporariamente a fonte de luz dentro da casa pré-fabricada com o personagem.





theEnergy, . Area, , , .



Quanto aos idiomas, se você não considerar o método de baixo nível, as opções mais comuns são as linguagens de script GDScript e C #, além de scripts visuais para algo simples. O GDScript é melhor integrado ao mecanismo, tem mais exemplos, não requer um ambiente externo e, em termos de estrutura geral, tudo será o mesmo que em C # - declaração de variáveis, chamada da função de inicialização, ciclo do processo, ciclo de processos físicos e assim por diante. Portanto, escolher o GDScript como sua principal linguagem de script de desenvolvimento faz sentido. Alterando para C # local, obteremos apenas maior precisão e detalhes do registro, perdendo a concisão, mas aumentando a inteligibilidade e o controle sobre a situação - chaves em vez de usar guias, marcadores de fim de linha, digitação mais formal.





Código anexado ao objeto acima (na linguagem GDScript). Um identificador de variável é configurado, cujo valor pode ser definido no editor. Em seguida, uma função de inicialização única, na qual nada de especial acontece (e pode ser apagado). A seguir, é descrito um método manipulador de sinal que deve excluir um objeto.



Quanto às variáveis ​​globais, para usá-las no GDScript e no C #, é necessário adicionar scripts / scripts globais para iniciar nos parâmetros do projeto, cujas variáveis ​​podem ser acessadas globalmente.

Também em Godot, há uma limitação - não pode haver mais de um script em cada objeto. Mas esse ponto pode ser contornado, por exemplo, pendurando o segundo script em um objeto filho.



Signals



Você também pode usar uma hierarquia para trocar dados entre nós no Godot, porque os objetos são anexados um ao outro, como ramificações em uma árvore. É verdade que essa abordagem tem suas armadilhas, porque em nosso jogo a hierarquia pode ser dinamicamente mutável. Além disso, referir-se à hierarquia dentro da mesma cena é uma coisa, mas quando você tem uma cena dentro de uma cena dentro de uma cena, há algumas dificuldades com isso, mesmo que seja apenas para entender o que está acontecendo.

Uma maneira de gerenciar tudo isso e não se apegar muito a uma hierarquia atual específica é através de sinais. Um certo número de sinais comuns já está predefinido - você pode olhar no painel de sinais do objeto para anexar uma linha com o processamento de recebimento de um deles ao script do mesmo objeto ou outro objeto com um script, dentro da cena. Se você precisar fazer seu próprio sinal, faça o seguinte:





Iniciamos o sinal Emitimos



no mesmo script quando um botão é pressionado ou em outras condições



Tudo está bem com isso, desde que você não precise transferir sinais de uma cena para outra. Por exemplo, porque você codifica um nível de cenas e precisa saber quando precisa destruir o nível atual e, por exemplo, montar o próximo.

Nesse caso, no momento da construção do nível com um código, você pode anexar um manipulador de sinal ao objeto que enviará o sinal para a cena raiz. Assim, nós, por assim dizer, iniciamos um agente espião nesse ramo gerado e ouviremos o que ele nos diz.





No momento da montagem do nível, encontramos uma nave espacial e nos apegamos ao ouvinte do sinal, indicando o método pelo qual processaremos as mensagens desse sinal.



Você também pode anexar algumas variáveis ​​ao sinal, o que pode ser bastante útil. Por exemplo, em vez de gerar sinais diferentes no objeto, podemos conviver com um, mas o enviaremos com parâmetros diferentes e o processaremos adicionalmente após o recebimento.





E aqui está a descrição do próprio método, que começamos acima. Recebendo um sinal, ele processa a variável enviada com ele.



Outra coisa útil que reduz o número de sinais desnecessários é que, em vez de enviar um sinal pessoal, um objeto pode bater em outro, para que ele envie o sinal já encerrado nele. Por exemplo, uma explosão recebe um sinal de que tocou um jogador e, no manipulador desse sinal, descobre se o jogador possui um método de autodestruição, iniciando-o se for detectado. O jogador, neste método chamado dele, envia um sinal para a cena raiz de que ele morreu. No script da cena raiz, o manipulador de sinais de morte do jogador apaga o mundo e monta o menu do jogo.





Ocorre um evento e procuramos ver se o objeto que entrou na zona possui o método correto.





, , . , , .



CSG-





Uma das ferramentas 3D úteis em Godot são as primitivas de geometria sólida construtiva. Simplificando, esses são objetos que suportam operações booleanas - interseção, exclusão, união. Além do conjunto de primitivas, há uma malha CSG universal, como um formulário para o qual você já pode definir uma malha arbitrária.







O manequim CSG Combiner será necessário para uso em uma hierarquia para controlar a prioridade das operações quando for necessário montar alguma estrutura complexa.





Um par de esferas das quais as esferas filho são esculpidas.



A principal aplicação do CSG é a conveniência e a simplicidade de prototipar a estática do nível e alguns de seus elementos. De fato, você pode fazer uma malha em um pacote 3D e repetir as mesmas formas resultantes, a menos que precise fazer isso fora do editor do jogo.



O próximo uso do CSG estático é simular destrutibilidade e danos. isso requer a colocação de primitivas CSG no modo de exclusão, como furos, "stubs" e amassados, e depois ocultá-las temporariamente, incluindo a visibilidade no momento certo. A limitação aqui é que só podemos "danificar" a superfície do objeto CSG; além disso, o "dano" deve ser inicialmente anexado a ele quando criança, ou através de código, como criança. Mas essa opção em termos de flexibilidade de personalização já vence significativamente em comparação com o objeto destrutível preparado no pacote 3D.





Existem 3 cilindros embutidos na ponte no modo de exclusão. Enquanto eles estão ocultos, a ponte está intacta.



Se ativada, a área excluída é cortada.



Em seguida, temos o CSG em movimento. Através de código ou animação gravada. Em geral, por esse método, você pode implementar algum tipo de efeito, mas é muito desejável que essas animações não girem no palco em um loop. Vários CSGs animados podem afetar significativamente o desempenho. Além disso, Godot não otimiza tudo, e se você não desativar os CSGs animados, eles continuarão a consumir o desempenho fora da vista da câmera.

No entanto, os efeitos dos CSGs animados já são difíceis de substituir pelas soluções de pacotes 3D, portanto, você pode estar interessado em usá-los (pelo menos se não quiser desenhar 3D avançado por meio de código). O principal é encontrar o aplicativo certo, é melhor usá-los no sentido horário, em certos lugares, incluindo animação de gatilho. Como o efeito de abrir a passagem ou outro efeito especial único. Naturalmente, quanto mais simples a forma de objetos CSG - melhor. E eles exercem a carga computacional principal precisamente no processo de contato em movimento; além disso, não há uma diferença particular de qual objeto é movido em relação a outro.





Há um momento no vídeo em que o carro cai através de um buraco na ponte, quando uma cápsula CSG animada passa através de uma malha CSG com um modelo da ponte.



Multimesh





Se você precisar replicar uma malha em grandes quantidades, por exemplo, espalhando pedras ou árvores por nível, o nó MultimeshInstance será útil aqui.

Após adicionar a multimídia à cena, você precisa especificar em qual objeto dispersar as cópias e o que levar como modelo para os clones. Ao longo do caminho, você pode escolher o tamanho dos clones e seu número. Quando um multimesh é "cozido", é um conjunto de clones, e os destinos que ele usou para gerá-lo podem ser excluídos se não forem mais necessários.





Um botão para selecionar destinos de multimídia aparece na janela do editor no canto superior direito quando ele é selecionado. Se você pressionar, esta janela com as configurações de geração será exibida.





Aqui temos dois objetos adicionados à cena como nós MeshInstance. Em seguida, deixamos o objeto esquerdo à direita.





Temos multimesh. Nessa situação, 10.000 clones foram definidos nas configurações. A propósito, se houvesse 3-4.000 deles, visualmente o resultado não seria muito diferente.



O multimesh "cozido" pode ser movido para qualquer lugar e, além disso, possui o parâmetro Visible Instance, que exibe inicialmente o número de clones especificados durante a geração. Alterando esse valor, você pode controlar quantos clones são mostrados no momento. Por padrão, há -1, mas esse é um valor especial para exibir o máximo de clones. Se você colocar 10, haverá 10 clones, se 100, depois 100. Se o máximo for 50, então em 100, e em 1000 e em -1, eles permanecerão 50.

Você pode usar esse recurso multimash para criar efeitos especiais animando o parâmetro Visible Instance por meio de código ou animação gravada. Para um controle mais preciso sobre a densidade dos clones, você pode usar o pacote 3D para criar uma malha separada com uma malha sólida exatamente nos locais onde é necessária a densidade máxima dos clones, e os locais onde eles não deveriam estar não devem ser cobertos por polígonos ou ter lacunas neles.





Defina a Instância visível para 500 e a densidade do preenchimento cai acentuadamente.



Diversos





O gerenciamento no Godot pode ser configurado abrindo o item Projeto no painel superior do editor. Em seguida, Configurações do projeto , guia Lista de ações .





Você pode ver como os botões padrão são chamados a saber por quais nomes eles são acessados ​​através do código. E também adicione o seu.



Por exemplo, o nome padrão do botão PgUP é "ui_page_up" e você pode manipular sua pressão no código escrevendo a seguinte linha no GDScript - se Input.is_action_pressed ("ui_page_up"):

Se uma ação for necessária para uma única pressão, is_action_pressed deve ser substituído por is_action_Just_pressed. O fim de pressionar - pressionado muda para liberado.



#



Se você precisar animar a tremulação de um material, poderá fazê-lo através de um sombreador auto-escrito. Para fazer isso, selecione New ShaderMaterial como o material do objeto.Em









seguida, selecione VisualShader em um campo vazio.Clique





nele, o editor visual será aberto abaixo do editor.Adicione



alguns nós, primeiro Input - All - Time , depois Scalar - Common - ScalarFunc , configurando-o na lista suspensa, digamos Pecado. Em princípio, esse design já dará algo como uma oscilação entre preto e branco, mas para melhor, adicione outro nó Scalar - Comum - ScalarFunce escolha Abs lá. Conectamos os nós juntos (observe que, clicando no olho fechado de cada nó, você pode abri-lo e ver como a imagem muda em cada estágio) e conectar-se ao canal Alpha, Emission ou Albedo. É isso aí, nosso objeto agora está piscando.







Naturalmente, isso está longe de ser o único caminho, mas uma das opções muito simples. E se você quiser que o flicker seja colorido, precisará criar alguns nós com cores, misturá-los em um nó especial (indo para Albedo) e anexar a saída da cadeia de nós ao que coletamos acima. Assim, essa cadeia atuará como um fator de mistura para essas cores.



#



Para transformar o nó selecionado em uma cena separada, clique com o botão direito do mouse e selecione "Salvar ramificação como cena". Em seguida, defina um nome para esta cena. Depois disso, o ícone “Abrir no editor” aparecerá ao lado do nome do nó, de onde você poderá prosseguir com a edição da cena resultante em uma nova janela.

Para executar a manipulação reversa, se, por exemplo, precisarmos levar os objetos da ramificação salva para a cena atual, a fim de reconstruí-los ou modificá-los, clique com o botão direito do mouse no nó que oculta a cena e selecione o item "Tornar local". A cena salva, que ele representou, não é destruída.



#



Para usar variáveis ​​globais, você precisa criar um script e soltá-lo no carregamento automático: Projeto -Configurações do projeto - Inicialização . Um singleton deve ser verificado.





O conteúdo do script SaveTheWorld, cujas variáveis ​​queremos usar como global. No momento, um certo indicador de saúde e uma série de estados inimigos são declarados aqui, que são preenchidos na etapa de inicialização.



Para se referir a essas variáveis ​​globais a partir do código, você primeiro precisa obter uma referência ao singleton e, em seguida, usar suas variáveis:





Encontre nosso SaveTheWorld e verifique se o estado desse inimigo em particular é zero. Nesse caso, o inimigo é removido.



UPD. Você pode acessar as variáveis ​​de um singleton diretamente através do nome, ou seja, no exemplo acima, não precisaríamos usar um link e, em vez de main.enemy_arr [myID], nos referiríamos a SaveTheWorld.enemy_arr [myID]. Mas você deve ter certeza de que este nó tem uma marca de seleção na coluna "singleton" em sua inicialização.



#



Um nó AnimationPlayer é adicionado à cena para gravar e reproduzir animações. Pode estar em qualquer lugar da hierarquia. Para dar a ele a oportunidade de gravar animação, você precisa clicar no botão "Animação" acima da linha do tempo aberta e criar uma nova animação.

Depois disso, em cada nó selecionado na cena atual, os ícones principais aparecerão à direita no inspetor. Se você clicar na tecla, o animador oferecerá a adição de uma nova faixa de animação.







Em seguida, movemos o controle deslizante da linha do tempo para os pontos desejados e, em cada um, alteramos o valor animado no inspetor de objetos, pressionando a tecla novamente para que esse ponto apareça na linha do tempo. Você pode expandir a linha do tempo disponível no campo com o relógio, à direita, por padrão, há 1 segundo. À direita do relógio, há um botão de animação em loop. Abaixo, a primeira da linha é uma das opções usadas com freqüência, que define a animação suave contínua ou discreta.

À direita do painel central com o nome da animação está o botão de execução automática; se você pressioná-lo, a animação selecionada será reproduzida quando o aplicativo iniciar. Se você precisar de vários objetos animados que são reproduzidos em um loop constantemente, poderá criar suas faixas em um AnimationPlayer criando uma animação comum para eles. Se você precisar alternar animações para um objeto específico, poderá iniciar um AnimationPlayer separado e criar várias animações para diferentes estados, enquanto apenas uma delas pode ser marcada como iniciada automaticamente.



#



Para vários nós, por exemplo, MeshInstance ou CollisionShape, no campo Mesh (Shape), você pode escolher em uma lista preparada de primitivas (incluindo carregar seu modelo personalizado, no caso de MeshInstance).







Para o MeshInstance, uma das primitivas mais caras será a esfera e a cápsula, pois provavelmente conterão muitos polígonos. Portanto, para partículas 3D, é melhor escolher algo como um polígono, cubo ou prisma. Para colisões, pelo contrário, a forma da esfera será a mais rápida de ler, uma vez que os parâmetros possuem apenas um raio. Na verdade, o exposto acima não se aplica apenas a Godot, mas também a outros mecanismos de jogos.

Godot também pode fazer um formulário de colisão para o MeshInstance automaticamente, para isso, você precisa clicar no botão "Matriz", que aparece no canto superior direito do editor quando o MeshInstance é selecionado. Em seguida, escolha entre as opções propostas, mas como regra geral, para o mesmo terreno, este será o primeiro item - "Criar um corpo estático côncavo" (após o qual um nó StaticBody com uma colisão exata aninhada nele será anexado ao objeto). Em todos os outros casos, quando não são necessárias colisões especialmente precisas, você pode conviver com as primitivas CollisionShape expostas independentemente ou coletar malhas ideais para colisões em um pacote 3D, adicioná-las via MeshInstance e também criar uma colisão com base em sua forma através do botão "Matriz".



#



Se em qualquer um dos campos numéricos do inspetor for necessário, por exemplo, adicionar um determinado número ao parâmetro, multiplicar o valor e assim por diante, você poderá fazer o seguinte: "315-180", "20 + 40", "64 * 5" ... o próprio editor calculará e substituirá o resultado final da operação no campo.



All Articles