How to load assets in editor script?

Hi,

I got an editor which could work without clicking the Play button. Because there is only async load in the Addressables system, it seems there is no way to load assets in editor mode now. I’ve tried something like unity-editor-coroutine, but it did not work.

1 Like

We don’t currently support editor loading. If you want to load something in Editor just use the normal AssetDatabase like so

var aaSettings = AddressableAssetSettings.GetDefault(true, true);
var entry = aaSettings.FindAssetEntry("My Asset");
var asset = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(entry.guid);
2 Likes

Thanks. This workaround seems good.

I tried the API, but the parameter of FindAssetEntry is guid. It is not the name of the asset.

Ok you can just get all the assets with GatherAllAssets and then iterate through looking for the name.

Seems this code is out dated.

@karl_jones Have you a new way to load addressables for editor script ?

Found new API

Replace

var aaSettings = AddressableAssetSettings.GetDefault(true, true)

with

AddressableAssetSettingsDefaultObject.GetSettings(true)

Adn for the “GatherAllAssets” from @karl_jones , do

                var assetsList = new List<AddressableAssetEntry>(1024);
                AddressableAssetSettingsDefaultObject.GetSettings(false).GetAllAssets(assetsList);

An example or a better API for find assets in editor UI could be great guys.

2 Likes

I write this helper, it’s not perfect with subassets but that works at least

using System.Collections.Generic;
using UnityEditor;
using UnityEditor.AddressableAssets;
using UnityEditor.AddressableAssets.Settings;
using UnityEngine;

namespace HMH.Editor
{
#if UNITY_EDITOR
    [InitializeOnLoad]
    public static class AddressableHelper
    {
        static AddressableHelper()
        {
            var assetsList = new List<AddressableAssetEntry>(2048);
            AddressableAssetSettingsDefaultObject.GetSettings(true).GetAllAssets(assetsList);

            foreach (var entry in assetsList)
                AddEntry(entry);

            AddressableAssetSettings.OnModificationGlobal += AddressableAssetSettingsOnOnModificationGlobal;
        }

        private static void AddressableAssetSettingsOnOnModificationGlobal(AddressableAssetSettings settings, AddressableAssetSettings.ModificationEvent modificationType, object entry)
        {
            var listEntries = entry as List<AddressableAssetEntry>;

            if (listEntries == null)
                switch (modificationType)
                {
                    case AddressableAssetSettings.ModificationEvent.EntryAdded:
                    case AddressableAssetSettings.ModificationEvent.EntryCreated:
                        AddEntry((AddressableAssetEntry)entry);

                        break;
                    case AddressableAssetSettings.ModificationEvent.EntryRemoved:
                        var addressableEntryRemoved = (AddressableAssetEntry)entry;

                        if (_addressesToEntry.TryGetValue(addressableEntryRemoved.address, out var entryList))
                            entryList.Remove(addressableEntryRemoved);

                        break;
                }
            else
                switch (modificationType)
                {
                    case AddressableAssetSettings.ModificationEvent.EntryAdded:
                    case AddressableAssetSettings.ModificationEvent.EntryCreated:

                        foreach (var entryItem in listEntries)
                            AddEntry(entryItem);

                        break;
                    case AddressableAssetSettings.ModificationEvent.EntryRemoved:

                        foreach (var entryItem in listEntries)
                            if (_addressesToEntry.TryGetValue(entryItem.address, out var entryList))
                                entryList.Remove(entryItem);

                        break;
                }
        }

        private static void AddEntry(AddressableAssetEntry entry)
        {
            if (_addressesToEntry.TryGetValue(entry.address, out var entryList) == false)
            {
                entryList = new List<AddressableAssetEntry>(1);
                _addressesToEntry.Add(entry.address, entryList);
            }

            entryList.Add(entry);
        }

        public static List<AddressableAssetEntry> FindEntry<T>(string address) where T : Object
        {
            if (_addressesToEntry.TryGetValue(address, out var entryList) == false)
                return null;

            var foundList = new List<AddressableAssetEntry>();

            foreach (var entry in entryList)
            {
                var p = entry.AssetPath;

                if (AssetDatabase.GetMainAssetTypeAtPath(p) == typeof(T))
                    foundList.Add(entry);
            }

            return foundList;
        }

        public static T FindFirstEntry<T>(string address) where T : Object
        {
            var entries = FindEntry<T>(address);

            if (entries == null || entries.Count < 1)
                return null;

            return AssetDatabase.LoadAssetAtPath<T>(entries[0].AssetPath);
        }

        #region Variables

        private static Dictionary<string, List<AddressableAssetEntry>> _addressesToEntry = new Dictionary<string, List<AddressableAssetEntry>>(2048);

        #endregion
    }
    #endif

}
2 Likes

Be careful! This will break your Addressables Settings if you update your unity version or share your project excluding the library folder (when using Version Control for example).

I changed the Constructor to be initialized by myself and not on load, if you do that it’s shareable.