Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

Parallasse 2D

Introduzione

L'effetto parallasse serve per simulare la profondità facendo muovere le texture a velocità diverse rispetto alla telecamera. Godot fornisce il nodo Parallax2D per ottenere questo effetto. Tuttavia, può comunque essere facile confondersi, quindi questa pagina fornisce descrizioni dettagliate di alcune proprietà e come correggere alcuni errori comuni.

Nota

Questa pagina spiega come utilizzare Parallax2D, che è consigliato utilizzare al posto dei nodi ParallaxLayer e ParallaxBackground.

Per cominciare

Il nodo parallasse supporta l'aggiunta di nodi che renderizzano cose come figli, quindi è possibile utilizzare uno o più nodi per comporre ogni livello. Per cominciare, aggiungi ciascun nodo o i nodi che vuoi far scorrere indipendentemente come figli del proprio nodo parallasse. Assicurati che l'angolo in alto a sinistra delle texture utilizzate si trovi all'incrocio (0, 0), come nell'immagine qui sotto. Consulta la sezione positioning per capire perché questo è importante.

../../_images/2d_parallax_size_viewport.webp

La scena qui sopra utilizza una texture preparata per le nuvole più alte in uno Sprite2D, ma si potrebbero altrettanto facilmente utilizzare più nodi distanziati tra loro per comporre il livello.

Scala di scorrimento

Il pilastro dell'effetto parallasse è la proprietà scroll_scale. Funziona come un moltiplicatore della velocità di scorrimento, consentendo ai livelli di muoversi a una velocità diversa rispetto alla telecamera per ogni asse impostato. Un valore di 1 fa scorrere il nodo parallasse alla stessa velocità della telecamera. Se vuoi che l'immagine appaia più lontana durante lo scorrimento, utilizza un valore inferiore a 1, con 0 che lo arresta completamente. Se vuoi che qualcosa appaia più vicino alla telecamera, utilizza un valore superiore a 1, rendendo lo scorrimento più veloce.

La scena qui sopra è composta da cinque livelli. Alcuni buoni valori per scroll_scale potrebbero essere:

  • (0.7, 1) - Forest (Foresta)

  • (0.5, 1) - Hills (Colline)

  • (0.3, 1) - Lower Clouds (Nuvole in basso)

  • (0.2, 1) - Higher Clouds (Nuvole in alto)

  • (0.1, 1) - Sky (Cielo)

Il video qui sotto mostra come questi valori influiscono sullo scorrimento durante il gioco:

Ripetizione infinita

Parallax2D fornisce un effetto in più che dà alle texture l'illusione di ripetersi all'infinito. repeat_size indica al nodo di agganciare la sua posizione in avanti o indietro quando la telecamera scorre del valore impostato. Questo effetto si ottiene aggiungendo una singola ripetizione a tutti gli elementi canvas figli, scostati da tale valore. Mentre la telecamera scorre tra l'immagine e la sua ripetizione, questa torna invisibilmente indietro, dando l'impressione di un'immagine in ciclo.

../../_images/2d_parallax_scroll.gif

Essendo un effetto delicato, è facile per gli utenti meno esperti commettere errori durante la configurazione. Analizziamo quindi il "come" e il "perché" di alcuni problemi comuni riscontrati dagli utenti.

Dimensionamento scarso

L'effetto di ripetizione infinita è più facile da gestire quando hai un'immagine progettata per ripetersi senza cuciture e ha le stesse dimensioni o è più grande della viewport prima di impostare repeat_size. Se non riesci a ottenere risorse progettate per questo compito, ci sono altre cose che potresti fare per preparare al meglio l'immagine in termini di dimensioni.

Ecco un esempio di una texture troppo piccola per la sua viewport:

../../_images/2d_parallax_size_bad.webp

Possiamo notare che le dimensioni della viewport sono 500x300, ma quelle della texture sono 288x208. Se impostiamo repeat_size sulle dimensioni della nostra immagine, l'effetto di ripetizione infinita non scorre correttamente perché la texture originale non copre la viewport. Se impostiamo repeat_size sulle dimensioni della viewport, abbiamo un grande spazio vuoto. Cosa possiamo fare?

