Hello Everyone, i am searching a way to mark an prefab as addressable and also to set the id through C#. I can't find anything. Does anyone have a clue? I would be thankfull. Best Regards,
Take a look at how our UI does things. It should be almost exclusively working through public APIs, so you could mimic it. AddressableAssetsSettingsGroupEditor is the main place, but there are lots of spots to look.
After your advise i looked further into it. In my opinion AddressableAssetsSettingsGroupEditor was not a good place to look after. But thank you it leads the way. Then i researched further and AssetInspectorGUI.cs was sounding promising. Then i implemented successfully easier access functions to edit addressable IDs (i will add them on the end for everybody who seeks an similar solution). I also want to mark them as adressables. In AssetInspectorGUI.cs is a function SetAaEntry which does this but it is using AddressableAssetUtility which is not accessable in another context. And i dont want to reimplement the moving of resources to groups and so on. @unity_bill could it be that you have another clue for me? [Following code can be ignored when an better solution come up. This code was created at version 0.8.6 Addressables System] Code (CSharp): public static class AddressableEditorExtension { /// <summary> /// Set Addressables Key/ID of an gameObject. /// </summary> /// <param name="gameObject">GameObject to set Key/ID</param> /// <param name="id">Key/ID</param> public static void SetAddressableID(this GameObject gameObject, string id) { SetAddressableID(gameObject as Object, id); } /// <summary> /// Set Addressables Key/ID of an object. /// </summary> /// <param name="o">Object to set Key/ID</param> /// <param name="id">Key/ID</param> public static void SetAddressableID(this Object o, string id) { if (id.Length == 0) { Debug.LogWarning($"Can not set an empty adressables ID."); } AddressableAssetEntry entry = GetAddressableAssetEntry(o); if (entry != null) { entry.address = id; } } /// <summary> /// Get Addressables Key/ID of an gameObject. /// </summary> /// <param name="gameObject">gameObject to recive addressables Key/ID</param> /// <returns>Addressables Key/ID</returns> public static string GetAddressableID(this GameObject gameObject) { return GetAddressableID(gameObject as Object); } /// <summary> /// Get Addressables Key/ID of an object. /// </summary> /// <param name="o">object to recive addressables Key/ID</param> /// <returns>Addressables Key/ID</returns> public static string GetAddressableID(this Object o) { AddressableAssetEntry entry = GetAddressableAssetEntry(o); if (entry != null) { return entry.address; } return ""; } /// <summary> /// Get addressable asset entry of an object. /// </summary> /// <param name="o">>object to recive addressable asset entry</param> /// <returns>addressable asset entry</returns> public static AddressableAssetEntry GetAddressableAssetEntry(Object o) { AddressableAssetSettings aaSettings = AddressableAssetSettingsDefaultObject.Settings; AddressableAssetEntry entry = null; string guid = string.Empty; long localID = 0; string path; bool foundAsset = AssetDatabase.TryGetGUIDAndLocalFileIdentifier(o, out guid, out localID); path = AssetDatabase.GUIDToAssetPath(guid); if (foundAsset && (path.ToLower().Contains("assets"))) { if (aaSettings != null) { entry = aaSettings.FindAssetEntry(guid); } } if (entry != null) { return entry; } return null; } }
Have You found maybe a way to mark asset as "Adressable" from code? I want to mark every scriptableObject created from script, but I don't know how to do this. Cheers.
I wrote something like this some weeks ago. I have customized my Addressables package a bit, so it's possible that something in this example is inaccessible, but give it a shot. Code (CSharp): [MenuItem("Tools/Refresh Addressables")] public static void RefreshAddressables() { var settings = AddressableAssetSettingsDefaultObject.Settings; var group = settings.DefaultGroup; var guids = AssetDatabase.FindAssets("t:ScriptableObject", new[] {"Assets/ScriptableObjects"}); var entriesAdded = new List<AddressableAssetEntry>(); for (int i = 0; i < guids.Length; i++) { var entry = settings.CreateOrMoveEntry(guids[i], group, readOnly: false, postEvent: false)); entry.address = AssetDatabase.GUIDToAssetPath(guids[i]); entry.labels.Add("MyLabel"); entriesAdded.Add(entry); } settings.SetDirty(AddressableAssetSettings.ModificationEvent.EntryMoved, entriesAdded, true); } Note that this will put them all flat in the default group root. I recommend you make a new group which you then get by changing line 5: var group = settings.FindGroup("My Group") Passing readOnly: true to CreateOrMoveEntry will fade out the entries in the Addressables panel so they can't be manually edited, if so wished. Edit: Since people seem to find my example useful, here's an updated one that clears old entries and labels for easier automation (in my old example, if you move an already registered asset and then run the method again, it will not update its address): Spoiler Code (CSharp): [MenuItem("Tools/Refresh Addressables")] public static void RefreshAddressables() { var settings = AddressableAssetSettingsDefaultObject.Settings; var group = settings.FindGroup("My Group"); var guids = AssetDatabase.FindAssets("t:ScriptableObject", new[] {"Assets/ScriptableObjects"}); var entriesAdded = new List<AddressableAssetEntry>(); for (int i = 0; i < guids.Length; i++) { var entry = settings.CreateOrMoveEntry(guids[i], group, readOnly: false, postEvent: false)); entry.address = AssetDatabase.GUIDToAssetPath(guids[i]); entry.labels.Clear(); entry.labels.Add("MyLabel"); entriesAdded.Add(entry); } foreach (AddressableAssetEntry entry in group.entries.Except(entriesAdded).ToArray()) group.RemoveAssetEntry(entry); settings.SetDirty(AddressableAssetSettings.ModificationEvent.EntryMoved, entriesAdded, true); } But make sure you use a custom group (update line 5 with your group name) for it exclusively since otherwise it would clear out all your manually added entries too.
I suppose this is a bit of a necro-post, but my use case was a little different. As part of a custom editor workflow for a Tilemaps related project I wanted to be able to mark assets addressable from code, just to make workflow easier (ie don't have to remember to tick the box on assets created during the workflow). I wanted something like: public static bool AddAssetToAddressables(Object target, string filter) No deletions, just adding. So I went thru the editor code (HT to Jetbrains' decompiler) and created something that works fine for that use case. But I'm a little confused: I don't believe that I can post it without violating the Unity license as it's derived from editor code. For my own use and not for distribution is a different matter, but can someone from Unity advise on whether it's OK to post it? It's confusing as about a year ago (in this thread) the advice was to inspect editor code... It seems a shame as examples for Addressables don't explain how to do this.
@Jobus Thanks for sharing your code. Though, it seems to be working only on non-scene assets. Is there any way to mark a scene asset as Adressable from code?
@FlorianBernard On line 6 in my example, you need to change the parameters to t:Scene and new[] {"Assets/Scenes"} (or wherever you are storing you scene assets).
@Jobus Thanks for the reply. Though, I just got it working. Not sure what the issue was (but I'm definitely not using AssetDatabase.FindAssets) Here's is the extension code if anyone's interested (make sure you're using it on an asset coming from AssetDatabase.LoadAssetAtPath): Code (CSharp): public static class AddressableExtensions { public static void SetAddressableGroup(this Object obj, string groupName) { var settings = AddressableAssetSettingsDefaultObject.Settings; if (settings) { var group = settings.FindGroup(groupName); if (!group) group = settings.CreateGroup(groupName, false, false, true, null, typeof(ContentUpdateGroupSchema), typeof(BundledAssetGroupSchema)); var assetpath = AssetDatabase.GetAssetPath(obj); var guid = AssetDatabase.AssetPathToGUID(assetpath); var e = settings.CreateOrMoveEntry(guid, group, false, false); var entriesAdded = new List<AddressableAssetEntry> {e}; group.SetDirty(AddressableAssetSettings.ModificationEvent.EntryMoved, entriesAdded, false, true); settings.SetDirty(AddressableAssetSettings.ModificationEvent.EntryMoved, entriesAdded, true, false); } } }