Marcher dans une scène 3DGS : prise en charge de la collision
LCC4Unreal prend en charge le chargement dynamique des données de collision : un personnage peut se déplacer et interagir librement dans le monde 3DGS.
Prérequis
La collision dépend des fichiers de collision fournis avec les données, et les exigences diffèrent selon le format :
| Format | Données de collision | Prise en charge |
|---|---|---|
.lcc | collision.lci dans le répertoire de données, collision.bin dans les versions antérieures | Prise en charge |
.lcc2 | Fichiers .ply dans data/mesh/ du répertoire de données | Prise en charge |
.sog / .spz / .ply | Aucune nativement ; l'édition Pro peut la dériver des gaussiennes | Prise en charge (édition Pro) |
Pour .lcc et .lcc2, le plugin recherche le fichier de collision fourni avec les données dans l'ordre collision.lci → collision.bin → data/mesh/*.ply ; en l'absence des trois, il émet un avertissement et désactive la collision.
Les formats à fichier unique (.sog / .spz / .ply) ne transportent aucune donnée de collision propre. L'édition Pro peut dériver automatiquement un maillage de collision à partir des gaussiennes, voir Génération automatique de collision pour les modèles mono-fichier ; l'édition gratuite nécessite de construire la collision vous-même.
Après le chargement des données, HaveValidCollisionData() permet de vérifier si les données courantes contiennent des données de collision utilisables.
Note :
collision.lcidoit être exporté avec LCC Studio v1.6.1 ou une version ultérieure ; les données exportées avec des versions antérieures utilisentcollision.bin.
Mécanisme de chargement
Comme les données de rendu, les données de collision sont stockées par blocs spatiaux. Le plugin ne charge pas toute la collision d'un coup : il ne charge que les blocs situés dans une certaine distance autour de la caméra et les échange dynamiquement au fil des déplacements de la caméra.
Camera position changes
│
▼
Compute the set of collision blocks to load within range
│
▼
Compare with the previous set ── Same ──▶ Skip, do nothing
│ Different
▼
Load the new blocks → Hand them to the physics system for baking → Generate collision bodies
Quelques points d'implémentation :
- La portée de chargement est contrôlée par
Max Load Collision Distance(m); les zones au-delà de cette distance n'ont pas de collision - Le premier chargement est synchrone, pour éviter qu'un personnage traverse le sol et tombe avant que la collision soit prête ; les mises à jour suivantes sont asynchrones et ne bloquent pas le thread principal
- Une limitation de fréquence est appliquée : la collision n'est pas reconstruite à chaque image lors des déplacements continus de la caméra
- Quand l'ensemble des blocs visibles n'a pas changé, le traitement est ignoré : un petit déplacement sur place ne déclenche pas de reconstruction
- Le calcul se fait uniquement selon la caméra principale : les SceneCapture ne participent pas au chargement de la collision
Avantages
- L'occupation mémoire ne dépend que de la portée de chargement, pas du volume total de données, donc les grandes scènes peuvent aussi avoir de la collision
- Le nombre de corps de collision que le système physique doit traiter reste toujours maîtrisé et ne ralentit pas les calculs physiques quand la taille de la scène augmente
Coûts et contournements
| Problème | Cause | Contournement |
|---|---|---|
| Le personnage traverse le sol et tombe au démarrage du jeu | La collision n'est pas encore construite | Surélevez le PlayerStart, ou n'activez le déplacement du personnage qu'une fois la collision prête |
| Saccade quand le personnage entre dans la zone de la scène 3DGS depuis le lointain | Le personnage apparaît en dehors de la portée de chargement de la collision, et l'entrée déclenche un premier chargement synchrone | Placez le point d'apparition du personnage dans la portée de chargement de la collision, ou chargez toute la collision d'un coup |
| Pas de collision au loin, les tests de rayon n'atteignent rien | Les zones au-delà de la portée de chargement ne génèrent pas de corps de collision | Augmentez Max Load Collision Distance(m), ou utilisez une méthode de détection qui ne dépend pas de la collision |
| Absence de collision pendant un court instant après une téléportation ou un déplacement rapide | Les blocs de collision de la nouvelle zone sont encore en chargement | Chargez toute la collision d'un coup |
Saccades pendant les déplacements, temps Update Collision élevé | Les blocs de collision sont échangés et rebakés fréquemment | Réduisez la portée de chargement, ou vérifiez si la collision est réellement nécessaire |
| Le maillage de navigation est reconstruit à répétition avec la navigation | Les changements de collision déclenchent la mise à jour du NavMesh | Augmentez la portée de chargement pour que la zone cible soit chargée d'un coup, et utilisez un bake Static ; voir Prise en charge du système de navigation |
Charger toute la collision d'un coup
La plupart des coûts ci-dessus viennent des échanges dynamiques à l'exécution. Si la taille de la scène est limitée et que la mémoire a de la marge, augmentez Max Load Collision Distance(m) jusqu'à couvrir toute la scène pour que la collision soit entièrement construite au chargement des données.
Il n'y a alors plus d'échange de blocs de collision à l'exécution, et les problèmes du tableau précédent (chute à travers le sol, absence de collision après téléportation, saccades en déplacement, reconstruction répétée de la navigation) disparaissent. C'est particulièrement recommandé avec le système de navigation.
Le coût est un temps de chargement plus long au démarrage et une occupation mémoire fixée à la taille de la collision de toute la scène. Pour juger de la faisabilité : consultez Collision Data Usage dans stat xgrids et vérifiez que l'occupation mémoire après chargement complet reste acceptable.
Activation
LCCComponent->SetLCCCollisionEnable(true);
Ou cochez bEnableCollision dans le panneau Details.