Rendere la viewport più piccola

La soluzione più semplice è impostare la viewport in modo che abbia le stesse dimensioni o sia più piccola delle texture. In Project Settings > Display > Window, modifica le impostazioni Viewport Width e Viewport Height così da corrispondere allo sfondo.

../../_images/2d_parallax_size_viewport.webp

Cambiare la scala del Parallax2D

Se non stai puntando a uno stile pixel-perfect o non importa avere una leggera sfocatura, è possibile ridimensionare le texture per adattarle allo schermo. Impostando la proprietà scale di Parallax2D, tutte le texture figlie verranno ridimensionate di conseguenza.

Cambiare la scala dei nodi figlio

Similmente a cambiare la scala del Parallax2D, è possibile cambiarla per i nodi Sprite2D affinché siano grandi abbastanza da coprire lo schermo. Tieni presente che alcune impostazioni come Parallax2D.repeat_size e Sprite2D.region_rect non tengono conto della scala, quindi è necessario regolare questi valori in base alla scala.

../../_images/2d_parallax_size_scale.webp

Ripetere le texture

Puoi anche cominciare con il piede giusto preparando i nodi figli in un passo precedente del processo. Se hai uno Sprite2D che vorresti ripetere, ma è troppo piccolo, puoi fare quanto segue per farlo ripetere:

Qui sotto, puoi vedere che ripetendo l'immagine due volte, questa diventa grande abbastanza da coprire l'intero schermo.

../../_images/2d_parallax_size_repeat.webp

Posizionamento inadeguato

È comune che gli utenti impostino per errore tutte le loro texture in modo che siano centrate su (0,0):

../../_images/2d_parallax_single_centered.webp

Questo crea problemi con l'effetto di ripetizione infinita e si dovrebbe evitare. Il "canvas di ripetizione infinita" inizia in (0,0) e si espande verso il basso e verso destra fino alle dimensioni del valore di repeat_size.

../../_images/2d_parallax_single_expand.webp

Se le texture sono centrate sull'incrocio (0,0), il canvas a ripetizione infinita è coperto solo parzialmente, quindi si ripete solo parzialmente.

Aumentando repeat_times si risolverebbe il problema?

Aumentare repeat_times tecnicamente funzionerebbe in alcuni scenari, ma è una soluzione bruta e non il problema per cui è stata progettata (ne parleremo tra poco). Una soluzione migliore, per prima cosa, è capire come funziona l'effetto di ripetizione e impostare le texture parallasse appropriatamente.

Per prima cosa, verifica che le texture non si estendano sulle parti negative del canvas. Assicurati che le texture utilizzate nei nodi parallasse si adattino al "canvas a ripetizione infinita" a partire da (0,0). In questo modo, se Parallax2D.repeat_size è impostato correttamente, dovrebbe apparire più o meno così, con un singolo ciclo dell'immagine delle stesse dimensioni o più grande della viewport:

../../_images/2d_parallax_repeat_good_norect.webp

Se pensi a come l'immagine scorre sullo schermo, inizia mostrando ciò che è dentro il rettangolo rosso (determinato da repeat_size), e quando raggiunge ciò che è dentro il rettangolo giallo, l'immagine scatta in avanti per dare l'illusione di uno scorrimento infinito.

../../_images/2d_parallax_repeat_good.webp

Se hai l'immagine posizionata lontano dal "canvas a ripetizione infinita", quando la telecamera raggiunge il rettangolo giallo, metà dell'immagine viene tagliata prima che scatti in avanti, come nell'immagine sottostante:

../../_images/2d_parallax_repeat_bad.webp

Offset di scorrimento

Se le tue texture parallasse funzionano già correttamente, ma preferisci che inizino da un punto diverso, Parallax2D include una proprietà scroll_offset usata per compensare dove inizia il canvas a ripetizione infinita. Ad esempio, se la tua immagine è 288x208, impostando scroll_offset su (-144,0) o (144,0), l'effetto inizierà a metà dell'immagine.

