Cannot traverse asset directory in Android?

:bust_in_silhouette: Reply From: jgodfrey

Interesting - I just stumbled into a similar situation after writing a Singleton AudioManager. In my case, I wanted to load a bunch of OGG files at runtime - similar to what your attempting to do. While the resources were properly loaded while running in-editor, they did not load when running in an exported build (Android or PC in my case).

After a lot of poking around, I discovered that the problem lies in the way resources are packaged into the build. They are not left in their original locations and they do not have their original names - which will trip up some of your code. Specifically, I think this code is likely failing in your case:

if filename.ends_with(".png"):

If you actually debug this on an Android device, you’ll see the folder you’re iterating does not contain the files you expect. It’ll only contain a variation of those file names that ends with .import. So, for example, if the folder originally contained a file named image.png, it will now contain one named image.png.import. The real image will have been moved to the .import folder, and will have been renamed to something like image.png.<hash>.<ext>

Where <hash> is some hash or GUID and <ext> is some other file extension.

Interestingly, Godot’s ResourceLoader.load() command knows how to deal with the mapping from original folder / original filename to new folder / new filename.

So, even in the face of the above example, you can still do a ResourceLoader.load("res://assets/images/words/image.png") and Godot will happily load the file you intended.

So, if you can get appropriate file names to the resource loader, things will work as expected.

However, you’re not getting that far as (I think) your code is failing at the point where it checks for a “png” extension, because there is no file there with a png extension.

So, how do you fix it?

Assuming that you ultimately load the resources via the resource loader, I’d guess something as simple as this might fix the issue:

    while (filename != ""):
        filename = filename.replace('.import', '') # <--- remove the .import
        if filename.ends_with(".png"):

Essentially, that just removes the “.import” from the end of the filename that was found in the folder, which should return the name your code is expecting. Assuming you eventually tell the ResouceLoader to load the files, giving it that original name should work, even though it’ll need to work some magic in the background to follow the folder and name mapping outlined above.

A similar change to my AudioManager’s loading mechanism fixed my runtime resource loading issues.

Great explanation and working solution.

blurrred | 2023-03-30 12:22

1 Like