Unity Prefab批量修改

下面实现的一个功能是对一个文件夹下的所有prefab批量修改,比如移除某个子物体,添加一个组件等,然后保存到另一个新的文件夹下; 

如下,我们实现一个扩展窗口,用于选择源文件夹和目标文件夹;然后遍历所有的prefab,进行修改,然后保存到新文件夹下,在保存之前检查资源是否存在,如果已存在,就移除再保存新的;

首先,在unity内加载资源时用的是工程的相对路径,而对于C#的IO来说,需要用绝对路径,那么先提供一组相对路径和绝对路径之间的转换接口,如下所示,这里使用了正则替换,注意模式字符串要用@前缀标记为原义;

    public static string GetRelativePath(string path){
        string srcPath = path.Replace("\\", "/");
        var retPath =  Regex.Replace(srcPath, @"\b.*Assets", "Assets");
        return retPath;
    }
    public static string GetAbsolutePath(string path){
        string srcPath = path.Replace("\\", "/");
        var retPath =  Regex.Replace(srcPath, @"\b.*Assets", Application.dataPath);
        return retPath;
    }

 然后就是简单的编辑器扩展功能,这里要使用PrefabUtility来进行prefab的保存,而不能使用AssetDatabase的接口;

using UnityEngine;
using UnityEditor;
using System.IO;

public class ArtActorPrefabModifyWindow : EditorWindow
{
    public static string assetSrcFolderPath = Application.dataPath + "/Resources/Prefabs/FashionPartPrefab";
    public static string assetDstFolderPath = "Assets/Resources/Prefabs/FashionPartPrefabNew";
    [MenuItem ("====Tools====/Prefab/移除时装部件内的骨骼")]
    public static void ShowWindow () {
        EditorWindow thisWindow = EditorWindow.GetWindow(typeof(ArtActorPrefabModifyWindow));
        thisWindow.titleContent = new GUIContent("骨骼移除");
        thisWindow.position = new Rect(Screen.width/2, Screen.height/2, 600, 800);
    }

    void OnGUI()
    {
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("选择源文件夹");
        EditorGUILayout.TextField(assetSrcFolderPath);
        if (GUILayout.Button("选择"))
        {
            assetSrcFolderPath = EditorUtility.OpenFolderPanel("选择文件夹", assetSrcFolderPath, "");
        }
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("选择源文件夹");
        EditorGUILayout.TextField(assetDstFolderPath);
        if (GUILayout.Button("选择"))
        {
            assetDstFolderPath = EditorUtility.OpenFolderPanel("选择文件夹", assetDstFolderPath, "");
        }
        EditorGUILayout.EndHorizontal();
 
        if (GUILayout.Button("开始提取") && assetSrcFolderPath != null && assetDstFolderPath != null)
        {
            Seperate();
        }
    }
    private static void Seperate(){
        assetSrcFolderPath = PathUtil.GetAbsolutePath(assetSrcFolderPath);
        var files = Directory.GetFiles(assetSrcFolderPath, "*.prefab");
        string dstPath = PathUtil.GetRelativePath(assetDstFolderPath);
        foreach (var file in files)
        {
            string srcPath = PathUtil.GetRelativePath(file);
            GameObject srcObj = AssetDatabase.LoadAssetAtPath(srcPath, typeof(GameObject)) as GameObject;
            if (srcObj == null)
                continue;

            GameObject dstObj = AssetDatabase.LoadAssetAtPath(dstPath, typeof(GameObject)) as GameObject;
            if (dstObj != null)
                AssetDatabase.DeleteAsset(dstPath);
            dstObj = GameObject.Instantiate(srcObj);
            Transform avatar = dstObj.transform.Find("Bip001");
            if (avatar != null) {
                GameObject.DestroyImmediate(avatar.gameObject);
                PrefabUtility.SaveAsPrefabAsset(dstObj, dstPath + "/" + srcObj.name + ".prefab");
            }
            GameObject.DestroyImmediate(dstObj);
        }
    }
}

 

你可能感兴趣的:(工具,Unity,Editor)