簡體   English   中英

如何遍歷所有 Assets 文件夾和子文件夾並列出此文件夾中的所有預制件?

[英]How do I loop over all Assets folders and sub folders and get to a list all the prefabs in this folders?

此代碼獲取資產特定文件夾中的所有子文件夾。

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

我想組合這兩個代碼,所以當我右鍵單擊和 select 獲取路徑時,它將從所選路徑中獲取所有預制件,右鍵單擊路徑和路徑所有子文件夾遞歸。

例子:

Assets
  Folder1
  Folder2
    Folder3
     Folder4
     Folder5
  Folder6

如果在資產中,我用鼠標右鍵單擊文件夾 Folder2,然后從菜單 Get Path 中單擊 select,我希望它從 Folder2 中獲取所有預制件以及 Folder2 下的所有子文件夾。 所以最后我會有一個包含文件夾的所有路徑的列表:

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

最后,我的目標是能夠為每個預制件添加一個組件,例如剛體。 因此,如果我有一個包含 10 個預制件的文件夾,並且在它下面有 30 個子文件夾,其中包含更多 200 個預制件,那么獲取所有文件夾和預制件,並將一個組件添加到所有文件夾中的所有預制件。

這是另一種簡單的方法來做到這一點。

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

您可以使用 "Resources.Load("[path]/[filename]") as [Class]" 這將為您提供所需的資產、預制件、精靈等。 需要注意的是,這只會在資產文件夾(統一項目中的根目錄)中的文件夾“Resources”中查看,因此您必須創建一個“Resources”文件夾。 這也是一個好主意,因為查看所有文件可能會非常慢,因此可以確保它只查看重要文件。 因此,您可以使用 Vivek nuna 的解決方案來獲取文件位置和 Resources.Load 來獲取資產:有關更多信息,請查看此處: https://docs.unity3d.com/ScriptReference/Resources.ZFC35FDC70D5FC69D2E526

希望這可以幫助!

要從路徑獲取實際預制件,請使用 AssetDatabase.LoadAssetAtPath(path) 和相關方法。

它只適用於編輯器,但我想這就是你需要的

這就是我想要的並且對我的情況有好處:

在資產中右鍵單擊任何文件夾,然后單擊添加組件。 它將循環您右鍵單擊添加組件的文件夾的所有文件夾和子文件夾。 然后它會發現所有的預制件都添加了剛體並保存更改。

根據您擁有的預制件數量,它可能會有點慢,但它正在完成這項工作。

要補充的東西:

添加更多組件或多個組件的選項。

創建一個包含所有更改的日志/文本文件,預制件會命名更改的內容和時間。

如果有選項可以撤消資產或使用讀取所做更改並恢復的文本文件進行撤消,則撤消。

備份:一旦添加組件以首先在原始預制件的臨時文件夾中進行備份(也可用於撤消案例)。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM