我如何在所有的资产文件夹和子文件夹中循环,并获得该文件夹中所有的预制件列表?

问题描述 投票:0回答:1

这段代码得到了所有子文件夹中的Assets特定文件夹。

using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEditor;
using UnityEngine;

public class AddComponents : Editor
{
    private static string GetClickedDirFullPath()
    {
        string clickedAssetGuid = Selection.assetGUIDs[0];
        string clickedPath = AssetDatabase.GUIDToAssetPath(clickedAssetGuid);
        string clickedPathFull = Path.Combine(Directory.GetCurrentDirectory(), clickedPath);

        FileAttributes attr = File.GetAttributes(clickedPathFull);
        return attr.HasFlag(FileAttributes.Directory) ? clickedPathFull : Path.GetDirectoryName(clickedPathFull);
    }

    private static string GetPath()
    {
        string path = GetClickedDirFullPath();
        int index = path.IndexOf("Assets");
        string result = path.Substring(index);

        return result;
    }

    private static string[] GetSubFoldersRecursive(string root)
    {
        var paths = new List<string>();

        // If there are no further subfolders then AssetDatabase.GetSubFolders returns 
        // an empty array => foreach will not be executed
        // This is the exit point for the recursion
        foreach (var path in AssetDatabase.GetSubFolders(root))
        {
            // add this subfolder itself
            paths.Add(path);

            // If this has no further subfolders then simply no new elements are added
            paths.AddRange(GetSubFoldersRecursive(path));
        }

        return paths.ToArray();
    }

    [MenuItem("Assets/Get Folders")]
    private static void GetFolders()
    {
        List<string> paths = new List<string>();
        string selectedPath = GetPath();
        var folders = GetSubFoldersRecursive(selectedPath);
        foreach (var path in folders)
        {
            paths.Add(path);
        }
    }
}

而这个得到所有的预制件从一个特定的文件夹,但当我输入文件夹名称。

public List<string> prefabsPaths;

    public void AddComponentsToObjects()
    {
        prefabsPaths = new List<string>();

        string[] assetsPaths = AssetDatabase.GetAllAssetPaths();

        foreach (string assetPath in assetsPaths)
        {
            if (assetPath.Contains("Archanor"))
            {
                if (assetPath.Contains("Prefabs"))
                {
                    prefabsPaths.Add(assetPath);
                }
            }
        }
    }

我想把这两个代码结合起来,所以当我点击右键并选择 "获取路径 "时,它将从所选路径中获取所有预制件,并在路径上点击右键,然后递归获取所有子文件夹。

例如:

Assets
  Folder1
  Folder2
    Folder3
     Folder4
     Folder5
  Folder6

如果在Assets中,我在文件夹Folder2上单击鼠标右键,然后从菜单Get Path中选择,我想让它从Folder2和Folder2下的所有子文件夹中获取所有的prefabs。因此,在最后,我将有一个列表的所有路径与文件夹。

Folder2\1.prefab
Folder2\Folder3\2.prefab
Folder2\Folder3\3.prefab
Folder2\Folder4\4.prefab

最后,我的目标是能够为每个预制件添加一个组件,例如一个Rigidbody.因此,如果我有一个包含10个预制件的文件夹,在它下面有30个子文件夹,有200多个预制件,那么就可以得到所有的文件夹和预制件,并为所有文件夹中的所有预制件添加一个组件。

c# unity3d
1个回答
1
投票

这里有一个替代的简单方法。

string[] files = Directory.GetFiles("DirectoryPath", "*.prefab", SearchOption.AllDirectories);

1
投票

你可以使用 "Resources.Load("[path][filename]")as [Class]",这将为你提供你所需要的资产、预制件、精灵等。需要注意的是,这只能在asset文件夹中的 "Resources "文件夹中查找(unity项目中的根目录),所以你必须创建一个 "Resources "文件夹。这也是一个好主意,因为它可以很慢地查看所有文件,所以这确保它只查看重要的文件。所以你可以使用Vivek nuna的解决方案来获取文件位置,并使用Resources.Load来获取资产。更多信息请看这里。https:/docs.unity3d.comScriptReferenceResources.html。

希望对大家有所帮助!


1
投票

要从路径中获取实际的预制件,使用AssetDatabase.LoadAssetAtPath(path)和相关方法。

它只在编辑器中工作,但我想这是你所需要的。


0
投票

这是我想要的,并为我的情况下工作良好。

在 "资产 "中右击任何文件夹,然后点击 "添加组件".它将循环所有文件夹和子文件夹的文件夹,你做了右击添加组件。然后它会找到所有的预制件,给它们添加一个Rigidbody并保存更改。

根据你有多少个预制件,它可能会有点慢,但它正在做这项工作。

要添加的东西 。

添加更多组件或多个组件的选项。

创建一个logtext文件,其中包含所有的变化prefabs的名字,什么时候做的变化。

Undo 如果有一个选项可以在Assets上进行撤销,或者使用文本文件读取所做的更改并恢复。

备份:一旦添加组件,首先在原始预制件的临时文件夹中进行备份(也可用于撤销的情况)。

using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using UnityEditor;
using UnityEngine;

public class AddComponents : Editor
{
    private static string GetClickedDirFullPath()
    {
        string clickedAssetGuid = Selection.assetGUIDs[0];
        string clickedPath = AssetDatabase.GUIDToAssetPath(clickedAssetGuid);
        string clickedPathFull = Path.Combine(Directory.GetCurrentDirectory(), clickedPath);

        FileAttributes attr = File.GetAttributes(clickedPathFull);
        return attr.HasFlag(FileAttributes.Directory) ? clickedPathFull : Path.GetDirectoryName(clickedPathFull);
    }

    private static string GetPath()
    {
        string path = GetClickedDirFullPath();
        int index = path.IndexOf("Assets");
        string result = path.Substring(index);

        return result;
    }

    static List<string> paths = new List<string>();
    private static void GetFolders()
    {

        string selectedPath = GetPath();

        string[] assetsPaths = AssetDatabase.GetAllAssetPaths();

        foreach (string assetPath in assetsPaths)
        {
            if (assetPath.Contains(selectedPath))
            {
                if (assetPath.Contains("Prefabs"))
                {
                    paths.Add(assetPath);
                }
            }
        }
    }


    [MenuItem("Assets/Add Components")]
    public static void AddComponents()
    {
        GetFolders();

        for (int i = 0; i < paths.Count; i++)
        {
            if (File.Exists(paths[i]))
            {
                GameObject contentsRoot = PrefabUtility.LoadPrefabContents(paths[i]);

                // Modify Prefab contents.
                contentsRoot.AddComponent<Rigidbody>();

                // Save contents back to Prefab Asset and unload contents.
                PrefabUtility.SaveAsPrefabAsset(contentsRoot, paths[i]);
                PrefabUtility.UnloadPrefabContents(contentsRoot);
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.