解析一个预设体上的引用资源并拷贝到新生成路径,同时替换预设体上的引用,指向新的拷贝。


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

public static class EditorPrefabToFolder
{
    [MenuItem("Assets/PrefabToFolder")]
    static void PrefabToFolder()
    {
        GameObject[] arr = Selection.GetFiltered(SelectionMode.Assets);
        if (arr == null || arr.Length == 0) return;
        foreach (var item in arr)
        {
            string dir = AssetDatabase.GetAssetPath(item);
            if (!dir.EndsWith("prefab"))
            {
                Debug.LogWarning("selected objects must be prefabs:" + dir);
                return;
            }
            string directoryPath = Path.Combine(Path.GetDirectoryName(dir), Path.GetFileNameWithoutExtension(dir));
            if (Directory.Exists(directoryPath))
            {
                Debug.LogWarning("directory path already existed:" + directoryPath);
            }
            else
            {
                Directory.CreateDirectory(directoryPath);
                Debug.Log(directoryPath);
            }
            string[] dependencies = AssetDatabase.GetDependencies(dir);
            List<string> listSourceFile = new List<string>();
            List<string> listDestClonedFile = new List<string>();
            Dictionary<string, string> dicSourceMaterial = new Dictionary<string, string>();
            foreach (var dependency in dependencies)
            {
                Debug.Log(dependency);
                System.Type t = AssetDatabase.GetMainAssetTypeAtPath(dependency);
                Debug.Log(t);
                if (t == typeof(GameObject))
                {
                    //File.Copy(dependency, Path.Combine(directoryPath, Path.GetFileName(dependency)));
                }
                else if (t.BaseType == typeof(Texture))
                {
                    //copy asset
                    string destDir = Path.Combine(directoryPath, "Textures");
                    if (!Directory.Exists(dependency))
                        Directory.CreateDirectory(destDir);
                    string destFile = Path.Combine(destDir, Path.GetFileName(dependency));
                    if (!File.Exists(destFile))
                        File.Copy(dependency, destFile);
                    else
                        Debug.Log(destFile + "has existed!");
                    listSourceFile.Add(dependency);
                    listDestClonedFile.Add(destFile);
                }
                else if (t == typeof(Material))
                {
                    //copy asset
                    string destDir = Path.Combine(directoryPath, "Materials");
                    if (!Directory.Exists(dependency))
                        Directory.CreateDirectory(destDir);
                    string destFile = Path.Combine(destDir, Path.GetFileName(dependency));
                    if (!File.Exists(destFile))
                        File.Copy(dependency, destFile);
                    else
                        Debug.Log(destFile + "has existed!");
                    dicSourceMaterial.Add(destFile, File.ReadAllText(dependency));
                    listSourceFile.Add(dependency);
                    listDestClonedFile.Add(destFile);
                }
            }
            //redirect prefab ref
            AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);
            StringBuilder builder1 = new StringBuilder();
            string line = string.Empty;
            using (StreamReader sr = new StreamReader(dir))
            {
                while ((line = sr.ReadLine()) != null)
                {
                    if (line.Contains("guid"))
                    {
                        for (int i = 0; i < listSourceFile.Count; i++)
                        {
                            string guidSource = AssetDatabase.AssetPathToGUID(listSourceFile[i]);
                            string guidCloned = AssetDatabase.AssetPathToGUID(listDestClonedFile[i]);
                            line = line.Replace(guidSource, guidCloned);
                        }
                    }
                    builder1.AppendLine(line);
                }
            }
            File.WriteAllText(Path.Combine(directoryPath, Path.GetFileName(dir)), builder1.ToString());
            //redirect materials ref
            foreach (var destPath_sourceMat in dicSourceMaterial)
            {
                string mat = destPath_sourceMat.Value;
                for (int i = 0; i < listSourceFile.Count; i++)
                {
                    string guidSource = AssetDatabase.AssetPathToGUID(listSourceFile[i]);
                    string guidCloned = AssetDatabase.AssetPathToGUID(listDestClonedFile[i]);
                    mat = mat.Replace(guidSource, guidCloned);
                }
                File.WriteAllText(destPath_sourceMat.Key, mat);
            }
        }
        AssetDatabase.Refresh();
    }
}