Guide de développement de l'accrochage aux arêtes et aux coins
Le LCC Unity SDK prend en charge la détection d'arêtes et de coins ainsi que l'aperçu d'accrochage sur les surfaces 3DGS, ce qui peut être utilisé dans des scénarios d'interaction nécessitant un positionnement précis tels que la mesure, l'annotation et le placement. Ce qui suit décrit les étapes complètes pour implémenter la détection d'arêtes/coins et l'accrochage.
Remarque :
La fonctionnalité d'accrochage (détection d'arêtes/coins, aperçu d'accrochage et raycasting avec accrochage) n'est prise en charge que sur les plateformes PC / Mac. L'appel des API associées sur les plateformes mobiles / VR n'a aucun effet et affiche un avertissement.
Étape 1 : Créer la scène et les GameObjects
Créez une toute nouvelle scène dans Unity. Unity crée Caméra principale et Lumière directionnelle par défaut.
Configurer la Caméra principale
Sélectionnez Caméra principale dans la fenêtre Hiérarchie, et définissez ses propriétés dans la fenêtre Inspecteur comme illustré ci-dessous.

Définir les propriétés de la Caméra principale
Créer LCCManager
Faites un clic droit dans une zone vide de la fenêtre Hiérarchie, sélectionnez Créer vide dans le menu contextuel pour créer un GameObject vide, nommez-le LCCManager, normalisez son Transform, et ajoutez-y le script LCCManager via Ajouter un composant.

Créer le GameObject LCCManager et ajouter le script LCCManager
Créer LCCRenderer
Faites un clic droit dans une zone vide de la fenêtre Hiérarchie, sélectionnez Créer vide pour créer un GameObject vide, nommez-le LCCRenderer, et définissez son Transform sur Rotation.x = -90 et Scale.x = -1.

Créer LCCRenderer et définir son Transform (Rotation.x = -90, Scale.x = -1)
Remarque :
Les réglages de Transform du GameObject LCCRenderer (Rotation.x = -90, Scale.x = -1) l'alignent avec le système de coordonnées des données LCC. Pour plus de détails sur l'alignement du système de coordonnées, voir « Système de coordonnées des données LCC » dans Introduction au SDK Unity.
Étape 2 : Ajouter une Render Feature
- Dans la barre de menus Unity, sélectionnez Fichier → Paramètres du projet, choisissez Graphismes à gauche, et confirmez le Default Render Pipeline Asset actuel. Cet exemple utilise URP (Universal Render Pipeline Asset).

Confirmer le Default Render Pipeline Asset dans les paramètres Graphismes
Cliquez sur cet Asset, localisez le fichier d'asset correspondant dans la fenêtre Projet, et trouvez son Renderer associé (
URP_Renderer.assetdans cet exemple).Sélectionnez ce fichier d'asset Renderer, cliquez sur Add Renderer Feature dans la fenêtre Inspecteur, et ajoutez la Snap Frame Capture Feature.

