c# - 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);
}
}
}
当我从一个图像切换到另一个图像时,它按预期工作,但是,如果我切换回来,没有任何反应,对象将不会再次切换可见状态。他们只在第一个 Switch上做。
解决方案
问题是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);
}
推荐阅读
- django - 从 django 中的模板访问呈现模板的视图
- ios - 如何为特定类型的字典定义扩展名?
- javascript - 如何使用 jQuery 在新窗口上显示模式
- android - Android 房间迁移代码多次执行
- ruby-on-rails - update_columns 更新一个字符串,但在 Rails 上获取时它是 nil
- ef-core-2.1 - EFCore MAC - Unable to find an entry point named 'AppleCryptoNative_SslCreateContext'
- c++ - bw模板类和实例有什么区别?
- xamarin.ios - Google API SignIn HostedDomain 清理问题
- xamarin - 如何从 Android 和 iOS 模拟器使用本地 HTTPS ASP.NET Core 2.1 API
- javascript - 将 jQuery find() 函数转换为 ES6 Alternative