Search Unity

Resources.FindObjectsOfTypeAll doesn't find everything

Discussion in 'Scripting' started by kattkieru, Aug 17, 2011.

  1. kattkieru

    kattkieru

    Joined:
    Jan 2, 2006
    Posts:
    130
    Hi folks,

    I have a Resources folder, and in it are the following objects:

    mat_generic_tileSet01 (Material)
    prefab_player_generic (prefab)
    prefab_factory_crate01 (prefab)

    Using Resources.FindObjectsOfTypeAll(typeof(GameObject)) and Resources.FindObjectsOfTypeAll(typeof(Material)) do *NOT* always load all objects.

    It seems like this function is going into the entire asset database (not just what's in the Resources folder) and coming back with a random list of objects of the requested type. It was working fine earlier today-- I'd load all GameObjects, sort through their names, and save the ones that I wanted (same for Materials), but the second half of today has seen the function find one, or all, or none of the objects I'm looking for. It's driving me nuts.

    Right now, in my game's master object's Awake() function, it calls its own init which in turn creates a GameObject called Factory. On Factory, I add the component ResourceFactory from the code below and then call the ResourceFactory's init function.

    Calling the init() function in Start() doesn't make a difference.

    As you may or may not be able to see from the output in the console, the number of objects returned is not consistent.

    Any help would be greatly appreciated. I'm so frustrated with this that I'm putting it aside for the evening. Again, this code works sporadically; I have had moments when I get the two objects and one material in my factory, but it doesn't always work.

    Thanks,
    ~ k


    Code (csharp):
    1.  
    2. // ----------------------------------------------------------------------
    3. /*
    4.     ResourceFactory.js
    5.    
    6.     Simple entity manager. Spawns entities by name and holds references
    7.     to all their prefabs.
    8. */
    9. // ----------------------------------------------------------------------
    10.  
    11. class ResourceFactory extends MonoBehaviour {
    12.     //public var levelMaster : GameObject;
    13.     public var prefabs : GameObject[];
    14.     private var prefabKeys : String[];
    15.    
    16.     public var materials : Material[];
    17.     private var materialKeys : String[];
    18.    
    19.     // ----------------------------------------------------------------------
    20.     function init() {
    21.         //lm = levelMaster.GetComponent("Level");
    22.         buildMappingTables();
    23.     }
    24.    
    25.     // ----------------------------------------------------------------------
    26.     function buildMappingTables() {
    27.         var i:int;
    28.         var split:String[];
    29.        
    30.         var prefabList = new Array();
    31.         var prefabCount:int = 0;
    32.         var materialList = new Array();
    33.         var materialCount:int = 0;
    34.  
    35.         var allRes:Object[] = Resources.FindObjectsOfTypeAll(typeof(GameObject));
    36.         for (var ob in allRes) {
    37.             if (ob.name.StartsWith("prefab_")) {
    38.                 prefabCount++;
    39.                 prefabList.Add(ob);
    40.             }
    41.         }
    42.        
    43.         allRes = Resources.FindObjectsOfTypeAll(typeof(Material));
    44.  
    45.         // This line is showing me that what I'm expecting to get back and what I
    46.         // actually get back are not in line with each other.
    47.  
    48.         Debug.Log("AllRes: " + allRes.Length + " objects.");
    49.         for (var mat in allRes) {
    50.             if (mat.name.StartsWith("mat_")) {
    51.                 materialCount++;
    52.                 materialList.Add(mat);
    53.             }
    54.         }
    55.        
    56.         prefabs = prefabList;
    57.         prefabKeys = new String[prefabs.Length];
    58.         materials = materialList;
    59.         materialKeys = new String[materials.Length];
    60.        
    61.         // set up keys for the lists
    62.         for (i = 0; i < prefabs.Length; i++) {
    63.             split = prefabs[i].name.Split("_"[0]);
    64.             prefabKeys[i] = split[1] + "_" + split[2];
    65.         }
    66.        
    67.         for (i = 0; i < materials.Length; i++) {
    68.             split = materials[i].name.Split("_"[0]);
    69.             materialKeys[i] = split[1] + "_" + split[2];
    70.         }
    71.        
    72.         Debug.Log("ResourceFactory: Found " + prefabCount + " prefabs and " + materialCount + " materials.");
    73.     }
    74.    
    75.     // ----------------------------------------------------------------------
    76.     function findMaterial(mat:String) : Material {
    77.         if (materialKeys) {
    78.             for (var i = 0; i < materialKeys.Length; i++) {
    79.                 if (materialKeys[i] == mat) {
    80.                     return(materials[i]);
    81.                 }
    82.             }
    83.             return(null);
    84.         }
    85.         else {
    86.             Debug.Log("ResourceFactory::findMaterial: no material keys.");
    87.             return(null);
    88.         }
    89.     }
    90.  
    91. }
    92.  
     
  2. rlindsay

    rlindsay

    Joined:
    Nov 4, 2011
    Posts:
    3
    Last edited: Nov 24, 2011
  3. Ntero

    Ntero

    Joined:
    Apr 29, 2010
    Posts:
    1,436
    From the Docs at:
    http://unity3d.com/support/documentation/ScriptReference/Resources.FindObjectsOfTypeAll.html

    Code (csharp):
    1.  
    2. This function can return any type of Unity object that is loaded,
    3. including game objects, prefabs, materials, meshes, textures, etc.
    4. It will also list internal stuff, therefore please be extra careful
    5. the way you handle the returned objects.
    6. Contrary to Object.FindObjectsOfType
    7. this function will also list disabled objects.
    It's designed to retrieve currently loaded objects, not objects on file in Resources. This means that what it retrieves is just what's currently in RAM, which will depend on recently loaded/used objects and current scene objects. When used in Editor it also retrieves Editor entities which causes a MASSIVE bloat to the number of items returned.

    It can't find objects not loaded into memory at the time of request, and it's not designed to find entities in the Resources bundle specifically (unless they are currently loaded).

    Edit:
    In Editor it can act really funky, because it will retrieve objects whose inspector you visited since the last Garbage Collect, or other, recently accessed objects that can appear extremely arbitrary sometimes.
     
    Last edited: Nov 24, 2011
    ilmario likes this.
  4. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    You want to use the Resources.LoadAll functions an alike to load the whole resource library (and hope to survive the ram bomb)
     
  5. luislodosm

    luislodosm

    Joined:
    Apr 26, 2016
    Posts:
    26
    Scriptable objects that are not referenced in any scene are not detected by Resources.FindObjectsOfTypeAll.
     
  6. eppz

    eppz

    Joined:
    Aug 2, 2014
    Posts:
    172
    This turned out to be so true. I wonder why is this missing from the docs. I burnt 2 hours on this.
    Thanks anyway, @luislodosm.
     
    r137, ivaylo5ev, digital_monk and 3 others like this.
  7. mahdiii

    mahdiii

    Joined:
    Oct 30, 2014
    Posts:
    856
    You can add the scriptableobject reference to a mono script in a scene or put them inside Resources folder.
     
    r137 likes this.
  8. tessellation

    tessellation

    Joined:
    Aug 11, 2015
    Posts:
    390
    What's so strange to me is if the scene references a ScriptableObject that references a second tier of ScriptableObjects (different type), that second tier is often not loaded. For example if you use FindObjectsOfTypeAll<Tier2Thing>() you won't get them all.
     
  9. OlgaB_BFX

    OlgaB_BFX

    Joined:
    Nov 19, 2020
    Posts:
    5
    use AssetDatabase.FindAssets instead