After I attempt to destroy a prefab after a delay, it destroys the prefab immediately with no delay. I am using the UnityEngine.Object.Destroy
method. I tried using coroutines as well and it did not work.
I am a high school student trying to figure this out, so sorry if this seems like a dumb question.
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;
using System;
[RequireComponent(typeof(ARTrackedImageManager))]
public class PlaceTrackedImages : MonoBehaviour
{
// Reference to AR tarcked image manager component
private ARTrackedImageManager _trackedImagesManager;
// List of prefabs to instaniate
public GameObject[] ArPrefabs;
// Dictionary array of created prefabs
private readonly Dictionary<string, GameObject> _instantiatedPrefabs = new Dictionary<string, GameObject>();
private void Awake()
{
//Cache a reference to the Tarcked IMage Manager component
_trackedImagesManager = GetComponent<ARTrackedImageManager>();
}
private void OnEnable()
{
// Attavh event handler when tarcked images change
_trackedImagesManager.trackedImagesChanged += OnTrackedImagesChanged;
}
private void OnDisable()
{
// Remove event handler
_trackedImagesManager.trackedImagesChanged -= OnTrackedImagesChanged;
}
// Event Handler
private void OnTrackedImagesChanged(ARTrackedImagesChangedEventArgs eventArgs)
{
// Loop through all new tracked images that have been detected
foreach (var trackedImage in eventArgs.updated)
{
// Get the name of the reference image
var imageName = trackedImage.referenceImage.name;
// Loop over the array of prefabs
foreach (var curPrefab in ArPrefabs)
{
// Check whether this prefab matches the tracked image name, and that the prefab hasn't already been created
if (string.Compare(curPrefab.name, imageName, StringComparison.OrdinalIgnoreCase) == 0 && !_instantiatedPrefabs.ContainsKey(imageName))
{
// Instantiate the prefab, parenting it to the ARTrackedImage
var newPrefab = Instantiate(curPrefab, trackedImage.transform);
// Add the created prefab to the array
_instantiatedPrefabs[imageName] = newPrefab;
}
}
}
// For all prefabs that have been created so far, set them active or not depending on wehter their corresponding image is currently being tracked
foreach (var trackedImage in eventArgs.updated)
{
_instantiatedPrefabs[trackedImage.referenceImage.name].SetActive(trackedImage.trackingState == TrackingState.Tracking);
}
// If the AR subsystem has given up looking for a tracked image
foreach (var trackedImage in eventArgs.removed)
{
// Destroy its prefab after 10 second delay
Destroy(_instantiatedPrefabs[trackedImage.referenceImage.name],10f);
// Remove instance from the array
_instantiatedPrefabs.Remove(trackedImage.referenceImage.name);
}
}
}
My trouble is in line 68 when I call the destroy method. Thanks!
It looks like you may be mistakenly interpreting the destruction of your instantiated object as being a result of your call to Destroy on line 68 - when in reality the destruction is occurring because the ARTrackedImageManager is destroying the ARTrackedImage itself - immediately after sending the 'removed' event.
As your instantiated object is parented to the ARTrackedImage, it is destroyed as soon as the ARTrackedImage itself is destroyed, meaning your own call to Destroy is essentially superseded:
var newPrefab = Instantiate(curPrefab, trackedImage.transform);
To prevent the automatic destruction of your instantiated object, you can set ARTrackedImage.destroyOnRemoval to false. This will mean that you need to manually destroy the ARTrackedImage gameObject, rather than just your own instantiated gameObject - but it should give the results you need.