You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AR图像识别后立方体生成偏移问题的解决方法咨询

AR图像识别叠加立方体偏移问题解决

问题描述

我正在开发一个AR项目,目标是识别指定图像后叠加生成立方体做功能测试,但测试时发现立方体生成存在偏移,希望找到方法让立方体精准贴合识别到的图像。

相关截图:

  • 带纹理的方块
  • AR Session Origin设置
  • 问题实拍图

原锚点脚本:

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;

public class ARObjectSpawner : MonoBehaviour
{
    public GameObject prefab;
    private ARRaycastManager raycastManager;
    private ARAnchorManager anchorManager;
    private List<ARRaycastHit> hits = new List<ARRaycastHit>();

    void Start()
    {
        raycastManager = FindObjectOfType<ARRaycastManager>();
        anchorManager = FindObjectOfType<ARAnchorManager>();
    }

    void Update()
    {
        if (Input.touchCount > 0)
        {
            Touch touch = Input.GetTouch(0);
            if (touch.phase == TouchPhase.Began)
            {
                if (raycastManager.Raycast(touch.position, hits, TrackableType.PlaneWithinPolygon))
                {
                    Pose hitPose = hits[0].pose;
                    GameObject spawnedObject = Instantiate(prefab, hitPose.position, hitPose.rotation);
                    ARAnchor anchor = anchorManager.AddAnchor(new Pose(hitPose.position, Quaternion.identity));
                    if (anchor != null)
                    {
                        spawnedObject.transform.SetParent(anchor.transform);
                    }
                    else
                    {
                        Debug.Log("Failed to create anchor.");
                    }
                }
            }
        }
    }
}

问题根源

原脚本通过ARRaycastManager检测平面生成物体,而非绑定到图像识别的跟踪目标上,导致立方体位置与图像识别结果脱节,自然出现偏移。

解决方法

改用ARTrackedImageManager监听图像识别事件,将立方体直接绑定到识别到的图像Transform上,确保位置精准对齐。

修改后的脚本

using UnityEngine;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;

public class ARImageSpawner : MonoBehaviour
{
    public GameObject cubePrefab;
    public ARTrackedImageManager trackedImageManager;
    private Dictionary<string, GameObject> spawnedCubes = new Dictionary<string, GameObject>();

    void OnEnable()
    {
        trackedImageManager.trackedImagesChanged += OnTrackedImagesChanged;
    }

    void OnDisable()
    {
        trackedImageManager.trackedImagesChanged -= OnTrackedImagesChanged;
    }

    void OnTrackedImagesChanged(ARTrackedImagesChangedEventArgs eventArgs)
    {
        // 处理新增的识别图像
        foreach (var trackedImage in eventArgs.added)
        {
            SpawnCubeOnImage(trackedImage);
        }

        // 更新已识别图像上的立方体位置
        foreach (var trackedImage in eventArgs.updated)
        {
            if (trackedImage.trackingState == TrackingState.Tracking && spawnedCubes.ContainsKey(trackedImage.referenceImage.name))
            {
                var cube = spawnedCubes[trackedImage.referenceImage.name];
                cube.transform.SetPositionAndRotation(trackedImage.transform.position, trackedImage.transform.rotation);
            }
        }

        // 移除丢失的识别图像对应的立方体
        foreach (var trackedImage in eventArgs.removed)
        {
            if (spawnedCubes.ContainsKey(trackedImage.referenceImage.name))
            {
                Destroy(spawnedCubes[trackedImage.referenceImage.name]);
                spawnedCubes.Remove(trackedImage.referenceImage.name);
            }
        }
    }

    void SpawnCubeOnImage(ARTrackedImage trackedImage)
    {
        // 确保每个识别图像只生成一次立方体
        if (!spawnedCubes.ContainsKey(trackedImage.referenceImage.name))
        {
            // 以识别图像的Transform为父物体,保证位置完全对齐
            GameObject cube = Instantiate(cubePrefab, trackedImage.transform.position, trackedImage.transform.rotation);
            cube.transform.SetParent(trackedImage.transform);
            
            // 可选:调整立方体大小适配识别图像的尺寸
            Vector3 imageSize = trackedImage.referenceImage.size;
            cube.transform.localScale = new Vector3(imageSize.x, 0.1f, imageSize.y);
            
            spawnedCubes.Add(trackedImage.referenceImage.name, cube);
        }
    }
}

配置步骤

  1. 在AR Session Origin对象下添加ARTrackedImageManager组件
  2. 在ARTrackedImageManager的Reference Library中导入你需要识别的图像资源库
  3. 将修改后的脚本挂载到场景中的空物体上,指定cubePrefab和trackedImageManager的引用
  4. 检查立方体预制体的原点是否在中心,若原点偏移会导致贴合错位,可调整预制体的轴心点

内容的提问来源于stack exchange,提问作者123456

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 03:35:07