Skip to content

4. Asset loading

Joni Savolainen edited this page Mar 15, 2026 · 3 revisions

IAssetSource

IAssetSource is the interface that UIComponents uses to load assets. Each source handles both path resolution and asset loading for a given backend.

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

    Task<bool> AssetExists(string assetPath);
}

ResourcesAssetSource

UIComponents load assets from Resources by default using ResourcesAssetSource. To use a different backend, declare a different provider for the IAssetSource dependency.

AssetDatabaseAssetSource

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

When using convention-based [Layout] and [Stylesheet] (without explicit paths), AssetDatabaseAssetSource searches for matching assets within the [AssetRoot] directory using AssetDatabase.FindAssets. It supports both flat and nested directory layouts.

using UIComponents;
using UIComponents.Editor;

[AssetRoot("Packages/org.example.mypackage/UI/")]
[Layout]
[Stylesheet]
[Dependency(typeof(IAssetSource), provide: typeof(AssetDatabaseAssetSource))]
public partial class MyComponent : UIComponent {}

This will search for MyComponent.uxml and MyComponent.style.uss anywhere within the Packages/org.example.mypackage/UI/ directory tree.

Explicit paths with file extensions are passed through without searching:

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

AddressableAssetSource

AddressableAssetSource is accessible via the UIComponents.Addressables namespace.

using UIComponents;
using UIComponents.Addressables;

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

Asset roots

You will likely have your layout and stylesheet assets in one place. The [AssetRoot] attribute specifies a root path that is prepended to every asset path.

[AssetRoot] is most useful when applied to a base class and inherited:

[AssetRoot("UI/Components/")]
[Dependency(typeof(IAssetSource), provide: typeof(AddressableAssetSource))]
public abstract class BaseComponent : UIComponent {}

[Layout]
[Stylesheet]
public partial class FirstComponent : BaseComponent {}

[Layout]
[Stylesheet]
public partial class SecondComponent : BaseComponent {}

With AssetDatabaseAssetSource, [AssetRoot] acts as a convention root — the source searches for assets by name within that directory. With other sources, the root is prepended to the asset path as a prefix.

[AssetRoot] also works with explicit paths:

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

Asset path validation

UIComponents generates a UIComponentAssetRegistry per assembly, mapping component types to their asset paths. You can validate these paths in the Unity Editor via Window > UIComponents > Validate Registry Asset Paths.

The validator checks whether registered asset paths resolve to files on disk via AssetDatabase or Resources. If a component uses a custom IAssetSource that resolves convention paths at runtime (e.g., AssetDatabaseAssetSource), the validator may report convention paths as unresolved — this is expected, since convention resolution happens at runtime inside the source.

Clone this wiki locally