Numero di ripetizioni

Idealmente, seguendo questa guida, le texture parallasse dovrebbero essere abbastanza grandi da coprire lo schermo anche riducendo lo zoom. Finora, abbiamo avuto una texture 288x208 perfettamente adatta all'interno di una viewport 288x208. Tuttavia, si verificano problemi quando riduciamo lo zoom impostando Camera2D.zoom su (0.5, 0.5):

../../_images/2d_parallax_zoom_single.webp

Sebbene tutto sia impostato correttamente per la viewport al livello predefinito di zoom, riducendo lo zoom l'immagine diventa più piccola della viewport, rovinando l'effetto di ripetizione infinita. È qui che repeat_times può essere d'aiuto. Impostando un valore di 3 (una ripetizione in più dietro e davanti), ora è abbastanza grande da accomodare l'effetto di ripetizione infinita.

../../_images/2d_parallax_zoom_repeat_times.webp

Se queste texture fossero state progettate per essere ripetute verticalmente, avremmo specificato un valore y per repeat_size. Il repeat_times avrebbe automaticamente aggiunto una ripetizione anche sopra e sotto. È solo una parallasse orizzontale, quindi lascia un blocco vuoto sopra e sotto l'immagine. Come lo risolviamo? Dobbiamo essere creativi! In questo esempio, ampliamo il cielo verso l'alto e lo sprite dell'erba verso il basso. Le texture ora supportano il livello normale di zoom e lo zoom indietro fino a metà dimensioni.

../../_images/2d_parallax_zoom_repeat_adjusted.webp

Schermo diviso

La maggior parte dei tutorial per creare un gioco a schermo diviso in Godot comincia scrivendo un piccolo script per assegnare il Viewport.world_2d della prima SubViewport alla seconda, così da condividere la loro visualizzazione. Spesso sorgono domande su come condividere un effetto parallasse tra i due schermi.

L'effetto parallasse simula una prospettiva spostando la posizione di diverse texture rispetto alla telecamera. Questo, comprensibilmente, può essere problematico se hai più telecamere, perché le texture non possono stare in due posti alla volta!

Questo è comunque possibile clonando i nodi parallasse nella seconda (o terza o quarta) SubViewport. Ecco come appare una configurazione per un gioco a due giocatori:

../../_images/2d_parallax_splitscreen.webp

Certo, ora entrambi gli sfondi appaiano in entrambe le SubViewport. Quello che vogliamo è che ogni effetto parallasse sia visibile solo nella loro viewport corrispondente. Possiamo farlo nel seguente modo:

  • Lascia tutti i nodi parallasse al loro visibility_layer predefinito di 1.

  • Imposta la proprietà canvas_cull_mask della prima SubViewport in modo da includere solo gli strati 1 e 2.

  • Fa lo stesso per la seconda SubViewport ma usa gli strati 1 e 3.

  • Assegna ai nodi parallasse della prima SubViewport un genitore comune e imposta il suo visibility_layer su 2.

  • Fai lo stesso per i nodi parallasse della seconda SubViewport, ma usa un livello di 3.

Come funziona? Se un elemento canvas ha un visibility_layer che non corrisponde al canvas_cull_mask della SubViewport, nasconderà tutti i figli, anche se corrispondono. Sfruttiamolo a nostro vantaggio, permettendo alle SubViewport di bloccare il rendering dei nodi parallasse il cui genitore non ha un visibility_layer supportato.

Vedere l'anteprima nell'editor

Prima della 4.3, la raccomandazione era di posizionare ogni livello nel proprio ParallaxBackground, abilitare la proprietà follow_viewport_enabled e scalare il singolo livello. Questo metodo è sempre stato difficile da implementare correttamente, ma è ancora realizzabile utilizzando un CanvasLayer invece di un ParallaxBackground.

Nota

Un'altra raccomandazione è il componente aggiuntivo "Parallax2D Preview" di KoBeWi. Offre diverse modalità di anteprima ed è molto utile!