Guía de desarrollo de ajuste a bordes y esquinas
El LCC Unity SDK admite la detección de bordes y esquinas y la previsualización de ajuste en superficies 3DGS, que pueden usarse en escenarios de interacción que requieren un posicionamiento preciso, como medición, anotación y colocación. A continuación se describen los pasos completos para implementar la detección y el ajuste de bordes/esquinas.
Nota:
La función de ajuste (detección de bordes/esquinas, previsualización de ajuste y raycasting con ajuste) solo es compatible con plataformas PC / Mac. Llamar a las API relacionadas en plataformas móviles / VR no surte efecto y emite una advertencia.
Paso 1: Crear la escena y los GameObjects
Crea una escena completamente nueva en Unity. Unity crea Main Camera y Directional Light por defecto.
Configurar Main Camera
Selecciona Main Camera en la ventana Jerarquía y establece sus propiedades en la ventana Inspector como se muestra a continuación.

Establecer las propiedades de Main Camera
Crear LCCManager
Haz clic con el botón derecho en un área vacía de la ventana Jerarquía, selecciona Create Empty en el menú emergente para crear un GameObject vacío, nómbralo LCCManager, normaliza su Transform y añádele el script LCCManager mediante Agregar componente.

Crear el GameObject LCCManager y añadir el script LCCManager
Crear LCCRenderer
Haz clic con el botón derecho en un área vacía de la ventana Jerarquía, selecciona Create Empty para crear un GameObject vacío, nómbralo LCCRenderer y establece su Transform como Rotation.x = -90 y Scale.x = -1.

Crear LCCRenderer y establecer su Transform (Rotation.x = -90, Scale.x = -1)
Nota:
Los ajustes de Transform del GameObject LCCRenderer (Rotation.x = -90, Scale.x = -1) lo alinean con el sistema de coordenadas de los datos LCC. Para más detalles sobre la alineación del sistema de coordenadas, consulta "Sistema de coordenadas de los datos LCC" en Introducción al SDK de Unity.
Paso 2: Añadir un Render Feature
- En la barra de menús de Unity, selecciona Archivo → Ajustes del proyecto, elige Gráficos a la izquierda y confirma el Default Render Pipeline Asset actual. Este ejemplo usa URP (Universal Render Pipeline Asset).

Confirmar el Default Render Pipeline Asset en los ajustes de Gráficos
Haz clic en ese Asset, localiza el archivo de asset correspondiente en la ventana Proyecto y encuentra su Renderer asociado (
URP_Renderer.asseten este ejemplo).Selecciona ese archivo de asset del Renderer, haz clic en Add Renderer Feature en la ventana Inspector y añade el Snap Frame Capture Feature.

Añadir el Snap Frame Capture Feature al URP Renderer
Paso 3: Escribir un script para activar el ajuste
Crea un nuevo script C# llamado Snap.cs con el siguiente código:
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("Iniciado ");
m_renderer = m_manager.GetRender(this.transform);
m_renderer.Load(m_FilePath, onProgress, onComplete);
}
private void onProgress(float _progress)
{
Debug.Log($"[LCCRenderer] progreso de carga del archivo: {_progress:P1}");
}
private void onComplete()
{
Debug.Log($"[LCCRenderer] archivo cargado");
m_loaded = true;
// Activa la detección de bordes/esquinas y la previsualización de ajuste
m_manager.SetSnapEnabled(true);
m_manager.SetSnapPreviewEnabled(true);
}
private void Update()
{
if (!m_loaded) return;
// Actualiza la previsualización de ajuste en tiempo real según la posición actual del ratón
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);
}
}
}
}
Nota:
La detección de bordes/esquinas (
SetSnapEnabled) y la previsualización de ajuste (SetSnapPreviewEnabled) deben activarse después de que la escena LCC termine de cargarse, por lo que ambas se llaman en la devolución de llamadaonComplete. La previsualización de ajuste también necesita actualizarse continuamente medianteUpdateSnapPreviewenUpdate.
El ejemplo anterior demuestra los siguientes puntos:
- Activar la detección de bordes y esquinas:
m_manager.SetSnapEnabled(true) - Activar la previsualización de ajuste:
m_manager.SetSnapPreviewEnabled(true) - Actualizar la previsualización de ajuste en tiempo real:
m_manager.UpdateSnapPreview(Input.mousePosition, m_camera) - Hacer raycast en el punto de ajuste y crear una esfera en el punto de impacto:
m_manager.RaycastWithSnap(...); al impactar, se crea una esfera roja enresult.hitPos
Paso 4: Adjuntar el script y establecer la ruta de datos
- Adjunta el script
Snap.csal GameObject LCCRenderer en la ventana Jerarquía. - En la ventana Inspector, arrastra el GameObject LCCManager a la propiedad Manager del script.
- Rellena la ruta del archivo LCC en la propiedad File Path del script.
Paso 5: Ejecutar
Haz clic en el botón Play de la ventana Game para ver los bordes y esquinas detectados en tiempo real y el icono de previsualización del objetivo de ajuste. Al mover el ratón, el icono de previsualización sigue al objetivo de ajuste más cercano en tiempo real; al hacer clic derecho se realiza un raycast en el punto de ajuste y se crea una esfera roja.

