Entwicklungsanleitung für Kanten- und Eckensnapping
Das LCC Unity SDK unterstützt die Kanten- und Eckenerkennung sowie die Snap-Vorschau auf 3DGS-Oberflächen, die in Interaktionsszenarien eingesetzt werden können, die eine präzise Positionierung erfordern, etwa Messung, Annotation und Platzierung. Im Folgenden werden die vollständigen Schritte zur Implementierung der Kanten-/Eckenerkennung und des Snappings beschrieben.
Hinweis:
Die Snapping-Funktion (Kanten-/Eckenerkennung, Snap-Vorschau und Raycasting mit Snapping) wird nur auf PC-/Mac-Plattformen unterstützt. Der Aufruf der zugehörigen APIs auf Mobil-/VR-Plattformen hat keine Wirkung und gibt eine Warnung aus.
Schritt 1: Die Szene und die GameObjects erstellen
Erstellen Sie in Unity eine brandneue Szene. Unity erstellt standardmäßig die Hauptkamera und das Richtungslicht.
Hauptkamera einrichten
Wählen Sie die Hauptkamera im Fenster Hierarchie aus und legen Sie deren Eigenschaften im Fenster Inspektor wie unten dargestellt fest.

Die Eigenschaften der Hauptkamera festlegen
LCCManager erstellen
Klicken Sie mit der rechten Maustaste in einen leeren Bereich des Fensters Hierarchie, wählen Sie im Popup-Menü Leeres GameObject erstellen, um ein leeres GameObject zu erstellen, benennen Sie es LCCManager, normalisieren Sie dessen Transform und fügen Sie über Komponente hinzufügen das Skript LCCManager hinzu.

Das GameObject LCCManager erstellen und das Skript LCCManager hinzufügen
LCCRenderer erstellen
Klicken Sie mit der rechten Maustaste in einen leeren Bereich des Fensters Hierarchie, wählen Sie Leeres GameObject erstellen, um ein leeres GameObject zu erstellen, benennen Sie es LCCRenderer und setzen Sie dessen Transform auf Rotation.x = -90 und Scale.x = -1.

LCCRenderer erstellen und dessen Transform festlegen (Rotation.x = -90, Scale.x = -1)
Hinweis:
Die Transform-Einstellungen des GameObject LCCRenderer (Rotation.x = -90, Scale.x = -1) richten es am LCC-Daten-Koordinatensystem aus. Details zur Ausrichtung am Koordinatensystem finden Sie unter „LCC-Daten-Koordinatensystem“ in Einführung in das Unity SDK.
Schritt 2: Ein Render Feature hinzufügen
- Wählen Sie in der Unity-Menüleiste Datei → Projekteinstellungen, wählen Sie links Grafik und bestätigen Sie das aktuelle Standard-Render-Pipeline-Asset. Dieses Beispiel verwendet URP (Universal Render Pipeline Asset).

Das Standard-Render-Pipeline-Asset in den Grafikeinstellungen bestätigen
Klicken Sie auf dieses Asset, lokalisieren Sie die entsprechende Asset-Datei im Fenster Projekt und suchen Sie den zugehörigen Renderer (
URP_Renderer.assetin diesem Beispiel).Wählen Sie diese Renderer-Asset-Datei aus, klicken Sie im Fenster Inspektor auf Renderer-Feature hinzufügen und fügen Sie das Snap Frame Capture Feature hinzu.

