Search Unity

Best way of dynamically loading assets for procedural content

Discussion in 'Editor & General Support' started by ArtyBoomshaka, Jan 13, 2020.

  1. ArtyBoomshaka

    ArtyBoomshaka

    Joined:
    Mar 5, 2013
    Posts:
    226
    Heya,

    I've been working with procedural generation and while prototyping I was using the Resources API.

    I'm now running into the limitations of my dirty prototyping code that relies on Resources.LoadAll to only choose one asset of such a subset which is obviously horrendous performance-wise.

    So, I'm looking for the best way of seeking through assets organized hierarchically and loading them at run time.
    I have a collection of assets organized in subdirectories at varying depth so for a specific type of assets I'll need to search all levels for the asset type or some subcategory.

    I've looked into AssetBundles and Addressables but as far as I can tell there's no way of looking at paths kinda like files and directories and using them requires prior knowledge of the topography of the contents?

    Do I need to roll out my own indexing system on top of either system to achieve what I'm looking for?

    Thanks for your help!
     
  2. MSplitz-PsychoK

    MSplitz-PsychoK

    Joined:
    May 16, 2015
    Posts:
    1,278
    The folder structure of your files gets lost when you build the game. The StreamingAssets folder is left as-is in your built project, but those files will be accessible and modifiable to users.

    I recommend using ScriptableObjects to organize your assets. A ScriptableObject is like a monobehaviour that doesn't attach to a GameObject or belong to a scene, and sits as an asset in your project folder. You could write a single ScriptableObject class and instantiate multiple copies to represent your different content categories and store references to them. https://docs.unity3d.com/Manual/class-ScriptableObject.html


    Here's an example.
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. [CreateAssetMenu(fileName = "AssetCategory", menuName = "Data/AssetCategory", order = 0)]
    4. public class AssetCategory : ScriptableObject
    5. {
    6.  
    7.     public Sprite[] spriteAssets;
    8.     public AudioClip[] audioAssets;
    9.  
    10. }
    11.  
    That will add a new "create" option when you right-click in the asset folder.
    upload_2020-1-13_11-42-26.png

    You can then assign references to your new asset like you could with a monobehaviour.
    upload_2020-1-13_11-46-16.png

    Objects in your scene can store references to your ScriptableObjects for easy access.
     
  3. ArtyBoomshaka

    ArtyBoomshaka

    Joined:
    Mar 5, 2013
    Posts:
    226
    Thanks for your input!
    I knew about ScriptableObjects but I fail to see how that can be useful in my use case.

    For instance I have a bunch of AudioClips organized in different levels of directories. I need to somehow keep the hierarchical meta data encoded in the path and references to the clips without actually loading them all in memory.
     
  4. MSplitz-PsychoK

    MSplitz-PsychoK

    Joined:
    May 16, 2015
    Posts:
    1,278
    Ahh sorry, I misunderstood your problem, I thought you were simply looking for a different way to organize and reference your assets. It looks like there aren't any simple solutions to your problem, but someone wrote an editor script that auto-updates a ScriptableObject with data about your resource folder so the information is available at runtime. https://answers.unity.com/questions...runti.html?childToView=1133114#answer-1133114
     
  5. ArtyBoomshaka

    ArtyBoomshaka

    Joined:
    Mar 5, 2013
    Posts:
    226
    No problem! ^^
    Yeah, I had something like that in mind. Hard to imagine this is still the only option to keep that kind of information at runtime.
    I had great hope with the new Addressables system, the documentation is confusing enough that surely I would have missed some things...
     
  6. RakNet

    RakNet

    Joined:
    Oct 9, 2013
    Posts:
    315
    The new addressables system has two major flaws that made it so we couldn't effectively use it, but it might work for some
    1. If your game uses DLLs, you can't make builds. I reported this over a year ago and subsequently on multiple occasions. It appears to be fixed if you want to use Unity 2020 beta
    2. You can't load assets synchronously, as in if (condition) prefab = LoadAsset(). Instead, you have to use IEnumerator and wait until the next frame. For established games this is a huge architectural roadblock.
     
    osamuede75 likes this.