using UnityEditor; using UnityEngine; using System; using UnityEditor.U2D.PSD; namespace AibisDream.SystemEditor { public static class EditorKit { public static readonly GUIStyle BoldFont = new(EditorStyles.label) { fontStyle = FontStyle.Bold }; public static int SortingLayerField(string label, int id) { // 先获取layer var layers = GetSortingLayerNames(); // 将ID转为idx var idx = TransSortingLayer2Idx(id); var newIdx = EditorGUILayout.Popup(label, idx, layers); return TransIdx2SortingLayer(newIdx); } /// /// 使用 SerializedProperty 绘制 SortingLayer 下拉菜单(基于ID) /// /// 显示的标签 /// 存储排序层ID的 SerializedProperty(int 类型) public static void SortingLayerField(GUIContent label, SerializedProperty property) { if (property == null || property.propertyType != SerializedPropertyType.Integer) { EditorGUILayout.HelpBox("Property must be an integer type for sorting layer ID.", MessageType.Error); return; } EditorGUI.BeginChangeCheck(); // 获取所有排序层名称 string[] sortingLayerNames = GetSortingLayerNames(); // 将当前ID转为索引 int currentId = property.intValue; int currentIndex = TransSortingLayer2Idx(currentId); // 显示下拉菜单 int newIndex = EditorGUILayout.Popup(label, currentIndex, sortingLayerNames); // 如果选择了新的排序层,更新属性值为新的ID if (EditorGUI.EndChangeCheck() || newIndex != currentIndex) { int newId = TransIdx2SortingLayer(newIndex); property.intValue = newId; } } private static string[] GetSortingLayerNames() { // 获取所有 Sorting Layer 名称 var layerCount = SortingLayer.layers.Length; var sortingLayerNames = new string[layerCount]; for (var i = 0; i < layerCount; i++) { sortingLayerNames[i] = SortingLayer.layers[i].name; } return sortingLayerNames; } private static int TransSortingLayer2Idx(int id) { var layers = SortingLayer.layers; for (var i = 0; i < layers.Length; i++) { if (layers[i].id == id) return i; } return 0; } private static int TransIdx2SortingLayer(int idx) { if (idx < 0 || idx >= SortingLayer.layers.Length) { return SortingLayer.layers[0].id; } return SortingLayer.layers[idx].id; } public static void RecordObjectAndChildren(GameObject parent, string actionName) { Transform[] transforms = parent.GetComponentsInChildren(true); UnityEngine.Object[] objectsToUndo = new UnityEngine.Object[transforms.Length]; for (int i = 0; i < transforms.Length; i++) { objectsToUndo[i] = transforms[i].gameObject; } Undo.RegisterCompleteObjectUndo(objectsToUndo, actionName); } public static string SaveSprite(Sprite sprite) { if (!sprite) return ""; string psdPath = AssetDatabase.GetAssetPath(sprite); var psdResPath = GetResourcePath(psdPath); int lastDotIndex = psdResPath.LastIndexOf('.'); if (lastDotIndex == -1) return psdResPath; var purePath = psdResPath.Substring(0, lastDotIndex); return purePath + "/" + sprite.name; } private static string GetResourcePath(string absolutePath) { const string resourcesFolderName = "Resources/"; var index = absolutePath.IndexOf(resourcesFolderName, StringComparison.Ordinal); return index >= 0 ? absolutePath[(index + resourcesFolderName.Length)..] : absolutePath; } public static bool GetAssetAddressableKey(T asset, out string addressableKey) where T : UnityEngine.Object { string path = AssetDatabase.GetAssetPath(asset); if (asset is Sprite sprite && AssetImporter.GetAtPath(path) is TextureImporter importer) { if (importer.textureType == TextureImporterType.Sprite && importer.spriteImportMode == SpriteImportMode.Multiple) { if (TryGetAddressableKey(path, out var addressableKeyPrefix)) { addressableKey = $"{addressableKeyPrefix}[{sprite.name}]"; return true; } addressableKey = addressableKeyPrefix; return false; } } else if (asset is Sprite texture && AssetImporter.GetAtPath(path) is PSDImporter) { if (TryGetAddressableKey(path, out var addressableKeyPrefix)) { addressableKey = $"{addressableKeyPrefix}[{texture.name}]"; return true; } addressableKey = addressableKeyPrefix; return false; } return TryGetAddressableKey(path, out addressableKey); } private static bool TryGetAddressableKey(string path, out string addressableKey) { var settings = UnityEditor.AddressableAssets.AddressableAssetSettingsDefaultObject.Settings; if (settings != null) { var entry = settings.FindAssetEntry(AssetDatabase.AssetPathToGUID(path)); if (entry != null) { addressableKey = entry.address; return true; } } Debug.Log($"资源{path}不存在于Addressables中"); addressableKey = path; return false; } } }