Ajouter la Snap Frame Capture Feature au Renderer URP
Étape 3 : Écrire un script pour activer l'accrochage
Créez un nouveau script C# nommé Snap.cs avec le code suivant :
using LCCCore;
using UnityEngine;
public class Snap : MonoBehaviour
{
public LCCManager m_manager;
public string m_FilePath;
private LCCCore.Renderer m_renderer;
private bool m_loaded = false;
private Camera m_camera;
void Start()
{
m_camera = Camera.main;
m_manager.SetPlatformType(PlatformType.PC);
Debug.Log("Démarré ");
m_renderer = m_manager.GetRender(this.transform);
m_renderer.Load(m_FilePath, onProgress, onComplete);
}
private void onProgress(float _progress)
{
Debug.Log($"[LCCRenderer] progression du chargement du fichier : {_progress:P1}");
}
private void onComplete()
{
Debug.Log($"[LCCRenderer] fichier chargé");
m_loaded = true;
// Activer la détection d'arêtes/coins et l'aperçu d'accrochage
m_manager.SetSnapEnabled(true);
m_manager.SetSnapPreviewEnabled(true);
}
private void Update()
{
if (!m_loaded) return;
// Mettre à jour l'aperçu d'accrochage en temps réel en fonction de la position actuelle de la souris
m_manager.UpdateSnapPreview(Input.mousePosition, m_camera);
if (Input.GetMouseButtonDown(1))
{
m_manager.RaycastWithSnap(Input.mousePosition, m_camera, out HitResult result);
if (result.isHit)
{
GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
sphere.transform.position = result.hitPos;
sphere.GetComponent<UnityEngine.Renderer>().material.color = Color.red;
sphere.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f);
}
}
}
}
Remarque :
La détection d'arêtes/coins (
SetSnapEnabled) et l'aperçu d'accrochage (SetSnapPreviewEnabled) doivent être activés après la fin du chargement de la scène LCC, donc les deux sont appelés dans le callbackonComplete. L'aperçu d'accrochage doit également être continuellement mis à jour viaUpdateSnapPreviewdansUpdate.
L'exemple ci-dessus démontre les points suivants :
- Activer la détection d'arêtes et de coins :
m_manager.SetSnapEnabled(true) - Activer l'aperçu d'accrochage :
m_manager.SetSnapPreviewEnabled(true) - Mettre à jour l'aperçu d'accrochage en temps réel :
m_manager.UpdateSnapPreview(Input.mousePosition, m_camera) - Effectuer un raycast au point d'accrochage et créer une sphère au point d'impact :
m_manager.RaycastWithSnap(...); en cas d'impact, une sphère rouge est créée àresult.hitPos
Étape 4 : Attacher le script et définir le chemin des données
- Attachez le script
Snap.csau GameObject LCCRenderer dans la fenêtre Hiérarchie. - Dans la fenêtre Inspecteur, faites glisser le GameObject LCCManager sur la propriété Manager du script.
- Renseignez le chemin du fichier LCC dans la propriété File Path du script.
Étape 5 : Exécuter
Cliquez sur le bouton Play dans la fenêtre Jeu pour voir les arêtes et les coins détectés en temps réel et l'icône d'aperçu de la cible d'accrochage. Lorsque vous déplacez la souris, l'icône d'aperçu suit la cible d'accrochage la plus proche en temps réel ; un clic droit effectue un raycast au point d'accrochage et crée une sphère rouge.

Arêtes, coins et icône d'aperçu d'accrochage détectés en temps réel après l'exécution
FAQ : Désactiver le mode de compatibilité
Si la fenêtre Console de Unity signale des erreurs et qu'aucune icône d'aperçu d'accrochage n'apparaît, désactivez le mode de compatibilité : ouvrez le panneau des paramètres via Édition → Paramètres du projet → Graphismes, sélectionnez l'onglet URP, et ne cochez pas la case après Render Graph → Compatibility Mode (Render Graph Disabled).

