Guida allo sviluppo del sistema di collisione
L'LCC Unity SDK dispone di un sistema di collisione integrato, focalizzato sulla risoluzione dell'accelerazione della costruzione dei collider e del rilevamento delle collisioni — ovvero il problema delle prestazioni di collisione. Il sistema Collider di Unity non può gestire il rilevamento in tempo reale in scene molto grandi.
L'LCC Unity SDK usa il proprio sistema di collisione integrato, non basandosi più sul componente MeshCollider di Unity e sulle capacità correlate, quindi non può agire direttamente sui GameObject di una scena Unity. Il formato dati LCC ufficiale generato da XGrids (LCC Studio) genera contemporaneamente, durante la ricostruzione, i dati Mesh usati per la collisione, e l'SDK usa questi dati di collisione per costruire in modo rapido ed efficiente la collisione della scena. Poiché si tratta di un sistema di collisione autonomo, l'uso della funzionalità di collisione richiede la chiamata dei metodi corrispondenti forniti dall'SDK.
Nota:
Il sistema di collisione integrato dell'SDK è incompatibile con il sistema Collider di Unity e non può agire direttamente sugli oggetti
Rigidbodyin Unity. La collisione per i personaggi come gli umani digitali deve essere guidata dai metodi di rilevamento dell'SDK (vedi "Implementazione della collisione dell'umano digitale" di seguito).Per le scene fisse, puoi anche estrarre i dati Mesh e farne il baking in una NavMesh in anticipo, che può essere compatibile con il sistema Collider di Unity; vedi la guida alla NavMesh per i dettagli.
Prerequisiti dei dati
Il prerequisito affinché il rilevamento delle collisioni funzioni è che la scena disponga dei corrispondenti dati di collisione. I dati ricostruiti in versioni precedenti potrebbero non contenere dati di collisione; in tal caso, la chiamata di SetColliderEnable(true) restituisce false e tutti i successivi metodi di rilevamento non sono disponibili.
Pertanto, dopo aver abilitato la collisione, assicurati di controllare il valore restituito:
bool ok = renderer.SetColliderEnable(true);
if (!ok)
{
Debug.LogWarning("I dati correnti non contengono alcun collider, impossibile abilitare il rilevamento delle collisioni");
}
Flusso di lavoro di base
Il flusso di lavoro di base per la funzionalità di collisione prevede tre passaggi:
- Carica i dati della scena tramite il metodo
Load(). - Nel callback di completamento del caricamento, abilita la collisione tramite
SetColliderEnable(true). - Esegui il rilevamento delle collisioni tramite i vari metodi di rilevamento (
RaycastMesh/IntersectsSphere/IntersectsCapsule).
// 1. Carica la scena
renderer.Load(dataPath, onProgress: null, onComplete: () =>
{
// 2. Abilita la collisione dopo il completamento del caricamento
if (renderer.SetColliderEnable(true))
{
colliderReady = true;
}
});
void Update()
{
if (!colliderReady) return;
// 3. Esegui il rilevamento delle collisioni a ogni fotogramma
var capsule = new Capsule(footPos, headPos, 0.3f);
if (m_manager.IntersectsCapsule(capsule, out Vector3 delta))
{
characterController.Move(delta);
}
}
Nota:
SetColliderEnable()è un metodo diRenderer, mentre i metodi di rilevamento (RaycastMesh/IntersectsSphere/IntersectsCapsule/Raycast) sono suLCCManager. Chiamali rispettivamente sugli oggetti corrispondenti.

Flusso di lavoro di base del sistema di collisione
Implementazione della collisione dell'umano digitale
Poiché il sistema di collisione dell'SDK non agisce sul Rigidbody di Unity, la collisione per gli umani digitali (personaggi) deve essere guidata dai metodi di rilevamento. Esistono tre approcci comuni:
- Rilevamento a doppio raggio: usa
RaycastMesh()per emettere un raggio verso il basso e uno in avanti, e giudica se il personaggio può camminare in base ai risultati restituiti dai raggi (sonda il terreno verso il basso, sonda gli ostacoli in avanti). - Rilevamento a capsula: usa
IntersectsCapsule()per rilevare se la capsula in cui si trova l'umano digitale interseca la mesh di collisione, e giudica se può camminare. La versione con overload restituisce in_deltal'offset del prossimo punto raggiungibile in sicurezza. - Rilevamento a sfera: usa
IntersectsSphere()per rilevare se la sfera in cui si trova l'umano digitale interseca la mesh di collisione, e giudica se può camminare. La versione con overload restituisce anch'essa in_deltal'offset di un punto raggiungibile in sicurezza.

