有时候需要复制一个场景目录制作新的场景,打包场景也是独立资源,不希望资源复用。我们直接使用Ctrl+D复制资源,里面的预设,材质等都还是指向原有的,所以废话不多说,直接上代码。
操作窗口
首先是制作一个复制资源窗口
下面是脚本和菜单调用
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
public class ResCopyWin : EditorWindow
{
public static ResCopyWin copyWin;
//[MenuItem("JFrameWork/Resources/复制文件夹(复制依赖关系) %#D", false, 0)] Ctrl+Shift+D
[MenuItem("JFrameWork/Resources/复制文件夹(复制依赖关系)", false, 0)]
public static void CopyIt()
{
//否则就弹出面板设置
copyWin = EditorWindow.GetWindow(typeof(ResCopyWin), true, "复制资源目录") as ResCopyWin;
copyWin.ShowModalUtility();
}
string sourcePath = "Assets/";
string toPath = "Assets/";
private void OnGUI()
{
using (new GUILayout.VerticalScope())
{
EditorGUILayout.Space(10);
EditorGUILayout.LabelField("原始路径:");
sourcePath = EditorGUILayout.TextField(sourcePath, GUILayout.Width(180));
EditorGUILayout.Space(10);
EditorGUILayout.LabelField("目标路径:");
toPath = EditorGUILayout.TextField(toPath, GUILayout.Width(180));
EditorGUILayout.Space(10);
if (GUILayout.Button("开始复制", GUILayout.Width(150), GUILayout.Height(20)))
{
OnOk();
}
}
}
void OnOk()
{
CopyFolderKeepAssetsUsingEditor.CopyDirectoryDeep(sourcePath, toPath);
}
}
原始路径就是要复制的目录,目标路径就是复制出来的目录。
复制函数
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;
public class CopyFolderKeepAssetsUsingEditor
{
//[MenuItem("Tools/复制文件夹(复制依赖关系) %#D", false, 0)]
//public static void CopyIt()
//{
// CopyDirectoryDeep("Assets/scenes/1", "Assets/scenes/2");
//}
public static void CopyDirectoryDeep(string sourcePath, string destinationPath)
{
CopyDirectoryRecursively(sourcePath, destinationPath);
List<string> metaFiles = GetFilesRecursively(destinationPath, (f) => f.EndsWith(".meta"));
List<(string originalGuid, string newGuid)> guidTable = new List<(string originalGuid, string newGuid)>();
foreach (string metaFile in metaFiles)
{
StreamReader file = new StreamReader(metaFile);
file.ReadLine();
string guidLine = file.ReadLine();
file.Close();
string originalGuid = guidLine.Substring(6, guidLine.Length - 6);
string newGuid = GUID.Generate().ToString().Replace("-", "");
guidTable.Add((originalGuid, newGuid));
}
List<string> allFiles = GetFilesRecursively(destinationPath);
foreach (string fileToModify in allFiles)
{
string content = File.ReadAllText(fileToModify);
foreach (var guidPair in guidTable)
{
content = content.Replace(guidPair.originalGuid, guidPair.newGuid);
}
File.WriteAllText(fileToModify, content);
}
AssetDatabase.Refresh();
}
private static void CopyDirectoryRecursively(string sourceDirName, string destDirName)
{
DirectoryInfo dir = new DirectoryInfo(sourceDirName);
DirectoryInfo[] dirs = dir.GetDirectories();
if (!Directory.Exists(destDirName))
{
Directory.CreateDirectory(destDirName);
}
FileInfo[] files = dir.GetFiles();
foreach (FileInfo file in files)
{
string temppath = Path.Combine(destDirName, file.Name);
file.CopyTo(temppath, false);
}
foreach (DirectoryInfo subdir in dirs)
{
string temppath = Path.Combine(destDirName, subdir.Name);
CopyDirectoryRecursively(subdir.FullName, temppath);
}
}
private static List<string> GetFilesRecursively(string path, Func<string, bool> criteria = null, List<string> files = null)
{
if (files == null)
{
files = new List<string>();
}
files.AddRange(Directory.GetFiles(path).Where(f => criteria == null || criteria(f)));
foreach (string directory in Directory.GetDirectories(path))
{
GetFilesRecursively(directory, criteria, files);
}
return files;
}
}
参考
https://discussions.unity.com/t/can-i-duplicate-folder-with-internal-dependencies-between-objects/119179/5