using XGame.Framework.Asset.Addressable; using XGame.Framework.Asset.Addressable.Data; using System; using System.Collections.Generic; using System.Linq; using UnityEditor; using UnityEngine; namespace XGame.Editor.Asset { public static class AddressableInfosSoExt { #region AddressableAssetInfoManifest /// /// 编辑器扩展方法 /// 返回manifest内已有数据 /// /// /// public static List GetAssetInfos(this AddressableInfosSo manifest) { if (manifest != null && manifest.assetInfos != null) { return manifest.assetInfos.Distinct().ToList(); } //var fileInfo = manifest.GetType().GetField("assetInfos", BindingFlags.NonPublic | BindingFlags.Instance); //if (fileInfo != null) //{ // var infos = (AssetInfo[])fileInfo.GetValue(manifest); // if (infos != null) // { // return infos.Distinct().ToList(); // } //} return new List(); } /// /// 返回以GUID做key的字典 /// /// /// public static Dictionary GetAssetInfoMapWithGUID(this AddressableInfosSo manifest) { var map = new Dictionary(); if (manifest != null && manifest.assetInfos != null) { foreach (var info in manifest.assetInfos) { var guid = info.assetGUID; if (!map.ContainsKey(guid)) { map.Add(guid, info); } else { Debug.LogError($"AssetInfo repeated. Last:{map[guid]} Next:{info}"); } } } return map; } /// /// 返回以addressableName做key的字典 /// /// /// public static Dictionary GetAssetInfoMapWithAddressableName(this AddressableInfosSo manifest) { var map = new Dictionary(); if (manifest != null && manifest.assetInfos != null) { foreach (var info in manifest.assetInfos) { map.Add(info.addressableName, info); } } return map; } /// /// 编辑器扩展方法 /// 设置AddressableAssetInfo数组 /// /// /// public static void SetAssetInfos(this AddressableInfosSo manifest, AssetInfo[] assetInfos) { if (manifest == null) return; if (assetInfos != null) { assetInfos = assetInfos.Distinct().ToArray(); Array.Sort(assetInfos); } manifest.assetInfos = assetInfos; EditorUtility.SetDirty(manifest); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } /// /// 编辑器扩展方法 /// 根据GUID查找addressableName /// /// /// /// /// public static bool TryGetAddressableNameByGUID(this AddressableInfosSo manifest, string guid, out string addressableName) { addressableName = string.Empty; if (manifest != null && manifest.assetInfos != null) { var index = Array.FindIndex(manifest.assetInfos, (info => info.assetGUID.Equals(guid))); if (index < 0) { return false; } addressableName = manifest.assetInfos[index].addressableName; } return true; } /// /// 编辑器扩展方法 /// 修改某个资源的addressableName /// /// /// /// /// /// public static bool TryApplyAddressableName(this AddressableInfosSo manifest, string guid, string addressableName, out AssetInfo assetInfo) { var assetInfos = manifest.assetInfos; //转成小写 addressableName = addressableName.ToLower(); //检查重名 var idxForName = Array.FindIndex(assetInfos, (info => info.addressableName.Equals(addressableName))); var idxForGUID = Array.FindIndex(assetInfos, (info => info.assetGUID.Equals(guid))); if (idxForName >= 0) { if (idxForGUID != idxForName) { Debug.LogError($"AddressableName repeat. Please rename it. Name:{addressableName} Path:{AssetDatabase.GUIDToAssetPath(guid)}"); } else { Debug.Log($"Asset info hasn't changed."); } assetInfo = default; return false; } if (idxForGUID >= 0) { assetInfo = assetInfos[idxForGUID]; assetInfo.addressableName = addressableName; assetInfos[idxForGUID] = assetInfo; //保存 manifest.SetAssetInfos(assetInfos); Debug.Log($"Apply AddressableName Success. Path:{assetInfo.GetAssetPath()} AddressableName:{addressableName}"); return true; } Debug.LogError("Can't Find Asset."); assetInfo = default; return false; } /// /// 编辑器扩展方法 /// 删除指定资源信息 /// /// /// /// public static bool TryRemoveAssetByGUID(this AddressableInfosSo manifest, string guid) { if (manifest.assetInfos == null || manifest.assetInfos.Length == 0) { Debug.Log($"AddressableInfosSo is null. Name:{manifest.name}"); return false; } var assetInfos = manifest.assetInfos.ToList(); var idxForGUID = assetInfos.FindIndex((info => info.assetGUID.Equals(guid))); if (idxForGUID == -1) { Debug.Log($"Can't find assetInfo by GUID:{guid}"); return false; } var assetInfo = assetInfos[idxForGUID]; assetInfos.RemoveAt(idxForGUID); //保存 manifest.SetAssetInfos(assetInfos.ToArray()); //EditorUtility.SetDirty(manifest); //AssetDatabase.SaveAssets(); //AssetDatabase.Refresh(); Debug.Log($"RemoveAsset Success. {assetInfo}"); return true; } public static bool RemoveAllInvalidAssets(this AddressableInfosSo manifest) { var assetInfos = manifest.assetInfos; if (assetInfos == null || assetInfos.Length == 0) { Debug.Log($"AddressableInfosSo is null. Name:{manifest.name}"); return false; } var validAssetInfos = Array.FindAll(assetInfos, (info => AddressableHelper.IsValidPath(info.GetAssetPath()))); if (assetInfos.Length == validAssetInfos.Length) { Debug.Log("No find invalid assets."); return false; } //保存 manifest.SetAssetInfos(validAssetInfos); //EditorUtility.SetDirty(manifest); //AssetDatabase.SaveAssets(); //AssetDatabase.Refresh(); Debug.Log("RemoveAllInvalidAssets Success."); return true; } #endregion #region i18n 国际化/本地化/多语言 public static void SetAddressableI18nInfos(this AddressableInfosSo manifest, AddressableI18nInfo[] i18nInfos, bool refresh = true) { if (manifest == null) return; manifest.i18nInfos = i18nInfos; if (refresh) { EditorUtility.SetDirty(manifest); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } } #endregion #region LOD public static void SetAddressableLodInfos(this AddressableInfosSo manifest, AddressableLodInfo[] lodInfos, bool refresh = true) { if (manifest == null) return; manifest.lodInfos = lodInfos; if (refresh) { EditorUtility.SetDirty(manifest); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } } #endregion } }