Tre approcci di implementazione per la collisione dell'umano digitale
Scelta tra RaycastMesh e Raycast
L'SDK fornisce due tipi di metodi di rilevamento a raggio con scopi diversi:
| Metodo | Obiettivo di rilevamento | Precisione | Velocità | Scenario applicabile |
|---|---|---|---|---|
RaycastMesh() | Mesh di collisione (dati Collider) | Relativamente bassa | Veloce | Collisione dell'umano digitale, rilevamento per fotogramma |
Raycast() | Primitive gaussiane (non si basa sulla mesh di collisione) | Relativamente alta | Lenta | Applicazioni di tipo misurazione |
Raycast() esegue il rilevamento a raggio direttamente sulle primitive gaussiane, con precisione maggiore ma velocità minore, ed è sconsigliato per le chiamate per fotogramma, quindi non è adatto alla collisione dell'umano digitale, ma solo per usi di tipo misurazione. Per la collisione dell'umano digitale, preferisci RaycastMesh(), che si basa sulla mesh di collisione.
API correlate
Tra i metodi relativi alla collisione di seguito, SetColliderEnable() è su Renderer, mentre i restanti metodi di rilevamento sono su LCCManager. Tutti i metodi di rilevamento sono disponibili solo dopo che la scena ha terminato il caricamento e dopo che SetColliderEnable(true) è stato chiamato con successo.
SetColliderEnable
// Valore restituito: bool → true=impostato con successo, false=i dati non contengono alcun collider o l'istanza non è attiva
public bool SetColliderEnable(bool _enable)
Attiva/disattiva la funzionalità del collider. Dopo l'abilitazione, IntersectsSphere / IntersectsCapsule / RaycastMesh diventano disponibili.
| Parametro | Tipo | Descrizione |
|---|---|---|
_enable | bool | Indica se abilitare il collider |
Esempio di utilizzo:
bool ok = renderer.SetColliderEnable(true);
if (!ok) Debug.LogWarning("I dati non contengono alcun collider");
Descrizione:
- I dati devono contenere dati di collisione (Mesh), altrimenti restituisce
false. - Richiede che il
Renderersia in uno stato attivo.
RaycastMesh (coordinate schermo)
// Valore restituito: bool → true=impatto
public bool RaycastMesh(Vector3 mousePos, out HitResult _finalResult, float _disatnce = 70.0f)
Emette un raggio dalle coordinate schermo per rilevare la mesh di collisione. Usa i dati Collider per il rilevamento, più veloce di Raycast ma con precisione minore.
| Parametro | Tipo | Descrizione |
|---|---|---|
mousePos | Vector3 | Coordinate schermo |
_finalResult | out HitResult | Risultato dell'impatto |
_disatnce | float | Distanza massima di rilevamento, predefinita 70.0 |
Esempio di utilizzo:
if (m_manager.RaycastMesh(Input.mousePosition, out HitResult hit))
{
Debug.Log(hit.hitPos);
}
Descrizione:
- Richiede che la collisione sia stata abilitata con successo prima.
- Richiede di chiamare prima
SetColliderEnable(true).
RaycastMesh (Ray + Bounds)
// Valore restituito: bool → true=impatto
public bool RaycastMesh(Ray ray, out HitResult result, out Bounds hitBounds, float maxDist = 70.0f)
Usa un Ray personalizzato per il rilevamento della mesh di collisione e restituisce anche le informazioni del box di delimitazione del nodo colpito.
| Parametro | Tipo | Descrizione |
|---|---|---|
ray | Ray | Il raggio |
result | out HitResult | Risultato dell'impatto |
hitBounds | out Bounds | Box di delimitazione del nodo colpito (box di delimitazione del nodo LOD colpito) |
maxDist | float | Distanza massima di rilevamento, predefinita 70.0 |
Esempio di utilizzo:
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (m_manager.RaycastMesh(ray, out HitResult hit, out Bounds bounds))
{
Debug.Log(bounds.center);
}
Descrizione:
- Richiede che la collisione sia stata abilitata con successo prima.
- Questo metodo è comunemente usato per il rilevamento a doppio raggio (verso il basso, in avanti) per giudicare se un umano digitale può camminare.
IntersectsSphere
// Valore restituito: bool → true=intersezione
public bool IntersectsSphere(Sphere sphere)
// Valore restituito: bool → true=intersezione
public bool IntersectsSphere(Sphere sphere, out Vector3 delta)
Rileva se una sfera interseca la mesh di collisione. Il secondo overload restituisce inoltre il vettore di penetrazione delta (direzione e distanza di espulsione), che può essere usato per calcolare il prossimo punto raggiungibile in sicurezza.
| Parametro | Tipo | Descrizione |
|---|---|---|
sphere | Sphere | La sfera da rilevare |
delta | out Vector3 | Vettore di penetrazione (direzione e distanza di espulsione) |
Esempio di utilizzo:
var sphere = new Sphere(transform.position, 0.5f);
if (m_manager.IntersectsSphere(sphere, out Vector3 delta))
{
transform.position += delta;
}
Descrizione:
- Richiede che la collisione sia stata abilitata con successo prima.
- Richiede di chiamare prima
SetColliderEnable(true). - Itera su tutti i
Rendererattivi.
IntersectsCapsule
// Valore restituito: bool → true=intersezione
public bool IntersectsCapsule(Capsule capsule)
// Valore restituito: bool → true=intersezione
public bool IntersectsCapsule(Capsule capsule, out Vector3 delta)
Rileva se una capsula interseca la mesh di collisione. Comunemente usato per il rilevamento delle collisioni del character controller. Il secondo overload restituisce il vettore di penetrazione delta, che può essere usato come offset verso il prossimo punto raggiungibile in sicurezza per un umano digitale.
| Parametro | Tipo | Descrizione |
|---|---|---|
capsule | Capsule | La capsula da rilevare |
delta | out Vector3 | Vettore di penetrazione |
Esempio di utilizzo:
var capsule = new Capsule(footPos, headPos, 0.3f);
if (m_manager.IntersectsCapsule(capsule, out Vector3 delta))
{
characterController.Move(delta);
}
Descrizione:
- Richiede che i dati contengano nodi di collisione.
- Richiede di chiamare prima
SetColliderEnable(true). - Adatto alla collisione dei personaggi in prima / terza persona.
Raycast
// Valore restituito: bool → true=impatto
public bool Raycast(Ray _ray, out HitResult _finalResult)
Usa un Ray personalizzato per eseguire il rilevamento a raggio sulle primitive gaussiane, iterando su tutti i Renderer attivi e restituendo l'impatto più vicino. Non si basa sulla mesh di collisione; precisione maggiore ma più lento.
| Parametro | Tipo | Descrizione |
|---|---|---|
_ray | Ray | Il raggio |
_finalResult | out HitResult | Risultato dell'impatto |
Esempio di utilizzo:
Ray ray = new Ray(origin, direction);
if (m_manager.Raycast(ray, out HitResult hit))
{
Debug.Log(hit.hitPos);
}
Descrizione:
- Non si basa sulla mesh di collisione, non necessita di
SetColliderEnable. - Precisione maggiore ma più lento, sconsigliato per le chiamate per fotogramma, adatto alle applicazioni di tipo misurazione, non adatto alla collisione dell'umano digitale.
HitResult
I risultati dell'impatto dei metodi di rilevamento sopra vengono restituiti tramite la struct HitResult:
public struct HitResult {
public bool isHit; // Se ha colpito
public float distance; // Distanza
public Vector3 hitPos; // Coordinate mondo del punto colpito (il nome del campo è hitPos, non position)
public Vector3 normal; // Normale del punto colpito
public float hitAlpha; // Alfa dell'ellissoide colpito
public float dist2Origin; // Distanza dall'origine del raggio
public float scale; // Scala dell'ellissoide
}
Nota:
Il nome del campo delle coordinate mondo del punto colpito è
hitPos, nonposition; accedi tramite il nome effettivo del campo.