Preload and Instantiate by Asset Name

I preload my assets and add them into an dictionary by their name:

string name = op.ToString();
_PreviewAssetsDict.Add(name, op);

Then I instantiate them inside a placeholder object that holds a AssetReference

GameObject newPreview = Instantiate(_PreviewAssetsDict[assetName], preview.transform, false);

This runs fine in the editor, however “editorAsset” is not available at runtime in the real app.

It seems that there is no way to get the name from the AssetReference(which is a bit ridiculous tbh)

Is there any other way to achieve this LoadAssetsAsync-Callback to AssetReference connection?

just a minor correction from the code above:
string name = op.ToString();
should be:
string name = op.name;

I could not edit the post above because of a false spam detection :confused:

You’ll have to build another lookup table (guid → name) when you build your assets, or inherit from AssetReference and store the name there, and use that everywhere instead of AssetReference. Yeah, it’s not ideal…

Thanks for the input, I already tried to solve it in a similar way by executing a script in the editor to save the name in a separate variable, that failed because this would require a static array, what I do not want.

The ideal case would be that the editor fills out the name variable as soon as I choose the Assetreference in my Array of stats.

Do you have further advice or how to execute code when I build assets?

Thanks!

I do this for a version lookup based on labels, but you can adapt it for name lookups. I created an addressables build script so when I runs, it generates the table and serializes it to a .txt asset and turns it into an addressable before the addressables build actually runs. Then when I initialize addressables, I load that .txt asset and deserialize it back into the lookup table so that I can look up the versions synchronously.

Yours doesn’t have to be this complicated. I did this because I have to work with multiple catalogs (my old version just wrote the lookup table to StreamingAssets, but it’s the same idea).

#if UNITY_EDITOR
        public static AssetVersionDictionary Create()
        {
            AssetVersionDictionary versionDictionary = new AssetVersionDictionary();

            var settings = UnityEditor.AddressableAssets.AddressableAssetSettingsDefaultObject.Settings;

            if (settings == null) return versionDictionary;

            foreach (var group in settings.groups)
            {
                foreach (var entry in group.entries)
                {
                    foreach (var label in entry.labels)
                    {
                        versionDictionary.TryAdd(entry.address, label);
                    }
                }
            }
            return versionDictionary;
        }
#endif
[InitializeOnLoad]
public static class AssetVersionGenerator
{
    [MenuItem("Build/Build Addressables")]
    public static void BuildAddressables()
    {
        // Generate lookup table for build.
        GenerateVersionLookup();
        UnityEditor.AddressableAssets.Settings.AddressableAssetSettings.BuildPlayerContent();
    }

    static AssetVersionGenerator()
    {
        EditorApplication.playModeStateChanged += EditorApplication_playModeStateChanged;
    }

    private static void EditorApplication_playModeStateChanged(PlayModeStateChange obj)
    {
        if (obj == PlayModeStateChange.ExitingEditMode)
        {
            // Make sure lookup table is generated for play mode in editor.
            GenerateVersionLookup();
        }
    }

    public static void GenerateVersionLookup()
    {
        var settings = UnityEditor.AddressableAssets.AddressableAssetSettingsDefaultObject.Settings;

        // Generate TextAsset
        string json = AssetVersionDictionary.Create().Serialize().ToString();

        string versionDir = Application.dataPath + "/GeneratedAssets/Text/";
        Directory.CreateDirectory(versionDir);
        File.WriteAllText(versionDir + "addressable-versions.txt", json);
        AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);

        string versionGUID = AssetDatabase.AssetPathToGUID("Assets/GeneratedAssets/Text/addressable-versions.txt");

        var group = settings.FindGroup("Generated");
        if (group == null)
        {
            // Create a read-only group if it doesn't already exist.
            group = settings.CreateGroup("Generated", false, true, true, settings.DefaultGroup.Schemas);
        }
        // Make text asset addressable in the "Generated" group.
        settings.CreateOrMoveEntry(versionGUID, group, true).address = "addressable-versions";
        AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
    }
}
1 Like

Thanks, that means a bunch :slight_smile:

edit, my solution for building the lookup table in a jsonfile

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

[InitializeOnLoad]
public static class BuildAddressableLookupTable
{

    [System.Serializable]
    public class addressableGUIDName
    {
        public string guid;
        public string name;
    }
    [System.Serializable]
    public class addressableGuidNameList
    {
        public List<addressableGUIDName> GuidNameData;
    }
    static BuildAddressableLookupTable()
    {
#if UNITY_EDITOR

        addressableGuidNameList addressableListObject = new addressableGuidNameList();
        addressableListObject.GuidNameData = new List<addressableGUIDName>();
        var settings = UnityEditor.AddressableAssets.AddressableAssetSettingsDefaultObject.Settings;

        foreach (var group in settings.groups)
        {
            foreach (var entry in group.entries)
            {
                    addressableGUIDName newitem = new addressableGUIDName();
                    newitem.name = entry.address.ToString();
                    newitem.guid = entry.guid.ToString();
                    addressableListObject.GuidNameData.Add(newitem);
            }
        }
        string json = JsonUtility.ToJson(addressableListObject, true);
        Debug.Log(json);

        File.WriteAllText(Application.persistentDataPath + "/assetLookupTable.json", json);
#endif
    }
}
1 Like