public interface IModelAsset<TModel>
{
TModel Model { get; }
}
[Serializable]
public class Instruction
{
public string[] words;
}
public class InstructionAsset : ScriptableObject, IModelAsset<Instruction>
{
[SerializeField]
private Instruction _model;
public Instruction Model =>
_model;
}
public class Main
{
public static void LoadInstruction()
{
// This works
Addressables.LoadAssetAsync<InstructionAsset>("instruction");
// This doesn't work
Addressables.LoadAssetAsync<IModelAsset<Instruction>>("instruction");
}
}
Above is some sample code illustrating the issue. The error I receive is KeyNotFound. My usecase is writing a helper method to handle the Release() call for my assets that can be converted to internal models.
That’s really enlightening. I assumed that inherited types would be returned, but I see that isn’t supported. The following tests succeed.
// Base.cs
using UnityEngine;
[CreateAssetMenu(menuName = "Base")]
public class Base : ScriptableObject
{ }
// Derived.cs
using UnityEngine;
[CreateAssetMenu(menuName = "Derived")]
public class Derived : ScriptableObject
{ }
// AddressableTest.cs
using System.Collections;
using System.Text.RegularExpressions;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.TestTools;
public class AddressableTest
{
[UnityTest]
public IEnumerator AddressablesShouldNotReturnDerivedAsBase()
{
LogAssert.Expect(LogType.Error, new Regex("InvalidKeyException"));
var operation = Addressables.LoadAssetAsync<Base>("Derived");
yield return operation;
Assert.IsNull(operation.Result);
}
[UnityTest]
public IEnumerator AddressablesShouldReturnDerivedAsDerived()
{
var operation = Addressables.LoadAssetAsync<Derived>("Derived");
yield return operation;
Assert.IsNotNull(operation.Result);
}
}
I went ahead and sent in a bug report. It makes sense to me that the intention of Addressables.LoadAssetAsync<TAsset>() is to return any addressable assets that inherit from TAsset to keep it consistent in the conditions that TAsset : UnityEngine.Object and TAsset : interface.
If the behavior is not intended to be consistent between the two cases, please let me know!