Bordes, esquinas e icono de previsualización de ajuste detectados en tiempo real tras la ejecución
Preguntas frecuentes: desactivar el modo de compatibilidad
Si la ventana Console de Unity informa de errores y no aparece ningún icono de previsualización de ajuste, desactiva el modo de compatibilidad: abre el panel de ajustes mediante Editar → Ajustes del proyecto → Gráficos, selecciona la pestaña URP y no marques la casilla situada después de Render Graph → Compatibility Mode (Render Graph Disabled).

No marcar el modo de compatibilidad de Render Graph (Render Graph Disabled)
Pasos clave
Los pasos clave para implementar la detección y el ajuste de bordes/esquinas:
- Asegúrate de que el Snap Frame Capture Feature se ha añadido al URP Renderer.
- Asegúrate de que la detección de bordes/esquinas (
SetSnapEnabled(true)) y la previsualización de ajuste (SetSnapPreviewEnabled(true)) se activan en el código después de que la escena LCC termine de cargarse. - Asegúrate de que
UpdateSnapPreviewse llama en tiempo real enUpdatepara actualizar el icono de previsualización.
API relacionadas con el ajuste
El LCC Unity SDK proporciona las siguientes API relacionadas con el ajuste a través de LCCManager. Solo son compatibles con plataformas PC / Mac — llamarlas en plataformas móviles / VR no surte efecto y emite una advertencia — y todas deben llamarse después de que la escena LCC termine de cargarse.
SetSnapEnabled
// Valor de retorno: void
public void SetSnapEnabled(bool enable)
Activa o desactiva la función de ajuste. Cuando está activada, RaycastWithSnap busca automáticamente bordes/esquinas cercanos a los que ajustarse.
| Parámetro | Tipo | Descripción |
|---|---|---|
enable | bool | Si se habilita el ajuste |
Ejemplo de uso:
m_manager.SetSnapEnabled(true);
Notas:
- Desactivado por defecto.
- Solo compatible con PC / Mac; llamarla en móvil / VR no surte efecto y emite una advertencia.
- Cuando está activada, se asignan recursos de GPU (EdgeDetect / CornerDetect / SnapSearch).
SetSnapRadius
// Valor de retorno: void
public void SetSnapRadius(float pixels)
Establece el radio de búsqueda del ajuste. El borde/esquina más cercano se busca dentro de este rango de píxeles.
| Parámetro | Tipo | Descripción |
|---|---|---|
pixels | float | Radio de búsqueda del ajuste (píxeles) |
Ejemplo de uso:
m_manager.SetSnapRadius(30f);
Notas:
- El valor por defecto es 20 píxeles.
- Cuanto mayor es el valor, más amplio es el rango de búsqueda, pero puede ajustarse a objetivos no deseados.
- Solo compatible con PC / Mac.
SetEdgeThreshold
// Valor de retorno: void
public void SetEdgeThreshold(float threshold)
Establece el umbral de detección de bordes de Sobel. Cuanto menor es el valor, más bordes se detectan.
| Parámetro | Tipo | Descripción |
|---|---|---|
threshold | float | Umbral de detección de bordes |
Ejemplo de uso:
m_manager.SetEdgeThreshold(0.2f);
Notas:
- El valor por defecto es 0.3.
- Rango recomendado
[0.1, 0.8]. - Un valor demasiado pequeño produce muchos bordes ruidosos.
- Solo compatible con PC / Mac.
SetSnapPreviewEnabled
// Valor de retorno: void
public void SetSnapPreviewEnabled(bool enable)
Activa o desactiva la función de previsualización de ajuste. Cuando está activada, el indicador del objetivo de ajuste más cercano se muestra en tiempo real a medida que se mueve el ratón.
| Parámetro | Tipo | Descripción |
|---|---|---|
enable | bool | Si se habilita la previsualización de ajuste |
Ejemplo de uso:
m_manager.SetSnapPreviewEnabled(true);
Notas:
- Requiere que
SetSnapEnabled(true)se llame primero. - La previsualización consume continuamente recursos de GPU (detección cada fotograma).
- Solo compatible con PC / Mac.
UpdateSnapPreview
// Valor de retorno: void
public void UpdateSnapPreview(Vector2 mousePos, Camera cam)
Actualiza el estado de la previsualización de ajuste. Llámala a medida que se mueve el ratón para actualizar la posición del indicador de previsualización.
| Parámetro | Tipo | Descripción |
|---|---|---|
mousePos | Vector2 | Coordenada de pantalla actual del ratón |
cam | Camera | Cámara |
Ejemplo de uso:
void Update()
{
m_manager.UpdateSnapPreview(Input.mousePosition, Camera.main);
}
Notas:
- Requiere que
SetSnapPreviewEnabled(true)se llame primero. - Se recomienda llamarla continuamente en
Update. - Solo compatible con PC / Mac.
GetSnapPreviewState
// Valor de retorno: SnapPreviewState (screenPos está en coordenadas de pantalla)
public SnapPreviewState GetSnapPreviewState()
Obtiene el estado actual de la previsualización de ajuste, incluido si hay un objetivo de ajuste, el tipo de objetivo, la posición en pantalla del objetivo y la distancia en píxeles al ratón.
Ejemplo de uso:
var state = m_manager.GetSnapPreviewState();
if (state.hasTarget)
{
// state.snapType: Corner / Edge
// state.screenPos: posición en pantalla del objetivo de ajuste
// state.distanceToMouse: distancia en píxeles
}
Notas:
- Requiere que
SetSnapPreviewEnabled(true)yUpdateSnapPreviewse llamen primero. - Devuelve
default(SnapPreviewState)cuando no hay objetivo. screenPoses una coordenada de pantalla, no una coordenada de mundo; si necesitas la coordenada de mundo, usaRaycastWithSnappara obtenerHitResult.hitPos.- Solo compatible con PC / Mac.
RaycastWithSnap
// Valor de retorno: bool (true = impacto)
public bool RaycastWithSnap(Vector2 screenPos, Camera cam, out HitResult result)
Raycasting con ajuste. Primero realiza un raycast normal y luego busca bordes/esquinas cerca del punto de impacto a los que ajustarse.
| Parámetro | Tipo | Descripción |
|---|---|---|
screenPos | Vector2 | Coordenada de pantalla |
cam | Camera | Cámara |
result | out HitResult | Resultado del impacto (incluye información de ajuste) |
Ejemplo de uso:
if (m_manager.RaycastWithSnap(Input.mousePosition, m_camera, out HitResult hit))
{
// hit.snapType: Corner / Edge / None
// hit.hitPos: posición en el mundo después del ajuste
// hit.originalHitPos: punto de impacto original antes del ajuste
}
Notas:
- Requiere que
SetSnapEnabled(true)se llame primero. - Prioridad de ajuste: Corner > Edge > None.
- Este punto de entrada bloquea síncronamente el hilo principal (esperando el resultado de lectura de la GPU); se recomienda llamarlo solo en eventos de interacción (como clics), no en cada fotograma.
- En modo de previsualización (
SetSnapPreviewEnabled(true)), si ya existe un objetivo de ajuste, se reutiliza la caché de previsualización directamente sin recalcular; de lo contrario, se usa el flujo de ajuste normal. - Solo compatible con PC / Mac.
Estructuras de datos relacionadas
SnapType
public enum SnapType { None, Edge, Corner }
Tipo de objetivo de ajuste: ninguno / borde / esquina.
SnapPreviewState
public struct SnapPreviewState {
public bool hasTarget; // si hay un objetivo de ajuste
public SnapType snapType; // None / Edge / Corner
public Vector2 screenPos; // posición en pantalla del objetivo de ajuste (no es posición de mundo)
public float distanceToMouse; // distancia en píxeles a la posición del ratón
}
⚠️
screenPoses una coordenada de píxel en pantalla, no una coordenada de mundo. Si necesitas la coordenada de mundo, usaRaycastWithSnappara obtenerHitResult.hitPos.
HitResult
public struct HitResult {
public bool isHit; // si hubo impacto
public float distance; // distancia
public Vector3 hitPos; // posición en el mundo del punto de impacto (el nombre del campo es hitPos, no position)
public Vector3 normal; // normal del impacto
public float hitAlpha; // alfa del elipsoide impactado
public float dist2Origin; // distancia al origen del rayo
public float scale; // escala del elipsoide
public SnapType snapType; // tipo de ajuste (None / Edge / Corner)
public Vector3 originalHitPos; // punto de impacto original antes del ajuste
}
⚠️ Diferencia en el nombre del campo: el campo de la posición en el mundo del punto de impacto es
hitPos(noposition); los llamadores deben acceder a él usando el nombre de campo real.