Skip to content

Instantly share code, notes, and snippets.

@egemenertugrul
Last active January 28, 2025 13:13
Show Gist options
  • Save egemenertugrul/0a2a54c44896610ec7ce9954a3589226 to your computer and use it in GitHub Desktop.
Save egemenertugrul/0a2a54c44896610ec7ce9954a3589226 to your computer and use it in GitHub Desktop.
StreamingAssets/Resources Extensions for Unity
using System.Collections.Generic;
using System.IO;
using UnityEngine;
public static class ResourcesExtension
{
/// <summary>
/// Recursively traverses each folder under <paramref name="path"/> and returns the list of file paths.
/// It will only work in Editor mode.
/// </summary>
/// <param name="path">Relative to Application.streamingAssetsPath.</param>
/// <param name="paths">List of file path strings.</param>
/// <returns>List of file path strings.</returns>
public static List<string> GetPathsRecursively(string path, ref List<string> paths)
{
var fullPath = Path.Combine(Application.dataPath, "Resources", path);
DirectoryInfo dirInfo = new DirectoryInfo(fullPath);
foreach (var file in dirInfo.GetFiles())
{
if (!file.Name.Contains(".meta"))
{
paths.Add(Path.Combine(path, Path.GetFileNameWithoutExtension(file.Name))); // Without file extension
}
}
foreach (var dir in dirInfo.GetDirectories())
{
GetPathsRecursively(Path.Combine(path, dir.Name), ref paths);
}
return paths;
}
public static List<string> GetPathsRecursively(string path)
{
List<string> paths = new List<string>();
return GetPathsRecursively(path, ref paths);
}
/// <summary>
/// Recursively traverses each folder under <paramref name="basePath"/> and loads each file as a <typeparamref name="T"/>.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="basePath"></param>
/// <returns>Returns the loaded object of type <typeparamref name="T"/></returns>
public static List<T> LoadRecursively<T>(string basePath) where T : Object
{
List<string> paths = GetPathsRecursively(basePath);
List<T> objects = new List<T>();
foreach (var path in paths)
{
objects.Add(Resources.Load<T>(path));
}
return objects;
}
public static List<(T, string)> LoadRecursivelyWithPaths<T>(string basePath) where T : Object
{
List<string> paths = new List<string>();
GetPathsRecursively(basePath, ref paths);
List<(T, string)> list = new List<(T, string)>();
foreach (var path in paths)
{
list.Add((Resources.Load<T>(path), path));
}
return list;
}
}
using System.Collections.Generic;
using System.IO;
using UnityEngine;
public static class StreamingAssetsExtension
{
/// <summary>
/// Recursively traverses each folder under <paramref name="path"/> and returns the list of file paths.
/// It will only work in Editor mode.
/// </summary>
/// <param name="path">Relative to Application.streamingAssetsPath.</param>
/// <param name="paths">List of file path strings.</param>
/// <returns>List of file path strings.</returns>
public static List<string> GetPathsRecursively(string path, ref List<string> paths)
{
var fullPath = Path.Combine(Application.streamingAssetsPath, path);
DirectoryInfo dirInfo = new DirectoryInfo(fullPath);
foreach (var file in dirInfo.GetFiles())
{
if (!file.Name.Contains(".meta"))
{
paths.Add(Path.Combine(path, file.Name)); // With file extension
}
}
foreach (var dir in dirInfo.GetDirectories())
{
GetPathsRecursively(Path.Combine(path, dir.Name), ref paths);
}
return paths;
}
public static List<string> GetPathsRecursively(string path)
{
List<string> paths = new List<string>();
return GetPathsRecursively(path, ref paths);
}
}
@egemenertugrul
Copy link
Author

@Kasuyakema
Copy link

Kasuyakema commented Jan 28, 2025

Thanks for sharing. If you do it like this it runs on every Asset change:

  using System.Collections.Generic;
  using System.IO;
  using UnityEditor;
  using UnityEngine;
  
  #if UNITY_EDITOR
  
  //https://stackoverflow.com/questions/43657461/how-to-find-list-of-files-in-streamingassets-folder-in-android/73303644#73303644
  [InitializeOnLoad]
  class ResourceLister : AssetPostprocessor
  {
      static ResourceLister()
      {
          EditorApplication.projectChanged += () => SaveResourceAssetPaths();
          Debug.Log("ResourceLister running");
      }
  
  
      private static void SaveStreamingAssetPaths(string directory = "", string file_name = "StreamingAssetPaths")
      {
          List<string> paths = StreamingAssetsExtension.GetPathsRecursively(directory); // Gets list of files from StreamingAssets/directory
  
          string txtPath = Path.Combine(Application.dataPath, "Resources", file_name + ".txt"); // writes the list of file paths to /Assets/Resources/
          if (File.Exists(txtPath))
          {
              File.Delete(txtPath);
          }
          using (FileStream fs = File.Create(txtPath)) { }
          using (StreamWriter writer = new StreamWriter(txtPath, false))
          {
              foreach (string path in paths)
              {
                  writer.WriteLine(path);
              }
          }
  
      }
  
      private static void SaveResourceAssetPaths(string directory = "", string file_name = "ResourceAssetPaths")
      {
  
          List<string> paths = ResourcesExtension.GetPathsRecursively(directory); // Gets list of files from Resources/directory
  
          string txtPath = Path.Combine(Application.dataPath, "Resources", file_name + ".txt"); // writes the list of file paths to /Assets/Resources/
          if (File.Exists(txtPath))
          {
              File.Delete(txtPath);
          }
          using (FileStream fs = File.Create(txtPath)) { }
          using (StreamWriter writer = new StreamWriter(txtPath, false))
          {
              foreach (string path in paths)
              {
                  writer.WriteLine(path);
              }
          }
  
      }
  }
  
  #endif

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment