I am trying to use a coroutine to make it so that the overlay prefab stays on the screen (in most cases it is an audio source or 2D Image) for 10 seconds after the camera no longer detects its reference image. The overlay stays on the screen forever and does not disappear after the 10 seconds are up.
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;
using System;
using System.Collections;
[RequireComponent(typeof(ARTrackedImageManager))]
public class PlaceTrackedImages : MonoBehaviour
{
private ARTrackedImageManager _trackedImagesManager;
public GameObject[] ArPrefabs;
private readonly Dictionary<string, (GameObject, float)> _instantiatedPrefabs = new Dictionary<string, (GameObject, float)>();
private void Awake()
{
_trackedImagesManager = GetComponent<ARTrackedImageManager>();
}
private void OnEnable()
{
_trackedImagesManager.trackedImagesChanged += OnTrackedImagesChanged;
}
private void OnDisable()
{
_trackedImagesManager.trackedImagesChanged -= OnTrackedImagesChanged;
}
private void OnTrackedImagesChanged(ARTrackedImagesChangedEventArgs eventArgs)
{
foreach (var trackedImage in eventArgs.updated)
{
var imageName = trackedImage.referenceImage.name;
if (!_instantiatedPrefabs.ContainsKey(imageName))
{
var curPrefab = Array.Find(ArPrefabs, prefab => prefab.name.Equals(imageName, StringComparison.OrdinalIgnoreCase));
if (curPrefab != null)
{
var newPrefab = Instantiate(curPrefab, trackedImage.transform);
_instantiatedPrefabs[imageName] = (newPrefab, Time.time);
}
}
if (trackedImage.trackingState == TrackingState.Tracking)
{
_instantiatedPrefabs[imageName].Item1.SetActive(true);
_instantiatedPrefabs[imageName] = (_instantiatedPrefabs[imageName].Item1, Time.time);
}
else
{
if (Time.time - _instantiatedPrefabs[imageName].Item2 < 10f)
{
_instantiatedPrefabs[imageName].Item1.SetActive(true);
}
else
{
StartCoroutine(DelayedDestroy(_instantiatedPrefabs[imageName].Item1, 10f));
_instantiatedPrefabs.Remove(imageName);
}
}
}
}
private IEnumerator DelayedDestroy(GameObject prefab, float delay)
{
yield return new WaitForSeconds(delay);
Destroy(prefab);
}
}