Camminare in una scena 3DGS: supporto delle collisioni
LCC4Unreal supporta il caricamento dinamico dei dati di collisione, così i personaggi possono muoversi e interagire liberamente nel mondo 3DGS.
Prerequisiti
Le collisioni si basano sul file di collisione distribuito con i dati, e i requisiti differiscono per formato:
| Formato | Dati di collisione | Supporto |
|---|---|---|
.lcc | collision.lci nella directory dei dati, collision.bin nelle versioni precedenti | Supportato |
.lcc2 | File .ply in data/mesh/ nella directory dei dati | Supportato |
.sog / .spz / .ply | Nessuno di tipo nativo; l'edizione Pro può derivarla automaticamente dalle gaussiane | Supportato (edizione Pro) |
Per .lcc e .lcc2, il plugin controlla il file di collisione distribuito nell'ordine collision.lci → collision.bin → data/mesh/*.ply, e registra un avviso e disabilita le collisioni quando nessuno di essi esiste.
I formati a file singolo (.sog / .spz / .ply) non contengono dati di collisione di tipo nativo. L'edizione Pro può derivare automaticamente la mesh di collisione dalle gaussiane, vedere Generazione automatica della collisione per i modelli a file singolo; nell'edizione gratuita occorre montare la collisione manualmente.
Dopo il caricamento dei dati, usare HaveValidCollisionData() per verificare se i dati correnti contengono dati di collisione utilizzabili.
Nota:
collision.lcirichiede l'esportazione da LCC Studio v1.6.1 o superiore; i dati esportati dalle versioni precedenti usanocollision.bin.
Meccanismo di caricamento
I dati di collisione sono memorizzati in blocchi spaziali esattamente come i dati di rendering. Il plugin non carica tutte le collisioni in una volta: carica solo i blocchi entro una certa distanza dalla camera e li scambia dentro e fuori dinamicamente al movimento della camera.
La posizione della camera cambia
│
▼
Calcolo dell'insieme di blocchi di collisione da caricare nell'estensione
│
▼
Confronto con l'insieme precedente ── uguale ──▶ salta, non fa nulla
│ diverso
▼
Carica i nuovi blocchi → li passa al sistema fisico per il baking → genera i corpi di collisione
Alcuni punti di implementazione:
- L'estensione di caricamento è controllata da
Max Load Collision Distance(m), e le aree oltre quella distanza non hanno collisioni - Il primo caricamento è sincrono, il che evita che il personaggio cada attraverso il terreno prima che le collisioni siano pronte; ogni aggiornamento successivo è asincrono e non blocca il thread principale
- Gli aggiornamenti sono limitati in frequenza, quindi le collisioni non vengono ricostruite a ogni fotogramma mentre la camera si muove in continuo
- Gli aggiornamenti vengono saltati quando l'insieme dei blocchi visibili non cambia, quindi piccoli movimenti sul posto non innescano una ricostruzione
- Per il calcolo viene usata solo la camera principale, e SceneCapture non partecipa al caricamento delle collisioni
Vantaggi
- L'uso della memoria dipende solo dall'estensione di caricamento, non dalla dimensione totale dei dati, quindi le collisioni funzionano anche per grandi scene
- Il numero di corpi di collisione che il sistema fisico deve elaborare resta sotto controllo e non rallenta la fisica al crescere della scena
Costi e mitigazioni
| Problema | Causa | Mitigazione |
|---|---|---|
| Il personaggio cade attraverso il terreno nell'istante in cui il gioco parte | Le collisioni non sono ancora costruite | Alzare un po' PlayerStart, oppure abilitare il movimento del personaggio solo quando le collisioni sono pronte |
| Scatto quando il personaggio entra nel raggio della scena 3DGS da lontano | Il punto di spawn è fuori dal raggio di caricamento delle collisioni; il primo caricamento sincrono si attiva all'ingresso | Posizionare il punto di spawn all'interno del raggio di caricamento delle collisioni oppure caricare tutte le collisioni in una volta |
| Nessuna collisione in lontananza, quindi i line trace non colpiscono nulla | Le aree oltre l'estensione di caricamento non hanno corpi di collisione | Aumentare Max Load Collision Distance(m), oppure passare a un controllo che non si basi sulle collisioni |
| Nessuna collisione per un breve periodo dopo un teletrasporto o un movimento rapido | I blocchi di collisione della nuova area sono ancora in caricamento | Caricare tutte le collisioni in una volta |
Scatti durante il movimento, con un costo elevato di Update Collision | I blocchi di collisione vengono scambiati dentro e fuori e ricostruiti frequentemente | Ridurre l'estensione di caricamento, oppure verificare che le collisioni servano davvero |
| La mesh di navigazione continua a ricostruirsi quando si usa la navigazione | Le variazioni delle collisioni innescano aggiornamenti della NavMesh | Aumentare l'estensione di caricamento in modo che l'area di destinazione venga caricata in un solo passaggio, e usare il baking Static, vedere Supporto del Navigation System |
Caricare tutte le collisioni in una volta
La maggior parte dei costi elencati sopra deriva dallo scambio dei blocchi dentro e fuori a runtime. Quando le dimensioni della scena sono contenute e la memoria lo consente, aumentare Max Load Collision Distance(m) a sufficienza per coprire l'intera scena, così che tutte le collisioni vengano costruite in un solo passaggio durante il caricamento dei dati.
Lo scambio a runtime dei blocchi di collisione scompare, e nessuno dei problemi precedenti si verifica: caduta attraverso il terreno, collisioni mancanti dopo un teletrasporto, scatti durante il movimento e ricostruzioni ripetute della navigazione. Questo è consigliato in particolare quando si usa il sistema di navigazione.
Il costo è un tempo di caricamento più lungo all'avvio e un uso di memoria fisso pari alle collisioni dell'intera scena. Per valutare se è praticabile, controllare Collision Data Usage in stat xgrids e verificare che l'uso di memoria dopo un caricamento completo sia accettabile.
Abilitazione
LCCComponent->SetLCCCollisionEnable(true);
Oppure spuntare bEnableCollision nel pannello Details.