Activation de la collision LCC dans le panneau Details

Collision dynamique d'un personnage dans une scène LCC
Vérification
Dans les réglages du mode d'affichage, choisissez la collision joueur ou la collision de visibilité pour observer si la collision est bien activée

Vérification des corps de collision avec le mode collision joueur ou collision de visibilité
Propriétés associées
| Propriété | Description |
|---|---|
| bEnableCollision | Active la collision |
| CollisionLoadMaxDistance | Distance de chargement maximale des données de collision (300 mètres par défaut) |

Configuration de l'état d'activation de la collision et de la distance de chargement maximale
Génération automatique de collision pour les modèles mono-fichier (fonctionnalité de l'édition Pro)
Les modèles mono-fichier (.ply / .spz / .sog) ne transportent aucune donnée de collision propre. Le plugin dérive un maillage de collision à partir des gaussiennes elles-mêmes, le met en cache sous la forme <nom>.collision.ply à côté du modèle, puis le charge et le réutilise via le chemin de collision PLY existant.
C'est une fonctionnalité de l'édition Pro, qui ne génère qu'après l'enregistrement d'une App Key ; voir Éditions et licences. Sans licence, aucun maillage de collision n'est généré et vous devez construire la collision vous-même, comme décrit dans Approche manuelle sans génération automatique.
Étapes
- Cochez bEnableCollision dans le panneau du LCC Actor.
- Chargez un modèle mono-fichier (
.ply/.spz/.sog). - Le premier chargement passe à l'état
Generatinget construit le maillage de collision sur place. Cela prend de quelques secondes à quelques minutes selon le volume de données ; une fois terminé, l'état passe àLoadedet<nom>.collision.plyest écrit à côté du modèle. - Lors d'un chargement ultérieur du même modèle, si le fichier de cache existe, l'état passe directement à
Loadedet la génération est ignorée.

Avec la collision activée, un message apparaît en bas à droite lors du premier chargement d'un modèle mono-fichier pendant la génération du maillage de collision
L'état de génération et de collision peut être interrogé avec GetCollisionState() ou en écoutant l'événement OnCollisionStateChanged ; pour les valeurs, voir ULCCComponentBase - Requête d'état.
Astuce : pour éviter la génération à l'exécution, distribuez ou packagez le
<nom>.collision.plygénéré avec le modèle ; à l'exécution, le cache est réutilisé directement dès sa détection.Astuce : il n'y a aucun message intégré lorsque la collision est générée dans un jeu packagé. Pour indiquer au joueur « génération de la collision », écoutez l'état
GeneratingdeOnCollisionStateChangedet affichez-le vous-même.Astuce : une génération échouée passe à l'état
Failed; la cause précise figure dans l'Output Log, et désactiver puis réactiver la collision relance la tentative. Pour retester le processus de génération, supprimez d'abord le fichier de cache.collision.plyà côté du modèle.
Approche manuelle sans génération automatique
Pour contrôler entièrement la forme de la collision, ou lorsque les données ne se prêtent pas à la dérivation, vous pouvez laisser la génération automatique désactivée et construire la collision dans la scène vous-même :
- Blocking Volume : composez le sol, les murs et les autres zones à bloquer avec les volumes de blocage du moteur. Adapté aux formes régulières, c'est la solution la moins coûteuse
- Maillage approximatif : placez un maillage épousant la forme du 3DGS et activez sa collision. Adapté aux scènes de forme complexe. Ce maillage peut réutiliser le maillage proxy, en passant son préréglage de collision en mode bloquant
Ces deux approches manuelles sont indépendantes du mécanisme de chargement de collision de LCC : elles ne sont pas soumises à CollisionLoadMaxDistance et ne sont pas échangées au fil des déplacements de la caméra.
Zones de découpe de collision
La collision peut être découpée en même temps que les volumes de découpe et plans de coupe, afin que la portée de collision corresponde à l'image rendue. Un volume de découpe n'affecte que le rendu par défaut : la zone supprimée disparaît de l'image mais la collision subsiste, et un personnage heurte un mur invisible. Avec la découpe de collision (Clip Collision) activée, la collision est également supprimée dans la zone découpée.
Étapes
- Ajoutez et configurez un volume de découpe ou un plan de coupe sur le LCC Actor comme décrit dans Édition de scène, et vérifiez que l'image rendue est découpée comme prévu.
- Cochez Activer la collision (bEnableCollision) dans le panneau du LCC Actor.
- Cochez Clip Collision dans le panneau ; la collision est alors découpée par le volume de découpe et aucun corps de collision n'est généré dans la zone supprimée.
Les images ci-dessous utilisent le mode d'affichage collision de visibilité pour comparer le filaire de collision avant et après l'activation de Clip Collision. Désactivé, la collision couvre toute la zone :

Clip Collision décoché : le filaire de collision couvre toute la zone
Activé, la collision à l'intérieur du volume de découpe est également supprimée, conformément au rendu :

Clip Collision coché : la collision à l'intérieur de la zone découpée est également supprimée
Astuce : Clip Collision nécessite d'abord l'activation de la collision, et s'applique aussi à la collision générée automatiquement pour les modèles mono-fichier.
Requête et événements d'état de la collision
Vous pouvez interroger l'état courant de la collision, ou écouter les changements d'état de la collision, pour des logiques telles que « ne faire apparaître le personnage qu'une fois la collision prête » ou « afficher la progression pendant la génération » :
GetCollisionState()retourne l'état courant :NoCollision(désactivée ou aucun modèle) /Generating(un modèle mono-fichier génère son maillage de collision) /Loading(la collision près de la caméra est en cours de chargement/cook) /Loaded(la collision près de la caméra est en place) /Failed(impossible à fournir).- L'événement
OnCollisionStateChangedest diffusé au changement d'état, ce qui permet d'activer le déplacement du personnage seulement aprèsLoaded, ou d'afficher un message pendantGenerating.
Pour l'interface complète et les conventions d'utilisation, voir ULCCComponentBase - Requête d'état.
Astuce :
Loadedsignifie que la collision près de la caméra est en place, pas que tout le modèle possède une collision — la collision continue d'être chargée en streaming au fil des déplacements de la caméra. Pour « ne pas traverser le sol sous les pieds », attendreLoadedsuffit ; pour la collision au loin, augmentez la distance de chargement.
Points de vigilance
- Une fois la collision activée, le LineTrace du moteur UE permet des tests de rayon basés sur les corps de collision, avec une portée de détection également limitée par la portée de chargement
- La mémoire occupée par les données de collision est visible dans
Collision Data Usagedestat xgrids, et le temps de mise à jour dansUpdate Collision; pour la signification des paramètres, voir Paramètres de performance