Das Snap Frame Capture Feature zum URP-Renderer hinzufügen
Schritt 3: Ein Skript zum Aktivieren des Snappings schreiben
Erstellen Sie ein neues C#-Skript namens Snap.cs mit folgendem Code:
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("Gestartet ");
m_renderer = m_manager.GetRender(this.transform);
m_renderer.Load(m_FilePath, onProgress, onComplete);
}
private void onProgress(float _progress)
{
Debug.Log($"[LCCRenderer] Datei-Ladefortschritt: {_progress:P1}");
}
private void onComplete()
{
Debug.Log($"[LCCRenderer] Datei geladen");
m_loaded = true;
// Kanten-/Eckenerkennung und Snap-Vorschau aktivieren
m_manager.SetSnapEnabled(true);
m_manager.SetSnapPreviewEnabled(true);
}
private void Update()
{
if (!m_loaded) return;
// Die Snap-Vorschau in Echtzeit anhand der aktuellen Mausposition aktualisieren
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);
}
}
}
}
Hinweis:
Die Kanten-/Eckenerkennung (
SetSnapEnabled) und die Snap-Vorschau (SetSnapPreviewEnabled) müssen nach Abschluss des Ladens der LCC-Szene aktiviert werden; daher werden beide im CallbackonCompleteaufgerufen. Die Snap-Vorschau muss außerdem kontinuierlich überUpdateSnapPreviewinUpdateaktualisiert werden.
Das obige Beispiel veranschaulicht die folgenden Punkte:
- Kanten- und Eckenerkennung aktivieren:
m_manager.SetSnapEnabled(true) - Snap-Vorschau aktivieren:
m_manager.SetSnapPreviewEnabled(true) - Snap-Vorschau in Echtzeit aktualisieren:
m_manager.UpdateSnapPreview(Input.mousePosition, m_camera) - Raycasting am Snap-Punkt und Erstellen einer Kugel am Trefferpunkt:
m_manager.RaycastWithSnap(...); bei einem Treffer wird eine rote Kugel anresult.hitPoserstellt
Schritt 4: Das Skript anhängen und den Datenpfad festlegen
- Hängen Sie das Skript
Snap.csim Fenster Hierarchie an das GameObject LCCRenderer. - Ziehen Sie im Fenster Inspektor das GameObject LCCManager auf die Eigenschaft Manager des Skripts.
- Tragen Sie den LCC-Dateipfad in die Eigenschaft File Path des Skripts ein.
Schritt 5: Ausführen
Klicken Sie im Fenster Spiel auf die Schaltfläche Play, um die in Echtzeit erkannten Kanten und Ecken sowie das Vorschau-Symbol des Snap-Ziels zu sehen. Wenn Sie die Maus bewegen, folgt das Vorschau-Symbol in Echtzeit dem nächstgelegenen Snap-Ziel; ein Rechtsklick führt ein Raycasting am Snap-Punkt aus und erstellt eine rote Kugel.

Nach dem Ausführen in Echtzeit erkannte Kanten, Ecken und das Snap-Vorschau-Symbol
FAQ: Kompatibilitätsmodus deaktivieren
Wenn das Unity-Fenster Konsole Fehler meldet und kein Snap-Vorschau-Symbol erscheint, deaktivieren Sie den Kompatibilitätsmodus: Öffnen Sie das Einstellungsfenster über Bearbeiten → Projekteinstellungen → Grafik, wählen Sie den Tab URP und aktivieren Sie das Kontrollkästchen hinter Render Graph → Compatibility Mode (Render Graph Disabled) nicht.

