diff --git a/Assets/Scripts/Editor/LowercaseFileRenamer.cs b/Assets/Scripts/Editor/LowercaseFileRenamer.cs new file mode 100644 index 00000000..2333e5a6 --- /dev/null +++ b/Assets/Scripts/Editor/LowercaseFileRenamer.cs @@ -0,0 +1,145 @@ +#if UNITY_EDITOR +using UnityEditor; +using UnityEngine; +using System.IO; +using System; + +public class WindowsLowercaseRenamer : EditorWindow +{ + [MenuItem("Assets/Windows安全重命名")] + private static void SafeRenameAll() + { + string dataPath = Global.dataPath; + + // 新增:处理根目录名称 + ProcessRootDirectory(dataPath); + + // 处理子目录和文件 + ProcessDirectoriesRecursive(dataPath); + ProcessFilesRecursive(dataPath); + + AssetDatabase.Refresh(); + Debug.Log("安全重命名完成!"); + } + // 新增方法:处理根目录 + private static void ProcessRootDirectory(string originalPath) + { + try + { + DirectoryInfo rootInfo = new DirectoryInfo(originalPath); + string targetRootName = rootInfo.Name.ToLowerInvariant(); + + // 如果根目录名称不符合规范 + if (rootInfo.Name != targetRootName) + { + string parentPath = rootInfo.Parent.FullName; + string newRootPath = Path.Combine(parentPath, targetRootName); + + // 特殊处理:根目录重命名需要额外权限 + if (Directory.Exists(newRootPath)) + { + string tempPath = Path.Combine(parentPath, Guid.NewGuid().ToString()); + Directory.Move(originalPath, tempPath); + Directory.Move(tempPath, newRootPath); + } + else + { + Directory.Move(originalPath, newRootPath); + } + + Debug.Log($"根目录重命名成功: {originalPath} → {newRootPath}"); + + // 更新全局路径(如果需要) + Global.dataPath = newRootPath; // 根据实际Global类的实现可能需要调整 + } + } + catch (Exception ex) + { + Debug.LogError($"根目录重命名失败: {ex.Message}"); + } + } + private static void ProcessDirectoriesRecursive(string path) + { + foreach (var dirPath in Directory.GetDirectories(path)) + { + // 递归处理子目录 + ProcessDirectoriesRecursive(dirPath); + + DirectoryInfo dirInfo = new DirectoryInfo(dirPath); + string targetName = dirInfo.Name.ToLowerInvariant(); + + // 仅当实际目录名不符合规范时才重命名 + if (dirInfo.Name != targetName) + { + string parentPath = dirInfo.Parent.FullName; + string newPath = Path.Combine(parentPath, targetName); + + try + { + // 特殊处理:Windows需要先重命名到临时名称 + //if (Directory.Exists(newPath)) + //{ + // string tempPath = Path.Combine(parentPath, Guid.NewGuid().ToString()); + // Directory.Move(dirPath, tempPath); + // Directory.Move(tempPath, newPath); + //} + //else + //{ + Directory.Move(dirPath, newPath); + //} + + Debug.Log($"目录重命名成功: {dirPath} → {newPath}"); + } + catch (Exception ex) + { + Debug.LogError($"目录重命名失败: {dirPath}\n{ex.Message}"); + } + } + } + } + + private static void ProcessFilesRecursive(string path) + { + foreach (var filePath in Directory.GetFiles(path)) + { + FileInfo fileInfo = new FileInfo(filePath); + string targetName = Path.GetFileNameWithoutExtension(fileInfo.Name).ToLowerInvariant(); + string targetExt = fileInfo.Extension.ToLowerInvariant(); + string newFileName = $"{targetName}{targetExt}"; + + // 比较实际文件名 + if (fileInfo.Name != newFileName) + { + string newPath = Path.Combine(fileInfo.DirectoryName, newFileName); + + try + { + // Windows特殊处理:如果目标存在但大小写不同 + if (File.Exists(newPath)) + { + string tempPath = Path.Combine(fileInfo.DirectoryName, Guid.NewGuid().ToString() + fileInfo.Extension); + File.Move(filePath, tempPath); + File.Move(tempPath, newPath); + } + else + { + File.Move(filePath, newPath); + } + + Debug.Log($"文件重命名成功: {filePath} → {newPath}"); + } + catch (Exception ex) + { + Debug.LogError($"文件重命名失败: {filePath}\n{ex.Message}"); + } + } + } + + // 递归子目录 + foreach (var dirPath in Directory.GetDirectories(path)) + { + ProcessFilesRecursive(dirPath); + } + } +} +#endif \ No newline at end of file diff --git a/Assets/Scripts/Editor/LowercaseFileRenamer.cs.meta b/Assets/Scripts/Editor/LowercaseFileRenamer.cs.meta new file mode 100644 index 00000000..852097e7 --- /dev/null +++ b/Assets/Scripts/Editor/LowercaseFileRenamer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3fc1a350612ff074eb9880438ed8d526 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Editor/VirtualFPostProcess.cs b/Assets/Scripts/Editor/VirtualFPostProcess.cs index a89bdefc..41b0b061 100644 --- a/Assets/Scripts/Editor/VirtualFPostProcess.cs +++ b/Assets/Scripts/Editor/VirtualFPostProcess.cs @@ -7,60 +7,72 @@ using UnityEngine; public class VirtualFPostProcess : IPostprocessBuildWithReport { - // 定义回调优先级(越低越先执行) public int callbackOrder => 0; - // 在打包完成后执行 public void OnPostprocessBuild(BuildReport report) { - // 获取项目根目录路径 string projectPath = Application.dataPath; - - // 获取Data文件夹的路径 string dataFolderPath = Path.Combine(projectPath, "../Data"); + string buildOutputPath = GetValidBuildPath(report); - // 获取打包后的输出目录 - string buildOutputPath = report.summary.outputPath; - if (buildOutputPath.Contains(".exe")) - { - var paths = buildOutputPath.Split('/'); - buildOutputPath = buildOutputPath.Replace(paths[paths.Length - 1], ""); - } - // 检查Data文件夹是否存在 if (Directory.Exists(dataFolderPath)) { - // 将Data文件夹复制到打包后的目标目录 - string targetDataPath = Path.Combine(buildOutputPath, "Data"); - CopyDirectory(dataFolderPath, targetDataPath); - Debug.Log($"Data folder copied to build output directory: {targetDataPath}"); + // 目标目录强制小写 + string targetDataPath = Path.Combine(buildOutputPath, "data"); + CopyDirectoryWithLowerCaseNames(dataFolderPath, targetDataPath); + Debug.Log($"数据目录已复制到: {targetDataPath}"); } else { - Debug.LogWarning("Data folder not found at: " + dataFolderPath); + Debug.LogWarning("未找到数据目录: " + dataFolderPath); } } - // 递归复制文件夹的辅助方法,覆盖已有文件和文件夹 - private void CopyDirectory(string sourceDir, string destinationDir) + private string GetValidBuildPath(BuildReport report) { - // 确保目标目录存在 - if (!Directory.Exists(destinationDir)) + string path = report.summary.outputPath; + if (path.Contains(".exe")) { - Directory.CreateDirectory(destinationDir); + return Path.GetDirectoryName(path); + } + return path; + } + + private void CopyDirectoryWithLowerCaseNames(string sourceDir, string targetDir) + { + // 创建小写目标目录 + var lowerTargetDir = ConvertToLowerPath(targetDir); + Directory.CreateDirectory(lowerTargetDir); + + // 复制文件(带小写转换) + foreach (var file in Directory.GetFiles(sourceDir)) + { + string fileName = Path.GetFileName(file); + string lowerName = ConvertToLowerPath(fileName); + File.Copy(file, Path.Combine(lowerTargetDir, lowerName), true); } - // 遍历源目录中的文件 - foreach (string file in Directory.GetFiles(sourceDir)) + // 递归处理子目录(带小写转换) + foreach (var dir in Directory.GetDirectories(sourceDir)) { - string destFile = Path.Combine(destinationDir, Path.GetFileName(file)); - File.Copy(file, destFile, true); // 覆盖已有文件 - } - - // 遍历源目录中的子文件夹 - foreach (string subDir in Directory.GetDirectories(sourceDir)) - { - string destSubDir = Path.Combine(destinationDir, Path.GetFileName(subDir)); - CopyDirectory(subDir, destSubDir); // 递归复制子文件夹 + string dirName = Path.GetFileName(dir); + string lowerDirName = ConvertToLowerPath(dirName); + CopyDirectoryWithLowerCaseNames(dir, Path.Combine(lowerTargetDir, lowerDirName)); } } -} + + // 中英文混合路径转小写 + private string ConvertToLowerPath(string input) + { + char[] chars = input.ToCharArray(); + for (int i = 0; i < chars.Length; i++) + { + // 只处理ASCII字母字符(中文等Unicode字符保持不变) + if (chars[i] >= 'A' && chars[i] <= 'Z') + { + chars[i] = (char)(chars[i] | 0x20); // 快速转小写 + } + } + return new string(chars); + } +} \ No newline at end of file