Resources.load only working in editor

So I’ve seen posts related to this but I didn’t find out why it happens or how to fix it. I’m creating a VR app and I’m using Resources.load for some sprites. To be fair, I have used this exact method in another app that I made for mobile devices and everything works fine there. But basically, when I’m testing my vr app in the editor, pictures are loaded. But not after I build it on the headset. Is there any size limit on how much we can put in Resources folder? Thanks.

I would include more of the code if it was necessary but it works in editor so i don’t think i have a code issue.

theImagePlaceHolderMR.sprite = Resources.Load<Sprite>(fileName);

The point of Resources.Load() is that it always works, assuming you meet all the requirements.

The next thing is to find out what that “fileName” is in the running app, and also to find out if the above code is even executed.

You must find a way to get the information you need in order to reason about what the problem is.

What is often happening in these cases is one of the following:

  • the code you think is executing is not actually executing at all
  • the code is executing far EARLIER or LATER than you think
  • the code is executing far LESS OFTEN than you think
  • the code is executing far MORE OFTEN than you think
  • the code is executing on another GameObject than you think it is
  • you’re getting an error or warning and you haven’t noticed it in the console window

To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.

Doing this should help you answer these types of questions:

  • is this code even running? which parts are running? how often does it run? what order does it run in?
  • what are the values of the variables involved? Are they initialized? Are the values reasonable?
  • are you meeting ALL the requirements to receive callbacks such as triggers / colliders (review the documentation)

Knowing this information will help you reason about the behavior you are seeing.

If your problem would benefit from in-scene or in-game visualization, Debug.DrawRay() or Debug.DrawLine() can help you visualize things like rays (used in raycasting) or distances.

You can also call Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene manually, looking for all the parts, where they are, what scripts are on them, etc.

You can also call GameObject.CreatePrimitive() to emplace debug-marker-ish objects in the scene at runtime.

You could also just display various important quantities in UI Text elements to watch them change as you play the game.

If you are running a mobile device you can also view the console output. Google for how on your particular mobile target, such as this answer or iOS: How To - Capturing Device Logs on iOS or this answer for Android: How To - Capturing Device Logs on Android

Another useful approach is to temporarily strip out everything besides what is necessary to prove your issue. This can simplify and isolate compounding effects of other items in your scene or prefab.

Here’s an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:

1 Like

Thank you Kurt, like always. Fair enough. I did more testing (can be seen in the messy code). Should have realized (System.IO.Directory.EnumerateFiles(“Assets/Resources/” + path).Count())/2; isn’t going to work after build.

public void UpdateImageCT()
    {

        // string fileName = "Medical images/1.1 P20/CT/Bone/CT Bone (2)";
        // theImagePlaceHolderCT.sprite = Resources.Load<Sprite>(fileName);
        // Debug.Log(fileName);
        // TMPReport.text = fileName;

        // vrUISliderCT = GetComponent<Slider>();
        TMPReport.text = "Update CT image called";
        string pNModel = transform.parent.parent.GetComponent<MedicalImageViewerDataHolder>().patientNModel;
        // string imgType = transform.name.Replace("Slider", "");
        string imgType = "CT";
        TMPReport.text = "2";
        path = "Medical images/" + pNModel + "/" + imgType + "/" + CTseries;
        Debug.Log("Path is: " + path);
        int count = (System.IO.Directory.EnumerateFiles("Assets/Resources/" + path).Count())/2;
        Debug.Log("Count is: " + count);
        TMPReport.text = "3";
        // TMPReport.text = transform.parent.parent.name;
        vrUISliderCT.maxValue = count;
        vrUISliderCT.minValue = 1;
        TMPReport.text = "4";

        theImagePlaceHolderCT.sprite = null;    
        TMPReport.text = "5";    

        if(theImagePlaceHolderCT.gameObject.activeSelf)
        {
            TMPReport.text = "6";
            // vrUISlider = GetComponent<Slider>();
            i = (int)vrUISliderCT.value;
            // i = 1;
            string fileName = path +"/CT " + CTseries.Replace("Series ", "") + " (" + i.ToString() + ")";
            TMPReport.text = "7";
            // TMP.text = fileName;
            Debug.Log("File name is: " + fileName);
            theImagePlaceHolderCT.sprite = Resources.Load<Sprite>(fileName);
            TMPReport.text = fileName;
        }
    }
1 Like

Wow, yeah, that wouldn’t make anyone down in the Resources.Load() boiler room happy. :slight_smile:

Unfortunately there’s no way (that I know of) to enumerate what you do have.

You can trivially make an editor script to create a text file directory at build time (or under tool control), basically a manifest of what could possibly be Resource.Load-ed

is it a bad idea to do something like this:

public static int TotalImgCount(string path)
    {
        UnityEngine.Object[] imgs = Resources.LoadAll(path);
        totalImgCount = imgs.Length;
        Resources.UnloadUnusedAssets();
        return totalImgCount;
    }

And then call it instead of enumerateFiles…?
I mean even unloading I don’t think is necessary since this is an image viewer with a slider so if I want to activate the viewer, I need the images to be loaded.

hey I just wanted to say, every now and then I read help-wanted posts but I can never help them. But once I can, I promise i’ll give as much (hopefully more) help as you’ve given me to others!

1 Like

Just understand that it WILL try to load all the objects from that path at the same time and it WILL require the maximum amount of memory. This may or may not matter in your context.

Also, never use Resources.LoadAll() unless you just want a blob of everything: images, text files, meshes, anything it can find in that directory.

Always use Resources.Load<T>(), never use Resources.Load() as T

https://discussions.unity.com/t/847547/4

And the same goes for Resources.LoadAll<T>()

1 Like

I once made the ResourceDB over here that did exactly that. It creates a ScriptableObject and stores all resources files (and even folder information) in a linear list of resource items so this metadata is available at runtime. Though I have to say I haven’t looked at this code for ages, so I can’t tell if it still works ^^.

1 Like

That’s pretty spiffy. If I read it correctly, it isn’t storing actual references to the items, just their names for use in the Load() method… am I seeing that right? I like the overall design.

ResourceDB smells like a far more useful version of my poor-man’s GameObjectCollection thingy, which I use everywhere, but it’s just a list-o-stuff: load it and you get EVERYTHING.

https://gist.github.com/kurtdekker/68b3fd9d4202888b4afc17b32eed6790

I think I shall throw a link to your above article into the comments for GOC.

Exactly. The main point was that resources that are not referenced can actually be unloaded / doesn’t need to be loaded by Unity. So we can avoid things like LoadAll because some people had like 5k+ assets and loading them all would be a bad idea.

It actually stores the file and folder names inside all resources folders and some other metadata like the file extension and the actual type of the asset.

The linear list of resource items was a workaround to avoid the usual nesting issues when it comes to serialization. However since we have now SerializeReference this could be simplified as we could store the actual hierarchy directly since Unity itself does a similar thing behind the scenes.

1 Like