Bundle with the same files is already loaded Editor vs Playmode

I am currently using addressables in editor and in playmode. Yes it isn’t mentioned once in the docs, but there is a forum post somewhere that links to a changelog where there is a note about that working. I do this to setup fonts, which need setup during edit time, but also during runtime. Yes TMPro still does not support addressables, I can’t fathom why, but no matter, I got that more or less working. My main problem is that Addressables/Asset Bundles seems unable to recognize when a requested asset/bundle/dependency is already loaded, resulting in the error above. It happens on entering/exiting playmode, so I think addressables separates between the two, but it doesn’t do it cleanly, otherwise the error above wouldn’t happen. In this case it’s the tmpro shaders, which are in their own addressable group so as not to be duplicated between each group that uses tmpro components/contains fonts. I have tried a bunch of things:

  • releasing all the addressables on enter playmode
  • releasing all asyncOperation handles
  • messing with the unloading dictionary
  • Unloading all asset bundles
  • Unloading all unused resources

But nothing seems to take. Maybe it is because the shaders are a pure dependency and never directly loaded, maybe it is because they are shaders, maybe it doesn’t matter and it would always break when trying to enter playmode after using addressables. I am unable to put even more time into this, there obviously seem to be some bugs attached to this, so for now I will refrain from using addressables in edit mode and try and figure out a more stable solution using the asset database. But I do have a couple of questions (besides reporting that this isn’t working):

  • Is using addressables in edit mode supported? The changelog says yes, the completely absent documentation and the fact that it breaks instantly when entering playmode (and trying to load the same asset again) speaks a clear no. So which is it?

  • Why is it even a problem to try and load an assetbundle with files that are already in a loaded bundle? In addressables a file can only ever be in one group, so obviously we are trying to load the same group, so just give me the already loaded stuff? And even if that wasn’t the case, you have already figured out that the exact file I am requesting is already loaded, so why not just give me that exact same file? Why is that a problem?

  • How come nearly no other system/package in unity is supporting addressables (with the exception of Localization)? It really is not a new system (with more than half a decade of released time under its belt), so why is it not adopted by unity itself more widely?

Sorry if I sound frustrated, but I spent quite some time with addressables lately and sometimes it works nicely but an inordinate amount of my time was used up by slogging through contradicting information with no explanation of the differences/intentions/current state(for example loading&unloading - even in the official doc), having no information at all (use in editor, use in packages, multiple catalogues in a single project, etc.) and looking at weird bugs or “not supported” messages.

out of curiosity, what do you mean you are using addressables in edit mode? are they built and loaded in from some external project? why would you do that?

Why wouldn’t I? I am loading & unloading a resource that I only need at specific moments. Which resource I need depends on how my stylesheets and configuration files are set up. Yes I can load these files during edit time via the asset database (if they are in project), but since I have the bundles anyway and it gives me (at least in theory) the option to not need all assets in the project at all times, why do the gymnastics to find all addressable assets, iterate through all keys and load the needed ones via asset database? All the linkup and code I need should already be there? Also we have a many vs many relation in terms of packages and projects, so it could be a nice option to only include the real assets if they should be worked on (although that is not as straightforward to achieve)

Alas, all of this isn’t properly supported/bugged, which is why I re-implemented the second code path to load everything via Asset Database in edit mode.

It seems very confusing what you are trying to do, but if I understand correctly, your theory is to load assets into your project through an external addressable, and then make changes to them? That is not going to be possible. I dont see any reason to have external addressables loaded into edit mode unless you were trying to do that.

If that is what you are wanting to do, there are other non addressable things you can do to accomplish something like that I could go into if that is what you are trying to do.

If they are in your project and will always be in your project, then theres nothing you need to do with addressables, they are just there.

I’ll stop commenting on this if you want to stick with your current method so others can reply. My next response would be digging into why you are doing this and other methods to accomplish what your goal is.

Our project is using Addressables in Edit mode. The problem I ran into was Addressables tried to load assets from asset bundles after entering Play Mode once with “Use Existing Build” enabled. I expect it to load from asset database directly. So I wrote a script to ensure it:

public class AddressablesEditorModeScope : IDisposable
{
    private readonly static string DefaultSettingsAsset
        = "Assets/AddressableAssetsData/AddressableAssetSettings.asset";

    private readonly string oldValue;

    public AddressablesEditorModeScope()
    {
        if (!EditorSettings.enterPlayModeOptionsEnabled)
            throw new Exception("'Enter Play Mode Options' is not enabled, Addressables will not reinitialize");

        var settings = AssetDatabase.LoadAssetAtPath<ScriptableObject>(DefaultSettingsAsset) as AddressableAssetSettings;
        if (settings == null)
            throw new Exception("Asset not exist: " + DefaultSettingsAsset);

        var field = typeof(Addressables).GetField("reinitializeAddressables", BindingFlags.NonPublic | BindingFlags.Static);
        if (field != null)
            field.SetValue(null, true);

        string path = AssetDatabase.GetAssetPath(settings);
        string guid = AssetDatabase.AssetPathToGUID(path);

        if (PlayerPrefs.HasKey(Addressables.kAddressablesRuntimeDataPath))
            oldValue = PlayerPrefs.GetString(Addressables.kAddressablesRuntimeDataPath);

        PlayerPrefs.SetString(Addressables.kAddressablesRuntimeDataPath, $"GUID:{guid}");
    }

    public void Dispose()
    {
        if (oldValue == null)
            PlayerPrefs.DeleteKey(Addressables.kAddressablesRuntimeDataPath);
        else
            PlayerPrefs.SetString(Addressables.kAddressablesRuntimeDataPath, oldValue);

        var field = typeof(Addressables).GetField("reinitializeAddressables", BindingFlags.NonPublic | BindingFlags.Static);
        if (field != null)
            field.SetValue(null, true);
    }
}

Example:

void ExecuteToolInEditMode()
{
    using var scope = new AddressablesEditorModeScope();
    Addressables.InitializeAsync().WaitForCompletion();

    // Load assets using Addressables
    var handle = Addressables.LoadAssetAsync<TextAsset>(path);
    handle.WaitForCompletion();

    // ...
    
    Addressables.Release(handle);
}

Tested with Unity 2020.3 and Addressables 1.19.19~1.21.12