- Home /
Attempting to use invalid operation handle in addressables.
Hi,
I'm trying to use addressables and I was able to load assets from remote sources if it was built within the same project. However, what I need is to load assets from remote resources that was built from another project. I've seen a lot of other posts that have this same desire, tried their solutions and it might not be working anymore on my addressables version so I decided to post here.
public class AssetLoader : MonoBehaviour { public string catalogPath; public string jsonFilename;
public Console console;
public List<IResourceLocation> locations = new List<IResourceLocation>();
void Start()
{
initAddressables();
}
void initAddressables()
{
catalogPath += jsonFilename;
Debug.Log("initAddressables");
AsyncOperationHandle<IResourceLocator> handle = Addressables.InitializeAsync();
handle.Completed += initDone;
}
private void initDone(AsyncOperationHandle<IResourceLocator> obj)
{
Debug.Log("Initialization Complete ==> " + obj.Status);
if (obj.Status == AsyncOperationStatus.Succeeded)
{
loadCatalog();
}
}
void loadCatalog()
{
Debug.Log("loadCatalog");
AsyncOperationHandle<IResourceLocator> handle = Addressables.LoadContentCatalogAsync(catalogPath);
handle.Completed += loadCatalogsCompleted;
}
void loadCatalogsCompleted(AsyncOperationHandle<IResourceLocator> obj)
{
Debug.Log("loadCatalogsCompleted ==> " + obj.Status);
if (obj.Status == AsyncOperationStatus.Succeeded)
{
loadResourceLocation();
}
else
{
Debug.LogError("LoadCatalogsCompleted is failed");
}
}
void loadResourceLocation()
{
Debug.Log("loadResourceLocation");
AsyncOperationHandle<IList<IResourceLocation>> handle = Addressables.LoadResourceLocationsAsync("Primitive Objects");
handle.Completed += locationsLoaded;
}
void locationsLoaded(AsyncOperationHandle<IList<IResourceLocation>> obj)
{
Debug.Log("locationsLoaded ==> " + obj.Status);
console.log("LocationsLoaded ==> " + obj.Status);
if (obj.Status == AsyncOperationStatus.Succeeded)
{
locations = new List<IResourceLocation>(obj.Result);
loadAssets();
}
else
{
Debug.LogError("locationsLoaded is failed");
}
}
void loadDependency()
{
console.log("loadDependency");
AsyncOperationHandle handle = Addressables.DownloadDependenciesAsync("Primitive Objects");
handle.Completed += dependencyLoaded;
}
void dependencyLoaded(AsyncOperationHandle obj)
{
Debug.Log("dependencyLoaded ==> " + obj.Status);
if (obj.Status == AsyncOperationStatus.Succeeded)
{
console.log("dependencyLoaded ==> Status: " + obj.Status);
loadAssets();
}
else
{
console.log("dependencyLoaded ==> Status: " + obj.Status, "error");
console.log("dependencyLoaded ==> Name: " + obj.DebugName);
console.log("dependencyLoaded ==> Exception: " + obj.OperationException);
console.log("dependencyLoaded ==> " + obj.IsValid());
Debug.LogError("dependencyLoaded is Failed");
}
}
void loadDependencies(List<IResourceLocation> dependencies, IResourceLocation mainAsset){
AsyncOperationHandle handle = Addressables.DownloadDependenciesAsync("Primitive Objects");
handle.Completed += dependencyLoaded;
}
private void loadAssets()
{
console.log("loadAssets");
Debug.Log(locations);
foreach(IResourceLocation location in locations){
console.log("InternalId");
console.log(location.InternalId );
console.log("ProviderId ");
console.log(location.ProviderId );
//loadDependencies();
AsyncOperationHandle<GameObject> handle = Addressables.LoadAssetAsync<GameObject>(location);
console.log(handle.DebugName);
handle.Completed += onAssetsLoaded;
}
}
private void onAssetsCategoryLoaded(GameObject obj)
{
SpawnItem(obj.name);
}
private void onAssetsLoaded(AsyncOperationHandle<GameObject> obj)
{
console.log("OnAssetsLoaded ==> Status: " + obj.Status, (obj.Status == AsyncOperationStatus.Succeeded ? "default" : "error"));
if(obj.Status != AsyncOperationStatus.Succeeded){
console.log("OnAssetsLoaded ==> Name: " + obj.DebugName, "error");
console.log("OnAssetsLoaded ==> Exception: " + obj.OperationException, "error");
console.log("OnAssetsLoaded ==> IsValid: " + obj.IsValid());
SpawnItem(obj.Result.name);
}
}
void SpawnItem(string addressableKey)
{
Debug.Log("SpawnItem ==> " + addressableKey);
AsyncOperationHandle<GameObject> asyncLoad = Addressables.InstantiateAsync(addressableKey, Vector3.zero, Quaternion.identity);
StartCoroutine(progressAsync(asyncLoad));
asyncLoad.Completed += assetSpawned;
}
void SpawnItem(GameObject addressableObj)
{
Debug.Log("SpawnItem ==> " + addressableObj);
AsyncOperationHandle<GameObject> asyncLoad = Addressables.InstantiateAsync(addressableObj);
StartCoroutine(progressAsync(asyncLoad));
asyncLoad.Completed += assetSpawned;
}
private System.Collections.IEnumerator progressAsync(AsyncOperationHandle<GameObject> asyncOperation)
{
float percentLoaded = asyncOperation.PercentComplete;
while (!asyncOperation.IsDone)
{
Debug.Log("Progress = " + percentLoaded + "%");
yield return 0;
}
Debug.Log("Progress Done= " + percentLoaded + "%");
}
void assetSpawned(AsyncOperationHandle<GameObject> obj)
{
Debug.Log("Instantiate completed ==> " + obj.Status);
}
}
Sorry for my horrible code. I'll be fine with just having the reason why I'm having the invalid operation handle error. But maybe someone can point me to an updated article with the same workflow that I'm trying to do. I've been searching for almost a month now and I'm still stuck here.
Thanks!
Answer by blackbookuser · Mar 19, 2021 at 02:08 PM
Having the same issue, but not seeing a good explanation to what is going on, here is what our code looks like when we get the error:
/// <summary>
/// Use this function to check if a scene/asset is available before attempting to load it.
/// Trying to load a non-exsistant scene will crash the app.
/// </summary>
/// <param name="key">Typically the scene name.</param>
/// <param name="onComplete">Called when the operation completes. First bool indicates success. Second bool indicates if it exsists.</param>
public static void ContentExistsAsync(object key, System.Action<bool, bool> onComplete)
{
Debug.Log($"Preparing to subscribing \"handle\" to Addressables.LoadResourceLocationsAsync({key}).Completed");
//TODO: Add a test on handle before subscribing???
var resourceLocationsAsync = Addressables.LoadResourceLocationsAsync(key);
Debug.Log($"Addressables.LoadResourceLocationsAsync({key}) is valid = {resourceLocationsAsync.IsValid()}");
resourceLocationsAsync.Completed += (handle) =>
{
Debug.Log("Subscription successfull!(?) This is now detached code!");
if (handle.Status != AsyncOperationStatus.Succeeded)
{
Debug.LogError($"Failed to check if resource exsists. This does not neccerily mean that it does not exsist.");
onComplete?.Invoke(false, false);
return;
}
Debug.Log("Preparing to evaluate handle result count");
bool result = handle.Result.Count > 0;
Debug.Log($"Handle result count > 0 evaluated as {result}");
Debug.Log($"Preparing to release handle");
Addressables.Release(handle);
Debug.Log($"Handle released");
Debug.Log($"Preparing to invoke onComplete");
onComplete?.Invoke(true, result);
Debug.Log($"onComlete invoked succesfully");
};
}