Search Unity

Possibilities to load uss/uxml when distributed as package?

Discussion in 'UI Toolkit' started by CxydaInno, Jun 5, 2020.

  1. CxydaInno

    CxydaInno

    Joined:
    Sep 5, 2017
    Posts:
    14
    Hey guys!
    First let me say that I was REALLY looking forward to use UIElements and the new System ... it's awesome!

    After I had my first dive into UIElements and built my first UIs with it i decided to build an UI for an Editor tool I've built with it. I did specify the paths to the uss / uxml files by hardcoding them and loading them via the AssetDatabase like this

    Code (CSharp):
    1.          
    2. string path = "Assets/MyAwesomeTool/Editor/EntityTypeDefinitionEditor";
    3.  
    4. _visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset> (Path.Combine(path, "EntityTypeDefinitionTemplate.uxml"));
    5.  
    6. StyleSheet styleSheet = AssetDatabase.LoadAssetAtPath<StyleSheet> (Path.Combine(path,
    7.                       "EntityTypeDefinitionStyle.uss"));
    8.  
    but of course this breaks as soon as I distribute my tool as a package via GitHub (or the AssetStore)

    How can I specify the paths more solid to also work from folders not inside the Asset folder (like for packages e.g. ./Library/PackageCache/de.oma.tools.myawesometool@8f41bd4884/Editor/EntityTypeDefinitionEditor/EntityTypeDefinitionStyle.uss)

    I'm using 2019.3.14 / UIBuilder 0.11.2

    Thanks for your help!

    Best, Cxyda
     
    Last edited: Jun 5, 2020
  2. CxydaInno

    CxydaInno

    Joined:
    Sep 5, 2017
    Posts:
    14
    As always ... you find the solution yourself right after you posted the question on the internet :mad:

    What i did:
    Code (CSharp):
    1.      
    2. public static T LoadFirstAssetByFilter<T>(string assetFilter,  string[] searchInFolders = null) where T : UnityEngine.Object
    3. {
    4.      var guids = AssetDatabase.FindAssets(assetFilter, searchInFolders);
    5.      if (guids.Length > 0)
    6.      {
    7.           var assetPath = AssetDatabase.GUIDToAssetPath(guids[0]);
    8.           return AssetDatabase.LoadAssetAtPath<T>(assetPath);
    9.      }
    10.  
    11.      Debug.LogError($"Unable to find asset '{assetFilter}'");
    12.  
    13.      return null;
    14. }
    15.  


    Is there an even better way ?
     
    Last edited: Jun 5, 2020
  3. silenterus

    silenterus

    Joined:
    Nov 8, 2019
    Posts:
    10
    as far as i know you can access the package folder with
    Code (CSharp):
    1. AssetDatabase.LoadAssetAtPath<T>("Packages/de.oma.tools.myawesometool/Editor/EntityTypeDefinitionEditor")
    Even if your package folder is named "MyAwesomeTool" you need to use "de.oma.tools.myawesometool"
     
  4. ErnestSurys

    ErnestSurys

    Joined:
    Jan 18, 2018
    Posts:
    94
    Just put your assets into a Resources folder and use the
    Resources.Load(relativePath)
    .
     
    NamelessPerson likes this.
  5. CxydaInno

    CxydaInno

    Joined:
    Sep 5, 2017
    Posts:
    14
    hey there !Thanks for the answers!

    putting it to a Resources would include my Editor UIs always into the builds right? This is unfortunately no option then :(

    Thanks silenterus i will try that !
     
    Last edited: Jun 5, 2020
  6. ErnestSurys

    ErnestSurys

    Joined:
    Jan 18, 2018
    Posts:
    94
    No, If the Resources folder is inside the Editor folder it will be ignored. Docs
     
    CxydaInno and NamelessPerson like this.
  7. Unity_Javier

    Unity_Javier

    Unity Technologies

    Joined:
    Mar 7, 2018
    Posts:
    190
    Hey, the AssetDatabase.FindAssets() is generally the most used approach, but that does traverse the entire project which, after a certain size, can get a bit heavy to do.

    If you're confident that your asset is immutable, you could hardcode the GUID for it and load it similar to your example.

    To find the GUID of an asset, you can look in its corresponding .meta file.

    So, if for example you have the com.unity.2d.animation package installed, inspecting the .meta file for dotYellow.png and dotCyan.png gives these 2 GUIDs:
    173a5eb1d13d68d4ea39f3e5d2c6e2c0
    5b56cb1a6bd97f348b3a3b6f875aafd6

    Then, expanding your example:

    Code (CSharp):
    1.     [MenuItem("AssetDatabase/Immutable GUIDs")]
    2.     public static void LoadAssetsFromKnownGUIDs()
    3.     {
    4.         var textures = LoadMyAssets<Texture2D>(new[] { "173a5eb1d13d68d4ea39f3e5d2c6e2c0", "5b56cb1a6bd97f348b3a3b6f875aafd6" });
    5.  
    6.         foreach (var curTexture in textures)
    7.         {
    8.             Debug.Log($"Texture: {curTexture.name}, width:{curTexture.width}, height:{curTexture.height}");
    9.         }
    10.     }
    11.  
    12.     public static T[] LoadMyAssets<T>(string[] guids) where T : UnityEngine.Object
    13.     {
    14.         T[] assets = new T[guids.Length];
    15.         if (guids.Length > 0)
    16.         {
    17.             int i = 0;
    18.             foreach (var curGUID in guids)
    19.             {
    20.                 var assetPath = AssetDatabase.GUIDToAssetPath(curGUID);
    21.                 assets[i] = AssetDatabase.LoadAssetAtPath<T>(assetPath);
    22.                 ++i;
    23.             }
    24.         }
    25.  
    26.         return assets;
    27.     }
    Is another approach with some different requirements, but it would scale with project size :)
     
  8. MaskedMouse

    MaskedMouse

    Joined:
    Jul 8, 2014
    Posts:
    1,092
    Another way of getting the GUID is to read it out directly from the AssetDatabase using another tool.
    I found myself hardcoding GUIDS often for loading assets that are in the project / package that I make myself.

    I made a simple Editor tool that has an object field, just drag drop the asset in there and request the GUID using
    AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(ObjectField));

    And for a copy button you can use
    EditorGUIUtility.systemCopyBuffer = guid;


    Maybe ever, unity will provide a way in the inspector to get / copy the GUID?
     
    Unity_Javier likes this.