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.
Checking the stable version of the documentation...
Interpolazione avanzata della fisica
Sebbene le istruzioni precedenti diano risultati soddisfacenti in molti giochi, in alcuni casi è consigliabile fare un passo in più per ottenere i migliori risultati possibili e un'esperienza di gioco più fluida.
Eccezioni all'interpolazione automatica della fisica
Anche con l'interpolazione della fisica attiva, potrebbero esserci alcune situazioni locali in cui sarebbe utile disabilitare l'interpolazione automatica per un Node (o un ramo dello SceneTree) e avere un controllo più preciso effettuando l'interpolazione manualmente.
Questo è possibile tramite la proprietà Node.physics_interpolation_mode presente in tutti i nodi. Se, ad esempio, si disattiva l'interpolazione per un nodo, anche i figli saranno influenzati ricorsivamente (poiché normalmente ereditano l'impostazione del genitore). Ciò significa che è possibile disabilitare facilmente l'interpolazione per un'intera sotto-scena.
È importante notare che, in entrambi 2D e 3D, l'interpolazione della fisica è effettuata sulla trasformazione locale di ogni istanza. Durante il rendering, le trasformazioni locali interpolate sono trasmesse ai figli.
Ciò significa che se un genitore ha physics_interpolation_mode impostato su On, ma per il figlio è impostato su Off, il figlio sarà comunque interpolato se il genitore è in movimento. Solo la trasformazione locale del figlio non è interpolata. Controllare il comportamento on/off dei nodi 2D richiede quindi un po' più cervello e pianificazione.
La situazione più comune in cui potrebbe essere necessario effettuare una propria interpolazione è per le telecamere.
Telecamere
In molti casi, un nodo Camera3D può usare l'interpolazione automatica come qualsiasi altro nodo. Tuttavia, per i migliori risultati, soprattutto a basse frequenze di tick di fisica, si consiglia di adottare un approccio manuale all'interpolazione della telecamera.
Questo perché gli utenti sono molto sensibili ai movimenti della telecamera. Ad esempio, una Camera3D che si riallinea leggermente ogni 1/10 di secondo (a una frequenza di 10 TPS) sarà spesso percettibile. È possibile ottenere un risultato molto più fluido spostando la telecamera a ogni frame in _process e seguendo manualmente un obiettivo interpolato.
Interpolazione manuale della telecamera
Assicurati che la telecamera utilizzi lo spazio delle coordinate globali
Il primo passo fondamentale quando si effettua l'interpolazione manuale della telecamera è assicurarsi che la trasformazione del Camera3D sia specificata nello spazio globale anziché ereditare la trasformazione di un nodo genitore in movimento. Questo perché può avvenire un feedback tra il movimento di un nodo genitore del Camera3D e il movimento del nodo telecamera stesso, il che può rovinare l'interpolazione.
Ci sono due modi per fare ciò:
Sposta la Camera3D in modo che sia indipendente e si trovi su un ramo separato, anziché essere un nodo figlio di un oggetto in movimento.
Chiama Node3D.top_level e imposta questo valore su
true, in modo che la telecamera ignori la trasformazione del suo genitore.
Esempio tipico
Un tipico esempio di approccio personalizzato consiste nell'utilizzare la funzione look_at nella Camera3D ad ogni frame in _process() per guardare un nodo obiettivo (come il giocatore).
C'è però un problema. Se usiamo il tradizionale get_global_transform() su un nodo "obiettivo" di una Camera3D, questa trasformazione metterà a fuoco la Camera3D solo sull'obiettivo al tick di fisica attuale. Questo non è ciò che vogliamo, poiché la telecamera salterà a ogni tick fisico man mano che l'obiettivo si muove. Anche se la telecamera è aggiornata a ogni frame, questo non aiuta a ottenere un movimento fluido se l'obiettivo cambia solo a ogni tick di fisica.
get_global_transform_interpolated()
Ciò su cui vogliamo mettere a fuoco la telecamera non è la posizione dell'obiettivo sul tick di fisica, bensì la posizione interpolata, ovvero la posizione in cui l'obiettivo sarà renderizzato.
Possiamo farlo attraverso la funzione Node3D.get_global_transform_interpolated. Questa si comporta esattamente come ottenere Node3D.global_transform, ma restituisce la trasformazione interpolata (durante una chiamata a _process()).
Importante
Si dovrebbe usare la funzione get_global_transform_interpolated() solo una o due volte in casi particolari, ad esempio per le telecamere. Non si dovrebbe usare dappertutto nel codice (sia per motivi di prestazioni, sia per garantire un'esperienza corretta).
Nota
A parte eccezioni come la telecamera, nella maggior parte dei casi la logica di gioco dovrebbe trovarsi in _physics_process(). Nella logica di gioco dovresti chiamare get_global_transform() o get_transform(), che restituiranno la trasformazione fisica attuale (nello spazio globale o locale, rispettivamente), che è solitamente ciò che servirà per il codice di gioco.
Script di esempio di camera manuale
Ecco un esempio di una semplice telecamera fissa che segue un obiettivo interpolato:
extends Camera3D
# Node that the camera will follow
var _target
# We will smoothly lerp to follow the target
# rather than follow exactly
var _target_pos : Vector3 = Vector3()
func _ready() -> void:
# Find the target node
_target = get_node("../Player")
# Turn off automatic physics interpolation for the Camera3D,
# we will be doing this manually
set_physics_interpolation_mode(Node.PHYSICS_INTERPOLATION_MODE_OFF)
func _process(delta: float) -> void:
# Find the current interpolated transform of the target
var tr : Transform = _target.get_global_transform_interpolated()
# Provide some delayed smoothed lerping towards the target position
_target_pos = lerp(_target_pos, tr.origin, min(delta, 1.0))
# Fixed camera position, but it will follow the target
look_at(_target_pos, Vector3(0, 1, 0))
Sguardo con il mouse
Il movimento del mouse è un metodo molto comune per controllare le telecamere. Tuttavia, c'è un problema. A differenza dell'input da tastiera, che si può campionare periodicamente ogni tick di fisica, gli eventi di movimento del mouse possono occorrere continuamente. La telecamera dovrà reagire e seguire questi movimenti del mouse nel frame successivo, anziché attendere il tick di fisica successivo.
In questa situazione, può essere meglio disabilitare l'interpolazione della fisica per il nodo della telecamera (tramite Node.physics_interpolation_mode) e applicare direttamente l'input dal mouse alla rotazione della telecamera, piuttosto che applicarlo in _physics_process.
A volte, soprattutto con le telecamere, potrebbe essere utile una combinazione di interpolazione e non interpolazione:
Una telecamera in prima persona potrebbe posizionare la telecamera nella posizione del giocatore (magari usando Node3D.get_global_transform_interpolated), ma controllare la rotazione della telecamera dal movimento del mouse senza interpolazione.
Una telecamera in terza persona potrebbe similmente determinare l'orientamento (posizione dell'obiettivo) della telecamera attraverso Node3D.get_global_transform_interpolated, ma posizionare la telecamera tramite il movimento del mouse senza interpolazione.
Esistono numerose permutazioni e variazioni di telecamere, ma dovrebbe essere chiaro che in molti casi, disabilitare l'interpolazione automatica della fisica e gestirla manualmente può fornire un risultato migliore.
Disabilitare l'interpolazione su altri nodi
Sebbene le telecamere siano l'esempio più comune, ci sono diversi casi in cui si potrebbe desiderare che altri nodi controllino la propria interpolazione o non siano interpolati. Considera, ad esempio, un giocatore in un gioco con visuale dall'alto la cui rotazione è controllata dal movimento del mouse. Disabilitando la rotazione fisica, la rotazione del giocatore corrisponde al movimento del mouse in tempo reale.
I MultiMesh
Sebbene la maggior parte dei nodi visivi segua il paradigma di un singolo nodo e una singola istanza visiva, i MultiMesh possono controllare diverse istanze dallo stesso nodo. Pertanto, includono qualche funzione in più per controllare la funzionalità di interpolazione per ogni singola istanza. È consigliabile esplorare queste funzioni se si utilizzano MultiMesh con interpolazione.
I dettagli completi sono disponibili nella documentazione MultiMesh.