【问题标题】:Spawned image from image detection is "glued" to the screen if image/anchor is lost如果图像/锚丢失,来自图像检测的生成图像会“粘”到屏幕上
【发布时间】:2023-03-30 14:53:01
【问题描述】:

因此,在 Unity 中,我正在尝试制作一个 AR 应用程序,该应用程序在检测到某个图像后会产生一些东西。如果相机丢失了图像或对象的跟踪,它会将生成的对象粘合到屏幕上。我怎样才能避免这种情况,是否有显示状态的变量?

我已经尝试过“TrackingState”变量,遗憾的是它不起作用。 “Limited 不仅适用于被胶合(到屏幕)的状态,而且还适用于“受损”,即使它仍然正确显示,也会导致对象消失。遗憾的是,这会导致非常敏感的相机处理,所以它不是到目前为止的一个选择。 另一方面,“无”从未出现过。

谁能说出我可以用来解决这个问题的其他元素吗?或者解释一下我在使用“TrackingState”时做错了什么?

这是我到目前为止尝试过的代码(我还有一个记录器来显示它每半秒处于哪个状态):

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

public class ImagesToFigures : MonoBehaviour
{
    private ARTrackedImageManager _arTrackedImageManager;
    private ARManager _arManager;
    private GameObject spawnedObject;
    private string existingString;
    private bool isActive;

    private GameObject[] children;
    private FoundStickerEvent foundStickerEvent;
    private string addedSticker = "";

    private XRReferenceImage referenceImage;



    void Awake()
    {
        _arTrackedImageManager = GetComponentInParent<ARTrackedImageManager>();
        // if (GetComponentInParent<ARManager>()) {
        _arManager = GetComponentInParent<ARManager>();
        // }
        existingString = "";

        children = new GameObject[this.transform.childCount];

        for (int i = 0; i < this.transform.childCount; i++)
        {
            GameObject child = this.transform.GetChild(i).gameObject;
            children[i] = child;
        }
    }

    public void activate()
    {
        isActive = true;
    }

    public void OnEnable()
    {
        _arTrackedImageManager.trackedImagesChanged += OnImageChanged;
    }

    public void OnDisable()
    {
        _arTrackedImageManager.trackedImagesChanged -= OnImageChanged;
    }

    public void destroySpawnedObject()
    {
        // existingString = "";
        foreach (var child in children)
        {
            child.SetActive(false);
        }
        // addedSticker = "";
        // GameManager.instance.log("destroyed");
    }

    private void OnImageChanged(ARTrackedImagesChangedEventArgs eventArgs)
    {
        if (GameManager.instance.currentState == GameState.AR_SCANNING)
        {
            // GameManager.instance.log(eventArgs.updated.Count +" " + referenceImage.name);
            foreach (GameObject child in children)
            {
                if (addedSticker == "")
                {
                    foreach (ARTrackedImage trackedImage in eventArgs.added)
                    {
                        addedSticker = trackedImage.referenceImage.name;
                        // GameManager.instance.log(addedSticker);
                    }
                }
                else
                {
                    // GameManager.instance.log(eventArgs.updated.Count.ToString());
                    foreach (ARTrackedImage trackedImage in eventArgs.updated)
                    {
                        try
                        {
                            if (child.name == trackedImage.referenceImage.name &&
                                (child.name == addedSticker || (referenceImage.name == trackedImage.referenceImage.name && child.name == referenceImage.name))
                            )
                            {
                                if (trackedImage.trackingState == TrackingState.Tracking /*|| trackedImage.trackingState == TrackingState.Limited*/)
                                {
                                    child.SetActive(true);
                                    GameManager.instance.currentState = GameState.AR_SCANNED;
                                    GameManager.instance.log(trackedImage.referenceImage.name);
                                    referenceImage = trackedImage.referenceImage;

                                    // GameManager.instance.log(child.transform.position.ToString());
                                    // trackedImage.destroyOnRemoval = true;
                                    _arManager.foundStickerEvent.Invoke(trackedImage.referenceImage.name);
                                    // _arManager.displayInfosEvent.Invoke("Tippe auf die Figur für spannende Infos!");

                                }
                            }
                            // else
                            // {
                            //     child.SetActive(false);
                            // }
                        }
                        catch (Exception e)
                        {
                            GameManager.instance.log("error: " + e.ToString());
                        }
                    }
                }
            }
        }

if ((currentlyActiveImage.trackingState == TrackingState.None) || currentlyActiveImage.trackingState == TrackingState.Limited))
{
  GameManager.instance.destroyARObject();
  GameManager.instance.ResetState();
}

【问题讨论】:

  • 您能添加您的代码吗?你可能想要OnTrackingLost -> SetActive(false)Destroy 你反对...
  • 我添加了到目前为止的代码。您能否链接“OnTrackingLost”的文档?或者告诉我在哪里可以找到?
  • 请添加完整的可重现代码...我们不知道您使用什么库/脚本等来执行after detecting a certain Image ...
  • 添加了检测后调用的脚本。我正在使用 ARFoundation Imagetracking。

标签: unity3d augmented-reality


【解决方案1】:

在 Tracked Image 脚本中,您可以定义丢失跟踪时会发生什么。然后,您可以根据需要将对象设置为非活动并销毁它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-16
    • 1970-01-01
    • 2015-12-14
    • 1970-01-01
    • 2014-06-04
    • 2021-03-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多