Non sono affatto d'accordo con la risposta di Philipp ; o almeno con come lo ha presentato. Dà l'impressione che spostare il mondo intorno al giocatore possa essere un'idea migliore; quando è l'esatto contrario. Quindi ecco la mia risposta ...
Entrambe le opzioni possono funzionare, ma in genere è una cattiva idea "invertire la fisica" spostando il mondo attorno al giocatore piuttosto che al giocatore in tutto il mondo.
Perdita / spreco di prestazioni:
Il mondo di solito avrà molti oggetti; molti se non la maggior parte, statici o addormentati. Il giocatore avrà uno o relativamente pochi oggetti. Spostare il mondo intero attorno al giocatore, significa spostare tutto nella scena tranne il giocatore. Oggetti statici, oggetti dinamici dormienti, oggetti dinamici attivi, sorgenti luminose, sorgenti sonore, ecc .; tutti devono essere spostati.
Questo è (ovviamente) considerevolmente più costoso che spostare solo ciò che si sta effettivamente muovendo (il giocatore, e forse qualche altra cosa).
Manutenibilità ed estensibilità:
Spostare il mondo intorno al giocatore fa sì che il mondo (e tutto ciò che contiene) sia il punto in cui le cose accadono più attivamente. Qualsiasi bug o cambiamento nel sistema significa che, potenzialmente, tutto cambia. Questo non è un buon modo di fare le cose; vuoi che i bug / le modifiche siano il più isolati possibile, in modo da non avere comportamenti imprevisti da qualche parte in cui non hai apportato modifiche.
Ci sono anche molti altri problemi con questo approccio. Ad esempio, infrange molte ipotesi su come le cose dovrebbero funzionare all'interno del motore. Non saresti in grado di usare la dinamica RigidBody
per qualcosa di diverso dal giocatore, per esempio; come un oggetto con un allegato RigidBody
non impostato su cinematica si comporterà inaspettatamente quando si imposta posizione / rotazione / scala (cosa che si farebbe in ogni fotogramma, per ogni oggetto nella scena, tranne il giocatore 😨)
Quindi la risposta è spostare il giocatore solo allora!
Bene ... sì e no . Come menzionato nella risposta di Philipp, in un tipo di gioco a corridore infinito (o qualsiasi gioco con una grande area esplorabile senza soluzione di continuità), andare troppo lontano dall'origine introdurrebbe alla fine degli FPPE evidenti ( errori di precisione a virgola mobile ) e, ancora, infine, straripare il tipo numerico, causando l'arresto anomalo del gioco o, fondamentalmente, facendo scoppiare il fumo del mondo di gioco ... Sugli steroidi! 😵 (perché a questo punto, gli FPPE renderebbero il gioco già in crack "normale")
La vera soluzione:
Non fare nessuno dei due e fare entrambi! Dovresti mantenere il mondo statico e muoverlo attorno. Ma "ri-root" sia il giocatore che il mondo, quando il giocatore inizia ad allontanarsi troppo dalla radice (posizione [0, 0, 0]
) della scena.
Se mantieni la posizione relativa delle cose (giocatore rispetto al mondo che lo circonda), e fai questo processo in un singolo aggiornamento di fotogrammi, il giocatore (effettivo) non se ne accorgerà nemmeno!
Per farlo, hai due opzioni principali:
- Sposta il giocatore nella radice della scena e sposta il blocco del mondo nella sua nuova posizione rispetto al giocatore.
- Pensa al mondo come una griglia; sposta la parte della griglia in cui si trova il giocatore nella radice e sposta il giocatore nella sua nuova posizione rispetto a quella parte della griglia.
Ecco un esempio di questo processo in azione
Ma quanto è troppo lontano?
Se guardi il codice sorgente di Unity, usano 1e-5
( 0.00001
) come base per considerare due valori in virgola mobile "uguali", dentro Vector2
e Vector3
(i tipi di dati responsabili delle posizioni degli oggetti, [eulero-] rotazioni e scale). Poiché la perdita di precisione in virgola mobile avviene in entrambi i modi a partire da zero, è lecito ritenere che qualsiasi cosa sotto 1e+5
( 100000
) unità lontana dalla radice / origine della scena sia sicuro da lavorare.
Ma! Da...
- È più appropriato creare un sistema per gestire automaticamente questi processi di re-rooting.
- Qualunque sia il tuo gioco, non è necessario che una "sezione" contigua del mondo sia larga 100000 unità (metri [?]).
... quindi è probabilmente una buona idea fare il rooting molto prima / più spesso di quel marchio di 100000 unità. Il video di esempio che ho fornito sembra farlo ogni 1000 unità circa, per esempio.