Ne pas cocher le mode de compatibilité Render Graph (Render Graph Disabled)
Étapes clés
Les étapes clés pour implémenter la détection d'arêtes/coins et l'accrochage :
- Assurez-vous que la Snap Frame Capture Feature a été ajoutée au Renderer URP.
- Assurez-vous que la détection d'arêtes/coins (
SetSnapEnabled(true)) et l'aperçu d'accrochage (SetSnapPreviewEnabled(true)) sont activés dans le code après la fin du chargement de la scène LCC. - Assurez-vous que
UpdateSnapPreviewest appelé en temps réel dansUpdatepour mettre à jour l'icône d'aperçu.
API liées à l'accrochage
Le LCC Unity SDK fournit les API liées à l'accrochage suivantes via LCCManager. Elles sont uniquement prises en charge sur les plateformes PC / Mac — les appeler sur les plateformes mobiles / VR n'a aucun effet et affiche un avertissement — et elles doivent toutes être appelées après la fin du chargement de la scène LCC.
SetSnapEnabled
// Valeur de retour : void
public void SetSnapEnabled(bool enable)
Active/désactive la fonctionnalité d'accrochage. Lorsqu'elle est activée, RaycastWithSnap recherche automatiquement les arêtes/coins proches auxquels s'accrocher.
| Paramètre | Type | Description |
|---|---|---|
enable | bool | S'il faut activer l'accrochage |
Exemple d'utilisation :
m_manager.SetSnapEnabled(true);
Remarques :
- Désactivé par défaut.
- Pris en charge uniquement sur PC / Mac ; l'appeler sur mobile / VR n'a aucun effet et affiche un avertissement.
- Lorsqu'il est activé, des ressources GPU sont allouées (EdgeDetect / CornerDetect / SnapSearch).
SetSnapRadius
// Valeur de retour : void
public void SetSnapRadius(float pixels)
Définit le rayon de recherche d'accrochage. L'arête/coin le plus proche est recherché dans cette plage de pixels.
| Paramètre | Type | Description |
|---|---|---|
pixels | float | Rayon de recherche d'accrochage (pixels) |
Exemple d'utilisation :
m_manager.SetSnapRadius(30f);
Remarques :
- La valeur par défaut est de 20 pixels.
- Plus la valeur est grande, plus la plage de recherche est large, mais elle peut s'accrocher à des cibles non voulues.
- Pris en charge uniquement sur PC / Mac.
SetEdgeThreshold
// Valeur de retour : void
public void SetEdgeThreshold(float threshold)
Définit le seuil de détection d'arêtes Sobel. Plus la valeur est petite, plus les arêtes détectées sont nombreuses.
| Paramètre | Type | Description |
|---|---|---|
threshold | float | Seuil de détection d'arêtes |
Exemple d'utilisation :
m_manager.SetEdgeThreshold(0.2f);
Remarques :
- La valeur par défaut est 0.3.
- Plage recommandée
[0.1, 0.8]. - Une valeur trop petite produit beaucoup d'arêtes bruyantes.
- Pris en charge uniquement sur PC / Mac.
SetSnapPreviewEnabled
// Valeur de retour : void
public void SetSnapPreviewEnabled(bool enable)
Active/désactive la fonctionnalité d'aperçu d'accrochage. Lorsqu'elle est activée, l'indicateur de la cible d'accrochage la plus proche est affiché en temps réel lorsque la souris se déplace.
| Paramètre | Type | Description |
|---|---|---|
enable | bool | S'il faut activer l'aperçu d'accrochage |
Exemple d'utilisation :
m_manager.SetSnapPreviewEnabled(true);
Remarques :
- Nécessite que
SetSnapEnabled(true)soit d'abord appelé. - L'aperçu consomme continuellement des ressources GPU (détection à chaque image).
- Pris en charge uniquement sur PC / Mac.
UpdateSnapPreview
// Valeur de retour : void
public void UpdateSnapPreview(Vector2 mousePos, Camera cam)
Met à jour l'état de l'aperçu d'accrochage. Appelez-le lorsque la souris se déplace pour mettre à jour la position de l'indicateur d'aperçu.
| Paramètre | Type | Description |
|---|---|---|
mousePos | Vector2 | Coordonnée écran actuelle de la souris |
cam | Camera | Caméra |
Exemple d'utilisation :
void Update()
{
m_manager.UpdateSnapPreview(Input.mousePosition, Camera.main);
}
Remarques :
- Nécessite que
SetSnapPreviewEnabled(true)soit d'abord appelé. - Il est recommandé de l'appeler continuellement dans
Update. - Pris en charge uniquement sur PC / Mac.
GetSnapPreviewState
// Valeur de retour : SnapPreviewState (screenPos est en coordonnées écran)
public SnapPreviewState GetSnapPreviewState()
Obtient l'état actuel de l'aperçu d'accrochage, y compris s'il existe une cible d'accrochage, le type de cible, la position écran de la cible et la distance en pixels par rapport à la souris.
Exemple d'utilisation :
var state = m_manager.GetSnapPreviewState();
if (state.hasTarget)
{
// state.snapType : Corner / Edge
// state.screenPos : position écran de la cible d'accrochage
// state.distanceToMouse : distance en pixels
}
Remarques :
- Nécessite que
SetSnapPreviewEnabled(true)etUpdateSnapPreviewsoient d'abord appelés. - Retourne
default(SnapPreviewState)lorsqu'il n'y a pas de cible. screenPosest une coordonnée écran, pas une coordonnée mondiale ; si vous avez besoin de la coordonnée mondiale, utilisezRaycastWithSnappour obtenirHitResult.hitPos.- Pris en charge uniquement sur PC / Mac.
RaycastWithSnap
// Valeur de retour : bool (true = impact)
public bool RaycastWithSnap(Vector2 screenPos, Camera cam, out HitResult result)
Raycasting avec accrochage. Il effectue d'abord un Raycast normal, puis recherche les arêtes/coins proches du point d'impact pour s'y accrocher.
| Paramètre | Type | Description |
|---|---|---|
screenPos | Vector2 | Coordonnée écran |
cam | Camera | Caméra |
result | out HitResult | Résultat de l'impact (incluant les informations d'accrochage) |
Exemple d'utilisation :
if (m_manager.RaycastWithSnap(Input.mousePosition, m_camera, out HitResult hit))
{
// hit.snapType : Corner / Edge / None
// hit.hitPos : position mondiale après accrochage
// hit.originalHitPos : point d'impact d'origine avant accrochage
}
Remarques :
- Nécessite que
SetSnapEnabled(true)soit d'abord appelé. - Priorité d'accrochage : Corner > Edge > None.
- Ce point d'entrée bloque de manière synchrone le thread principal (en attendant le résultat de la lecture GPU) ; il est recommandé de ne l'appeler que sur des événements d'interaction (tels que des clics), pas à chaque image.
- En mode aperçu (
SetSnapPreviewEnabled(true)), si une cible d'accrochage existe déjà, le cache d'aperçu est réutilisé directement sans recalcul ; sinon le flux d'accrochage normal est utilisé. - Pris en charge uniquement sur PC / Mac.
Structures de données associées
SnapType
public enum SnapType { None, Edge, Corner }
Type de cible d'accrochage : aucune / arête / coin.
SnapPreviewState
public struct SnapPreviewState {
public bool hasTarget; // s'il existe une cible d'accrochage
public SnapType snapType; // None / Edge / Corner
public Vector2 screenPos; // position écran de la cible d'accrochage (pas la position mondiale)
public float distanceToMouse; // distance en pixels par rapport à la position de la souris
}
⚠️
screenPosest une coordonnée en pixels d'écran, pas une coordonnée mondiale. Si vous avez besoin de la coordonnée mondiale, utilisezRaycastWithSnappour obtenirHitResult.hitPos.
HitResult
public struct HitResult {
public bool isHit; // s'il y a eu impact
public float distance; // distance
public Vector3 hitPos; // position mondiale du point d'impact (le nom du champ est hitPos, pas position)
public Vector3 normal; // normale d'impact
public float hitAlpha; // alpha de l'ellipsoïde impacté
public float dist2Origin; // distance par rapport à l'origine du rayon
public float scale; // échelle de l'ellipsoïde
public SnapType snapType; // type d'accrochage (None / Edge / Corner)
public Vector3 originalHitPos; // point d'impact d'origine avant accrochage
}
⚠️ Différence de nom de champ : le champ de la position mondiale du point d'impact est
hitPos(pasposition) ; les appelants doivent y accéder en utilisant le nom de champ réel.