在Unity中使用Resources.Load时搜索所有子文件夹

时间:2019-07-18 12:08:53

标签: c# unity3d

是否可以让Resources.Load(名称,类型)不仅在基本Resources文件夹/指定的子文件夹中搜索合适的资产,还可以在Resources下的完整子文件夹结构中搜索?

示例文件夹结构

Resources
  - Subfolder
    - image.png

我希望像Resources.Load(“ image”,typeof(Texture2D))这样的东西返回图像,而无需用户指定“ Subfolder / image”。

我知道它很丑陋,但它应该是“将它放到一个废弃的项目中,而不必担心您的文件夹结构”类型的实用程序脚本,而我不会知道该子文件夹。

3 个答案:

答案 0 :(得分:1)

无法更改Resouces.Load()静态方法的功能,它是Unity Internal。但是,您可以编写自己的自定义类来实现所需的功能。该代码需要找到Resources文件夹中的所有目录并搜索文件。让我们将类称为ResourcesExtension

public class ResourcesExtension
{
    public static string ResourcesPath = Application.dataPath+"/Resources";

    public static UnityEngine.Object Load(string resourceName, System.Type systemTypeInstance) 
    {
    string[] directories = Directory.GetDirectories(ResourcesPath,"*",SearchOption.AllDirectories);
    foreach (var item in directories)
    {
        string itemPath = item.Substring(ResourcesPath.Length+1);
        UnityEngine.Object result = Resources.Load(itemPath+"\\"+resourceName,systemTypeInstance);
        if(result!=null)
            return result;
    }
    return null;
    }
}

然后您需要做的就是调用静态方法。

ResourcesExtension.Load("image", typeof(Texture2D))

答案 1 :(得分:1)

接受的答案仅在编辑器上下文中有效,而在构建游戏后无效。资源文件夹在构建游戏时会打包,并且不再是您可以通过Directory.GetDirectories遍历的文件层次结构。使其生效的唯一方法是在仍处于编辑器上下文中的情况下保存所有文件路径,并使用此文件层次结构在运行时加载资源。在我的项目中,我使用以下代码将一个按钮添加到使用资源文件夹中名为AssetGen的资产的组件。单击此按钮时,“资源”文件夹中所有子文件夹中的所有png文件都将保存到CharacterGen具有的名为filePaths的公共属性中。

[CustomEditor(typeof(CharacterGen))]
public class RefreshCharacterList : Editor
{
    CharacterGen charGen;
    public void OnEnable()
    {
        charGen = (CharacterGen)target;
    }

    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();
        if (GUILayout.Button("Load resource paths"))
        {
            List<String> paths = new List<string>();
            LoadPathsRecursive("", ref paths);
            charGen.filePaths = paths;
        }
    }


    void LoadPathsRecursive(string path, ref List<string> paths)
    {
        var fullPath = Application.dataPath + "/Resources/" + path;
        Debug.Log("fullPath: " + fullPath);
        DirectoryInfo dirInfo = new DirectoryInfo(fullPath);
        foreach(var file in dirInfo.GetFiles())
        {
            if (file.Name.Contains(".PNG") && !file.Name.Contains(".meta"))
            {
                paths.Add(path + "/" + file.Name.Replace(".PNG", ""));
            }
        }
      
        foreach (var dir in dirInfo.GetDirectories())
        {
            LoadPathsRecursive(path + "/" + dir.Name, ref paths);
        }
    }

}

稍后我在CharacterGen中使用单击按钮时保存的路径来调用Resources.Load。

foreach (var filePath in filePaths)
{
   var loadedSprite = Resources.Load<Sprite>(filePath);
   //Do something with loadedSprite
}

答案 2 :(得分:1)

如果你想找到一个类型的所有对象并作为列表返回。
它 Emad 代码编辑了一下。

private List<T> FindAllObject<T>()
{
    List<T> tmp = new List<T>();
    string ResourcesPath = Application.dataPath + "/Resources";
    string[] directories = Directory.GetDirectories(ResourcesPath, "*", SearchOption.AllDirectories);

    foreach (string item in directories)
    {
        string itemPath = item.Substring(ResourcesPath.Length + 1);
        T[] reasult = Resources.LoadAll(itemPath, typeof(T)).Cast<T>().ToArray();

        foreach (T x in reasult)
        {
            if (!tmp.Contains(x))
            {
                tmp.Add(x);
            }
        }
    }

    return tmp;
}

使用它。

List<MyClass> myClasses = FindAllObject<MyClass>();