unity3d 我如何循环所有资产文件夹和子文件夹,并得到一个列表中的所有预制在这个文件夹?

niknxzdl  于 2023-01-13  发布在  其他
关注(0)|答案(4)|浏览(285)

此代码获取特定于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

如果在资产中,我使鼠标右键单击文件夹Folder2,然后从菜单中选择获取路径,我希望它从Folder2和Folder2下的所有子文件夹中获取所有预制件。所以,最后我会有一个所有路径与文件夹的列表:

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

最后,我的目标是能够添加到每个预制件的组件,例如刚体。所以,如果我有一个文件夹与10个预制件和它下面的30个子文件夹与200多个预制件,然后得到所有的文件夹和预制件,并添加一个组件/s到所有文件夹中的所有预制件。

vq8itlhq

vq8itlhq1#

下面是一个替代的简单方法。

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

zujrkrfu2#

您可以使用“资源.加载(“[path]/[filename]”)as [Class]”这将为您提供所需的资源、预置、精灵等。需要注意的是,这将仅在资源文件夹的“Resources”文件夹中查找(在Unity项目中的根),所以你必须创建一个“资源”文件夹!这也是一个好主意,因为它可以非常缓慢地寻找所有的文件,所以这可以确保它只看重要的文件。所以你可以使用Vivek nuna'的解决方案以获取文件位置和资源。加载以获取资源。有关详细信息,请查看此处:https://docs.unity3d.com/ScriptReference/Resources.html
希望这有帮助!

r55awzrz

r55awzrz3#

要从路径中获取实际的预置,请使用AssetDatabase.LoadAssetAtPath(path)和相关方法。
它只能在编辑器中工作,但我想这就是你所需要的

jbose2ul

jbose2ul4#

这是我想要的,对我的案子很有帮助:
在资源中,右键单击任何文件夹,然后单击添加组件。它将循环所有文件夹和右键单击添加组件的文件夹的子文件夹。然后它将找到所有预制件,并将其添加到刚体中,然后保存更改。
取决于你有多少预制件,它可能有点慢,但它正在做的工作。
补充说明:
用于添加更多组件或多个组件的选项。
创建一个日志/文本文件,其中包含所做的所有更改,以及所做更改的名称和时间。
撤消:如果有选项可撤消资源,或使用文本文件阅读所做的更改并还原,则进行撤消。
备份:添加组件后,首先在原始预制件的临时文件夹中进行备份(也可用于撤销情况)。

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);
            }
        }
    }
}

相关问题