I want to check if an asset exists or not before calling Instantiate method.
Addressables.LoadResourceLocationsAsync(address, type), then check the if the location exists.
This method also prints error when the address doesnât exist.
I need a silent method that just returns a status of an asset.
Then it is a bug. Could submit a bug report to Unity?
This is definitely a bug. It would seem that we had a partial fix for this, and simply didnât deliver. We will get to to fixing this.
I am currently doing this via the below technique, but it is inefficient and only works in editor. It seems like a simple âhasAddressâ method should exist for this somewhere.
public static bool DoesAddressExist(AddressableAssetSettings settings, string testAddress)
{
List<AddressableAssetEntry> allEntries = new List<AddressableAssetEntry>();
settings.GetAllAssets(allEntries);
foreach (AddressableAssetEntry entry in allEntries)
{
if (entry.address == testAddress)
return true;
}
return false;
}
Here is how I do it.
public static bool AssetExists(object key) {
if (Application.isPlaying) {
foreach (var l in Addressables.ResourceLocators) {
IList<IResourceLocation> locs;
if (l.Locate(key, null, out locs))
return true;
}
return false;
}
else if (Application.isEditor && !Application.isPlaying) {
#if UNITY_EDITOR
// note: my keys are always asset file paths
return FileExists(System.IO.Path.Combine(Application.dataPath, (string)key));
#endif
}
return false;
}
Addressables must have been initialized (Addressables.InitializeAsync() must have completed.)
Then you can do a simple sync call of AssetExists(myAssetPathToCheck)
This still works in 1.1.7
It is very convenient because you can just await for Addressables.InitializeAsync() once when you start your game, and then can always do the sync AssetExists call.
I donât know why Addressable devs donât provide something simple like this for such a basic and highly needed requirement.
Just to check whether an asset exists they want you to do an async call.
I use AssetExists for âconvention over configurationâ style code, where, for example, the game checks if an image exists or not and if it doesnât then uses the default image. Being able to do it in a sync call greatly reduces the code complexity and helps with perceived performance.
You answered your own question. We do that so it can be called at any time (even before init is done), and will give you a correct result when ready.
fixed in 1.1.7
For all those coming in the future, this method seems to be deprecated, as the ResourceLocators donât seem to support Locate anymore.
Hmm⊠Iâm still using it just fine in 1.4.0.
And to answer unity_bill ⊠the advantage of my method is you can await Addressables.InitializeAsync() once in the initial loading screen of your game. (Addressables Initialize only once anyways.) Then you can use my AssetExists method synchronously anywhere afterwards.
While if you use the built-in method, then you will have to do an async call every time you want to just check if an asset exists ⊠which many times are in places that canât or you donât want to use async cause it will complicate your code a lot more.
maybe you should try async/await:
var list = await Addressables.LoadResourceLocationsAsync(assetId).Task;
if (list != null && list.Count > 0)
{
}
do I need release the AsyncOperationHandle returned by LoadResourceLocationsAsync?
I know that async/await can be used. I use async/await throughout my code where needed. The point of my code above is that just to check whether an asset at a path exists I donât want to have to use async/await.
var list = await Addressables.LoadResourceLocationsAsync(assetAddr).Task;
if (list != null && list.Count > 0)
{
//assetAddr is existed in Addressable Groups
}
I think this codes is as easy as sync mode codes.
There many places in code where it isnât convenient to use async, such as property getters/setters.
Anyways, we can agree to disagree. I am just explaining my reasons.
Thank you VERY MUCH for doing this!!
@unity_bill This should at least be mentioned in the documentation as an example, if it wasnât for this answer, Iâd be spending so much time figuring this out. Speaking of documentations, there is definitely more questions than answers out there. I really hope thereâs more info and tutorials on this subject because so far I am truly amazed by how helpful addressables are going to be on my project. I can see a lot of people steering away from this because its hard to find things and miss out.
it is now, but unfortunately it takes time for google search to catch up with what weâve posted in docs. in case someone lands here in the futureâŠ
https://docs.unity3d.com/Packages/com.unity.addressables@1.16/manual/LoadResourceLocations.html
âŠthis operation cannot fail. If no matching IResourceLocations can be found then the Result is an empty list. This makes the API useful for verifying that a key exists without fear of an InvalidKeyException getting thrown.
Please help!
How can i access .dat file from s3 as addressable ?
public void LoadAddressableComponentTextAssets(string name, Action OnLoad, Action OnFail) {
ResultTextAsset = OnLoad;
try {
Addressables.LoadAssetAsync(name).Completed += OnLoadDone;
}
catch (Exception e) {
OnFail?.Invoke();
}
}
private void OnLoadDone(AsyncOperationHandle obj) {
Debug.Log(obj.Result.name);
ResultTextAsset?.Invoke(obj.Result);
}
Error :
Exception encountered in operation UnityEngine.ResourceManagement.ResourceManager+CompletedOperation`1[UnityEngine.TextAsset], result=ââ, status=âFailedâ: Exception of type âUnityEngine.AddressableAssets.InvalidKeyExceptionâ was thrown., Key=Shirt_1_00_26, Type=UnityEngine.TextAsset