Search Unity

Resources.Load randomly returns null on existing files

Discussion in 'Scripting' started by bitinn, Jun 28, 2017.

  1. bitinn

    bitinn

    Joined:
    Aug 20, 2016
    Posts:
    961
    Hi all,

    This is driving me crazy, but I encounter a case where Resources.Load() randomly can't find a file that's 100% in the path.

    My code looks like this:

    Code (CSharp):
    1.         /*
    2.             Load a map file
    3.         */
    4.         private static string LoadMapFile (string mapPath) {
    5.             var mapFile = Resources.Load(mapPath) as TextAsset;
    6.  
    7.             if (mapFile == null) {
    8.                 throw new MapFileNotFoundException(mapPath);
    9.             }
    10.  
    11.             if (string.IsNullOrEmpty(mapFile.text)) {
    12.                 throw new EmptyMapFileException(mapPath);
    13.             }
    14.  
    15.             return mapFile.text;
    16.         }
    I call this in a loop as I am loading multiple map files.

    And it failed randomly with MapFileNotFoundException, I can verify the paths are right, and it doesn't fail at a certain map file, but randomly.

    (I can put the files out of resources folder and use File.ReadAllText to load them without issues, however that won't work with Unity build as my map files are not referenced by GameObject directly.)
     
    kingslayer005 likes this.
  2. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    let's see the loop then
     
  3. bitinn

    bitinn

    Joined:
    Aug 20, 2016
    Posts:
    961
    It's a dead simple for loop.

    Code (CSharp):
    1.         private IEnumerator RenderMap (string[,] overviewMap) {
    2.             for (int y = 0; y < overviewMap.GetLength(1); y++) {
    3.                 for (int x = 0; x < overviewMap.GetLength(0); x++) {
    4.                     var sector = LoadSector(overviewMap[x,y]);
    5.  
    6.                     yield return RenderSector(
    7.                         sector, new Vector3(_sectorSize * x, 0, -1 * _sectorSize * y)
    8.                     );
    9.                 }
    10.             }
    11.         }
    LoadSector calls LoadLayer calls LoadMapFile.

    (and yes I have tried removing coroutines as well, they are not relevant to my problem.)
     
  4. bitinn

    bitinn

    Joined:
    Aug 20, 2016
    Posts:
    961
    Let me will give you the LoadSector and LoadLayer for reference as well:

    Code (CSharp):
    1.         private int[,] LoadSector (string mapName) {
    2.             return MapReader.LoadLayer(
    3.                 String.Format("sector-{0}", mapName), _mapLayerName
    4.             );
    5.         }
    Code (CSharp):
    1.         /*
    2.             Read a map layer
    3.         */
    4.         public static int[,] LoadLayer (string mapName, string layerName) {
    5.             var mapPath = CreateMapPath(mapName);
    6.             var mapFile = LoadMapFile(mapPath);
    7.             var parsedMapFile = ParseMapFile(mapFile, mapPath);
    8.             var mapData = ExtractMapLayer(parsedMapFile.layers, layerName, mapPath);
    9.  
    10.             return mapData;
    11.         }
     
  5. bitinn

    bitinn

    Joined:
    Aug 20, 2016
    Posts:
    961
    I can place my files in the StreamingAssets folder with this LoadMapFile, and it will work without throwing any errors.

    (Obviously I need to change the file name to include my file extension as well, as Resources.Load doesn't take file extension.)

    Code (CSharp):
    1.         /*
    2.             Load a map file
    3.         */
    4.         private static string LoadMapFile (string mapPath) {
    5.             if (!File.Exists(mapPath)) {
    6.                 throw new MapFileNotFoundException(mapPath);
    7.             }
    8.  
    9.             var mapFile = File.ReadAllText(mapPath);
    10.  
    11.             if (string.IsNullOrEmpty(mapFile)) {
    12.                 throw new EmptyMapFileException(mapPath);
    13.             }
    14.  
    15.             return mapFile;
    16.         }
     
  6. CrystalConflux

    CrystalConflux

    Joined:
    May 25, 2017
    Posts:
    107
    Files under a Resource folder have a path relative to the Resource folder. Could that be the problem?

    Edit:
    Hmm I see you said it happens randomly, not just to a specific asset. In that case, this probably isn't it.
     
    Last edited: Jun 28, 2017
  7. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    If, say, Resources.Load( a_path ); returns null, can you make sure that there is actually a file at a_path inside Resources folder in Unity editor? Because if you put some files inside Resources folder runtime, Resources.Load doesn't work for these files.
     
  8. bitinn

    bitinn

    Joined:
    Aug 20, 2016
    Posts:
    961
    Yes I can confirm they are static json, just sitting there. I didn't generate them at runtime.
     
  9. Nidhii

    Nidhii

    Joined:
    Jan 28, 2015
    Posts:
    26
    were you able to solve it? I am facing same problem. All files are static, Paths are correct but its returning null on random files.
     
  10. bitinn

    bitinn

    Joined:
    Aug 20, 2016
    Posts:
    961
    I can't remember how I solved it, but I also stopped using Resource folder, see best practice:

    https://unity3d.com/learn/tutorials/topics/best-practices/resources-folder

    It always feel awkward that file extensions are ignored when loading resources, most of my map data are now either ScriptableObject fields or JSON file being referenced by ScriptableObject.