using System; using UnityEngine; using UnityEditor; using System.Collections.Generic; using System.Linq; using System.IO; using System.Text.RegularExpressions; using Object = UnityEngine.Object; /// /// 编辑器代码用工具类型 /// public static class EditorCommonUtility { // 不缓存AssetPaths,防止路径无法及时刷新导致更多问题 public static string[] AssetPaths { get { return AssetDatabase.GetAllAssetPaths(); } } private const string _assetHeader = "Assets"; private const string _metaExtension = ".meta"; /// /// 获得所有选中资源,包括文件夹中包含的部分 /// public static List GetItemsFromSelect() where T : Object { var result = new List(); var allPaths = GetAllAssetPathsFromSelect(); for (var i = 0; i < allPaths.Count; i++) { var item = AssetDatabase.LoadAssetAtPath(allPaths[i]); if (item != null) result.Add(item); } return result; } /// /// 获得所有选中资源中规定后缀名的路径,会迭代搜索路径 /// public static List GetPathsFromSelectByExtension(string extension, StringComparison comparisonType = StringComparison.Ordinal) { var result = new List(); if (!extension.Contains(".")) extension = "." + extension; var allPaths = GetAllAssetPathsFromSelect(); for (var i = 0; i < allPaths.Count; i++) { if (string.Equals(Path.GetExtension(allPaths[i]), extension, comparisonType)) result.Add(allPaths[i]); } return result; } /// /// 迭代获得路径下面,所有资源文件的路径 /// public static List GetAllAssetPathsFromSelect() { var allPaths = new List(); var assets = Selection.GetFiltered(typeof(Object), SelectionMode.Assets); for (var i = 0; i < assets.Length; i++) { var path = AssetDatabase.GetAssetPath(assets[i]); var containPaths = from assetPath in AssetPaths where assetPath.StartsWith(path) select assetPath; foreach (var containPath in containPaths) { if (!allPaths.Contains(containPath)) allPaths.Add(containPath); } } return allPaths; } private static int GetIndex(string[] array, string item) { var result = -1; for (var i = 0; i < array.Length; i++) if (array[i].Equals(item, StringComparison.OrdinalIgnoreCase)) { result = i; break; } return result; } public static string GetSafePath(string path) { path = path.ToUrl(); while (GetIndex(AssetPaths, path) >= 0) { var extension = Path.GetExtension(path); var name = string.IsNullOrEmpty(extension) ? path : path.Remove(path.Length - extension.Length); // Windows处理方式,名称添加副本 name += "-备份"; path = name; if (!string.IsNullOrEmpty(extension)) path += extension; } return path; } /// /// 修改文件名,保持路径不变 /// public static string SwitchFileNameInPath(string path, string newName) { var newFileName = Path.GetFileName(newName); if (newFileName == newName) { var fileName = Path.GetFileName(path); var directory = path.Remove(path.Length - fileName.Length - 1); // 有扩展名 if (Path.HasExtension(newName)) fileName = newFileName; else { var extension = Path.GetExtension(fileName); if (string.IsNullOrEmpty(extension)) fileName = newFileName; else fileName = newFileName + extension; } return (directory + "/" + fileName).ToUrl(); } else { Debug.LogError(string.Format("新名称{0}包括路径!", newName)); return path; } } public static int GetMaskCount(int source) { var sum = 0; while (source > 0) { sum++; source = source & (source - 1); } return sum; } /// /// 检查目标位置是否存在文件,如果存在,就将目标文件改名 /// public static bool RenameTargetFile(string targetFile) { var result = GetIndex(AssetPaths, targetFile) >= 0; if (result) { var safePath = GetSafePath(targetFile); AssetDatabase.MoveAsset(targetFile, safePath); AssetDatabase.Refresh(); Debug.LogWarning(string.Format("目标文件{0}已存在,现目标文件被改名为{1}!", targetFile, safePath)); } return result; } public static void MoveAsset(string source, string target) { if (!source.StartsWith(_assetHeader)) Debug.LogError("Source资源路径不是Assets路径 " + source); else if (!target.StartsWith(_assetHeader)) Debug.LogError("Target资源路径不是Assets路径 " + target); else { var sourceFile = Application.dataPath + source.Substring(_assetHeader.Length); var targetFile = Application.dataPath + target.Substring(_assetHeader.Length); MoveFile(sourceFile, targetFile); } } public static void MoveFile(string source, string target) { if (source != target) { var targetDir = Path.GetDirectoryName(target); if (string.IsNullOrEmpty(targetDir)) Debug.LogError("目标路径不存在!"); else { if (!Directory.Exists(targetDir)) Directory.CreateDirectory(targetDir); if (File.Exists(source + _metaExtension)) File.Move(source + _metaExtension, target + _metaExtension); File.Move(source, target); } } } /// /// 获得物品在AssetDatabase里面的完整路径 /// public static string GetAssetPath(this Object asset) { return AssetDatabase.GetAssetPath(asset); } /// /// 获得路径下的全部GameObject的列表 /// public static List GetGameObjects(Transform root) { var gameObjectList = new List(); while (root.parent != null) root = root.parent; GetGameObjectRecursively(root, gameObjectList); return gameObjectList; } public static void UpdateT4MTextureImporter(string path) { var importer = (TextureImporter)AssetImporter.GetAtPath(path); importer.isReadable = true; importer.textureCompression = TextureImporterCompression.Uncompressed; importer.textureFormat = TextureImporterFormat.ARGB32; importer.anisoLevel = 9; importer.mipmapEnabled = false; importer.wrapMode = TextureWrapMode.Clamp; importer.SaveAndReimport(); AssetDatabase.Refresh(); } public static string FileToAssetPath(string path) { var dataPath = Application.dataPath; if (path.StartsWith(dataPath)) path = AssetConst.nonInternalHeader + path.Substring(dataPath.Length + 1); return path; } public static string AssetToFilePath(string path) { const string assetHeader = "Assets/"; if (path.StartsWith(assetHeader)) path = path.Substring(assetHeader.Length); return Application.dataPath.Open(path); } public static void SetStaticRecursively(this GameObject gameObject, bool isStatic) { gameObject.isStatic = isStatic; foreach (Transform child in gameObject.transform) SetStaticRecursively(child.gameObject, isStatic); } private static readonly Regex _invalidPathRegex = new Regex(@"[^a-zA-Z\\/_]"); public static bool ContainInvalidPath(string source) { return _invalidPathRegex.IsMatch(source); } // public static Texture2D CreateUncompressedTexture(int width, int height, Color color, string path) // { // var texture = new Texture2D(width, height, TextureFormat.ARGB32, false); // var colors = new Color[width * height]; // for (var i = 0; i < colors.Length; i++) // colors[i] = color; // texture.SetPixels(colors); // var data = texture.EncodeToPNG(); // Object.DestroyImmediate(texture); // File.WriteAllBytes(path, data); // var textureImporter = (TextureImporter)AssetImporter.GetAtPath(path); // textureImporter.textureCompression = TextureImporterCompression.Uncompressed; // textureImporter.SaveAndReimport(); // return AssetDatabase.LoadAssetAtPath(path); // } // // public static void SaveChannelTexture(Texture2D texture) // { // var path = AssetDatabase.GetAssetPath(texture); // path = Application.dataPath + Path.DirectorySeparatorChar + path.Substring("Assets/".Length); // var data = texture.EncodeToPNG(); // File.WriteAllBytes(path, data); // var textureImporter = (TextureImporter)AssetImporter.GetAtPath(path); // textureImporter.textureCompression = TextureImporterCompression.Uncompressed; // textureImporter.SaveAndReimport(); // } // private static void GetGameObjectRecursively(Transform root, List gameObjectList) { gameObjectList.Add(root.gameObject); foreach (Transform child in root) GetGameObjectRecursively(child, gameObjectList); } public static void DeleteAllFiles(string path) { var info = new DirectoryInfo(path); foreach (var file in info.GetFiles()) file.Delete(); foreach (var dir in info.GetDirectories().Where(a => a.FullName != path)) dir.Delete(true); } } /// /// Unity中不同平台的名称字符串,用于PlatformTextureSettings相关 /// // 注:这东西和BuildTarget之类枚举的对应关系也不明确,无法很快关联这些诡异玩意 public static class PlatformName { public const string standalone = "Standalone"; public const string iPhone = "iPhone"; public const string android = "Android"; public const string webGl = "WebGL"; public const string windowStoreApp = "Windows Store Apps"; public const string ps4 = "PS4"; public const string xBoxOne = "XboxOne"; public const string nintendo3Ds = "Nintendo 3DS"; public const string tvOs = "tvOS"; public static string GetCurrentPlatformName() { return GetPlatformName(Application.platform); } public static string GetEditorPlatformName() { var buildTarget = EditorUserBuildSettings.activeBuildTarget; switch (buildTarget) { case BuildTarget.Android: return android; case BuildTarget.iOS: return iPhone; // 暂时不区分主机和WebGL - 现在不知道明确对应关系,也不需要这些平台 default: return standalone; } } public static string GetPlatformName(RuntimePlatform platform) { switch (platform) { case RuntimePlatform.Android: return android; case RuntimePlatform.IPhonePlayer: return iPhone; // 暂时不区分主机和WebGL - 现在不知道明确对应关系,也不需要这些平台 default: return standalone; } } }