Paralaxe 2D (Parallax)
Introdução
Parallax é um efeito usado para simular profundidade fazendo com que texturas se movam em velocidades diferentes em relação à câmera. O Godot oferece o nó Parallax2D para alcançar esse efeito. Ainda assim, é fácil cometer erros, então esta página fornece descrições detalhadas de algumas propriedades e como corrigir erros comuns.
Nota
Esta página aborda como usar o Parallax2D, que é recomendado em vez dos nós ParallaxLayer e ParallaxBackground.
Primeiros passos
O nó de parallax suporta a adição de nós que renderizam elementos como filhos, então você pode usar um ou vários nós para compor cada camada. Para começar, coloque cada nó ou grupo de nós que você deseja que rolem de forma independente como filho de seu próprio nó de parallax. Certifique-se de que o canto superior esquerdo das texturas usadas esteja no cruzamento (0, 0), como mostrado na imagem abaixo. Veja a seção sobre posicionamento para entender por que isso é importante.
A cena acima usa uma textura preparada para as nuvens mais altas em um Sprite2D, mas você pode facilmente usar vários nós espaçados para compor a camada.
Scroll scale
A base do efeito de parallax é a propriedade scroll_scale. Ela funciona como um multiplicador de velocidade de rolagem, permitindo que as camadas se movam em uma velocidade diferente da câmera para cada eixo configurado. Um valor de 1 faz com que o nó de parallax role na mesma velocidade da câmera. Se você quiser que sua imagem pareça mais distante durante a rolagem, use um valor menor que 1, sendo que 0 a deixará completamente parada. Se quiser que algo pareça mais próximo da câmera, use um valor maior que 1, fazendo com que role mais rápido.
A cena acima é composta por cinco camadas. Alguns bons valores para scroll_scale podem ser:
(0,7, 1)- Floresta(0,5, 1)- Colinas(0,3, 1)- Nuvens baixas(0,2, 1)- Nuvens mais altas(0,1, 1)- Céu
O vídeo abaixo mostra como esses valores afetam a rolagem durante o jogo:
Repetição infinita
O Parallax2D oferece um efeito adicional que dá às texturas a ilusão de se repetirem infinitamente. A propriedade repeat_size informa ao nó para ajustar sua posição para frente ou para trás quando a câmera se move pelo valor definido. Esse efeito é alcançado ao adicionar uma repetição única a todos os itens de canvas filhos com um deslocamento baseado nesse valor. Enquanto a câmera se move entre a imagem e sua repetição, ela é ajustada de forma invisível, criando a aparência de uma imagem em loop.
Por ser um efeito delicado, é fácil para usuários não familiarizados cometerem erros de configuração. Vamos analisar o "como" e o "porquê" de alguns problemas comuns que os usuários encontram.
Poor sizing
O efeito de repetição infinita é mais fácil de trabalhar quando você tem uma imagem projetada para se repetir perfeitamente e que seja do mesmo tamanho ou maior que o seu viewport antes de definir a propriedade repeat_size. Se não for possível obter assets projetados para essa finalidade, há algumas outras coisas que você pode fazer para preparar melhor sua imagem em relação ao tamanho.
Here is an example of a texture that is too small for its viewport:
Podemos ver que o tamanho do viewport é 500x300, mas a textura tem 288x208. Se definirmos a propriedade repeat_size com a dimensão da nossa imagem, o efeito de repetição infinita não funciona corretamente porque a textura original não cobre a janela de exibição. Se definirmos a repeat_size com o tamanho da janela de exibição, teremos um grande espaço em branco. O que podemos fazer?
Diminua a janela de exibição
A resposta mais simples é fazer com que a janela de exibição tenha o mesmo tamanho, ou seja, menor que suas texturas. Em Configurações do Projeto > Exibição > Janela, altere as configurações Largura da Viewport e Altura da Viewport para corresponder ao seu plano de fundo.
Alterar a escala do Parallax2D
Se você não estiver buscando um estilo pixel-perfect ou não se importar com um pouco de desfoque, pode optar por aumentar a escalar das texturas para ficarem maiores e se ajustem à sua tela. Defina a propriedade scale do Parallax2D, e todas as texturas filhas serão escaladas com ele.
Scale the child nodes
Semelhantemente à escala do Parallax2D, você pode escalar seus nós Sprite2D para ficarem grandes o suficiente para cobrir a tela. Lembre-se de que algumas configurações, como Parallax2D.repeat_size e Sprite2D.region_rect, não levam a escala em consideração, portanto é necessário ajustar esses valores com base na escala.
Repeat the textures
Você também pode começar com o pé direito preparando os nós filhos mais cedo no processo. Se você tiver um Sprite2D que deseja repetir, mas que é pequeno demais, você pode fazer o seguinte para repeti-lo:
defina texture_repeat como CanvasItem.TEXTURE_REPEAT_ENABLED
defina region_enabled como
truedefina region_rect como um múltiplo da dimensão da sua textura, grande o suficiente para cobrir a janela de visualização.
Abaixo, você pode ver que repetir a imagem duas vezes a torna grande o suficiente para cobrir a tela.
Poor positioning
É comum ver usuários erroneamente definindo todas as suas texturas para serem centralizadas em (0,0):
Isso cria problemas com o efeito de repetição infinita e deve ser evitado. O "canvas de repetição infinita" começa em (0,0) e se expande para baixo e para a direita até o tamanho definido pela propriedade repeat_size.
Se as texturas estiverem centralizadas no cruzamento (0,0), o canvas de repetição infinita será coberto apenas parcialmente, então a repetição ocorrerá de forma incompleta.
Aumentar repeat_times resolveria isso?
Aumentar a propriedade repeat_times tecnicamente funcionaria em alguns cenários, mas é uma solução forçada e não resolve o problema para o qual essa propriedade foi projetada (vamos abordar isso em breve). Uma correção melhor é entender como o efeito de repetição funciona e configurar as texturas de parallax corretamente desde o início.
Primeiro, verifique se alguma textura está se estendendo para as partes negativas do canvas. Certifique-se de que as texturas usadas nos nós de parallax se encaixem dentro do "canvas de repetição infinita", que começa em (0,0). Dessa forma, se a propriedade Parallax2D.repeat_size estiver configurada corretamente, o resultado deve se parecer com isso: um único loop da imagem com o mesmo tamanho ou maior que a janela de exibição:
Se você pensar em como a imagem se move pela tela, ela começa exibindo o que está dentro do retângulo vermelho (determinado por repeat_size), e quando atinge o que está dentro do retângulo amarelo, ela reposiciona rapidamente a imagem para frente, criando a ilusão de rolagem infinita.
Se você posicionar a imagem longe da "tela de repetição infinita", quando a câmera atingir o retângulo amarelo, metade da imagem será cortada antes de avançar, como na imagem abaixo:
Deslocamento de rolagem (Scroll)
Se suas texturas de parallax já estão funcionando corretamente, mas você prefere que comecem em um ponto diferente, o Parallax2D possui a propriedade scroll_offset, usada para deslocar o ponto de início do canvas de repetição infinita. Por exemplo, se sua imagem mede 288x208, definir o scroll_offset como (-144,0) ou (144,0) permite que ela comece no meio da imagem.
Repeat times
Idealmente, seguindo este guia, suas texturas de parallax devem ser grandes o suficiente para cobrir a tela mesmo quando houver zoom out. Até agora, tínhamos uma textura de 288x208 que se encaixava perfeitamente em uma janela de exibição de 288x208. No entanto, problemas surgem quando aplicamos zoom out definindo o Camera2D.zoom para (0.5, 0.5):
Mesmo que tudo esteja configurado corretamente para a janela de exibição no nível de zoom padrão, ao aplicar zoom out a textura fica menor do que a janela de exibição, quebrando o efeito de repetição infinita. É aqui que a propriedade repeat_times pode ajudar. Definindo um valor de 3 (uma repetição extra atrás e uma na frente), agora ela é grande o suficiente para acomodar o efeito de repetição infinita.
Se essas texturas fossem feitas para se repetir verticalmente, teríamos especificado um valor em y na propriedade repeat_size. A propriedade repeat_times adicionaria automaticamente uma repetição acima e abaixo também. Como este é um parallax apenas horizontal, ele deixa um espaço vazio acima e abaixo da imagem. Como resolvemos isso? Precisamos ser criativos! Neste exemplo, esticamos o céu para cima e o sprite da grama para baixo. As texturas agora suportam tanto o nível de zoom normal quanto o zoom out para metade do tamanho.
Split screen
A maioria dos tutoriais para criar um jogo com tela dividida no Godot começa com um pequeno script para atribuir o Viewport.world_2d do primeiro SubViewport ao segundo, para que ambos compartilhem a mesma exibição. Frequentemente surgem dúvidas sobre como compartilhar um efeito de parallax entre as duas telas.
O efeito de parallax simula uma perspectiva movendo as posições de diferentes texturas em relação à câmera. Isso é compreensivelmente problemático se você tiver várias câmeras, pois suas texturas não podem estar em dois lugares ao mesmo tempo!
Isso ainda pode ser alcançado clonando os nós de parallax no segundo (ou terceiro ou quarto) SubViewport. Veja como fica a configuração para um jogo de dois jogadores:
Claro, agora ambos os fundos são exibidos em ambas as SubViewports. O que queremos é que cada parallax seja exibido somente na sua viewport correspondente. Podemos conseguir isso fazendo o seguinte:
Deixe todos os nós de parallax em seu padrão visibility_layer de 1.
Defina canvas_cull_mask do primeiro SubViewport para apenas as camadas 1 e 2.
Faça o mesmo para o segundo SubViewport, mas use as camadas 1 e 3.
Dê aos seus nós de parallax no primeiro SubViewport um pai comum e defina seu visibility_layer como 2.
Faça o mesmo para os nós de parallax do segundo SubViewport, mas use uma camada de 3.
Como isso funciona? Se um item de canvas tiver uma visibility_layer que não corresponde à canvas_cull_mask do SubViewport, ele ocultará todos os filhos, mesmo que eles correspondam. Usamos isso a nosso favor, permitindo que os SubViewports interrompam a renderização de nós de parallax cujo pai não possui uma visibility_layer compatível.
Previewing in the editor
Antes da versão 4.3, a recomendação era colocar cada camada em seu próprio ParallaxBackground, ativar a propriedade follow_viewport_enabled e escalar a camada individualmente. Esse método sempre foi complicado de acertar, mas ainda é possível utilizá-lo com um CanvasLayer em vez de um ParallaxBackground.
Nota
Outra recomendação é o plugin KoBeWi's "Parallax2D Preview". Ele oferece alguns modos de visualização diferentes e é muito prático!