Abilitazione delle collisioni LCC nel pannello Details

Collisioni dinamiche di un personaggio in una scena LCC
Verifica
Usare le impostazioni della modalità di visualizzazione e selezionare player collision o visibility collision per osservare se le collisioni sono abilitate.

Verifica dei corpi di collisione con la modalità player collision o visibility collision
Proprietà correlate
| Proprietà | Descrizione |
|---|---|
| bEnableCollision | Abilita le collisioni |
| CollisionLoadMaxDistance | Distanza massima di caricamento dei dati di collisione (300 metri per impostazione predefinita) |

Configurazione dello stato di abilitazione delle collisioni e della distanza massima di caricamento
Generazione automatica della collisione per i modelli a file singolo
Funzionalità dell'edizione Pro. I modelli a file singolo (.ply / .spz / .sog) non contengono dati di collisione di tipo nativo. Il plugin deriva la mesh di collisione dalle gaussiane stesse e la memorizza nella cache come <nome>.collision.ply accanto al modello, così che in seguito venga caricata e riutilizzata tramite il percorso di collisione PLY già esistente.
È una funzionalità dell'edizione Pro: viene generata solo dopo la registrazione di un App Key, vedere Edizioni e licenze. Senza licenza la mesh di collisione non viene generata e occorre montarla manualmente secondo l'alternativa manuale senza generazione automatica.
Passaggi
- Selezionare bEnableCollision nel pannello del LCC Actor.
- Caricare il modello a file singolo (
.ply/.spz/.sog). - Il primo caricamento passa allo stato
Generatinge genera la mesh di collisione sul momento, con un tempo da pochi secondi a qualche minuto in base al volume dei dati; al termine passa aLoadede scrive<nome>.collision.plyaccanto al modello. - Caricando di nuovo lo stesso modello, se il file di cache esiste si passa direttamente a
Loadede la generazione viene saltata.

