Unity-Technologies/Addressables-Sample

Having trouble deleting an InstantiateAsync object

Sterling-Malory-Archer opened this issue · 1 comments

Hi,

I have an AR App where when an Image gets detected, it should Instantiate an AssetReference that image is associated with.

But I have another method where if a new Image is detected, I want to first delete the previously instantiated AssetReference, and then instantiate the AssetReference associated with the new Image.

Here is my code:

`
public class MultiTrackedImageManager : MonoBehaviour
{

public static MultiTrackedImageManager Instance { get { return instance; } }
private static MultiTrackedImageManager instance;

private ARTrackedImageManager m_TrackedImageManager;
private GameObject curobject;
private string PREFABFOLDER = "Prefabs/";

AssetBundle myLoadedAssetBundle;
[SerializeField]
private string imageName;
private GameObject prefabToLoad;

public List<MultiTrackedImage> Images = new List<MultiTrackedImage>();

// Addressables necessities for test
GameObject target;
private Vector3 spawnPosition;
GameObject testObj;

private void Awake()
{
    //if (instance != null) { Destroy(instance); }
    instance = this;
    m_TrackedImageManager = GetComponent<ARTrackedImageManager>();
    curobject = null;
    spawnPosition = Vector3.zero;
}
void OnEnable()
{
    m_TrackedImageManager.trackedImagesChanged += OnTrackedImagesChanged;
}

void OnDisable()
{
    m_TrackedImageManager.trackedImagesChanged -= OnTrackedImagesChanged;
}

void OnTrackedImagesChanged(ARTrackedImagesChangedEventArgs eventArgs)
{

    foreach (var trackedImage in eventArgs.updated)
    {
        OnImageUpdated(trackedImage.referenceImage.texture.name, trackedImage.name, trackedImage);
    }

    foreach (var trackedImage in eventArgs.added)
    {
        OnImageAdded(trackedImage.referenceImage.texture.name, trackedImage.name, trackedImage);
    }
}

public void OnImageUpdated(string textureName, string name, ARTrackedImage m_ARTrackedImage)
{
    
    for (int i = 0; i < Images.Count; i++)
    {
        //if we have a match for the object and we have regained tracking and the current object is not the one for the trigger we just found
        if (m_ARTrackedImage.trackingState == TrackingState.Tracking)
        {

            //this checks to make sure we are tracking the right image target
            if(!string.Equals(Images[i].target.name, textureName)) { continue; }

            //this checks to see if our current object is equal to the name of the image target so we don't delete and duplicate
            if (string.Equals(curobject.name, Images[i].target.name)) { continue; }

            //for some reason we are getting updates from non visible targets
            if (curobject != null) { Destroy(curobject);}

            GameObject go = GameObject.Find(name);

            //Instantiate the prefab with the position of go
            var addresableTarget = Addressables.InstantiateAsync(Images[i]._prefabReference, go.transform.position, Quaternion.identity);

            if(target != null) {Addressables.Release(target); Addressables.ReleaseInstance(addresableTarget); }
            target = addresableTarget.Result;

            curobject = target;
            curobject.name = Images[i].target.name;

            TextManager.s.txtContent1 = Images[i].txt1 == "" ? "  " : Images[i].txt1;
            TextManager.s.txtContent2 = Images[i].txt2 == "" ? "  " : Images[i].txt2;
            TextManager.s.ResetText();

            Images[i].go = go;
            target.transform.rotation = go.transform.rotation;
            target.transform.SetParent(go.transform);
            target.transform.localPosition = Vector3.zero;
        }
    }
}

public void OnImageAdded(string textureName, string name, ARTrackedImage m_ARTrackedImage)
{

    //PrefabManager.s.ClearPrefabs();
    for (int i = 0; i < Images.Count; i++)
    {
        if (string.Equals(Images[i].target.name, textureName) && Images[i].go == null)
        {
            //Destroy the existing AR Animation
            if (curobject != null) { Destroy(curobject);}

            GameObject go = GameObject.Find(name);

            //Instantiate the prefab with the position of go
            var addresableTarget = Addressables.InstantiateAsync(Images[i]._prefabReference, 
go.transform.position, Quaternion.identity);

            if (target != null) { Addressables.Release(target); Addressables.ReleaseInstance(addresableTarget); }
            target = addresableTarget.Result;

            curobject = target;
            curobject.name = Images[i].target.name;

            TextManager.s.txtContent1 = Images[i].txt1 == "" ? "  " : Images[i].txt1;
            TextManager.s.txtContent2 = Images[i].txt2 == "" ? "  " : Images[i].txt2;
            TextManager.s.ResetText();

            Images[i].go = go;
            target.transform.rotation = go.transform.rotation;
            target.transform.SetParent(go.transform);
            target.transform.localPosition = Vector3.zero;
        }
    }
}

`

Hi @Sterling-Malory-Archer I think this is what your code is missing:

//Destroy the existing AR Animation
// No need to call Destroy(curobject) here. Calling Addressables.Release will also destroy the object created by InstantiateAsync.

var addresableTarget = Addressables.InstantiateAsync();
addressableTarget.WaitForCompletion(); // Make sure that InstantiateAsync is complete

if (target != null)
{
Addressables.Release(target);
// If we call ReleaseInstance(addresableTarget) here, we can't access addresableTarget.Result below
}
target = addresableTarget.Result;

For more information about instantiating/releasing addressables, see https://docs.unity3d.com/Packages/com.unity.addressables@1.19/manual/LoadingAddressableAssets.html#instantiating-objects-from-addressables