Help with : Resources, dynamic subfolder name grabbing/searching?

Hello all.
Thank you in advance for any assistance.

I’m attempting to create a dynamic Resources subfolder searcher. The point is to load sprites within subfolders in a dynamic way. ( As well as name the Library.sections after the folder they are located in )

So, again.
I have a library, that I want to populate with sections named after the subfolders which themselves contain the images that will be a part of that section.
I need to access the subfolders, and I’m not sure how to do that dynamically.

Now. I know that when built, the Assets are packaged into a datafile. So I can’t just get there using System.IO. So, that just stumps me more.

Here’s what I want.

Search through : Resources/ImageLibraryFolder/* multiple sub folders / multiple sub sprite files
returns : string[ ] where each string = sub Folder name.

then use those sub folder names to access those folders, and assign the sprites from there.
Resources.LoadAll<Sprite>( path: "ImageLibraryFolder/" + string_*)*_
_*...*```_
_*Why do I want to do this dynamically? There are a lot of images... and this will take far too much manual labor to do otherwise. Let alone each time the image database is updated.*_
_*I could also use AssetsStreaming? ( I think ) but that apparently has oddnesses with WebGL?*_
_*I really don't know.*_
*Would appreciate any help, or wisdom.*

There isn’t really a way to do this with ‘Resources’. Really all that has happened is that the assets were processed and placed in the data files like you said. When you call “Resources.Load(path)”, path is really just an “id” string associated with that resource. It looks like a path generated from the folder it was in, but it’s not actually in a folder.

What you can do is maybe create an asset which on build (and/or click of a button) searches the file hierarchy and builds the list of folders/names that can then be used at runtime to do what you need.

But as is, Resources doesn’t have the interface to return the needed information. Mainly because Resources is kind of an outdated way to deal with assets and Unity doesn’t appear to pour as much time into it as back in the day.

2 Likes

Thanks Lod that’s incredibly helpful.
Concise answer, everything I could dream for.

I will take that solution. With a small adjustment to do it during Editor runtime as well. Luckily I realise I can store those paths in a ScriptableObject and preserve them.

Excellent stuff.

Right. I’ve engineered a solution.

A combo, of Lod’s suggestion and my needs.

Effectively, I needed to be able to dynamically search Resources folders and extract images catalogued under certain folders. Then also extract those folder names as the names of the sections of this “Image Library”.

Resources doesn’t allow you to do this dynamically normally. So I would otherwise be forced to perform manual connections.

The entire point, is so that my client can easily send me huge numbers of folders with pictures catalogued within them according to the folder name.

Using ScriptableObjects - which remain populated after PlayMode, and upon built - I establish the paths through the project, and cut off everything but the folder names. Then store those names in a directoryInfo : ScriptableObject.
Ensuring, that when built and playing it will instead run off of the established database of paths.

Works like a charm.
Hopefully, someone else can use this to great effect too.

...public void LibraryEstablish()
{

#if UNITY_EDITOR
        _subDirectories = new List<string>(1000);
        _subDirectoriePaths = new List<string>(1000);

        TextAsset[] _locator = Resources.LoadAll<TextAsset>(library_images_path);
        string _path_locator = AssetDatabase.GetAssetPath(_locator[0]);

        if (_locator[0] == null)
            {
            Debug.LogError("ImLibMaster : Locator Null");
            }

        if (debug_log == true)
            Debug.Log("ImLibMaster : Locator " + _locator[0].name + " : " + _path_locator);

        _path_locator = _path_locator.Replace(_locator[0].name + ".txt", "");
        _path_locator = Directory.GetCurrentDirectory() + @"\" + _path_locator;

        _path_locator = _path_locator.Replace(@"/", @"\");
        Debug.Log("ImLibMaster : Locator Path 2 : " + _path_locator);


        _subDirectories.Clear();
        _subDirectoriePaths = new List<string>(Directory.GetDirectories(_path_locator));

        foreach (string _path in _subDirectoriePaths)
            {
            int _pos = 0;
            int _index = 0;
            while (_index < _path.Length)
                {
                if (_path[_index] == '\\')
                    {
                    _pos = _index;
                    }
                _index++;
                }

            string _text = _path.Remove( 0, _pos+1 );

            _subDirectories.Add(_text);
            //string directoryName = new DirectoryInfo(directory).Name;
            //_subDirectories.Add(directoryName); // Currently 0ing
            }

        directoryinfo.paths = _subDirectoriePaths;
        directoryinfo.names = _subDirectories;
#else 
        // If you're out of the Editor. Populate using the 
        Debug.Log("ImLibMaster : Establish : #Else");
        _subDirectories = directoryinfo.names;
        _subDirectoriePaths = directoryinfo.paths;


#endif

for ...
blah blah;
 Resources.Load(_path + _subDirectories[i]); // Dynamically goes through all "folders" even when built.
blah blah

}

Note : I should have it also perform this operation on Build. However I don’t need to at this moment.
Though it will be necessary to facilitate even less unnecissary effort.

Good day.
Luke AP