Con le collisioni abilitate, al primo caricamento di un modello a file singolo un avviso in basso a destra indica che la mesh di collisione è in generazione
Lo stato della generazione e della collisione può essere interrogato con GetCollisionState() oppure rimanendo in ascolto dell'evento OnCollisionStateChanged; per i valori, vedere ULCCComponentBase - Query dello stato.
Suggerimento: per evitare la generazione a runtime, basta distribuire o pacchettizzare il
<nome>.collision.plygià generato insieme al modello; a runtime, se la cache viene rilevata, viene riutilizzata direttamente.Suggerimento: generando la collisione in un gioco pacchettizzato non c'è alcun avviso di UI integrato; per avvisare il giocatore che «la collisione è in generazione», rimanere in ascolto dello stato
GeneratingdiOnCollisionStateChangede mostrarlo per conto proprio.Suggerimento: se la generazione fallisce, si passa allo stato
Failed; il motivo preciso è nell'Output Log, e si può riprovare disabilitando e riabilitando le collisioni. Per riprovare il processo di generazione, eliminare prima il file di cache.collision.plyaccanto al modello.
Alternativa manuale senza generazione automatica
Se si vuole controllare completamente la forma della collisione, o i dati non sono adatti a derivarla, si può anche lasciare disattivata la generazione automatica e montare la collisione per conto proprio nella scena:
- Blocking Volume: usare i blocking volume del motore per costruire terreno, pareti e altre aree che devono bloccare. Adatto a forme regolari e l'opzione più economica
- Mesh approssimata: posizionare una mesh che corrisponde alla forma del 3DGS e abilitarne le collisioni. Adatto a scene con forme complesse. Questa mesh può riutilizzare la mesh proxy cambiandone il preset di collisione in blocco
Questi due approcci manuali non utilizzano il meccanismo di caricamento delle collisioni LCC, quindi non sono influenzati da CollisionLoadMaxDistance e non vengono scambiati dentro e fuori al movimento della camera.
Aree di ritaglio della collisione
La collisione può essere ritagliata insieme ai volumi di taglio e ai piani di sezione, così che l'estensione della collisione resti uguale all'immagine renderizzata. Per impostazione predefinita, i volumi di taglio influiscono solo sul rendering: l'immagine dell'area tagliata scompare, ma la collisione resta e il personaggio urta contro un muro invisibile. Abilitando il ritaglio della collisione, la collisione viene rimossa anche all'interno dell'area tagliata.
Passaggi
- Aggiungere e configurare un volume di taglio o un piano di sezione sul LCC Actor secondo Modifica della scena e verificare che l'immagine renderizzata venga tagliata come previsto.
- Selezionare Abilita collisione (bEnableCollision) nel pannello del LCC Actor.
- Selezionare Ritaglio della collisione nel pannello; la collisione viene ritagliata subito secondo il volume di taglio, e nell'area tagliata non vengono più generati corpi di collisione.
L'immagine seguente confronta, con la modalità di visualizzazione «visibility collision», il contorno di collisione prima e dopo l'abilitazione del ritaglio della collisione. Quando è disattivato, la collisione copre l'intera area:

Senza selezionare «Ritaglio della collisione»: il contorno di collisione copre l'intera area
Una volta abilitato, la collisione all'interno del volume di taglio viene rimossa anch'essa, come il rendering:

Con «Ritaglio della collisione» selezionato: la collisione all'interno dell'area tagliata viene rimossa anch'essa
Suggerimento: il ritaglio della collisione richiede di abilitare prima la collisione, e funziona anche con la collisione generata automaticamente per i modelli a file singolo.
Query dello stato della collisione ed eventi
È possibile interrogare lo stato corrente della collisione, oppure rimanere in ascolto delle sue variazioni di stato, per logiche come «collocare il personaggio solo quando la collisione è pronta» o «mostrare l'avanzamento durante la generazione»:
GetCollisionState()restituisce lo stato corrente:NoCollision(disattivata o nessun modello) /Generating(il modello a file singolo sta generando la mesh di collisione) /Loading(la collisione vicina alla camera è in caricamento / baking) /Loaded(la collisione vicina alla camera è pronta) /Failed(non è possibile fornirla).- L'evento
OnCollisionStateChangedviene inviato quando lo stato cambia, cosa che permette di abilitare il movimento del personaggio dopoLoaded, oppure di mostrare un avviso duranteGenerating.
Per l'interfaccia completa e le convenzioni d'uso, vedere ULCCComponentBase - Query dello stato.
Suggerimento:
Loadedsignifica che la collisione vicina alla camera è pronta, non che l'intero modello abbia collisione; la collisione continua a essere caricata in streaming al movimento della camera. Quando serve solo «non attraversare il terreno sotto i piedi», basta attendereLoaded; per la collisione in lontananza, aumentare la distanza di caricamento.
Note
- Una volta abilitate le collisioni, il LineTrace di Unreal Engine può essere usato per i test dei raggi contro i corpi di collisione, e anche l'estensione del test è limitata dall'estensione di caricamento
- La memoria usata dai dati di collisione è visibile in
Collision Data Usagedistat xgrids, il costo degli aggiornamenti inUpdate Collision, e il significato delle voci in Parametri di prestazione