Skip to content

4. Asset loading

Joni Savolainen edited this page May 26, 2023 · 2 revisions

IAssetResolver

IAssetResolver is an interface for classes whose purpose is to load assets and determine whether they exist.

public interface IAssetResolver
{
    Task<T> LoadAsset<T>(string assetPath) where T : UnityEngine.Object;

    Task<bool> AssetExists(string assetPath);
}

ResourcesAssetResolver

UIComponents load assets from Resources by default using ResourcesAssetResolver. To use a different method, declare a different provider for the IAssetResolver dependency. See an example below.

AssetDatabaseAssetResolver

AssetDatabaseAssetResolver is accessible via the UIComponents.Editor namespace. It is useful for editor extensions.

using UIComponents;
using UIComponents.Editor;

[Layout("Packages/org.example.mypackage/UI/Layout.xml")]
[Dependency(typeof(IAssetResolver), provide: typeof(AssetDatabaseAssetResolver))]
public partial class MyComponent : UIComponent {}

AddressableAssetResolver

AddressableAssetResolver is accessible via the UIComponents.Addressables namespace.

using UIComponents;
using UIComponents.Addressables;

[Layout("UI/Components/MyComponent.uxml")]
[Dependency(typeof(IAssetResolver), provide: typeof(AddressableAssetResolver))]
public partial class MyComponent : UIComponent {}

Common asset paths

You will likely have your layout and stylesheet assets in one place. The [AssetPrefix] attribute is used to attach a prefix to every asset path.

Here is an example of its usage alongside asset loading using Addressables:

[AssetPrefix("UI/Components/MyComponent/")]
[Layout("MyComponent.uxml")]
[Stylesheet("MyComponent.style.uss")]
[Dependency(typeof(IAssetResolver), provide: typeof(AddressableAssetResolver))]
public partial class MyComponent : UIComponent {}

[AssetPrefix] doesn't have much of an impact when applied to a single component. However, it can be applied to a parent class and inherited.

[AssetPrefix("UI/Components/")]
[Dependency(typeof(IAssetResolver), provide: typeof(AddressableAssetResolver))]
public abstract class BaseComponent : UIComponent {}

[Layout("MyComponent/MyComponent.uxml")]
[Stylesheet("MyComponent/MyComponent.style.uss")]
public partial class FirstComponent : BaseComponent {}

[Layout("SecondComponent/SecondComponent.uxml")]
[Stylesheet("SecondComponent/SecondComponent.style.uss")]
public partial class SecondComponent : BaseComponent {}