Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Most Efficient If String From List Contains Other String?

Discussion in 'Scripting' started by JudahMantell, Oct 22, 2021.

  1. JudahMantell

    JudahMantell

    Joined:
    Feb 28, 2017
    Posts:
    476
    Basically, I have a folder of png files and allow the user to create materials from them at runtime. The way I'm doing that is looping through all PNG files in the specified folder and if they contain "_base" load that in. Next I want to see if the files contain the base texture's name AND the extention "metallic", "normal", etc.
    My code seems extremely inefficient with a bunch of loops and I'm just looking for a better way of doing it. Maybe using Linq? I'm not sure!

    I would appreciate any and all pointers!

    Thanks so much!

    Code (CSharp):
    1.     public IEnumerator initializeCustomTextureLibrary()
    2.     {
    3.         Debug.Log("INITIALIZING TEXTURES");
    4.         textureFilePaths = Directory.GetFiles(texturePath, "*.png", SearchOption.AllDirectories).ToList();
    5.         for (int i = 0; i < textureFilePaths.Count; i++)
    6.         {
    7.             if (textureFilePaths[i].ToLower().Contains("_base")) // if the found texture is the base map...
    8.             {
    9.                 // Get the "prefix" to the material's name and create the material...
    10.                 string[] fileName = Path.GetFileName(textureFilePaths[i]).Split('_');
    11.                 Material newMat = new Material(Shader.Find("Universal Render Pipeline/Lit"));
    12.                 newMat.name = fileName[0];
    13.  
    14.                 newMat.mainTexture = HelperMethods.LoadPNG(textureFilePaths[i]);
    15.                
    16.                 // Now loop back through and see if any other pngs in the folder contain that prefix plus the suffix of the appropriate map...
    17.                 foreach(string s in textureFilePaths)
    18.                 {
    19.                     if (s.ToLower().Contains(fileName[0]))
    20.                     {
    21.                         if(s.ToLower().Contains("_metallic") || s.ToLower().Contains("_specular"))
    22.                         {
    23.                             newMat.EnableKeyword("_METALLICGLOSSMAP");
    24.                             newMat.SetTexture("_MetallicGlossMap", HelperMethods.LoadPNG(s));
    25.                         }
    26.                         if (s.ToLower().Contains("_normal") || s.ToLower().Contains("_bump"))
    27.                         {
    28.                             newMat.EnableKeyword("_NORMALMAP");
    29.                             newMat.SetTexture("_BumpMap", HelperMethods.LoadPNG(s));
    30.                         }
    31.                     }
    32.                 }
    33.             }
    34.         }
    35.         Debug.Log("TEXTURES DONE");
    36.         yield return null;
    37.     }
    PS: If anyone knows the shader code for the occlusion map of URP's standard lit shader, that would be super helpful too!
     
  2. RadRedPanda

    RadRedPanda

    Joined:
    May 9, 2018
    Posts:
    1,646
    You could use the built in
    FindAll()
    on a List or Array to find all strings which match your condition.

    string[] matches = Array.FindAll(textureFilePaths, x => x.ToLower().Contains("_base"));

    List<string> matches = textureFilePaths.FindAll(x => x.ToLower().Contains("_base"));
     
  3. JudahMantell

    JudahMantell

    Joined:
    Feb 28, 2017
    Posts:
    476
    No way! That's so helpful, I had no idea, thanks for sharing that!