Den Render-Graph-Kompatibilitätsmodus nicht aktivieren (Render Graph Disabled)
Schlüsselschritte
Die Schlüsselschritte zur Implementierung der Kanten-/Eckenerkennung und des Snappings:
- Sicherstellen, dass das Snap Frame Capture Feature zum URP-Renderer hinzugefügt wurde.
- Sicherstellen, dass die Kanten-/Eckenerkennung (
SetSnapEnabled(true)) und die Snap-Vorschau (SetSnapPreviewEnabled(true)) im Code nach Abschluss des Ladens der LCC-Szene aktiviert werden. - Sicherstellen, dass
UpdateSnapPreviewinUpdatein Echtzeit aufgerufen wird, um das Vorschau-Symbol zu aktualisieren.
Snap-bezogene APIs
Das LCC Unity SDK stellt über LCCManager die folgenden snap-bezogenen APIs bereit. Sie werden nur auf PC-/Mac-Plattformen unterstützt — der Aufruf auf Mobil-/VR-Plattformen hat keine Wirkung und gibt eine Warnung aus — und müssen alle nach Abschluss des Ladens der LCC-Szene aufgerufen werden.
SetSnapEnabled
// Rückgabewert: void
public void SetSnapEnabled(bool enable)
Schaltet die Snapping-Funktion um. Wenn aktiviert, sucht RaycastWithSnap automatisch nach nahegelegenen Kanten/Ecken zum Einrasten.
| Parameter | Typ | Beschreibung |
|---|---|---|
enable | bool | Ob das Snapping aktiviert werden soll |
Verwendungsbeispiel:
m_manager.SetSnapEnabled(true);
Hinweise:
- Standardmäßig deaktiviert.
- Nur auf PC/Mac unterstützt; der Aufruf auf Mobil/VR hat keine Wirkung und gibt eine Warnung aus.
- Wenn aktiviert, werden GPU-Ressourcen zugewiesen (EdgeDetect / CornerDetect / SnapSearch).
SetSnapRadius
// Rückgabewert: void
public void SetSnapRadius(float pixels)
Legt den Suchradius für das Snapping fest. Innerhalb dieses Pixelbereichs wird nach der nächstgelegenen Kante/Ecke gesucht.
| Parameter | Typ | Beschreibung |
|---|---|---|
pixels | float | Suchradius für das Snapping (Pixel) |
Verwendungsbeispiel:
m_manager.SetSnapRadius(30f);
Hinweise:
- Standard ist 20 Pixel.
- Je größer der Wert, desto breiter der Suchbereich, es kann jedoch an unbeabsichtigten Zielen eingerastet werden.
- Nur auf PC/Mac unterstützt.
SetEdgeThreshold
// Rückgabewert: void
public void SetEdgeThreshold(float threshold)
Legt den Sobel-Kantenerkennungs-Schwellenwert fest. Je kleiner der Wert, desto mehr Kanten werden erkannt.
| Parameter | Typ | Beschreibung |
|---|---|---|
threshold | float | Schwellenwert der Kantenerkennung |
Verwendungsbeispiel:
m_manager.SetEdgeThreshold(0.2f);
Hinweise:
- Standard ist 0.3.
- Empfohlener Bereich
[0.1, 0.8]. - Ein zu kleiner Wert erzeugt viele verrauschte Kanten.
- Nur auf PC/Mac unterstützt.
SetSnapPreviewEnabled
// Rückgabewert: void
public void SetSnapPreviewEnabled(bool enable)
Schaltet die Snap-Vorschau-Funktion um. Wenn aktiviert, wird das Anzeigesymbol des nächstgelegenen Snap-Ziels in Echtzeit angezeigt, während sich die Maus bewegt.
| Parameter | Typ | Beschreibung |
|---|---|---|
enable | bool | Ob die Snap-Vorschau aktiviert werden soll |
Verwendungsbeispiel:
m_manager.SetSnapPreviewEnabled(true);
Hinweise:
- Erfordert, dass zuerst
SetSnapEnabled(true)aufgerufen wurde. - Die Vorschau verbraucht kontinuierlich GPU-Ressourcen (Erkennung in jedem Frame).
- Nur auf PC/Mac unterstützt.
UpdateSnapPreview
// Rückgabewert: void
public void UpdateSnapPreview(Vector2 mousePos, Camera cam)
Aktualisiert den Zustand der Snap-Vorschau. Rufen Sie die Methode bei Mausbewegungen auf, um die Position des Vorschau-Anzeigers zu aktualisieren.
| Parameter | Typ | Beschreibung |
|---|---|---|
mousePos | Vector2 | Aktuelle Bildschirmkoordinate der Maus |
cam | Camera | Kamera |
Verwendungsbeispiel:
void Update()
{
m_manager.UpdateSnapPreview(Input.mousePosition, Camera.main);
}
Hinweise:
- Erfordert, dass zuerst
SetSnapPreviewEnabled(true)aufgerufen wurde. - Es wird empfohlen, die Methode kontinuierlich in
Updateaufzurufen. - Nur auf PC/Mac unterstützt.
GetSnapPreviewState
// Rückgabewert: SnapPreviewState (screenPos liegt in Bildschirmkoordinaten vor)
public SnapPreviewState GetSnapPreviewState()
Ruft den aktuellen Zustand der Snap-Vorschau ab, einschließlich ob ein Snap-Ziel vorhanden ist, des Zieltyps, der Bildschirmposition des Ziels und der Pixeldistanz zur Maus.
Verwendungsbeispiel:
var state = m_manager.GetSnapPreviewState();
if (state.hasTarget)
{
// state.snapType: Corner / Edge
// state.screenPos: Bildschirmposition des Snap-Ziels
// state.distanceToMouse: Pixeldistanz
}
Hinweise:
- Erfordert, dass zuerst
SetSnapPreviewEnabled(true)undUpdateSnapPreviewaufgerufen wurden. - Gibt
default(SnapPreviewState)zurück, wenn kein Ziel vorhanden ist. screenPosist eine Bildschirmkoordinate, keine Weltkoordinate; wenn Sie die Weltkoordinate benötigen, verwenden SieRaycastWithSnap, umHitResult.hitPoszu erhalten.- Nur auf PC/Mac unterstützt.
RaycastWithSnap
// Rückgabewert: bool (true = Treffer)
public bool RaycastWithSnap(Vector2 screenPos, Camera cam, out HitResult result)
Raycasting mit Snapping. Zuerst wird ein normales Raycast ausgeführt, anschließend wird nach Kanten/Ecken in der Nähe des Trefferpunkts zum Einrasten gesucht.
| Parameter | Typ | Beschreibung |
|---|---|---|
screenPos | Vector2 | Bildschirmkoordinate |
cam | Camera | Kamera |
result | out HitResult | Trefferergebnis (einschließlich Snapping-Informationen) |
Verwendungsbeispiel:
if (m_manager.RaycastWithSnap(Input.mousePosition, m_camera, out HitResult hit))
{
// hit.snapType: Corner / Edge / None
// hit.hitPos: Weltposition nach dem Snapping
// hit.originalHitPos: ursprünglicher Trefferpunkt vor dem Snapping
}
Hinweise:
- Erfordert, dass zuerst
SetSnapEnabled(true)aufgerufen wurde. - Snap-Priorität: Corner > Edge > None.
- Dieser Einstiegspunkt blockiert den Hauptthread synchron (wartet auf das GPU-Rückleseergebnis); es wird empfohlen, ihn nur bei Interaktionsereignissen (z. B. Klicks) aufzurufen, nicht in jedem Frame.
- Im Vorschau-Modus (
SetSnapPreviewEnabled(true)), wenn bereits ein Snap-Ziel vorhanden ist, wird der Vorschau-Cache direkt ohne Neuberechnung wiederverwendet; andernfalls wird der normale Snap-Ablauf verwendet. - Nur auf PC/Mac unterstützt.
Zugehörige Datenstrukturen
SnapType
public enum SnapType { None, Edge, Corner }
Snap-Zieltyp: keiner / Kante / Ecke.
SnapPreviewState
public struct SnapPreviewState {
public bool hasTarget; // Ob ein Snap-Ziel vorhanden ist
public SnapType snapType; // None / Edge / Corner
public Vector2 screenPos; // Bildschirmposition des Snap-Ziels (keine Weltposition)
public float distanceToMouse; // Pixeldistanz zur Mausposition
}
⚠️
screenPosist eine Bildschirmpixelkoordinate, keine Weltkoordinate. Wenn Sie die Weltkoordinate benötigen, verwenden SieRaycastWithSnap, umHitResult.hitPoszu erhalten.
HitResult
public struct HitResult {
public bool isHit; // Ob ein Treffer aufgetreten ist
public float distance; // Distanz
public Vector3 hitPos; // Weltposition des Trefferpunkts (Feldname ist hitPos, nicht position)
public Vector3 normal; // Treffernormale
public float hitAlpha; // Alpha des getroffenen Ellipsoids
public float dist2Origin; // Distanz zum Strahlursprung
public float scale; // Ellipsoid-Skalierung
public SnapType snapType; // Snap-Typ (None / Edge / Corner)
public Vector3 originalHitPos; // Ursprünglicher Trefferpunkt vor dem Snapping
}
⚠️ Unterschied im Feldnamen: Das Feld für die Weltposition des Trefferpunkts heißt
hitPos(nichtposition); Aufrufer sollten es über den tatsächlichen Feldnamen abrufen.