Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Count number of files in resources folder

Discussion in 'Scripting' started by filipetakanap, Feb 23, 2022.

  1. filipetakanap

    filipetakanap

    Joined:
    Nov 16, 2021
    Posts:
    35
    Hello,

    I need something like:
    Code (CSharp):
    1. System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo("c:\\");
    2. int count = dir.GetFiles().Length;
    But instead of looking through my computer folder I need to look into some folder in "Resources"
    The solutions i found are overcomplicated that don't do what i need or are outdated.
     
  2. filipetakanap

    filipetakanap

    Joined:
    Nov 16, 2021
    Posts:
    35
    Im proud, did it myself with VisualStudio's help:
    Code (CSharp):
    1. int PufeAustralLenght = 0;
    2. var PufeAustralTextures = Resources.LoadAll("Austral Pufe Textures/");
    3. PufeAustralLenght = PufeAustralTextures.Length;
    4.                    
     
    davidnibi and AnimalMan like this.
  3. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,043
    That's not a good solution, because you also LOAD everything.
    When you want to count rice grains do you have to eat it all?

    What is the purpose of what you're trying? Is it like an editor thing?
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,954
  5. filipetakanap

    filipetakanap

    Joined:
    Nov 16, 2021
    Posts:
    35
    It is a sofa arrangement app that changes colors when I click the sofa. There are alot of colors for one sofa and i need to have the lenght of colors inside the folder:

    Code (CSharp):
    1. if (_color == true)
    2.         {
    3.            
    4.  
    5.             if (Input.GetMouseButtonDown(0))
    6.             {
    7.  
    8.                 //Debug.Log(clicked);
    9.  
    10.                 RaycastHit hit;
    11.                 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    12.  
    13.                     objectName = gameObject.name;
    14.                     if (gameObject.name.Equals(objectName))
    15.                     {
    16.                     if (colorChoose == PufeAustralLenght)
    17.                     {
    18.                         colorChoose = 0;
    19.                     }
    20.                     else
    21.                     {
    22.                         if (Physics.Raycast(ray, out hit, 100))
    23.                         {
    24.                             colorChoose++;
    25.                             m_Renderer = hit.collider.gameObject.GetComponent<Renderer>();
    26.                             var texture = Resources.Load<Texture2D>("Austral Pufe Textures/texture" + colorChoose);
    27.                            
    28.                             m_Renderer.material.mainTexture = texture;
    29.                             Debug.Log("Estou a pintar!");
    30.                         }
    31.                     }
    32.                    
    33.                    
    34.                 }
    35.             }
    36.         }
    so, it reads "texture1", "texture2" by filename. when it reaches the max value (lenght) it returns to the first color.
    I basically cicles through all the colors for the sofa
     
  6. filipetakanap

    filipetakanap

    Joined:
    Nov 16, 2021
    Posts:
    35
    Not sure what the "T" is ... but when i used it like "var PufeAustralTextures = Resources.LoadAll<T>("Austral Pufe Textures/");" it gives error on the T saying name type or namespace "T" could not be found...
     
  7. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,043
    Ok, so you've stumbled upon a known and really stupid problem, for which I thought there was a decent solution. There isn't one, at least not one that comes bundled with Unity itself. The best solution I've found so far, is this one by @Bunny83 -- hopefully he can come by and tell us whether it's still valid or not.

    That's one of the staple features of C#, a generic type declaration of the so-called generic types, which are a compile-time thing, and you ought to know about them if you want to program in C#. Btw your code already uses the generic variant of LoadAll, but at this point I have to assume you've copy pasted it from somewhere.

    Generic classes and methods

    Edit: I missed to say this, but only a declaration is supposed to have a "T". You can name it however you want, but the word is supposed to start with T, as a notation convention. Once you actually start instantiating or calling things that were declared as generics, you're supposed to use only concrete types (this is why you get an error, you're referring to a type T which is unknown in that use context).

    Generic types (in general, not just in C#) have been developed through many iterations over several decades of computer science. In C++ they're called templates, and this is actually very revealing to what they really are: a way to instruct the compiler to get ready for any number of potentially very different statically typed declarations that share the same underlying implementation.

    So if I declare a class as MyClass<T> and then instantiate two objects in my code, once with
    new MyClass<string>()
    and once with
    new MyClass<int>()
    it is telling to the compiler to prepare two entirely separate classes based on how I used them. It's as if you'd write a dedicated
    MyClassForStrings
    and
    MyClassForIntegers
    . But on top of that here you can instantiate
    MyClass<float>
    as well without having to introduce a new class, and there are also many other related features, for example generic methods and generic variables, and likewise a plethora of ways to make your code smarter and implemented just once, instead of fighting with all kinds of types constantly, which may lead to abuse, redundancy, performance issues and critical errors.

    To narrow things down, which is obviously very important in everyday scenarios, the actual declaration can be made more specific by employing type constraints.

    Edit2:
    Kurt-Dekker's comment was about making sure that you're using the generic variant of LoadAll method, because Unity actually has both a generic-one and the legacy non-generic one. How does this work? Well, prior to having generics, C# relied on having to dynamically cast compatible types to and fro System.Object, a super type, right, and this happens in a process known as boxing/unboxing. Here I'm banalizing a lot of it, but basically C# bundles some data along with some metadata to specify which type it actually was. Once you pass that information around, it has to be boxed to preserve compatibility with the System.Object receivers, but then the receiver loses sight on the actual type and cannot process the data immediately without unboxing it and learning more about it, all of which is typically an expensive operation, especially when you have many individual pieces of information, like you do with lists and similar enumerations collections which are frequently accessed.

    And so the rule of thumb is to avoid the legacy non-generic methods in Unity as much as possible. That's the takeaway here.
     
    Last edited: Feb 24, 2022
  8. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,954
    T is the standard C# notation for "your classname here"
     
  9. filipetakanap

    filipetakanap

    Joined:
    Nov 16, 2021
    Posts:
    35
    Ok, thanks for the tip. This community is amazing.
    I was top of my class in cooding, but it was a networks course so i didn't explore it much.

    All i'm loading is small jpegs, is that really cpu heavy? I have a samsung s21 ultra for testing, but not everyone has an high end phone
     
  10. filipetakanap

    filipetakanap

    Joined:
    Nov 16, 2021
    Posts:
    35
    Ok, maybe because i'm really tired i missunderstood something. When I use :
    Code (CSharp):
    1. var PufeAustralTextures = Resources.LoadAll<ObjetoScript>("Austral Pufe Textures/");
    which ObjetoScript is my class name
    Code (CSharp):
    1. public class ObjetoScript : MonoBehaviour
    the textures are not loaded

    Do you mean
    Code (CSharp):
    1. Resources.LoadAll<Texture2D>
    ?
     
  11. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,043
    Obviously the only objects in that folder are supposed to be textures, right? You tell it which kind of object to load. There isn't much more to it. However if you also have your MonoBehaviour script there, it should work (but this probably isn't what you wanted, just technically, anything that's derived from UnityEngine.Object should be fine in general*).

    (* Take this statement with a grain of salt, I'm not a 100% expert on Resources, and the docs are abysmally poor in this regard, as usual. There isn't even a generic variant LoadAll<> listed even though it's in the API.)