如何解决ARTrackedImage仅在第一次切换
这是用于使用ARFoundation检测图像并根据设备正在扫描的图像启用对象的代码
[SerializeField]
public GameObject[] placeablePrefabs;
private Dictionary<string,GameObject> spawnedPrefabs = new Dictionary<string,GameObject>();
private ARTrackedImageManager trackedImageManager;
private JSONObject warnings;
public void Awake()
{
trackedImageManager = GetComponent<ARTrackedImageManager>();
foreach(GameObject prefab in placeablePrefabs)
{
GameObject newPrefab = Instantiate(prefab,Vector3.zero,Quaternion.identity);
newPrefab.name = prefab.name;
spawnedPrefabs.Add(prefab.name,newPrefab);
}
}
private void OnEnable()
{
trackedImageManager.trackedImagesChanged += ImageChanged;
}
private void OnDisable()
{
trackedImageManager.trackedImagesChanged -= ImageChanged;
}
private void ImageChanged(ARTrackedImagesChangedEventArgs eventArgs)
{
foreach(ARTrackedImage trackedImage in eventArgs.added)
{
UpdateImage(trackedImage);
}
foreach (ARTrackedImage trackedImage in eventArgs.updated)
{
UpdateImage(trackedImage);
}
foreach (ARTrackedImage trackedImage in eventArgs.removed)
{
spawnedPrefabs[trackedImage.name].SetActive(false);
}
}
private void UpdateImage(ARTrackedImage trackedImage)
{
string name = trackedImage.referenceImage.name;
Vector3 position = trackedImage.transform.position;
GameObject prefab = spawnedPrefabs[name];
prefab.transform.position = position;
prefab.SetActive(true);
foreach(GameObject go in spawnedPrefabs.Values)
{
if(go.name != name)
{
go.SetActive(false);
}
}
}
当我从一个图像切换到另一个图像时,它可以按预期工作,但是,如果我切换回去,则什么也没有发生,对象将不会再次切换可见状态。它们仅在第一个交换机上执行。
解决方法
问题在于 eventArgs.removed 没有被调用。不知道为什么。
我使用3.1.3 ARFoundation和ARCore版本。
无论如何,我设法找到了解决方案。如果有人想要整个思考,我将发布整个代码。
它是这样的:
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.ARFoundation;
using System;
using UnityEngine.UI;
using UnityEngine.XR.ARSubsystems;
public class ImageRecognitionExample : MonoBehaviour
{
private ARTrackedImageManager m_ImageManager;
[SerializeField]
private GameObject welcomePanel;
[SerializeField]
private Button dismissButton;
[SerializeField]
private Text imageTrackedText;
[SerializeField]
private GameObject[] arObjectsToPlace;
[SerializeField]
private Vector3 scaleFactor = new Vector3(0.1f,0.1f,0.1f);
private ARTrackedImageManager m_TrackedImageManager;
private Dictionary<string,GameObject> arObjects = new Dictionary<string,GameObject>();
String currentActiveQR;
void Awake()
{
dismissButton.onClick.AddListener(Dismiss);
m_ImageManager = GetComponent<ARTrackedImageManager>();
foreach (GameObject arObject in arObjectsToPlace)
{
GameObject newARObject = Instantiate(arObject,Vector3.zero,Quaternion.identity);
newARObject.name = arObject.name;
arObjects.Add(arObject.name,newARObject);
}
}
void OnEnable()
{
m_ImageManager.trackedImagesChanged += OnTrackedImagesChanged;
}
void OnDisable()
{
m_ImageManager.trackedImagesChanged -= OnTrackedImagesChanged;
}
void OnTrackedImagesChanged(ARTrackedImagesChangedEventArgs eventArgs)
{
foreach (ARTrackedImage trackedImage in eventArgs.added)
{
currentActiveQR = trackedImage.referenceImage.name;
UpdateARImage(trackedImage,currentActiveQR);
}
foreach (ARTrackedImage trackedImage in eventArgs.updated)
{
if (trackedImage.trackingState == TrackingState.Tracking)
{
currentActiveQR = trackedImage.referenceImage.name;
imageTrackedText.text = currentActiveQR;
AssignGameObject(currentActiveQR,trackedImage.transform.position);
}
else
{
if (currentActiveQR != trackedImage.referenceImage.name)
{
ReAssignGameObject(trackedImage.referenceImage.name,trackedImage.transform.position);
}
}
}
}
private void UpdateARImage(ARTrackedImage trackedImage,String name)
{
imageTrackedText.text = trackedImage.referenceImage.name;
AssignGameObject(name,trackedImage.transform.position);
}
void AssignGameObject(string name,Vector3 newPosition)
{
if (arObjectsToPlace != null)
{
GameObject goARObject = arObjects[name];
goARObject.SetActive(true);
goARObject.transform.position = newPosition;
goARObject.transform.localScale = scaleFactor;
foreach (GameObject go in arObjects.Values)
{
//Debug.Log($"Go in arObjects.Values: {go.name}");
if (go.name != name)
{
go.SetActive(false);
}
}
}
}
void ReAssignGameObject(string name,Vector3 newPosition)
{
if (arObjectsToPlace != null)
{
GameObject goARObject = arObjects[name];
goARObject.SetActive(true);
goARObject.transform.position = newPosition;
goARObject.transform.localScale = scaleFactor;
foreach (GameObject go in arObjects.Values)
{
if (go.name == name)
{
go.SetActive(false);
}
}
}
}
private void Dismiss() => welcomePanel.SetActive(false);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。