Example Scenario: I have image A and B. I scan image A, then scanned image B. Both were doing as its supposed to do. But when I try to scan image A again, this error shows
Exception in callback: An item with the same key has already been added:
And the quad displaying on the target image is the quad for image B. According to debug logs, the image target for image A is still being retrieved correctly. Help me fix this.
Here’s the script:
using System.Diagnostics;
using UnityEngine;
using Vuforia;
public class SimpleCloudRecoEventHandler : MonoBehaviour
{
CloudRecoBehaviour mCloudRecoBehaviour;
bool mIsScanning = false;
string mTargetMetadata = "";
public ImageTargetBehaviour ImageTargetTemplate;
void Awake()
{
mCloudRecoBehaviour = GetComponent<CloudRecoBehaviour>();
mCloudRecoBehaviour.RegisterOnInitializedEventHandler(OnInitialized);
mCloudRecoBehaviour.RegisterOnInitErrorEventHandler(OnInitError);
mCloudRecoBehaviour.RegisterOnUpdateErrorEventHandler(OnUpdateError);
mCloudRecoBehaviour.RegisterOnStateChangedEventHandler(OnStateChanged);
mCloudRecoBehaviour.RegisterOnNewSearchResultEventHandler(OnNewSearchResult);
}
void Start()
{
// Register status change callback
if (ImageTargetTemplate)
{
ImageTargetTemplate.OnTargetStatusChanged += OnTargetStatusChanged;
}
}
void OnDestroy()
{
// Unregister event handlers when the handler is destroyed
mCloudRecoBehaviour.UnregisterOnInitializedEventHandler(OnInitialized);
mCloudRecoBehaviour.UnregisterOnInitErrorEventHandler(OnInitError);
mCloudRecoBehaviour.UnregisterOnUpdateErrorEventHandler(OnUpdateError);
mCloudRecoBehaviour.UnregisterOnStateChangedEventHandler(OnStateChanged);
mCloudRecoBehaviour.UnregisterOnNewSearchResultEventHandler(OnNewSearchResult);
if (ImageTargetTemplate)
{
ImageTargetTemplate.OnTargetStatusChanged -= OnTargetStatusChanged;
}
}
public void OnInitialized(CloudRecoBehaviour cloudRecoBehaviour)
{
UnityEngine.Debug.Log("Cloud Reco initialized");
}
public void OnInitError(CloudRecoBehaviour.InitError initError)
{
UnityEngine.Debug.Log("Cloud Reco init error: " + initError.ToString());
}
public void OnUpdateError(CloudRecoBehaviour.QueryError updateError)
{
UnityEngine.Debug.Log("Cloud Reco update error: " + updateError.ToString());
}
public void OnStateChanged(bool scanning)
{
mIsScanning = scanning;
if (scanning)
{
// Clear all known targets
UnityEngine.Debug.Log("Scanning...");
}
}
public void OnNewSearchResult(CloudRecoBehaviour.CloudRecoSearchResult cloudRecoSearchResult)
{
mTargetMetadata = cloudRecoSearchResult.MetaData;
mCloudRecoBehaviour.enabled = false;
if (ImageTargetTemplate)
{
// Enable the new result with the same ImageTargetBehaviour
mCloudRecoBehaviour.EnableObservers(cloudRecoSearchResult, ImageTargetTemplate.gameObject);
// Retrieve the ImageTargetBehaviour
ImageTargetBehaviour imageTarget = ImageTargetTemplate.GetComponent<ImageTargetBehaviour>();
// Find the VideoLoader on the Quad
VideoLoader videoLoader = ImageTargetTemplate.GetComponentInChildren<VideoLoader>();
if (videoLoader != null && imageTarget != null)
{
string videoUrl = FindObjectOfType<FirebaseManager>().GetGithubPageUrlByDocumentId(cloudRecoSearchResult.TargetName);
if (!string.IsNullOrEmpty(videoUrl))
{
videoLoader.OnTargetDetected(videoUrl, imageTarget);
}
else
{
UnityEngine.Debug.LogError("Video URL not found for target: " + cloudRecoSearchResult.TargetName);
}
}
else
{
UnityEngine.Debug.LogError("VideoLoader or ImageTargetBehaviour component not found.");
}
}
}
// Handle changes in target tracking status
void OnTargetStatusChanged(ObserverBehaviour observerBehaviour, TargetStatus status)
{
// Retrieve the VideoLoader component from the child Quad
VideoLoader videoLoader = ImageTargetTemplate.GetComponentInChildren<VideoLoader>();
if (videoLoader != null)
{
// Show or hide the Quad based on tracking status
bool isVisible = status.Status == Status.TRACKED;
videoLoader.SetQuadVisibility(isVisible);
}
// Automatically restart scanning when the target is lost
if (status.Status != Status.TRACKED && mCloudRecoBehaviour != null && !mIsScanning)
{
RestartScanning();
}
}
private void RestartScanning()
{
mCloudRecoBehaviour.enabled = true; // Re-enable Cloud Recognition
mIsScanning = true; // Update the scanning state
mTargetMetadata = ""; // Clear the previous metadata
UnityEngine.Debug.Log("Restarted scanning for new targets.");
}
}