using System; using System.Linq; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; using AibisDream.Utility; using UnityEditor.U2D.PSD; #if UNITY_EDITOR using UnityEditor; #endif namespace AibisDream.Framework { public static class ResourceKit { public static string SaveSprite(Sprite sprite) { #if UNITY_EDITOR if (!sprite) return ""; // 先读Psd的路径 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; #else return null; #endif } 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 Sprite LoadSpriteFromPsd(string path) { int lastIndex = path.LastIndexOf('/'); string spriteName = path[(lastIndex + 1)..]; string resPath = path[..lastIndex]; // 加载 var sprites = Resources.LoadAll(resPath); return sprites.FirstOrDefault(sprite => sprite.name == spriteName); } public static T LoadAssetSync(string key) where T : UnityEngine.Object { var operation = Addressables.LoadAssetAsync(key); operation.WaitForCompletion(); if (operation.Status == AsyncOperationStatus.Succeeded) { return operation.Result; } else { Debug.Log($"资源{key}不存在"); return default; } } public static void LoadAssetAsync(string key, Action callback) where T : UnityEngine.Object { Addressables.LoadAssetAsync(key).Completed += operation => { if (operation.Status == AsyncOperationStatus.Succeeded) { callback(operation.Result); } else { Debug.Log($"资源{key}不存在"); } }; } /// /// 异步加载 Addressable 资源,callback 接收完整 handle。调用方需在适当时机调用 Release 释放。 /// public static void LoadAssetAsyncWithHandle(string key, Action> callback) where T : UnityEngine.Object { var handle = Addressables.LoadAssetAsync(key); handle.Completed += operation => { if (operation.Status != AsyncOperationStatus.Succeeded) { Debug.Log($"资源{key}不存在"); } callback(operation); }; } /// /// 释放 Addressable 加载的 handle /// public static void Release(AsyncOperationHandle handle) { if (handle.IsValid()) Addressables.Release(handle); } #if UNITY_EDITOR public static bool GetAssetAddressableKey(T asset, out string addressableKey) where T : UnityEngine.Object { string path = AssetDatabase.GetAssetPath(asset); // 如果是Sprite,并且是Multiple模式,则单独处理 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; } else { addressableKey = addressableKeyPrefix; return false; } } } else if (asset is Sprite texture && AssetImporter.GetAtPath(path) is PSDImporter psdImporter) { if (TryGetAddressableKey(path, out var addressableKeyPrefix)) { addressableKey = $"{addressableKeyPrefix}[{texture.name}]"; return true; } else { addressableKey = addressableKeyPrefix; return false; } } // 其他情况正常输出 return TryGetAddressableKey(path, out addressableKey); } private static bool TryGetAddressableKey(string path, out string addressableKey) { // 获取其在Addressables里的路径 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; } #endif } }