355 lines
12 KiB
C#
355 lines
12 KiB
C#
using System;
|
||
using UnityEngine;
|
||
using UnityEditor;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.IO;
|
||
using System.Text.RegularExpressions;
|
||
using Object = UnityEngine.Object;
|
||
|
||
/// <summary>
|
||
/// 编辑器代码用工具类型
|
||
/// </summary>
|
||
public static class EditorCommonUtility
|
||
{
|
||
// 不缓存AssetPaths,防止路径无法及时刷新导致更多问题
|
||
public static string[] AssetPaths
|
||
{
|
||
get
|
||
{
|
||
return AssetDatabase.GetAllAssetPaths();
|
||
}
|
||
}
|
||
|
||
private const string _assetHeader = "Assets";
|
||
private const string _metaExtension = ".meta";
|
||
/// <summary>
|
||
/// 获得所有选中资源,包括文件夹中包含的部分
|
||
/// </summary>
|
||
public static List<T> GetItemsFromSelect<T>() where T : Object
|
||
{
|
||
var result = new List<T>();
|
||
var allPaths = GetAllAssetPathsFromSelect();
|
||
for (var i = 0; i < allPaths.Count; i++)
|
||
{
|
||
var item = AssetDatabase.LoadAssetAtPath<T>(allPaths[i]);
|
||
if (item != null)
|
||
result.Add(item);
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获得所有选中资源中规定后缀名的路径,会迭代搜索路径
|
||
/// </summary>
|
||
public static List<string> GetPathsFromSelectByExtension(string extension, StringComparison comparisonType = StringComparison.Ordinal)
|
||
{
|
||
var result = new List<string>();
|
||
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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 迭代获得路径下面,所有资源文件的路径
|
||
/// </summary>
|
||
public static List<string> GetAllAssetPathsFromSelect()
|
||
{
|
||
var allPaths = new List<string>();
|
||
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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 修改文件名,保持路径不变
|
||
/// </summary>
|
||
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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 检查目标位置是否存在文件,如果存在,就将目标文件改名
|
||
/// </summary>
|
||
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);
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获得物品在AssetDatabase里面的完整路径
|
||
/// </summary>
|
||
public static string GetAssetPath(this Object asset)
|
||
{
|
||
return AssetDatabase.GetAssetPath(asset);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获得路径下的全部GameObject的列表
|
||
/// </summary>
|
||
public static List<GameObject> GetGameObjects(Transform root)
|
||
{
|
||
var gameObjectList = new List<GameObject>();
|
||
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<Texture2D>(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<GameObject> 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);
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// Unity中不同平台的名称字符串,用于PlatformTextureSettings相关
|
||
/// </summary>
|
||
// 注:这东西和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;
|
||
}
|
||
}
|
||
} |